Describe the bug
I noticed that when --engine.legacy-state-root is enabled, the cache prewarming for multiproof is entirely disabled.
This is due to the logic in insert_block_inner, where spawn_cache_exclusive() is used if use_state_root_task is true and trie_input.prefix_sets is empty.
let mut handle = if use_state_root_task {
// ....
// Use state root task only if prefix sets are empty, otherwise proof generation is too
// expensive because it requires walking over the paths in the prefix set in every
// proof.
if trie_input.prefix_sets.is_empty() {
self.payload_processor.spawn(
header,
txs,
provider_builder,
consistent_view,
trie_input,
&self.config,
)
} else {
debug!(target: "engine::tree", block=?block_num_hash, "Disabling state root task due to non-empty prefix sets");
use_state_root_task = false;
self.payload_processor.spawn_cache_exclusive(header, txs, provider_builder)
}
} else {
self.payload_processor.spawn_cache_exclusive(header, txs, provider_builder)
};
In that case, to_multi_proof is always set to None, so no prewarming happens for multiproof targets.
// crates/engine/tree/src/tree/payload_processor/mod.rs:250
let prewarm_handle = self.spawn_caching_with(header, transactions, provider_builder, None);
This creates a performance issue: even though we're using the legacy state root calculation (which is already parallel in foreground, not backgroud task), the multiproof task could still benefit from cache prewarming — but it doesn't work under this logic.
BTW, if --engine.legacy-state-root is not set, and the parallel root calculation fails (e.g. due to mismatch), it falls back to serial calculation.
2025-07-28T09:25:58.325384Z WARN engine::tree: State root task returned incorrect state root state_root=0xc3ce4734893ed87f062462c90db3d745994865be65ec2575a500a70d1b1cbd1f block_state_root=0xe0c8c6fe648270d3b2ab29f33d386d70070d6ff097dbc522868515012a2f89ad
2025-07-28T09:25:58.325389Z WARN engine::tree: Failed to compute state root in parallel block=NumHash { number: 1000050, hash: 0xf30cdb4efe57d0980026a79775a8dda83cb05763d3a329a994a9882bd3d799fb } persisting_kind=NotPersisting
Is this behavior expected? This cause that i can't have both parallel state root and prewarm proofs at the same. So the questions are: (:TLDR)
- Why is prewarming proofs only enabled when use_state_root_task is true and prefix_sets is empty? What’s the reason behind this condition?
- Why does the parallel root calculation always fail and fall back to the serial path when using state root task?
Thanks! Any feedback or clarification would be greatly appreciated.
Steps to reproduce
- pipeline sync to 100w
RUST_LOG=info ./target/release/reth-bsc node \
--chain=bsc \
--datadir=./data_dir \
--debug.tip=0x48917a17f56f1f1e67771be69f08f0de69e76bed3149433d74ef7bcdba296546
- live sync
RUST_LOG=info ./target/release/reth-bsc node \
--chain=bsc \
--datadir=./data_dir \
--authrpc.addr "0.0.0.0" \
--authrpc.port 8551 \
--authrpc.jwtsecret ./data_dir/jwt.hex \
--http \
--engine.legacy-state-root \
--http.addr "0.0.0.0" \
--http.port 8545 \
--metrics 0.0.0.0:6060 \
--http.api "admin, debug, eth, net, trace, txpool, web3, rpc, reth, ots" ' > reth-bsc.log
Node logs
Platform(s)
Linux (x86)
Container Type
Not running in a container
What version/commit are you on?
v1.5.1
What database version are you on?
Current database version: 2
Local database version: 2
Which chain / network are you on?
bsc
What type of node are you running?
Full via --full flag
What prune config do you use, if any?
No response
If you've built Reth from source, provide the full command you used
cargo build --release
Code of Conduct
Describe the bug
I noticed that when
--engine.legacy-state-rootis enabled, the cache prewarming for multiproof is entirely disabled.This is due to the logic in
insert_block_inner, wherespawn_cache_exclusive()is used ifuse_state_root_taskis true andtrie_input.prefix_setsis empty.In that case,
to_multi_proofis always set to None, so no prewarming happens for multiproof targets.This creates a performance issue: even though we're using the legacy state root calculation (which is already parallel in foreground, not backgroud task), the multiproof task could still benefit from cache prewarming — but it doesn't work under this logic.
BTW, if
--engine.legacy-state-rootis not set, and the parallel root calculation fails (e.g. due to mismatch), it falls back to serial calculation.Is this behavior expected? This cause that i can't have both parallel state root and prewarm proofs at the same. So the questions are: (:TLDR)
Thanks! Any feedback or clarification would be greatly appreciated.
Steps to reproduce
Node logs
Platform(s)
Linux (x86)
Container Type
Not running in a container
What version/commit are you on?
v1.5.1
What database version are you on?
Current database version: 2
Local database version: 2
Which chain / network are you on?
bsc
What type of node are you running?
Full via --full flag
What prune config do you use, if any?
No response
If you've built Reth from source, provide the full command you used
cargo build --release
Code of Conduct