From 624bfa1f491288b4a842c49dabf4e408aec2cd90 Mon Sep 17 00:00:00 2001 From: fig <1gusredo@gmail.com> Date: Mon, 29 Dec 2025 10:06:08 +0000 Subject: [PATCH] perf(engine): paralellize evm_state_to_hashed_post_state() (#20635) --- .../src/tree/payload_processor/multiproof.rs | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/crates/engine/tree/src/tree/payload_processor/multiproof.rs b/crates/engine/tree/src/tree/payload_processor/multiproof.rs index 0804e4bf6c..6c44873838 100644 --- a/crates/engine/tree/src/tree/payload_processor/multiproof.rs +++ b/crates/engine/tree/src/tree/payload_processor/multiproof.rs @@ -10,6 +10,7 @@ use crossbeam_channel::{unbounded, Receiver as CrossbeamReceiver, Sender as Cros use dashmap::DashMap; use derive_more::derive::Deref; use metrics::{Gauge, Histogram}; +use rayon::prelude::*; use reth_metrics::Metrics; use reth_provider::AccountReader; use reth_revm::state::EvmState; @@ -202,35 +203,38 @@ impl Drop for StateHookSender { } pub(crate) fn evm_state_to_hashed_post_state(update: EvmState) -> HashedPostState { - let mut hashed_state = HashedPostState::with_capacity(update.len()); + update.into_par_iter() + .filter_map(|(address, account)| { + if !account.is_touched() { + return None; + } - for (address, account) in update { - if account.is_touched() { let hashed_address = keccak256(address); trace!(target: "engine::tree::payload_processor::multiproof", ?address, ?hashed_address, "Adding account to state update"); let destroyed = account.is_selfdestructed(); let info = if destroyed { None } else { Some(account.info.into()) }; - hashed_state.accounts.insert(hashed_address, info); - let mut changed_storage_iter = account - .storage - .into_iter() - .filter(|(_slot, value)| value.is_changed()) - .map(|(slot, value)| (keccak256(B256::from(slot)), value.present_value)) - .peekable(); + let hashed_storage = if destroyed { + Some(HashedStorage::new(true)) + } else { + let storage: Vec<_> = account + .storage + .into_iter() + .filter(|(_slot, value)| value.is_changed()) + .map(|(slot, value)| (keccak256(B256::from(slot)), value.present_value)) + .collect(); - if destroyed { - hashed_state.storages.insert(hashed_address, HashedStorage::new(true)); - } else if changed_storage_iter.peek().is_some() { - hashed_state - .storages - .insert(hashed_address, HashedStorage::from_iter(false, changed_storage_iter)); - } - } - } + if storage.is_empty() { + None + } else { + Some(HashedStorage::from_iter(false, storage)) + } + }; - hashed_state + Some((hashed_address, info, hashed_storage)) + }) + .collect() } /// Input parameters for dispatching a multiproof calculation.