diff --git a/crates/storage/provider/src/providers/bundle_state_provider.rs b/crates/storage/provider/src/providers/bundle_state_provider.rs index 0ea481ca82..dd4d478c51 100644 --- a/crates/storage/provider/src/providers/bundle_state_provider.rs +++ b/crates/storage/provider/src/providers/bundle_state_provider.rs @@ -136,7 +136,12 @@ impl StateRootProvider let bundle_state = self.block_execution_data_provider.execution_outcome().state(); let mut storage = bundle_state .account(&address) - .map(|account| HashedStorage::from_bundle_state(account.status, &account.storage)) + .map(|account| { + HashedStorage::from_plain_storage( + account.status, + account.storage.iter().map(|(slot, value)| (slot, &value.present_value)), + ) + }) .unwrap_or_else(|| HashedStorage::new(false)); storage.extend(hashed_storage); self.state_provider.hashed_storage_root(address, storage) diff --git a/crates/trie/trie/src/state.rs b/crates/trie/trie/src/state.rs index 5d25c44c44..679cefc15a 100644 --- a/crates/trie/trie/src/state.rs +++ b/crates/trie/trie/src/state.rs @@ -5,7 +5,7 @@ use crate::{ use itertools::Itertools; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use reth_primitives::{keccak256, Account, Address, B256, U256}; -use revm::db::{states::StorageSlot, AccountStatus, BundleAccount}; +use revm::db::{states::CacheAccount, AccountStatus, BundleAccount}; use std::collections::{hash_map, HashMap, HashSet}; /// Representation of in-memory hashed state. @@ -29,8 +29,37 @@ impl HashedPostState { .map(|(address, account)| { let hashed_address = keccak256(address); let hashed_account = account.info.clone().map(Into::into); - let hashed_storage = - HashedStorage::from_bundle_state(account.status, &account.storage); + let hashed_storage = HashedStorage::from_plain_storage( + account.status, + account.storage.iter().map(|(slot, value)| (slot, &value.present_value)), + ); + (hashed_address, (hashed_account, hashed_storage)) + }) + .collect::, HashedStorage))>>(); + + let mut accounts = HashMap::with_capacity(hashed.len()); + let mut storages = HashMap::with_capacity(hashed.len()); + for (address, (account, storage)) in hashed { + accounts.insert(address, account); + storages.insert(address, storage); + } + Self { accounts, storages } + } + + /// Initialize [`HashedPostState`] from cached state. + /// Hashes all changed accounts and storage entries that are currently stored in cache. + pub fn from_cache_state<'a>( + state: impl IntoParallelIterator, + ) -> Self { + let hashed = state + .into_par_iter() + .map(|(address, account)| { + let hashed_address = keccak256(address); + let hashed_account = account.account.as_ref().map(|a| a.info.clone().into()); + let hashed_storage = HashedStorage::from_plain_storage( + account.status, + account.account.as_ref().map(|a| a.storage.iter()).into_iter().flatten(), + ); (hashed_address, (hashed_account, hashed_storage)) }) .collect::, HashedStorage))>>(); @@ -155,13 +184,15 @@ impl HashedStorage { Self { wiped, storage: HashMap::from_iter(iter) } } - /// Create new hashed storage from bundle state account entry. - pub fn from_bundle_state(status: AccountStatus, storage: &HashMap) -> Self { - let storage = storage - .iter() - .map(|(key, value)| (keccak256(B256::from(*key)), value.present_value)) - .collect(); - Self { wiped: status.was_destroyed(), storage } + /// Create new hashed storage from account status and plain storage. + pub fn from_plain_storage<'a>( + status: AccountStatus, + storage: impl IntoIterator, + ) -> Self { + Self::from_iter( + status.was_destroyed(), + storage.into_iter().map(|(key, value)| (keccak256(B256::from(*key)), *value)), + ) } /// Construct [`PrefixSetMut`] from hashed storage.