diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index 27c6a48fe..4557adb3f 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -288,6 +288,7 @@ impl Command { let (state_root, trie_updates) = StateRoot::overlay_root_with_updates( provider_factory.provider()?.tx_ref(), hashed_post_state.clone(), + Default::default(), )?; if state_root != block_with_senders.state_root { diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index bcbccac58..df288b5ef 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -152,6 +152,7 @@ impl Command { let (in_memory_state_root, in_memory_updates) = StateRoot::overlay_root_with_updates( provider.tx_ref(), execution_outcome.hash_state_slow(), + Default::default(), )?; if in_memory_state_root == block.state_root { diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index 13b3aea28..092e85104 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -260,7 +260,7 @@ impl<'b, TX: DbTx> StateRootProvider for HistoricalStateProviderRef<'b, TX> { fn hashed_state_root(&self, hashed_state: HashedPostState) -> ProviderResult { let mut revert_state = self.revert_state()?; revert_state.extend(hashed_state); - StateRoot::overlay_root(self.tx, revert_state) + StateRoot::overlay_root(self.tx, revert_state, Default::default()) .map_err(|err| ProviderError::Database(err.into())) } @@ -270,7 +270,7 @@ impl<'b, TX: DbTx> StateRootProvider for HistoricalStateProviderRef<'b, TX> { ) -> ProviderResult<(B256, TrieUpdates)> { let mut revert_state = self.revert_state()?; revert_state.extend(hashed_state); - StateRoot::overlay_root_with_updates(self.tx, revert_state) + StateRoot::overlay_root_with_updates(self.tx, revert_state, Default::default()) .map_err(|err| ProviderError::Database(err.into())) } } diff --git a/crates/storage/provider/src/providers/state/latest.rs b/crates/storage/provider/src/providers/state/latest.rs index c84342e8a..b2722fdc6 100644 --- a/crates/storage/provider/src/providers/state/latest.rs +++ b/crates/storage/provider/src/providers/state/latest.rs @@ -76,7 +76,7 @@ impl<'b, TX: DbTx> BlockHashReader for LatestStateProviderRef<'b, TX> { impl<'b, TX: DbTx> StateRootProvider for LatestStateProviderRef<'b, TX> { fn hashed_state_root(&self, hashed_state: HashedPostState) -> ProviderResult { - StateRoot::overlay_root(self.tx, hashed_state) + StateRoot::overlay_root(self.tx, hashed_state, Default::default()) .map_err(|err| ProviderError::Database(err.into())) } @@ -84,7 +84,7 @@ impl<'b, TX: DbTx> StateRootProvider for LatestStateProviderRef<'b, TX> { &self, hashed_state: HashedPostState, ) -> ProviderResult<(B256, TrieUpdates)> { - StateRoot::overlay_root_with_updates(self.tx, hashed_state) + StateRoot::overlay_root_with_updates(self.tx, hashed_state, Default::default()) .map_err(|err| ProviderError::Database(err.into())) } } diff --git a/crates/storage/provider/src/writer/mod.rs b/crates/storage/provider/src/writer/mod.rs index eb21e9099..f9989184a 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -1280,7 +1280,8 @@ mod tests { 0, Vec::new() ) - .hash_state_slow() + .hash_state_slow(), + Default::default() ) .unwrap(), state_root(expected.clone().into_iter().map(|(address, (account, storage))| ( diff --git a/crates/trie/db/src/state.rs b/crates/trie/db/src/state.rs index 8ad38a209..4c00295d5 100644 --- a/crates/trie/db/src/state.rs +++ b/crates/trie/db/src/state.rs @@ -4,7 +4,7 @@ use reth_primitives::{BlockNumber, B256}; use reth_trie::{ hashed_cursor::{DatabaseHashedCursorFactory, HashedPostStateCursorFactory}, prefix_set::PrefixSetLoader, - trie_cursor::DatabaseTrieCursorFactory, + trie_cursor::{DatabaseTrieCursorFactory, InMemoryTrieCursorFactory}, updates::TrieUpdates, HashedPostState, StateRoot, StateRootProgress, }; @@ -72,7 +72,7 @@ pub trait DatabaseStateRoot<'a, TX>: Sized { /// use reth_db::test_utils::create_test_rw_db; /// use reth_db_api::database::Database; /// use reth_primitives::{Account, U256}; - /// use reth_trie::{HashedPostState, StateRoot}; + /// use reth_trie::{updates::TrieUpdates, HashedPostState, StateRoot}; /// use reth_trie_db::DatabaseStateRoot; /// /// // Initialize the database @@ -85,21 +85,29 @@ pub trait DatabaseStateRoot<'a, TX>: Sized { /// Some(Account { nonce: 1, balance: U256::from(10), bytecode_hash: None }), /// ); /// + /// // Initialize intermediate nodes if any. + /// let intermediate_nodes = TrieUpdates::default(); + /// /// // Calculate the state root /// let tx = db.tx().expect("failed to create transaction"); - /// let state_root = StateRoot::overlay_root(&tx, hashed_state); + /// let state_root = StateRoot::overlay_root(&tx, hashed_state, intermediate_nodes); /// ``` /// /// # Returns /// /// The state root for this [`HashedPostState`]. - fn overlay_root(tx: &'a TX, post_state: HashedPostState) -> Result; + fn overlay_root( + tx: &'a TX, + post_state: HashedPostState, + intermediate_nodes: TrieUpdates, + ) -> Result; /// Calculates the state root for this [`HashedPostState`] and returns it alongside trie /// updates. See [`Self::overlay_root`] for more info. fn overlay_root_with_updates( tx: &'a TX, post_state: HashedPostState, + intermediate_nodes: TrieUpdates, ) -> Result<(B256, TrieUpdates), StateRootError>; } @@ -142,12 +150,17 @@ impl<'a, TX: DbTx> DatabaseStateRoot<'a, TX> Self::incremental_root_calculator(tx, range)?.root_with_progress() } - fn overlay_root(tx: &'a TX, post_state: HashedPostState) -> Result { + fn overlay_root( + tx: &'a TX, + post_state: HashedPostState, + intermediate_nodes: TrieUpdates, + ) -> Result { let prefix_sets = post_state.construct_prefix_sets().freeze(); - let sorted = post_state.into_sorted(); + let state_sorted = post_state.into_sorted(); + let nodes_sorted = intermediate_nodes.into_sorted(); StateRoot::new( - DatabaseTrieCursorFactory::new(tx), - HashedPostStateCursorFactory::new(DatabaseHashedCursorFactory::new(tx), &sorted), + InMemoryTrieCursorFactory::new(DatabaseTrieCursorFactory::new(tx), &nodes_sorted), + HashedPostStateCursorFactory::new(DatabaseHashedCursorFactory::new(tx), &state_sorted), ) .with_prefix_sets(prefix_sets) .root() @@ -156,12 +169,14 @@ impl<'a, TX: DbTx> DatabaseStateRoot<'a, TX> fn overlay_root_with_updates( tx: &'a TX, post_state: HashedPostState, + intermediate_nodes: TrieUpdates, ) -> Result<(B256, TrieUpdates), StateRootError> { let prefix_sets = post_state.construct_prefix_sets().freeze(); - let sorted = post_state.into_sorted(); + let state_sorted = post_state.into_sorted(); + let nodes_sorted = intermediate_nodes.into_sorted(); StateRoot::new( - DatabaseTrieCursorFactory::new(tx), - HashedPostStateCursorFactory::new(DatabaseHashedCursorFactory::new(tx), &sorted), + InMemoryTrieCursorFactory::new(DatabaseTrieCursorFactory::new(tx), &nodes_sorted), + HashedPostStateCursorFactory::new(DatabaseHashedCursorFactory::new(tx), &state_sorted), ) .with_prefix_sets(prefix_sets) .root_with_updates() @@ -202,7 +217,7 @@ mod tests { let db = create_test_rw_db(); let tx = db.tx().expect("failed to create transaction"); assert_eq!( - StateRoot::overlay_root(&tx, post_state).unwrap(), + StateRoot::overlay_root(&tx, post_state, Default::default()).unwrap(), hex!("b464525710cafcf5d4044ac85b72c08b1e76231b8d91f288fe438cc41d8eaafd") ); }