From c10b0dd7fbad29b7cdf5272347f82ae8e2cf369e Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Thu, 13 Mar 2025 22:39:38 +0100 Subject: [PATCH] feat(ress): max witness window (#15029) --- bin/reth/src/ress.rs | 3 ++- book/cli/reth/node.md | 5 +++++ crates/node/core/src/args/ress_args.rs | 8 ++++++++ crates/ress/provider/src/lib.rs | 19 +++++++++++++++---- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/bin/reth/src/ress.rs b/bin/reth/src/ress.rs index a42bbe1f99..0eb8480fd4 100644 --- a/bin/reth/src/ress.rs +++ b/bin/reth/src/ress.rs @@ -41,9 +41,10 @@ where provider, block_executor, Box::new(task_executor.clone()), - pending_state, + args.max_witness_window, args.witness_max_parallel, args.witness_cache_size, + pending_state, )?; network.add_rlpx_sub_protocol( RessProtocolHandler { diff --git a/book/cli/reth/node.md b/book/cli/reth/node.md index 407b375139..f5f780af1f 100644 --- a/book/cli/reth/node.md +++ b/book/cli/reth/node.md @@ -730,6 +730,11 @@ Ress: [default: 5] + --ress.max-witness-window + The maximum witness lookback window + + [default: 1024] + --ress.witness-max-parallel The maximum number of witnesses to generate in parallel diff --git a/crates/node/core/src/args/ress_args.rs b/crates/node/core/src/args/ress_args.rs index 4b9cfbb631..74b4ff64bc 100644 --- a/crates/node/core/src/args/ress_args.rs +++ b/crates/node/core/src/args/ress_args.rs @@ -3,6 +3,9 @@ use clap::Args; /// The default number of maximum active connections. const MAX_ACTIVE_CONNECTIONS_DEFAULT: u64 = 5; +/// The default maximum witness lookback window. +const MAX_WITNESS_WINDOW_DEFAULT: u64 = 1024; + /// The default maximum number of witnesses to generate in parallel. const WITNESS_MAX_PARALLEL_DEFAULT: usize = 5; @@ -21,6 +24,10 @@ pub struct RessArgs { #[arg(long = "ress.max-active-connections", default_value_t = MAX_ACTIVE_CONNECTIONS_DEFAULT)] pub max_active_connections: u64, + /// The maximum witness lookback window. + #[arg(long = "ress.max-witness-window", default_value_t = MAX_WITNESS_WINDOW_DEFAULT)] + pub max_witness_window: u64, + /// The maximum number of witnesses to generate in parallel. #[arg(long = "ress.witness-max-parallel", default_value_t = WITNESS_MAX_PARALLEL_DEFAULT)] pub witness_max_parallel: usize, @@ -35,6 +42,7 @@ impl Default for RessArgs { Self { enabled: false, max_active_connections: MAX_ACTIVE_CONNECTIONS_DEFAULT, + max_witness_window: MAX_WITNESS_WINDOW_DEFAULT, witness_max_parallel: WITNESS_MAX_PARALLEL_DEFAULT, witness_cache_size: WITNESS_CACHE_SIZE_DEFAULT, } diff --git a/crates/ress/provider/src/lib.rs b/crates/ress/provider/src/lib.rs index c4b5758e9b..cbc44c93c2 100644 --- a/crates/ress/provider/src/lib.rs +++ b/crates/ress/provider/src/lib.rs @@ -31,9 +31,10 @@ pub struct RethRessProtocolProvider { provider: P, block_executor: E, task_spawner: Box, - pending_state: PendingState, + max_witness_window: u64, witness_semaphore: Arc, witness_cache: Arc>>>>, + pending_state: PendingState, } impl Clone for RethRessProtocolProvider { @@ -42,9 +43,10 @@ impl Clone for RethRessProtocolProvider { provider: self.provider.clone(), block_executor: self.block_executor.clone(), task_spawner: self.task_spawner.clone(), - pending_state: self.pending_state.clone(), + max_witness_window: self.max_witness_window, witness_semaphore: self.witness_semaphore.clone(), witness_cache: self.witness_cache.clone(), + pending_state: self.pending_state.clone(), } } } @@ -59,17 +61,19 @@ where provider: P, block_executor: E, task_spawner: Box, - pending_state: PendingState, + max_witness_window: u64, witness_max_parallel: usize, cache_size: u32, + pending_state: PendingState, ) -> eyre::Result { Ok(Self { provider, block_executor, task_spawner, - pending_state, + max_witness_window, witness_semaphore: Arc::new(Semaphore::new(witness_max_parallel)), witness_cache: Arc::new(Mutex::new(LruMap::new(ByLength::new(cache_size)))), + pending_state, }) } @@ -103,6 +107,13 @@ where let block = self.block_by_hash(block_hash)?.ok_or(ProviderError::BlockHashNotFound(block_hash))?; + let best_block_number = self.provider.best_block_number()?; + if best_block_number.saturating_sub(block.number()) > self.max_witness_window { + return Err(ProviderError::TrieWitnessError( + "witness target block exceeds maximum witness window".to_owned(), + )) + } + let mut executed_ancestors = Vec::new(); let mut ancestor_hash = block.parent_hash(); let historical = 'sp: loop {