From aecf5e321cf4c855c8a74ef192aa954397b06d5d Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 30 May 2025 20:07:01 +0200 Subject: [PATCH] feat(engine): allow configuring tree to always use state root fallback (#16569) --- book/cli/reth/node.md | 3 +++ crates/engine/primitives/src/config.rs | 16 ++++++++++++++++ crates/engine/tree/src/tree/mod.rs | 13 ++++++++++--- crates/node/core/src/args/engine.rs | 6 ++++++ 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/book/cli/reth/node.md b/book/cli/reth/node.md index 251ae8af76..4fa733ffb2 100644 --- a/book/cli/reth/node.md +++ b/book/cli/reth/node.md @@ -768,6 +768,9 @@ Engine: --engine.precompile-cache Enable precompile cache + --engine.state-root-fallback + Enable state root fallback, useful for testing + Ress: --ress.enable Enable support for `ress` subprotocol diff --git a/crates/engine/primitives/src/config.rs b/crates/engine/primitives/src/config.rs index d34c1addeb..87c059ad1f 100644 --- a/crates/engine/primitives/src/config.rs +++ b/crates/engine/primitives/src/config.rs @@ -77,6 +77,8 @@ pub struct TreeConfig { reserved_cpu_cores: usize, /// Whether to enable the precompile cache precompile_cache_enabled: bool, + /// Whether to use state root fallback for testing + state_root_fallback: bool, } impl Default for TreeConfig { @@ -96,6 +98,7 @@ impl Default for TreeConfig { max_proof_task_concurrency: DEFAULT_MAX_PROOF_TASK_CONCURRENCY, reserved_cpu_cores: DEFAULT_RESERVED_CPU_CORES, precompile_cache_enabled: false, + state_root_fallback: false, } } } @@ -118,6 +121,7 @@ impl TreeConfig { max_proof_task_concurrency: u64, reserved_cpu_cores: usize, precompile_cache_enabled: bool, + state_root_fallback: bool, ) -> Self { Self { persistence_threshold, @@ -134,6 +138,7 @@ impl TreeConfig { max_proof_task_concurrency, reserved_cpu_cores, precompile_cache_enabled, + state_root_fallback, } } @@ -204,6 +209,11 @@ impl TreeConfig { self.precompile_cache_enabled } + /// Returns whether to use state root fallback. + pub const fn state_root_fallback(&self) -> bool { + self.state_root_fallback + } + /// Setter for persistence threshold. pub const fn with_persistence_threshold(mut self, persistence_threshold: u64) -> Self { self.persistence_threshold = persistence_threshold; @@ -307,6 +317,12 @@ impl TreeConfig { self } + /// Setter for whether to use state root fallback, useful for testing. + pub const fn with_state_root_fallback(mut self, state_root_fallback: bool) -> Self { + self.state_root_fallback = state_root_fallback; + self + } + /// Whether or not to use state root task pub const fn use_state_root_task(&self) -> bool { self.has_enough_parallelism && !self.legacy_state_root diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 6fbdfdb923..ce6ab48910 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -2077,7 +2077,9 @@ where // // See https://github.com/paradigmxyz/reth/issues/12688 for more details let persisting_kind = self.persisting_kind_for(block.header()); - let run_parallel_state_root = persisting_kind.can_run_parallel_state_root(); + // don't run parallel if state root fallback is set + let run_parallel_state_root = + persisting_kind.can_run_parallel_state_root() && !self.config.state_root_fallback(); // use prewarming background task let header = block.clone_sealed_header(); @@ -2215,8 +2217,13 @@ where maybe_state_root } else { // fallback is to compute the state root regularly in sync - warn!(target: "engine::tree", block=?block_num_hash, ?persisting_kind, "Failed to compute state root in parallel"); - self.metrics.block_validation.state_root_parallel_fallback_total.increment(1); + if self.config.state_root_fallback() { + debug!(target: "engine::tree", block=?block_num_hash, "Using state root fallback for testing"); + } else { + warn!(target: "engine::tree", block=?block_num_hash, ?persisting_kind, "Failed to compute state root in parallel"); + self.metrics.block_validation.state_root_parallel_fallback_total.increment(1); + } + let (root, updates) = ensure_ok!(state_provider.state_root_with_updates(hashed_state.clone())); (root, updates, root_time.elapsed()) diff --git a/crates/node/core/src/args/engine.rs b/crates/node/core/src/args/engine.rs index 783e37dcfa..381771d8b5 100644 --- a/crates/node/core/src/args/engine.rs +++ b/crates/node/core/src/args/engine.rs @@ -63,6 +63,10 @@ pub struct EngineArgs { /// Enable precompile cache #[arg(long = "engine.precompile-cache", default_value = "false")] pub precompile_cache_enabled: bool, + + /// Enable state root fallback, useful for testing + #[arg(long = "engine.state-root-fallback", default_value = "false")] + pub state_root_fallback: bool, } impl Default for EngineArgs { @@ -80,6 +84,7 @@ impl Default for EngineArgs { max_proof_task_concurrency: DEFAULT_MAX_PROOF_TASK_CONCURRENCY, reserved_cpu_cores: DEFAULT_RESERVED_CPU_CORES, precompile_cache_enabled: false, + state_root_fallback: false, } } } @@ -98,6 +103,7 @@ impl EngineArgs { .with_max_proof_task_concurrency(self.max_proof_task_concurrency) .with_reserved_cpu_cores(self.reserved_cpu_cores) .with_precompile_cache_enabled(self.precompile_cache_enabled) + .with_state_root_fallback(self.state_root_fallback) } }