diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index 2a191a45cbd..8cb08d44dce 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -26,8 +26,8 @@ use reth_trie::{ TrieInputSorted, }; use reth_trie_db::{ - DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, DatabaseStateRoot, - DatabaseStorageProof, DatabaseStorageRoot, DatabaseTrieWitness, + storage_overlay_root, DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, + DatabaseStateRoot, DatabaseStorageProof, DatabaseTrieWitness, }; use std::fmt::Debug; @@ -335,7 +335,7 @@ impl StorageRootProvider ) -> ProviderResult { let mut revert_storage = self.revert_storage(address)?; revert_storage.extend(&hashed_storage); - StorageRoot::overlay_root(self.tx(), address, revert_storage) + storage_overlay_root(self.tx(), address, revert_storage) .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 e8b8a8410b0..a82d9c38da9 100644 --- a/crates/storage/provider/src/providers/state/latest.rs +++ b/crates/storage/provider/src/providers/state/latest.rs @@ -12,10 +12,10 @@ use reth_trie::{ updates::TrieUpdates, witness::TrieWitness, AccountProof, HashedPostState, HashedStorage, KeccakKeyHasher, MultiProof, MultiProofTargets, - StateRoot, StorageMultiProof, StorageRoot, TrieInput, TrieInputSorted, + StateRoot, StorageMultiProof, TrieInput, TrieInputSorted, }; use reth_trie_db::{ - DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot, + storage_overlay_root, DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseTrieWitness, }; @@ -95,7 +95,7 @@ impl StorageRootProvider for LatestStateProviderRef address: Address, hashed_storage: HashedStorage, ) -> ProviderResult { - StorageRoot::overlay_root(self.tx(), address, hashed_storage) + storage_overlay_root(self.tx(), address, hashed_storage) .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 0c67634dbfc..9f0593db663 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -16,9 +16,11 @@ mod tests { use reth_storage_api::{DatabaseProviderFactory, HashedPostStateProvider, StateWriter}; use reth_trie::{ test_utils::{state_root, storage_root_prehashed}, - HashedPostState, HashedStorage, StateRoot, StorageRoot, StorageRootProgress, + HashedPostState, HashedStorage, StateRoot, StorageRootProgress, + }; + use reth_trie_db::{ + storage_overlay_root, storage_root_from_tx_hashed, DatabaseStateRoot, }; - use reth_trie_db::{DatabaseStateRoot, DatabaseStorageRoot}; use revm_database::{ states::{ bundle_state::BundleRetention, changes::PlainStorageRevert, PlainStorageChangeset, @@ -1117,7 +1119,7 @@ mod tests { // calculate database storage root and write intermediate storage nodes. let StorageRootProgress::Complete(storage_root, _, storage_updates) = - StorageRoot::from_tx_hashed(tx, hashed_address) + storage_root_from_tx_hashed(tx, hashed_address) .with_no_threshold() .calculate(true) .unwrap() @@ -1148,7 +1150,7 @@ mod tests { provider_rw.write_hashed_state(&state.clone().into_sorted()).unwrap(); // re-calculate database storage root - let storage_root = StorageRoot::overlay_root(tx, address, updated_storage.clone()).unwrap(); + let storage_root = storage_overlay_root(tx, address, updated_storage.clone()).unwrap(); assert_eq!(storage_root, storage_root_prehashed(updated_storage.storage)); } } diff --git a/crates/trie/db/src/lib.rs b/crates/trie/db/src/lib.rs index 5417e5bd1e5..2b091765165 100644 --- a/crates/trie/db/src/lib.rs +++ b/crates/trie/db/src/lib.rs @@ -16,7 +16,10 @@ pub use hashed_cursor::{ pub use prefix_set::PrefixSetLoader; pub use proof::{DatabaseProof, DatabaseStorageProof}; pub use state::{DatabaseHashedPostState, DatabaseStateRoot}; -pub use storage::{DatabaseHashedStorage, DatabaseStorageRoot}; +pub use storage::{ + storage_overlay_root, storage_root_from_tx, storage_root_from_tx_hashed, DatabaseHashedStorage, + DatabaseStorageRoot, +}; pub use trie_cursor::{ DatabaseAccountTrieCursor, DatabaseStorageTrieCursor, DatabaseTrieCursorFactory, }; diff --git a/crates/trie/db/src/storage.rs b/crates/trie/db/src/storage.rs index 42d0d464c77..68553726b40 100644 --- a/crates/trie/db/src/storage.rs +++ b/crates/trie/db/src/storage.rs @@ -11,20 +11,58 @@ use reth_trie::{ #[cfg(feature = "metrics")] use reth_trie::metrics::TrieRootMetrics; -/// Extends [`StorageRoot`] with operations specific for working with a database transaction. -pub trait DatabaseStorageRoot<'a, TX> { - /// Create a new storage root calculator from database transaction and raw address. - fn from_tx(tx: &'a TX, address: Address) -> Self; +/// A type alias for [`StorageRoot`] configured with database cursor factories. +pub type DatabaseStorageRoot<'a, TX> = + StorageRoot, DatabaseHashedCursorFactory<&'a TX>>; - /// Create a new storage root calculator from database transaction and hashed address. - fn from_tx_hashed(tx: &'a TX, hashed_address: B256) -> Self; +/// Create a new [`StorageRoot`] calculator from database transaction and raw address. +pub fn storage_root_from_tx<'a, TX: DbTx>( + tx: &'a TX, + address: Address, +) -> DatabaseStorageRoot<'a, TX> { + StorageRoot::new( + DatabaseTrieCursorFactory::new(tx), + DatabaseHashedCursorFactory::new(tx), + address, + Default::default(), + #[cfg(feature = "metrics")] + TrieRootMetrics::new(reth_trie::TrieType::Storage), + ) +} + +/// Create a new [`StorageRoot`] calculator from database transaction and hashed address. +pub fn storage_root_from_tx_hashed<'a, TX: DbTx>( + tx: &'a TX, + hashed_address: B256, +) -> DatabaseStorageRoot<'a, TX> { + StorageRoot::new_hashed( + DatabaseTrieCursorFactory::new(tx), + DatabaseHashedCursorFactory::new(tx), + hashed_address, + Default::default(), + #[cfg(feature = "metrics")] + TrieRootMetrics::new(reth_trie::TrieType::Storage), + ) +} - /// Calculates the storage root for this [`HashedStorage`] and returns it. - fn overlay_root( - tx: &'a TX, - address: Address, - hashed_storage: HashedStorage, - ) -> Result; +/// Calculates the storage root for the given [`HashedStorage`] and returns it. +pub fn storage_overlay_root( + tx: &TX, + address: Address, + hashed_storage: HashedStorage, +) -> Result { + let prefix_set = hashed_storage.construct_prefix_set().freeze(); + let state_sorted = + HashedPostState::from_hashed_storage(keccak256(address), hashed_storage).into_sorted(); + StorageRoot::new( + DatabaseTrieCursorFactory::new(tx), + HashedPostStateCursorFactory::new(DatabaseHashedCursorFactory::new(tx), &state_sorted), + address, + prefix_set, + #[cfg(feature = "metrics")] + TrieRootMetrics::new(reth_trie::TrieType::Storage), + ) + .root() } /// Extends [`HashedStorage`] with operations specific for working with a database transaction. @@ -34,51 +72,6 @@ pub trait DatabaseHashedStorage: Sized { fn from_reverts(tx: &TX, address: Address, from: BlockNumber) -> Result; } -impl<'a, TX: DbTx> DatabaseStorageRoot<'a, TX> - for StorageRoot, DatabaseHashedCursorFactory<&'a TX>> -{ - fn from_tx(tx: &'a TX, address: Address) -> Self { - Self::new( - DatabaseTrieCursorFactory::new(tx), - DatabaseHashedCursorFactory::new(tx), - address, - Default::default(), - #[cfg(feature = "metrics")] - TrieRootMetrics::new(reth_trie::TrieType::Storage), - ) - } - - fn from_tx_hashed(tx: &'a TX, hashed_address: B256) -> Self { - Self::new_hashed( - DatabaseTrieCursorFactory::new(tx), - DatabaseHashedCursorFactory::new(tx), - hashed_address, - Default::default(), - #[cfg(feature = "metrics")] - TrieRootMetrics::new(reth_trie::TrieType::Storage), - ) - } - - fn overlay_root( - tx: &'a TX, - address: Address, - hashed_storage: HashedStorage, - ) -> Result { - let prefix_set = hashed_storage.construct_prefix_set().freeze(); - let state_sorted = - HashedPostState::from_hashed_storage(keccak256(address), hashed_storage).into_sorted(); - StorageRoot::new( - DatabaseTrieCursorFactory::new(tx), - HashedPostStateCursorFactory::new(DatabaseHashedCursorFactory::new(tx), &state_sorted), - address, - prefix_set, - #[cfg(feature = "metrics")] - TrieRootMetrics::new(reth_trie::TrieType::Storage), - ) - .root() - } -} - impl DatabaseHashedStorage for HashedStorage { fn from_reverts(tx: &TX, address: Address, from: BlockNumber) -> Result { let mut storage = Self::new(false); diff --git a/crates/trie/db/tests/fuzz_in_memory_nodes.rs b/crates/trie/db/tests/fuzz_in_memory_nodes.rs index b7b9f3a946a..d081a4e7a69 100644 --- a/crates/trie/db/tests/fuzz_in_memory_nodes.rs +++ b/crates/trie/db/tests/fuzz_in_memory_nodes.rs @@ -13,9 +13,9 @@ use reth_trie::{ test_utils::{state_root_prehashed, storage_root_prehashed}, trie_cursor::InMemoryTrieCursorFactory, updates::TrieUpdates, - HashedPostState, HashedStorage, StateRoot, StorageRoot, + HashedPostState, HashedStorage, StateRoot, }; -use reth_trie_db::{DatabaseStateRoot, DatabaseStorageRoot, DatabaseTrieCursorFactory}; +use reth_trie_db::{storage_root_from_tx_hashed, DatabaseStateRoot, DatabaseTrieCursorFactory}; use std::collections::BTreeMap; proptest! { @@ -91,7 +91,7 @@ proptest! { // Compute initial storage root and updates let (_, _, mut storage_trie_nodes) = - StorageRoot::from_tx_hashed(provider.tx_ref(), hashed_address).root_with_updates().unwrap(); + storage_root_from_tx_hashed(provider.tx_ref(), hashed_address).root_with_updates().unwrap(); let mut storage = init_storage; for (is_deleted, mut storage_update) in storage_updates { @@ -111,7 +111,7 @@ proptest! { let mut trie_nodes = TrieUpdates::default(); trie_nodes.insert_storage_updates(hashed_address, storage_trie_nodes.clone()); let (storage_root, _, trie_updates) = - StorageRoot::from_tx_hashed(provider.tx_ref(), hashed_address) + storage_root_from_tx_hashed(provider.tx_ref(), hashed_address) .with_prefix_set(hashed_storage.construct_prefix_set().freeze()) .with_trie_cursor_factory(InMemoryTrieCursorFactory::new( DatabaseTrieCursorFactory::new(provider.tx_ref()), diff --git a/crates/trie/db/tests/trie.rs b/crates/trie/db/tests/trie.rs index 8f543a711d8..9eee921d0d0 100644 --- a/crates/trie/db/tests/trie.rs +++ b/crates/trie/db/tests/trie.rs @@ -23,9 +23,9 @@ use reth_trie::{ triehash::KeccakHasher, updates::StorageTrieUpdates, BranchNodeCompact, HashBuilder, IntermediateStateRootState, Nibbles, StateRoot, - StateRootProgress, StorageRoot, TrieMask, + StateRootProgress, TrieMask, }; -use reth_trie_db::{DatabaseStateRoot, DatabaseStorageRoot}; +use reth_trie_db::{storage_root_from_tx, storage_root_from_tx_hashed, DatabaseStateRoot}; use std::{collections::BTreeMap, ops::Mul, str::FromStr, sync::Arc}; fn insert_account( @@ -64,7 +64,7 @@ fn incremental_vs_full_root(inputs: &[&str], modified: &str) { // Generate the intermediate nodes on the receiving end of the channel let (_, _, trie_updates) = - StorageRoot::from_tx_hashed(tx.tx_ref(), hashed_address).root_with_updates().unwrap(); + storage_root_from_tx_hashed(tx.tx_ref(), hashed_address).root_with_updates().unwrap(); // 1. Some state transition happens, update the hashed storage to the new value let modified_key = B256::from_str(modified).unwrap(); @@ -77,7 +77,7 @@ fn incremental_vs_full_root(inputs: &[&str], modified: &str) { .unwrap(); // 2. Calculate full merkle root - let loader = StorageRoot::from_tx_hashed(tx.tx_ref(), hashed_address); + let loader = storage_root_from_tx_hashed(tx.tx_ref(), hashed_address); let modified_root = loader.root().unwrap(); // Update the intermediate roots table so that we can run the incremental verification @@ -90,7 +90,7 @@ fn incremental_vs_full_root(inputs: &[&str], modified: &str) { // 3. Calculate the incremental root let mut storage_changes = PrefixSetMut::default(); storage_changes.insert(Nibbles::unpack(modified_key)); - let loader = StorageRoot::from_tx_hashed(tx.tx_ref(), hashed_address) + let loader = storage_root_from_tx_hashed(tx.tx_ref(), hashed_address) .with_prefix_set(storage_changes.freeze()); let incremental_root = loader.root().unwrap(); @@ -130,7 +130,7 @@ fn arbitrary_storage_root() { tx.commit().unwrap(); let tx = factory.provider_rw().unwrap(); - let got = StorageRoot::from_tx(tx.tx_ref(), address).root().unwrap(); + let got = storage_root_from_tx(tx.tx_ref(), address).root().unwrap(); let expected = storage_root(storage.into_iter()); assert_eq!(expected, got); }); @@ -189,7 +189,7 @@ fn test_empty_storage_root() { tx.commit().unwrap(); let tx = factory.provider_rw().unwrap(); - let got = StorageRoot::from_tx(tx.tx_ref(), address).root().unwrap(); + let got = storage_root_from_tx(tx.tx_ref(), address).root().unwrap(); assert_eq!(got, EMPTY_ROOT_HASH); } @@ -214,7 +214,7 @@ fn test_storage_root() { tx.commit().unwrap(); let tx = factory.provider_rw().unwrap(); - let got = StorageRoot::from_tx(tx.tx_ref(), address).root().unwrap(); + let got = storage_root_from_tx(tx.tx_ref(), address).root().unwrap(); assert_eq!(storage_root(storage.into_iter()), got); } @@ -324,7 +324,7 @@ fn storage_root_regression() { tx.commit().unwrap(); let tx = factory.provider_rw().unwrap(); - let account3_storage_root = StorageRoot::from_tx(tx.tx_ref(), address3).root().unwrap(); + let account3_storage_root = storage_root_from_tx(tx.tx_ref(), address3).root().unwrap(); let expected_root = storage_root_prehashed(storage); assert_eq!(expected_root, account3_storage_root); } @@ -386,7 +386,7 @@ fn account_and_storage_trie() { } hashed_storage_cursor.upsert(key3, &StorageEntry { key: hashed_slot, value }).unwrap(); } - let account3_storage_root = StorageRoot::from_tx(tx.tx_ref(), address3).root().unwrap(); + let account3_storage_root = storage_root_from_tx(tx.tx_ref(), address3).root().unwrap(); hash_builder .add_leaf(Nibbles::unpack(key3), &encode_account(account3, Some(account3_storage_root))); @@ -685,7 +685,7 @@ fn storage_trie_around_extension_node() { let (expected_root, expected_updates) = extension_node_storage_trie(&tx, hashed_address); let (got, _, updates) = - StorageRoot::from_tx_hashed(tx.tx_ref(), hashed_address).root_with_updates().unwrap(); + storage_root_from_tx_hashed(tx.tx_ref(), hashed_address).root_with_updates().unwrap(); assert_eq!(expected_root, got); assert_eq!(expected_updates, updates); assert_trie_updates(updates.storage_nodes_ref());