diff --git a/node/src/daser.rs b/node/src/daser.rs index b33f6064..518ca31a 100644 --- a/node/src/daser.rs +++ b/node/src/daser.rs @@ -49,11 +49,6 @@ use crate::p2p::{P2p, P2pError}; use crate::store::{BlockRanges, SamplingStatus, Store, StoreError}; const MAX_SAMPLES_NEEDED: usize = 16; - -const HOUR: u64 = 60 * 60; -const DAY: u64 = 24 * HOUR; -pub const DEFAULT_SAMPLING_WINDOW: Duration = Duration::from_secs(30 * DAY); -pub const MIN_SAMPLING_WINDOW: Duration = Duration::from_secs(60); const GET_SAMPLE_TIMEOUT: Duration = Duration::from_secs(10); type Result = std::result::Result; diff --git a/node/src/node.rs b/node/src/node.rs index 1b4ac6ad..dd28f248 100644 --- a/node/src/node.rs +++ b/node/src/node.rs @@ -32,11 +32,14 @@ use crate::syncer::{Syncer, SyncerArgs}; mod builder; -pub use self::builder::NodeBuilder; +pub use self::builder::{ + NodeBuilder, NodeBuilderError, DEFAULT_PRUNING_DELAY, DEFAULT_SAMPLING_WINDOW, + DEFAULT_SYNCING_WINDOW, MIN_PRUNING_DELAY, MIN_SAMPLING_WINDOW, MIN_SYNCING_WINDOW, +}; pub use crate::daser::DaserError; pub use crate::p2p::{HeaderExError, P2pError}; pub use crate::peer_tracker::PeerTrackerInfo; -pub use crate::syncer::{SyncerError, SyncingInfo, DEFAULT_SYNCING_WINDOW}; +pub use crate::syncer::{SyncerError, SyncingInfo}; /// Alias of [`Result`] with [`NodeError`] error type /// @@ -46,6 +49,10 @@ pub type Result = std::result::Result; /// Representation of all the errors that can occur when interacting with the [`Node`]. #[derive(Debug, thiserror::Error)] pub enum NodeError { + /// An error propagated from the [`NodeBuilder`] component. + #[error("NodeBuilder: {0}")] + NodeBuilder(#[from] NodeBuilderError), + /// An error propagated from the `P2p` component. #[error("P2p: {0}")] P2p(#[from] P2pError), diff --git a/node/src/node/builder.rs b/node/src/node/builder.rs index f17de9d6..070731aa 100644 --- a/node/src/node/builder.rs +++ b/node/src/node/builder.rs @@ -7,14 +7,28 @@ use libp2p::Multiaddr; use tracing::{info, warn}; use crate::blockstore::InMemoryBlockstore; -use crate::daser::{DEFAULT_SAMPLING_WINDOW, MIN_SAMPLING_WINDOW}; use crate::events::EventSubscriber; use crate::network::Network; -use crate::node::DEFAULT_SYNCING_WINDOW; use crate::node::{Node, NodeConfig, Result}; -use crate::pruner::{DEFAULT_PRUNING_DELAY, MIN_PRUNING_DELAY}; use crate::store::{InMemoryStore, Store}; -use crate::syncer::MIN_SYNCING_WINDOW; + +const HOUR: u64 = 60 * 60; +const DAY: u64 = 24 * HOUR; + +/// Default maximum age of block headers [`Node`] will synchronise and store. +pub const DEFAULT_SYNCING_WINDOW: Duration = Duration::from_secs(30 * DAY); +/// Minimum configurable syncing window that can be used in [`NodeBuilder`]. +pub const MIN_SYNCING_WINDOW: Duration = Duration::from_secs(60); + +/// Default maximum age of block [`Node`] will sample and store. +pub const DEFAULT_SAMPLING_WINDOW: Duration = Duration::from_secs(30 * DAY); +/// Minimum configurable sampling window that can be used in [`NodeBuilder`]. +pub const MIN_SAMPLING_WINDOW: Duration = Duration::from_secs(60); + +/// Default delay after the syncing window before [`Node`] prunes the block. +pub const DEFAULT_PRUNING_DELAY: Duration = Duration::from_secs(HOUR); +/// Minimum pruning delay that can be used in [`NodeBuilder`]. +pub const MIN_PRUNING_DELAY: Duration = Duration::from_secs(60); /// [`Node`] builder. pub struct NodeBuilder @@ -34,6 +48,22 @@ where pruning_delay: Option, } +/// Representation of all the errors that can occur when interacting with the [`NodeBuilder`]. +#[derive(Debug, thiserror::Error)] +pub enum NodeBuilderError { + /// Syncing window is smaller than [`MIN_SYNCING_WINDOW`]. + #[error("Syncing window is {0:?} but cannot be smaller than {MIN_SYNCING_WINDOW:?}")] + VerySmallSynincWindow(Duration), + + /// Sampling window is smaller than [`MIN_SAMPLING_WINDOW`]. + #[error("Sampling window is {0:?} but cannot be smaller than {MIN_SAMPLING_WINDOW:?}")] + VerySmallSamplingWindow(Duration), + + /// Sampling window is smaller than [`MIN_PRUNING_DELAY`]. + #[error("Pruning delay is {0:?} but cannot be smaller than {MIN_PRUNING_DELAY:?}")] + VerySmallPruningDelay(Duration), +} + impl NodeBuilder { /// Creates a new [`NodeBuilder`] that is using in-memory stores. /// @@ -195,8 +225,8 @@ where /// Syncing window defines maximum age of headers considered for syncing. /// Headers older than syncing window by more than an hour are eligible for pruning. /// - /// **Default if [`InMemoryStore`] is used:** 60 seconds. - /// **Default:** 30 days. + /// **Default if [`InMemoryStore`] is used:** 60 seconds.\ + /// **Default:** 30 days.\ /// **Minimum:** 60 seconds. pub fn syncing_window(self, dur: Duration) -> Self { NodeBuilder { @@ -210,8 +240,8 @@ where /// Sampling window defines the maximum age of a block considered for sampling. /// Sampling window will be truncated to syncing window, if latter is smaller. /// - /// **Default if [`InMemoryBlockstore`] is used:** 60 seconds. - /// **Default:** 30 days. + /// **Default if [`InMemoryBlockstore`] is used:** 60 seconds.\ + /// **Default:** 30 days.\ /// **Minimum:** 60 seconds. pub fn sampling_window(self, dur: Duration) -> Self { NodeBuilder { @@ -225,8 +255,8 @@ where /// Pruning delay how much time the pruner should wait after syncing window in /// order to prune the block. /// - /// **Default if [`InMemoryStore`] is used: 60 seconds. - /// **Default:** 1 hour. + /// **Default if [`InMemoryStore`] is used:** 60 seconds.\ + /// **Default:** 1 hour.\ /// **Minimum:** 60 seconds. pub fn pruning_delay(self, dur: Duration) -> Self { NodeBuilder { @@ -235,7 +265,7 @@ where } } - fn build_config(self) -> Result> { + fn build_config(self) -> Result, NodeBuilderError> { let network = self.network.expect("todo"); let bootnodes = if self.bootnodes.is_empty() { @@ -286,18 +316,18 @@ where }; if syncing_window < MIN_SYNCING_WINDOW { - panic!("todo"); + return Err(NodeBuilderError::VerySmallSynincWindow(syncing_window)); } // Truncate sampling window if needed. let sampling_window = sampling_window.min(syncing_window); if sampling_window < MIN_SAMPLING_WINDOW { - panic!("todo"); + return Err(NodeBuilderError::VerySmallSamplingWindow(sampling_window)); } if pruning_delay < MIN_PRUNING_DELAY { - panic!("todo"); + return Err(NodeBuilderError::VerySmallPruningDelay(pruning_delay)); } let pruning_window = syncing_window.saturating_add(pruning_delay); diff --git a/node/src/pruner.rs b/node/src/pruner.rs index 9f40ffc5..b0e05619 100644 --- a/node/src/pruner.rs +++ b/node/src/pruner.rs @@ -13,10 +13,6 @@ use crate::executor::{sleep, spawn, JoinHandle}; use crate::p2p::P2pError; use crate::store::{Store, StoreError}; -// pruning window is 1 hour behind the end of the syncing window -pub const DEFAULT_PRUNING_DELAY: Duration = Duration::from_secs(60 * 60); -pub const MIN_PRUNING_DELAY: Duration = Duration::from_secs(60); - pub const DEFAULT_PRUNING_INTERVAL: Duration = Duration::from_secs(12); type Result = std::result::Result; diff --git a/node/src/syncer.rs b/node/src/syncer.rs index 573772b0..82513200 100644 --- a/node/src/syncer.rs +++ b/node/src/syncer.rs @@ -35,10 +35,6 @@ use crate::utils::{FusedReusableFuture, OneshotSenderExt}; type Result = std::result::Result; const TRY_INIT_BACKOFF_MAX_INTERVAL: Duration = Duration::from_secs(60); -/// Default maximum age of headers Lumina will synchronise and store -pub const DEFAULT_SYNCING_WINDOW: Duration = Duration::from_secs(30 * 24 * 60 * 60); // 30 days - -pub const MIN_SYNCING_WINDOW: Duration = Duration::from_secs(60); /// Representation of all the errors that can occur in `Syncer` component. #[derive(Debug, thiserror::Error)]