From 0596fdb26f7bb858557a06b379ef75039fe7e4b0 Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com> Date: Wed, 18 Dec 2024 00:12:04 +0200 Subject: [PATCH 1/4] feat(root): prefetch account proofs for the block --- crates/engine/tree/src/tree/mod.rs | 1 + crates/engine/tree/src/tree/root.rs | 43 ++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 35907800ce3a..aa66c638ec6a 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -2255,6 +2255,7 @@ where // // let state_root_task = StateRootTask::new(state_root_config, // blinded_provider_factory); let state_hook = state_root_task.state_hook(); + // state_root_task.prefetch_account_proofs(&sealed_block.body); // (Some(state_root_task.spawn(scope)), Box::new(state_hook) as Box) // } else { // (None, Box::new(|_state: &EvmState| {}) as Box) diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index cb64d95d8f92..375319335e43 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -1,10 +1,11 @@ //! State root task related functionality. -use alloy_primitives::{map::HashSet, Address}; +use alloy_primitives::map::HashSet; use derive_more::derive::Deref; use rayon::iter::{ParallelBridge, ParallelIterator}; use reth_errors::{ProviderError, ProviderResult}; use reth_evm::system_calls::OnStateHook; +use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_provider::{ providers::ConsistentDbView, BlockReader, DBProvider, DatabaseProviderFactory, StateCommitmentProvider, @@ -25,7 +26,7 @@ use reth_trie_sparse::{ errors::{SparseStateTrieError, SparseStateTrieResult, SparseTrieError, SparseTrieErrorKind}, SparseStateTrie, }; -use revm_primitives::{keccak256, EvmState, B256}; +use revm_primitives::{keccak256, map::AddressHashSet, EvmState, B256}; use std::{ collections::BTreeMap, sync::{ @@ -109,7 +110,7 @@ impl StateRootConfig { #[allow(dead_code)] pub enum StateRootMessage { /// Prefetch proof targets - PrefetchProofs(HashSet
), + PrefetchProofs(AddressHashSet), /// New state update from transaction execution StateUpdate(EvmState), /// Proof calculation completed for a specific state update @@ -342,11 +343,45 @@ where } } + /// Prefetch proofs for the accounts in the provided block. + /// + /// Accounts that will be prefetched are: + /// - Transaction senders + /// - Transaction recipients + /// - Withdrawal recipients + /// + /// This method does not prefetch the proofs on its own, but only sends the message to the + /// [`StateRootTask`] that will be processed by the loop in [`StateRootTask::run`] method. + pub fn prefetech_account_proofs< + T: SignedTransaction + alloy_consensus::Transaction, + B: BlockBody, + >( + &self, + body: B, + ) { + let mut accounts = AddressHashSet::with_capacity_and_hasher( + body.transactions().len() + + body.withdrawals().map_or(0, |withdrawals| withdrawals.len()), + Default::default(), + ); + accounts.extend( + body.transactions() + .iter() + .flat_map(|tx| [tx.recover_signer(), tx.kind().to().copied()]) + .filter_map(|address| address), + ); + if let Some(withdrawals) = body.withdrawals() { + accounts.extend(withdrawals.iter().map(|withdrawal| withdrawal.address)); + } + + let _ = self.tx.send(StateRootMessage::PrefetchProofs(accounts)); + } + /// Handles request for proof prefetch. fn on_prefetch_proof( scope: &rayon::Scope<'env>, config: StateRootConfig, - targets: HashSet
, + targets: AddressHashSet, fetched_proof_targets: &mut MultiProofTargets, proof_sequence_number: u64, state_root_message_sender: Sender>, From e9254b6338b6976220f68e03de4ea3c42582aab1 Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com> Date: Wed, 18 Dec 2024 00:19:02 +0200 Subject: [PATCH 2/4] flatten bruh --- crates/engine/tree/src/tree/root.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index 375319335e43..8f53a961ead7 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -351,7 +351,7 @@ where /// - Withdrawal recipients /// /// This method does not prefetch the proofs on its own, but only sends the message to the - /// [`StateRootTask`] that will be processed by the loop in [`StateRootTask::run`] method. + /// [`StateRootTask`] that will be processed by the main loop. pub fn prefetech_account_proofs< T: SignedTransaction + alloy_consensus::Transaction, B: BlockBody, @@ -368,7 +368,7 @@ where body.transactions() .iter() .flat_map(|tx| [tx.recover_signer(), tx.kind().to().copied()]) - .filter_map(|address| address), + .flatten(), ); if let Some(withdrawals) = body.withdrawals() { accounts.extend(withdrawals.iter().map(|withdrawal| withdrawal.address)); From c513e8e6514b66413bde92dabce34f5d2979cb85 Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:45:29 +0200 Subject: [PATCH 3/4] thanks roman --- crates/engine/tree/src/tree/mod.rs | 2 +- crates/engine/tree/src/tree/root.rs | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index aa66c638ec6a..585d821f3089 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -2255,7 +2255,7 @@ where // // let state_root_task = StateRootTask::new(state_root_config, // blinded_provider_factory); let state_hook = state_root_task.state_hook(); - // state_root_task.prefetch_account_proofs(&sealed_block.body); + // state_root_task.prefetch_account_proofs(&block); // (Some(state_root_task.spawn(scope)), Box::new(state_hook) as Box) // } else { // (None, Box::new(|_state: &EvmState| {}) as Box) diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index 8f53a961ead7..9ef08805c01a 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -5,6 +5,7 @@ use derive_more::derive::Deref; use rayon::iter::{ParallelBridge, ParallelIterator}; use reth_errors::{ProviderError, ProviderResult}; use reth_evm::system_calls::OnStateHook; +use reth_primitives::BlockWithSenders; use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_provider::{ providers::ConsistentDbView, BlockReader, DBProvider, DatabaseProviderFactory, @@ -352,24 +353,20 @@ where /// /// This method does not prefetch the proofs on its own, but only sends the message to the /// [`StateRootTask`] that will be processed by the main loop. - pub fn prefetech_account_proofs< + pub fn prefetch_account_proofs< T: SignedTransaction + alloy_consensus::Transaction, B: BlockBody, >( &self, - body: B, + body: &BlockWithSenders, ) { let mut accounts = AddressHashSet::with_capacity_and_hasher( body.transactions().len() + body.withdrawals().map_or(0, |withdrawals| withdrawals.len()), Default::default(), ); - accounts.extend( - body.transactions() - .iter() - .flat_map(|tx| [tx.recover_signer(), tx.kind().to().copied()]) - .flatten(), - ); + accounts.extend(body.senders.iter().copied()); + accounts.extend(body.transactions().iter().filter_map(|tx| tx.kind().to().copied())); if let Some(withdrawals) = body.withdrawals() { accounts.extend(withdrawals.iter().map(|withdrawal| withdrawal.address)); } From 3906e824eec0c144c03dc17044e57178725e485f Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:49:21 +0200 Subject: [PATCH 4/4] multiply by 2 --- crates/engine/tree/src/tree/root.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/engine/tree/src/tree/root.rs b/crates/engine/tree/src/tree/root.rs index 9ef08805c01a..d0cb5032fc23 100644 --- a/crates/engine/tree/src/tree/root.rs +++ b/crates/engine/tree/src/tree/root.rs @@ -361,7 +361,7 @@ where body: &BlockWithSenders, ) { let mut accounts = AddressHashSet::with_capacity_and_hasher( - body.transactions().len() + + body.transactions().len() * 2 + body.withdrawals().map_or(0, |withdrawals| withdrawals.len()), Default::default(), );