feat(trie): trie cursor abstraction (#5643)

This commit is contained in:
Roman Krasiuk
2023-12-21 11:22:15 -08:00
committed by GitHub
parent fff7d1579d
commit d8b1771cdd
14 changed files with 418 additions and 293 deletions

View File

@ -181,7 +181,7 @@ impl Command {
let (account_prefix_set, storage_prefix_set) = hashed_post_state.construct_prefix_sets(); let (account_prefix_set, storage_prefix_set) = hashed_post_state.construct_prefix_sets();
let tx = provider.tx_ref(); let tx = provider.tx_ref();
let hashed_cursor_factory = HashedPostStateCursorFactory::new(tx, &hashed_post_state); let hashed_cursor_factory = HashedPostStateCursorFactory::new(tx, &hashed_post_state);
let (in_memory_state_root, in_memory_updates) = StateRoot::new(tx) let (in_memory_state_root, in_memory_updates) = StateRoot::from_tx(tx)
.with_hashed_cursor_factory(hashed_cursor_factory) .with_hashed_cursor_factory(hashed_cursor_factory)
.with_changed_account_prefixes(account_prefix_set) .with_changed_account_prefixes(account_prefix_set)
.with_changed_storage_prefixes(storage_prefix_set) .with_changed_storage_prefixes(storage_prefix_set)

View File

@ -76,7 +76,7 @@ impl Command {
entry = storage_trie_cursor.next()?; entry = storage_trie_cursor.next()?;
} }
let state_root = StateRoot::new(tx_mut).root()?; let state_root = StateRoot::from_tx(tx_mut).root()?;
if state_root != best_header.state_root { if state_root != best_header.state_root {
eyre::bail!( eyre::bail!(
"Recovery failed. Incorrect state root. Expected: {:?}. Received: {:?}", "Recovery failed. Incorrect state root. Expected: {:?}. Received: {:?}",

View File

@ -126,8 +126,9 @@ pub(crate) fn txs_testdata(num_blocks: u64) -> PathBuf {
db.insert_accounts_and_storages(start_state.clone()).unwrap(); db.insert_accounts_and_storages(start_state.clone()).unwrap();
// make first block after genesis have valid state root // make first block after genesis have valid state root
let (root, updates) = let (root, updates) = StateRoot::from_tx(db.factory.provider_rw().unwrap().tx_ref())
StateRoot::new(db.factory.provider_rw().unwrap().tx_ref()).root_with_updates().unwrap(); .root_with_updates()
.unwrap();
let second_block = blocks.get_mut(1).unwrap(); let second_block = blocks.get_mut(1).unwrap();
let cloned_second = second_block.clone(); let cloned_second = second_block.clone();
let mut updated_header = cloned_second.header.unseal(); let mut updated_header = cloned_second.header.unseal();
@ -154,7 +155,7 @@ pub(crate) fn txs_testdata(num_blocks: u64) -> PathBuf {
// make last block have valid state root // make last block have valid state root
let root = { let root = {
let tx_mut = db.factory.provider_rw().unwrap(); let tx_mut = db.factory.provider_rw().unwrap();
let root = StateRoot::new(tx_mut.tx_ref()).root().unwrap(); let root = StateRoot::from_tx(tx_mut.tx_ref()).root().unwrap();
tx_mut.commit().unwrap(); tx_mut.commit().unwrap();
root root
}; };

View File

@ -191,7 +191,7 @@ impl<DB: Database> Stage<DB> for MerkleStage {
}); });
let tx = provider.tx_ref(); let tx = provider.tx_ref();
let progress = StateRoot::new(tx) let progress = StateRoot::from_tx(tx)
.with_intermediate_state(checkpoint.map(IntermediateStateRootState::from)) .with_intermediate_state(checkpoint.map(IntermediateStateRootState::from))
.root_with_progress() .root_with_progress()
.map_err(|e| StageError::Fatal(Box::new(e)))?; .map_err(|e| StageError::Fatal(Box::new(e)))?;

View File

@ -159,10 +159,10 @@ impl BundleStateWithReceipts {
&self, &self,
tx: &'a TX, tx: &'a TX,
hashed_post_state: &'b HashedPostState, hashed_post_state: &'b HashedPostState,
) -> StateRoot<'a, TX, HashedPostStateCursorFactory<'a, 'b, TX>> { ) -> StateRoot<&'a TX, HashedPostStateCursorFactory<'a, 'b, TX>> {
let (account_prefix_set, storage_prefix_set) = hashed_post_state.construct_prefix_sets(); let (account_prefix_set, storage_prefix_set) = hashed_post_state.construct_prefix_sets();
let hashed_cursor_factory = HashedPostStateCursorFactory::new(tx, hashed_post_state); let hashed_cursor_factory = HashedPostStateCursorFactory::new(tx, hashed_post_state);
StateRoot::new(tx) StateRoot::from_tx(tx)
.with_hashed_cursor_factory(hashed_cursor_factory) .with_hashed_cursor_factory(hashed_cursor_factory)
.with_changed_account_prefixes(account_prefix_set) .with_changed_account_prefixes(account_prefix_set)
.with_changed_storage_prefixes(storage_prefix_set) .with_changed_storage_prefixes(storage_prefix_set)
@ -1236,7 +1236,7 @@ mod tests {
} }
} }
let (_, updates) = StateRoot::new(tx).root_with_updates().unwrap(); let (_, updates) = StateRoot::from_tx(tx).root_with_updates().unwrap();
updates.flush(tx).unwrap(); updates.flush(tx).unwrap();
}) })
.unwrap(); .unwrap();

View File

@ -2077,7 +2077,7 @@ impl<TX: DbTxMut + DbTx> HashingWriter for DatabaseProvider<TX> {
{ {
// This is the same as `StateRoot::incremental_root_with_updates`, only the prefix sets // This is the same as `StateRoot::incremental_root_with_updates`, only the prefix sets
// are pre-loaded. // are pre-loaded.
let (state_root, trie_updates) = StateRoot::new(&self.tx) let (state_root, trie_updates) = StateRoot::from_tx(&self.tx)
.with_changed_account_prefixes(account_prefix_set.freeze()) .with_changed_account_prefixes(account_prefix_set.freeze())
.with_changed_storage_prefixes( .with_changed_storage_prefixes(
storage_prefix_set.into_iter().map(|(k, v)| (k, v.freeze())).collect(), storage_prefix_set.into_iter().map(|(k, v)| (k, v.freeze())).collect(),
@ -2261,7 +2261,7 @@ impl<TX: DbTxMut + DbTx> BlockExecutionWriter for DatabaseProvider<TX> {
// Calculate the reverted merkle root. // Calculate the reverted merkle root.
// This is the same as `StateRoot::incremental_root_with_updates`, only the prefix sets // This is the same as `StateRoot::incremental_root_with_updates`, only the prefix sets
// are pre-loaded. // are pre-loaded.
let (new_state_root, trie_updates) = StateRoot::new(&self.tx) let (new_state_root, trie_updates) = StateRoot::from_tx(&self.tx)
.with_changed_account_prefixes(account_prefix_set.freeze()) .with_changed_account_prefixes(account_prefix_set.freeze())
.with_changed_storage_prefixes( .with_changed_storage_prefixes(
storage_prefix_set.into_iter().map(|(k, v)| (k, v.freeze())).collect(), storage_prefix_set.into_iter().map(|(k, v)| (k, v.freeze())).collect(),

View File

@ -2,7 +2,7 @@ use crate::{
hashed_cursor::{HashedCursorFactory, HashedStorageCursor}, hashed_cursor::{HashedCursorFactory, HashedStorageCursor},
node_iter::{AccountNode, AccountNodeIter, StorageNode, StorageNodeIter}, node_iter::{AccountNode, AccountNodeIter, StorageNode, StorageNodeIter},
prefix_set::PrefixSetMut, prefix_set::PrefixSetMut,
trie_cursor::{AccountTrieCursor, StorageTrieCursor}, trie_cursor::{DatabaseAccountTrieCursor, DatabaseStorageTrieCursor},
walker::TrieWalker, walker::TrieWalker,
StateRootError, StorageRootError, StateRootError, StorageRootError,
}; };
@ -51,7 +51,8 @@ where
let mut account_proof = AccountProof::new(address); let mut account_proof = AccountProof::new(address);
let hashed_account_cursor = self.hashed_cursor_factory.hashed_account_cursor()?; let hashed_account_cursor = self.hashed_cursor_factory.hashed_account_cursor()?;
let trie_cursor = AccountTrieCursor::new(self.tx.cursor_read::<tables::AccountsTrie>()?); let trie_cursor =
DatabaseAccountTrieCursor::new(self.tx.cursor_read::<tables::AccountsTrie>()?);
// Create the walker. // Create the walker.
let mut prefix_set = PrefixSetMut::default(); let mut prefix_set = PrefixSetMut::default();
@ -119,7 +120,7 @@ where
let target_nibbles = proofs.iter().map(|p| p.nibbles.clone()).collect::<Vec<_>>(); let target_nibbles = proofs.iter().map(|p| p.nibbles.clone()).collect::<Vec<_>>();
let prefix_set = PrefixSetMut::from(target_nibbles.clone()).freeze(); let prefix_set = PrefixSetMut::from(target_nibbles.clone()).freeze();
let trie_cursor = StorageTrieCursor::new( let trie_cursor = DatabaseStorageTrieCursor::new(
self.tx.cursor_dup_read::<tables::StoragesTrie>()?, self.tx.cursor_dup_read::<tables::StoragesTrie>()?,
hashed_address, hashed_address,
); );
@ -221,7 +222,7 @@ mod tests {
}); });
provider.insert_storage_for_hashing(alloc_storage)?; provider.insert_storage_for_hashing(alloc_storage)?;
let (_, updates) = StateRoot::new(provider.tx_ref()) let (_, updates) = StateRoot::from_tx(provider.tx_ref())
.root_with_updates() .root_with_updates()
.map_err(Into::<reth_db::DatabaseError>::into)?; .map_err(Into::<reth_db::DatabaseError>::into)?;
updates.flush(provider.tx_mut())?; updates.flush(provider.tx_mut())?;

View File

@ -3,13 +3,13 @@ use crate::{
node_iter::{AccountNode, AccountNodeIter, StorageNode, StorageNodeIter}, node_iter::{AccountNode, AccountNodeIter, StorageNode, StorageNodeIter},
prefix_set::{PrefixSet, PrefixSetLoader, PrefixSetMut}, prefix_set::{PrefixSet, PrefixSetLoader, PrefixSetMut},
progress::{IntermediateStateRootState, StateRootProgress}, progress::{IntermediateStateRootState, StateRootProgress},
trie_cursor::{AccountTrieCursor, StorageTrieCursor}, trie_cursor::TrieCursorFactory,
updates::{TrieKey, TrieOp, TrieUpdates}, updates::{TrieKey, TrieOp, TrieUpdates},
walker::TrieWalker, walker::TrieWalker,
StateRootError, StorageRootError, StateRootError, StorageRootError,
}; };
use alloy_rlp::{BufMut, Encodable}; use alloy_rlp::{BufMut, Encodable};
use reth_db::{tables, transaction::DbTx}; use reth_db::transaction::DbTx;
use reth_primitives::{ use reth_primitives::{
constants::EMPTY_ROOT_HASH, constants::EMPTY_ROOT_HASH,
keccak256, keccak256,
@ -24,9 +24,9 @@ use tracing::{debug, trace};
/// StateRoot is used to compute the root node of a state trie. /// StateRoot is used to compute the root node of a state trie.
#[derive(Debug)] #[derive(Debug)]
pub struct StateRoot<'a, TX, H> { pub struct StateRoot<T, H> {
/// A reference to the database transaction. /// The factory for trie cursors.
pub tx: &'a TX, pub trie_cursor_factory: T,
/// The factory for hashed cursors. /// The factory for hashed cursors.
pub hashed_cursor_factory: H, pub hashed_cursor_factory: H,
/// A set of account prefixes that have changed. /// A set of account prefixes that have changed.
@ -42,7 +42,7 @@ pub struct StateRoot<'a, TX, H> {
threshold: u64, threshold: u64,
} }
impl<'a, TX, H> StateRoot<'a, TX, H> { impl<T, H> StateRoot<T, H> {
/// Set the changed account prefixes. /// Set the changed account prefixes.
pub fn with_changed_account_prefixes(mut self, prefixes: PrefixSet) -> Self { pub fn with_changed_account_prefixes(mut self, prefixes: PrefixSet) -> Self {
self.changed_account_prefixes = prefixes; self.changed_account_prefixes = prefixes;
@ -80,33 +80,43 @@ impl<'a, TX, H> StateRoot<'a, TX, H> {
} }
/// Set the hashed cursor factory. /// Set the hashed cursor factory.
pub fn with_hashed_cursor_factory<HF>( pub fn with_hashed_cursor_factory<HF>(self, hashed_cursor_factory: HF) -> StateRoot<T, HF> {
self,
hashed_cursor_factory: HF,
) -> StateRoot<'a, TX, HF> {
StateRoot { StateRoot {
tx: self.tx, trie_cursor_factory: self.trie_cursor_factory,
hashed_cursor_factory,
changed_account_prefixes: self.changed_account_prefixes,
changed_storage_prefixes: self.changed_storage_prefixes,
destroyed_accounts: self.destroyed_accounts,
threshold: self.threshold,
previous_state: self.previous_state,
}
}
/// Set the trie cursor factory.
pub fn with_trie_cursor_factory<TF>(self, trie_cursor_factory: TF) -> StateRoot<TF, H> {
StateRoot {
trie_cursor_factory,
hashed_cursor_factory: self.hashed_cursor_factory,
changed_account_prefixes: self.changed_account_prefixes, changed_account_prefixes: self.changed_account_prefixes,
changed_storage_prefixes: self.changed_storage_prefixes, changed_storage_prefixes: self.changed_storage_prefixes,
destroyed_accounts: self.destroyed_accounts, destroyed_accounts: self.destroyed_accounts,
threshold: self.threshold, threshold: self.threshold,
previous_state: self.previous_state, previous_state: self.previous_state,
hashed_cursor_factory,
} }
} }
} }
impl<'a, TX: DbTx> StateRoot<'a, TX, &'a TX> { impl<'a, TX: DbTx> StateRoot<&'a TX, &'a TX> {
/// Create a new [StateRoot] instance. /// Create a new [StateRoot] instance.
pub fn new(tx: &'a TX) -> Self { pub fn from_tx(tx: &'a TX) -> Self {
Self { Self {
tx, trie_cursor_factory: tx,
hashed_cursor_factory: tx,
changed_account_prefixes: PrefixSetMut::default().freeze(), changed_account_prefixes: PrefixSetMut::default().freeze(),
changed_storage_prefixes: HashMap::default(), changed_storage_prefixes: HashMap::default(),
destroyed_accounts: HashSet::default(), destroyed_accounts: HashSet::default(),
previous_state: None, previous_state: None,
threshold: 100_000, threshold: 100_000,
hashed_cursor_factory: tx,
} }
} }
@ -121,7 +131,7 @@ impl<'a, TX: DbTx> StateRoot<'a, TX, &'a TX> {
range: RangeInclusive<BlockNumber>, range: RangeInclusive<BlockNumber>,
) -> Result<Self, StateRootError> { ) -> Result<Self, StateRootError> {
let loaded_prefix_sets = PrefixSetLoader::new(tx).load(range)?; let loaded_prefix_sets = PrefixSetLoader::new(tx).load(range)?;
Ok(Self::new(tx) Ok(Self::from_tx(tx)
.with_changed_account_prefixes(loaded_prefix_sets.account_prefix_set.freeze()) .with_changed_account_prefixes(loaded_prefix_sets.account_prefix_set.freeze())
.with_changed_storage_prefixes( .with_changed_storage_prefixes(
loaded_prefix_sets loaded_prefix_sets
@ -178,9 +188,9 @@ impl<'a, TX: DbTx> StateRoot<'a, TX, &'a TX> {
} }
} }
impl<'a, TX, H> StateRoot<'a, TX, H> impl<T, H> StateRoot<T, H>
where where
TX: DbTx, T: TrieCursorFactory + Clone,
H: HashedCursorFactory + Clone, H: HashedCursorFactory + Clone,
{ {
/// Walks the intermediate nodes of existing state trie (if any) and hashed entries. Feeds the /// Walks the intermediate nodes of existing state trie (if any) and hashed entries. Feeds the
@ -226,7 +236,7 @@ where
let mut trie_updates = TrieUpdates::default(); let mut trie_updates = TrieUpdates::default();
let hashed_account_cursor = self.hashed_cursor_factory.hashed_account_cursor()?; let hashed_account_cursor = self.hashed_cursor_factory.hashed_account_cursor()?;
let trie_cursor = AccountTrieCursor::new(self.tx.cursor_read::<tables::AccountsTrie>()?); let trie_cursor = self.trie_cursor_factory.account_trie_cursor()?;
let (mut hash_builder, mut account_node_iter) = match self.previous_state { let (mut hash_builder, mut account_node_iter) = match self.previous_state {
Some(state) => { Some(state) => {
@ -267,14 +277,17 @@ where
// progress. // progress.
// TODO: We can consider introducing the TrieProgress::Progress/Complete // TODO: We can consider introducing the TrieProgress::Progress/Complete
// abstraction inside StorageRoot, but let's give it a try as-is for now. // abstraction inside StorageRoot, but let's give it a try as-is for now.
let storage_root_calculator = StorageRoot::new_hashed(self.tx, hashed_address) let storage_root_calculator = StorageRoot::new_hashed(
.with_hashed_cursor_factory(self.hashed_cursor_factory.clone()) self.trie_cursor_factory.clone(),
.with_changed_prefixes( self.hashed_cursor_factory.clone(),
self.changed_storage_prefixes hashed_address,
.get(&hashed_address) )
.cloned() .with_changed_prefixes(
.unwrap_or_default(), self.changed_storage_prefixes
); .get(&hashed_address)
.cloned()
.unwrap_or_default(),
);
let storage_root = if retain_updates { let storage_root = if retain_updates {
let (root, storage_slots_walked, updates) = let (root, storage_slots_walked, updates) =
@ -336,9 +349,9 @@ where
/// StorageRoot is used to compute the root node of an account storage trie. /// StorageRoot is used to compute the root node of an account storage trie.
#[derive(Debug)] #[derive(Debug)]
pub struct StorageRoot<'a, TX, H> { pub struct StorageRoot<T, H> {
/// A reference to the database transaction. /// A reference to the database transaction.
pub tx: &'a TX, pub trie_cursor_factory: T,
/// The factory for hashed cursors. /// The factory for hashed cursors.
pub hashed_cursor_factory: H, pub hashed_cursor_factory: H,
/// The hashed address of an account. /// The hashed address of an account.
@ -347,40 +360,23 @@ pub struct StorageRoot<'a, TX, H> {
pub changed_prefixes: PrefixSet, pub changed_prefixes: PrefixSet,
} }
impl<'a, TX: DbTx> StorageRoot<'a, TX, &'a TX> { impl<T, H> StorageRoot<T, H> {
/// Creates a new storage root calculator given an raw address. /// Creates a new storage root calculator given a raw address.
pub fn new(tx: &'a TX, address: Address) -> Self { pub fn new(trie_cursor_factory: T, hashed_cursor_factory: H, address: Address) -> Self {
Self::new_hashed(tx, keccak256(address)) Self::new_hashed(trie_cursor_factory, hashed_cursor_factory, keccak256(address))
} }
/// Creates a new storage root calculator given a hashed address. /// Creates a new storage root calculator given a hashed address.
pub fn new_hashed(tx: &'a TX, hashed_address: B256) -> Self { pub fn new_hashed(
Self { trie_cursor_factory: T,
tx,
hashed_address,
changed_prefixes: PrefixSetMut::default().freeze(),
hashed_cursor_factory: tx,
}
}
}
impl<'a, TX, H> StorageRoot<'a, TX, H> {
/// Creates a new storage root calculator given an raw address.
pub fn new_with_factory(tx: &'a TX, hashed_cursor_factory: H, address: Address) -> Self {
Self::new_hashed_with_factory(tx, hashed_cursor_factory, keccak256(address))
}
/// Creates a new storage root calculator given a hashed address.
pub fn new_hashed_with_factory(
tx: &'a TX,
hashed_cursor_factory: H, hashed_cursor_factory: H,
hashed_address: B256, hashed_address: B256,
) -> Self { ) -> Self {
Self { Self {
tx, trie_cursor_factory,
hashed_cursor_factory,
hashed_address, hashed_address,
changed_prefixes: PrefixSetMut::default().freeze(), changed_prefixes: PrefixSetMut::default().freeze(),
hashed_cursor_factory,
} }
} }
@ -391,22 +387,41 @@ impl<'a, TX, H> StorageRoot<'a, TX, H> {
} }
/// Set the hashed cursor factory. /// Set the hashed cursor factory.
pub fn with_hashed_cursor_factory<HF>( pub fn with_hashed_cursor_factory<HF>(self, hashed_cursor_factory: HF) -> StorageRoot<T, HF> {
self,
hashed_cursor_factory: HF,
) -> StorageRoot<'a, TX, HF> {
StorageRoot { StorageRoot {
tx: self.tx, trie_cursor_factory: self.trie_cursor_factory,
hashed_cursor_factory,
hashed_address: self.hashed_address,
changed_prefixes: self.changed_prefixes,
}
}
/// Set the trie cursor factory.
pub fn with_trie_cursor_factory<TF>(self, trie_cursor_factory: TF) -> StorageRoot<TF, H> {
StorageRoot {
trie_cursor_factory,
hashed_cursor_factory: self.hashed_cursor_factory,
hashed_address: self.hashed_address, hashed_address: self.hashed_address,
changed_prefixes: self.changed_prefixes, changed_prefixes: self.changed_prefixes,
hashed_cursor_factory,
} }
} }
} }
impl<'a, TX, H> StorageRoot<'a, TX, H> impl<'a, TX: DbTx> StorageRoot<&'a TX, &'a TX> {
/// Create a new storage root calculator from database transaction and raw address.
pub fn from_tx(tx: &'a TX, address: Address) -> Self {
Self::new(tx, tx, address)
}
/// Create a new storage root calculator from database transaction and hashed address.
pub fn from_tx_hashed(tx: &'a TX, hashed_address: B256) -> Self {
Self::new_hashed(tx, tx, hashed_address)
}
}
impl<T, H> StorageRoot<T, H>
where where
TX: DbTx, T: TrieCursorFactory,
H: HashedCursorFactory, H: HashedCursorFactory,
{ {
/// Walks the hashed storage table entries for a given address and calculates the storage root. /// Walks the hashed storage table entries for a given address and calculates the storage root.
@ -444,10 +459,7 @@ where
)) ))
} }
let trie_cursor = StorageTrieCursor::new( let trie_cursor = self.trie_cursor_factory.storage_tries_cursor(self.hashed_address)?;
self.tx.cursor_dup_read::<tables::StoragesTrie>()?,
self.hashed_address,
);
let walker = TrieWalker::new(trie_cursor, self.changed_prefixes.clone()) let walker = TrieWalker::new(trie_cursor, self.changed_prefixes.clone())
.with_updates(retain_updates); .with_updates(retain_updates);
@ -545,7 +557,7 @@ mod tests {
// Generate the intermediate nodes on the receiving end of the channel // Generate the intermediate nodes on the receiving end of the channel
let (_, _, trie_updates) = let (_, _, trie_updates) =
StorageRoot::new_hashed(tx.tx_ref(), hashed_address).root_with_updates().unwrap(); StorageRoot::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 // 1. Some state transition happens, update the hashed storage to the new value
let modified_key = B256::from_str(modified).unwrap(); let modified_key = B256::from_str(modified).unwrap();
@ -559,7 +571,7 @@ mod tests {
.unwrap(); .unwrap();
// 2. Calculate full merkle root // 2. Calculate full merkle root
let loader = StorageRoot::new_hashed(tx.tx_ref(), hashed_address); let loader = StorageRoot::from_tx_hashed(tx.tx_ref(), hashed_address);
let modified_root = loader.root().unwrap(); let modified_root = loader.root().unwrap();
// Update the intermediate roots table so that we can run the incremental verification // Update the intermediate roots table so that we can run the incremental verification
@ -568,7 +580,7 @@ mod tests {
// 3. Calculate the incremental root // 3. Calculate the incremental root
let mut storage_changes = PrefixSetMut::default(); let mut storage_changes = PrefixSetMut::default();
storage_changes.insert(Nibbles::unpack(modified_key)); storage_changes.insert(Nibbles::unpack(modified_key));
let loader = StorageRoot::new_hashed(tx.tx_ref(), hashed_address) let loader = StorageRoot::from_tx_hashed(tx.tx_ref(), hashed_address)
.with_changed_prefixes(storage_changes.freeze()); .with_changed_prefixes(storage_changes.freeze());
let incremental_root = loader.root().unwrap(); let incremental_root = loader.root().unwrap();
@ -608,7 +620,7 @@ mod tests {
tx.commit().unwrap(); tx.commit().unwrap();
let tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let got = StorageRoot::new(tx.tx_ref(), address).root().unwrap(); let got = StorageRoot::from_tx(tx.tx_ref(), address).root().unwrap();
let expected = storage_root(storage.into_iter()); let expected = storage_root(storage.into_iter());
assert_eq!(expected, got); assert_eq!(expected, got);
}); });
@ -667,7 +679,7 @@ mod tests {
tx.commit().unwrap(); tx.commit().unwrap();
let tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let got = StorageRoot::new(tx.tx_ref(), address).root().unwrap(); let got = StorageRoot::from_tx(tx.tx_ref(), address).root().unwrap();
assert_eq!(got, EMPTY_ROOT_HASH); assert_eq!(got, EMPTY_ROOT_HASH);
} }
@ -692,7 +704,7 @@ mod tests {
tx.commit().unwrap(); tx.commit().unwrap();
let tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let got = StorageRoot::new(tx.tx_ref(), address).root().unwrap(); let got = StorageRoot::from_tx(tx.tx_ref(), address).root().unwrap();
assert_eq!(storage_root(storage.into_iter()), got); assert_eq!(storage_root(storage.into_iter()), got);
} }
@ -732,7 +744,7 @@ mod tests {
let mut intermediate_state: Option<Box<IntermediateStateRootState>> = None; let mut intermediate_state: Option<Box<IntermediateStateRootState>> = None;
while got.is_none() { while got.is_none() {
let calculator = StateRoot::new(tx.tx_ref()) let calculator = StateRoot::from_tx(tx.tx_ref())
.with_threshold(threshold) .with_threshold(threshold)
.with_intermediate_state(intermediate_state.take().map(|state| *state)); .with_intermediate_state(intermediate_state.take().map(|state| *state));
match calculator.root_with_progress().unwrap() { match calculator.root_with_progress().unwrap() {
@ -763,7 +775,7 @@ mod tests {
let expected = state_root(state.into_iter()); let expected = state_root(state.into_iter());
let tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let got = StateRoot::new(tx.tx_ref()).root().unwrap(); let got = StateRoot::from_tx(tx.tx_ref()).root().unwrap();
assert_eq!(expected, got); assert_eq!(expected, got);
} }
@ -802,7 +814,7 @@ mod tests {
tx.commit().unwrap(); tx.commit().unwrap();
let tx = factory.provider_rw().unwrap(); let tx = factory.provider_rw().unwrap();
let account3_storage_root = StorageRoot::new(tx.tx_ref(), address3).root().unwrap(); let account3_storage_root = StorageRoot::from_tx(tx.tx_ref(), address3).root().unwrap();
let expected_root = storage_root_prehashed(storage.into_iter()); let expected_root = storage_root_prehashed(storage.into_iter());
assert_eq!(expected_root, account3_storage_root); assert_eq!(expected_root, account3_storage_root);
} }
@ -869,7 +881,7 @@ mod tests {
} }
hashed_storage_cursor.upsert(key3, StorageEntry { key: hashed_slot, value }).unwrap(); hashed_storage_cursor.upsert(key3, StorageEntry { key: hashed_slot, value }).unwrap();
} }
let account3_storage_root = StorageRoot::new(tx.tx_ref(), address3).root().unwrap(); let account3_storage_root = StorageRoot::from_tx(tx.tx_ref(), address3).root().unwrap();
hash_builder.add_leaf( hash_builder.add_leaf(
Nibbles::unpack(key3), Nibbles::unpack(key3),
&encode_account(account3, Some(account3_storage_root)), &encode_account(account3, Some(account3_storage_root)),
@ -918,7 +930,7 @@ mod tests {
assert_eq!(hash_builder.root(), computed_expected_root); assert_eq!(hash_builder.root(), computed_expected_root);
// Check state root calculation from scratch // Check state root calculation from scratch
let (root, trie_updates) = StateRoot::new(tx.tx_ref()).root_with_updates().unwrap(); let (root, trie_updates) = StateRoot::from_tx(tx.tx_ref()).root_with_updates().unwrap();
assert_eq!(root, computed_expected_root); assert_eq!(root, computed_expected_root);
// Check account trie // Check account trie
@ -983,7 +995,7 @@ mod tests {
B256::from_str("8e263cd4eefb0c3cbbb14e5541a66a755cad25bcfab1e10dd9d706263e811b28") B256::from_str("8e263cd4eefb0c3cbbb14e5541a66a755cad25bcfab1e10dd9d706263e811b28")
.unwrap(); .unwrap();
let (root, trie_updates) = StateRoot::new(tx.tx_ref()) let (root, trie_updates) = StateRoot::from_tx(tx.tx_ref())
.with_changed_account_prefixes(prefix_set.freeze()) .with_changed_account_prefixes(prefix_set.freeze())
.root_with_updates() .root_with_updates()
.unwrap(); .unwrap();
@ -1035,7 +1047,7 @@ mod tests {
(key6, encode_account(account6, None)), (key6, encode_account(account6, None)),
]); ]);
let (root, trie_updates) = StateRoot::new(tx.tx_ref()) let (root, trie_updates) = StateRoot::from_tx(tx.tx_ref())
.with_changed_account_prefixes(account_prefix_set.freeze()) .with_changed_account_prefixes(account_prefix_set.freeze())
.root_with_updates() .root_with_updates()
.unwrap(); .unwrap();
@ -1092,7 +1104,7 @@ mod tests {
(key6, encode_account(account6, None)), (key6, encode_account(account6, None)),
]); ]);
let (root, trie_updates) = StateRoot::new(tx.tx_ref()) let (root, trie_updates) = StateRoot::from_tx(tx.tx_ref())
.with_changed_account_prefixes(account_prefix_set.freeze()) .with_changed_account_prefixes(account_prefix_set.freeze())
.root_with_updates() .root_with_updates()
.unwrap(); .unwrap();
@ -1131,7 +1143,7 @@ mod tests {
let expected = extension_node_trie(&tx); let expected = extension_node_trie(&tx);
let (got, updates) = StateRoot::new(tx.tx_ref()).root_with_updates().unwrap(); let (got, updates) = StateRoot::from_tx(tx.tx_ref()).root_with_updates().unwrap();
assert_eq!(expected, got); assert_eq!(expected, got);
// Check account trie // Check account trie
@ -1156,7 +1168,7 @@ mod tests {
let expected = extension_node_trie(&tx); let expected = extension_node_trie(&tx);
let (got, updates) = StateRoot::new(tx.tx_ref()).root_with_updates().unwrap(); let (got, updates) = StateRoot::from_tx(tx.tx_ref()).root_with_updates().unwrap();
assert_eq!(expected, got); assert_eq!(expected, got);
updates.flush(tx.tx_ref()).unwrap(); updates.flush(tx.tx_ref()).unwrap();
@ -1195,7 +1207,7 @@ mod tests {
} }
} }
let (state_root, trie_updates) = StateRoot::new(tx.tx_ref()) let (state_root, trie_updates) = StateRoot::from_tx(tx.tx_ref())
.with_changed_account_prefixes(changes.freeze()) .with_changed_account_prefixes(changes.freeze())
.root_with_updates() .root_with_updates()
.unwrap(); .unwrap();
@ -1220,7 +1232,7 @@ mod tests {
let (expected_root, expected_updates) = extension_node_storage_trie(&tx, hashed_address); let (expected_root, expected_updates) = extension_node_storage_trie(&tx, hashed_address);
let (got, _, updates) = let (got, _, updates) =
StorageRoot::new_hashed(tx.tx_ref(), hashed_address).root_with_updates().unwrap(); StorageRoot::from_tx_hashed(tx.tx_ref(), hashed_address).root_with_updates().unwrap();
assert_eq!(expected_root, got); assert_eq!(expected_root, got);
// Check account trie // Check account trie

View File

@ -1,92 +0,0 @@
use super::TrieCursor;
use crate::updates::TrieKey;
use reth_db::{cursor::DbCursorRO, tables, DatabaseError};
use reth_primitives::trie::{BranchNodeCompact, StoredNibbles};
/// A cursor over the account trie.
#[derive(Debug)]
pub struct AccountTrieCursor<C>(C);
impl<C> AccountTrieCursor<C> {
/// Create a new account trie cursor.
pub fn new(cursor: C) -> Self {
Self(cursor)
}
}
impl<C> TrieCursor for AccountTrieCursor<C>
where
C: DbCursorRO<tables::AccountsTrie>,
{
type Key = StoredNibbles;
fn seek_exact(
&mut self,
key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(self.0.seek_exact(key)?.map(|value| (value.0 .0.to_vec(), value.1)))
}
fn seek(
&mut self,
key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(self.0.seek(key)?.map(|value| (value.0 .0.to_vec(), value.1)))
}
fn current(&mut self) -> Result<Option<TrieKey>, DatabaseError> {
Ok(self.0.current()?.map(|(k, _)| TrieKey::AccountNode(k)))
}
}
#[cfg(test)]
mod tests {
use super::*;
use reth_db::{
cursor::{DbCursorRO, DbCursorRW},
tables,
transaction::DbTxMut,
};
use reth_primitives::hex_literal::hex;
use reth_provider::test_utils::create_test_provider_factory;
#[test]
fn test_account_trie_order() {
let factory = create_test_provider_factory();
let provider = factory.provider_rw().unwrap();
let mut cursor = provider.tx_ref().cursor_write::<tables::AccountsTrie>().unwrap();
let data = vec![
hex!("0303040e").to_vec(),
hex!("030305").to_vec(),
hex!("03030500").to_vec(),
hex!("0303050a").to_vec(),
];
for key in data.clone() {
cursor
.upsert(
key.into(),
BranchNodeCompact::new(
0b0000_0010_0000_0001,
0b0000_0010_0000_0001,
0,
Vec::default(),
None,
),
)
.unwrap();
}
let db_data = cursor.walk_range(..).unwrap().collect::<Result<Vec<_>, _>>().unwrap();
assert_eq!(db_data[0].0 .0.to_vec(), data[0]);
assert_eq!(db_data[1].0 .0.to_vec(), data[1]);
assert_eq!(db_data[2].0 .0.to_vec(), data[2]);
assert_eq!(db_data[3].0 .0.to_vec(), data[3]);
assert_eq!(
cursor.seek(hex!("0303040f").to_vec().into()).unwrap().map(|(k, _)| k.0.to_vec()),
Some(data[1].clone())
);
}
}

View File

@ -0,0 +1,191 @@
use super::{TrieCursor, TrieCursorFactory};
use crate::updates::TrieKey;
use reth_db::{
cursor::{DbCursorRO, DbDupCursorRO},
tables,
transaction::DbTx,
DatabaseError,
};
use reth_primitives::{
trie::{BranchNodeCompact, StoredNibbles, StoredNibblesSubKey},
B256,
};
/// Implementation of the trie cursor factory for a database transaction.
impl<'a, TX: DbTx> TrieCursorFactory for &'a TX {
fn account_trie_cursor(
&self,
) -> Result<Box<dyn TrieCursor<Key = StoredNibbles> + '_>, DatabaseError> {
Ok(Box::new(DatabaseAccountTrieCursor::new(self.cursor_read::<tables::AccountsTrie>()?)))
}
fn storage_tries_cursor(
&self,
hashed_address: B256,
) -> Result<Box<dyn TrieCursor<Key = StoredNibblesSubKey> + '_>, DatabaseError> {
Ok(Box::new(DatabaseStorageTrieCursor::new(
self.cursor_dup_read::<tables::StoragesTrie>()?,
hashed_address,
)))
}
}
/// A cursor over the account trie.
#[derive(Debug)]
pub struct DatabaseAccountTrieCursor<C>(C);
impl<C> DatabaseAccountTrieCursor<C> {
/// Create a new account trie cursor.
pub fn new(cursor: C) -> Self {
Self(cursor)
}
}
impl<C> TrieCursor for DatabaseAccountTrieCursor<C>
where
C: DbCursorRO<tables::AccountsTrie>,
{
type Key = StoredNibbles;
fn seek_exact(
&mut self,
key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(self.0.seek_exact(key)?.map(|value| (value.0 .0.to_vec(), value.1)))
}
fn seek(
&mut self,
key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(self.0.seek(key)?.map(|value| (value.0 .0.to_vec(), value.1)))
}
fn current(&mut self) -> Result<Option<TrieKey>, DatabaseError> {
Ok(self.0.current()?.map(|(k, _)| TrieKey::AccountNode(k)))
}
}
/// A cursor over the storage tries stored in the database.
#[derive(Debug)]
pub struct DatabaseStorageTrieCursor<C> {
/// The underlying cursor.
pub cursor: C,
hashed_address: B256,
}
impl<C> DatabaseStorageTrieCursor<C> {
/// Create a new storage trie cursor.
pub fn new(cursor: C, hashed_address: B256) -> Self {
Self { cursor, hashed_address }
}
}
impl<C> TrieCursor for DatabaseStorageTrieCursor<C>
where
C: DbDupCursorRO<tables::StoragesTrie> + DbCursorRO<tables::StoragesTrie>,
{
type Key = StoredNibblesSubKey;
fn seek_exact(
&mut self,
key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(self
.cursor
.seek_by_key_subkey(self.hashed_address, key.clone())?
.filter(|e| e.nibbles == key)
.map(|value| (value.nibbles.to_vec(), value.node)))
}
fn seek(
&mut self,
key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(self
.cursor
.seek_by_key_subkey(self.hashed_address, key)?
.map(|value| (value.nibbles.to_vec(), value.node)))
}
fn current(&mut self) -> Result<Option<TrieKey>, DatabaseError> {
Ok(self.cursor.current()?.map(|(k, v)| TrieKey::StorageNode(k, v.nibbles)))
}
}
#[cfg(test)]
mod tests {
use super::*;
use reth_db::{
cursor::{DbCursorRO, DbCursorRW},
tables,
transaction::DbTxMut,
};
use reth_primitives::{
hex_literal::hex,
trie::{BranchNodeCompact, StorageTrieEntry},
};
use reth_provider::test_utils::create_test_provider_factory;
#[test]
fn test_account_trie_order() {
let factory = create_test_provider_factory();
let provider = factory.provider_rw().unwrap();
let mut cursor = provider.tx_ref().cursor_write::<tables::AccountsTrie>().unwrap();
let data = vec![
hex!("0303040e").to_vec(),
hex!("030305").to_vec(),
hex!("03030500").to_vec(),
hex!("0303050a").to_vec(),
];
for key in data.clone() {
cursor
.upsert(
key.into(),
BranchNodeCompact::new(
0b0000_0010_0000_0001,
0b0000_0010_0000_0001,
0,
Vec::default(),
None,
),
)
.unwrap();
}
let db_data = cursor.walk_range(..).unwrap().collect::<Result<Vec<_>, _>>().unwrap();
assert_eq!(db_data[0].0 .0.to_vec(), data[0]);
assert_eq!(db_data[1].0 .0.to_vec(), data[1]);
assert_eq!(db_data[2].0 .0.to_vec(), data[2]);
assert_eq!(db_data[3].0 .0.to_vec(), data[3]);
assert_eq!(
cursor.seek(hex!("0303040f").to_vec().into()).unwrap().map(|(k, _)| k.0.to_vec()),
Some(data[1].clone())
);
}
// tests that upsert and seek match on the storage trie cursor
#[test]
fn test_storage_cursor_abstraction() {
let factory = create_test_provider_factory();
let provider = factory.provider_rw().unwrap();
let mut cursor = provider.tx_ref().cursor_dup_write::<tables::StoragesTrie>().unwrap();
let hashed_address = B256::random();
let key = vec![0x2, 0x3];
let value = BranchNodeCompact::new(1, 1, 1, vec![B256::random()], None);
cursor
.upsert(
hashed_address,
StorageTrieEntry { nibbles: key.clone().into(), node: value.clone() },
)
.unwrap();
let mut cursor = DatabaseStorageTrieCursor::new(cursor, hashed_address);
assert_eq!(cursor.seek(key.into()).unwrap().unwrap().1, value);
}
}

View File

@ -1,17 +1,37 @@
use crate::updates::TrieKey; use crate::updates::TrieKey;
use reth_db::DatabaseError; use reth_db::DatabaseError;
use reth_primitives::trie::BranchNodeCompact; use reth_primitives::{
trie::{BranchNodeCompact, StoredNibbles, StoredNibblesSubKey},
mod account_cursor; B256,
mod storage_cursor;
mod subnode;
pub use self::{
account_cursor::AccountTrieCursor, storage_cursor::StorageTrieCursor, subnode::CursorSubNode,
}; };
mod database_cursors;
mod subnode;
/// Noop trie cursor implementations.
pub mod noop;
pub use self::{
database_cursors::{DatabaseAccountTrieCursor, DatabaseStorageTrieCursor},
subnode::CursorSubNode,
};
/// Factory for creating trie cursors.
pub trait TrieCursorFactory {
/// Create an account trie cursor.
fn account_trie_cursor(
&self,
) -> Result<Box<dyn TrieCursor<Key = StoredNibbles> + '_>, DatabaseError>;
/// Create a storage tries cursor.
fn storage_tries_cursor(
&self,
hashed_address: B256,
) -> Result<Box<dyn TrieCursor<Key = StoredNibblesSubKey> + '_>, DatabaseError>;
}
/// A cursor for navigating a trie that works with both Tables and DupSort tables. /// A cursor for navigating a trie that works with both Tables and DupSort tables.
#[auto_impl::auto_impl(&mut)] #[auto_impl::auto_impl(&mut, Box)]
pub trait TrieCursor { pub trait TrieCursor {
/// The key type of the cursor. /// The key type of the cursor.
type Key: From<Vec<u8>>; type Key: From<Vec<u8>>;

View File

@ -0,0 +1,80 @@
use reth_db::DatabaseError;
use reth_primitives::trie::{BranchNodeCompact, StoredNibbles, StoredNibblesSubKey};
use crate::updates::TrieKey;
use super::{TrieCursor, TrieCursorFactory};
/// Noop trie cursor factory.
#[derive(Default, Debug)]
#[non_exhaustive]
pub struct NoopTrieCursorFactory;
impl TrieCursorFactory for NoopTrieCursorFactory {
fn account_trie_cursor(
&self,
) -> Result<Box<dyn TrieCursor<Key = StoredNibbles> + '_>, DatabaseError> {
Ok(Box::<NoopAccountTrieCursor>::default())
}
fn storage_tries_cursor(
&self,
_hashed_address: reth_primitives::B256,
) -> Result<Box<dyn TrieCursor<Key = StoredNibblesSubKey> + '_>, DatabaseError> {
Ok(Box::<NoopStorageTrieCursor>::default())
}
}
/// Noop account trie cursor.
#[derive(Default, Debug)]
#[non_exhaustive]
pub struct NoopAccountTrieCursor;
impl TrieCursor for NoopAccountTrieCursor {
type Key = StoredNibbles;
fn seek(
&mut self,
_key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(None)
}
fn seek_exact(
&mut self,
_key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(None)
}
fn current(&mut self) -> Result<Option<TrieKey>, DatabaseError> {
Ok(None)
}
}
/// Noop account trie cursor.
#[derive(Default, Debug)]
#[non_exhaustive]
pub struct NoopStorageTrieCursor;
impl TrieCursor for NoopStorageTrieCursor {
type Key = StoredNibblesSubKey;
fn seek(
&mut self,
_key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(None)
}
fn seek_exact(
&mut self,
_key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(None)
}
fn current(&mut self) -> Result<Option<TrieKey>, DatabaseError> {
Ok(None)
}
}

View File

@ -1,88 +0,0 @@
use super::TrieCursor;
use crate::updates::TrieKey;
use reth_db::{
cursor::{DbCursorRO, DbDupCursorRO},
tables, DatabaseError,
};
use reth_primitives::{
trie::{BranchNodeCompact, StoredNibblesSubKey},
B256,
};
/// A cursor over the storage trie.
#[derive(Debug)]
pub struct StorageTrieCursor<C> {
/// The underlying cursor.
pub cursor: C,
hashed_address: B256,
}
impl<C> StorageTrieCursor<C> {
/// Create a new storage trie cursor.
pub fn new(cursor: C, hashed_address: B256) -> Self {
Self { cursor, hashed_address }
}
}
impl<C> TrieCursor for StorageTrieCursor<C>
where
C: DbDupCursorRO<tables::StoragesTrie> + DbCursorRO<tables::StoragesTrie>,
{
type Key = StoredNibblesSubKey;
fn seek_exact(
&mut self,
key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(self
.cursor
.seek_by_key_subkey(self.hashed_address, key.clone())?
.filter(|e| e.nibbles == key)
.map(|value| (value.nibbles.to_vec(), value.node)))
}
fn seek(
&mut self,
key: Self::Key,
) -> Result<Option<(Vec<u8>, BranchNodeCompact)>, DatabaseError> {
Ok(self
.cursor
.seek_by_key_subkey(self.hashed_address, key)?
.map(|value| (value.nibbles.to_vec(), value.node)))
}
fn current(&mut self) -> Result<Option<TrieKey>, DatabaseError> {
Ok(self.cursor.current()?.map(|(k, v)| TrieKey::StorageNode(k, v.nibbles)))
}
}
#[cfg(test)]
mod tests {
use super::*;
use reth_db::{cursor::DbCursorRW, tables, transaction::DbTxMut};
use reth_primitives::trie::{BranchNodeCompact, StorageTrieEntry};
use reth_provider::test_utils::create_test_provider_factory;
// tests that upsert and seek match on the storagetrie cursor
#[test]
fn test_storage_cursor_abstraction() {
let factory = create_test_provider_factory();
let provider = factory.provider_rw().unwrap();
let mut cursor = provider.tx_ref().cursor_dup_write::<tables::StoragesTrie>().unwrap();
let hashed_address = B256::random();
let key = vec![0x2, 0x3];
let value = BranchNodeCompact::new(1, 1, 1, vec![B256::random()], None);
cursor
.upsert(
hashed_address,
StorageTrieEntry { nibbles: key.clone().into(), node: value.clone() },
)
.unwrap();
let mut cursor = StorageTrieCursor::new(cursor, hashed_address);
assert_eq!(cursor.seek(key.into()).unwrap().unwrap().1, value);
}
}

View File

@ -250,7 +250,7 @@ mod tests {
use super::*; use super::*;
use crate::{ use crate::{
prefix_set::PrefixSetMut, prefix_set::PrefixSetMut,
trie_cursor::{AccountTrieCursor, StorageTrieCursor}, trie_cursor::{DatabaseAccountTrieCursor, DatabaseStorageTrieCursor},
}; };
use reth_db::{cursor::DbCursorRW, tables, transaction::DbTxMut}; use reth_db::{cursor::DbCursorRW, tables, transaction::DbTxMut};
use reth_primitives::trie::StorageTrieEntry; use reth_primitives::trie::StorageTrieEntry;
@ -286,7 +286,7 @@ mod tests {
for (k, v) in &inputs { for (k, v) in &inputs {
account_cursor.upsert(k.clone().into(), v.clone()).unwrap(); account_cursor.upsert(k.clone().into(), v.clone()).unwrap();
} }
let account_trie = AccountTrieCursor::new(account_cursor); let account_trie = DatabaseAccountTrieCursor::new(account_cursor);
test_cursor(account_trie, &expected); test_cursor(account_trie, &expected);
let hashed_address = B256::random(); let hashed_address = B256::random();
@ -299,7 +299,7 @@ mod tests {
) )
.unwrap(); .unwrap();
} }
let storage_trie = StorageTrieCursor::new(storage_cursor, hashed_address); let storage_trie = DatabaseStorageTrieCursor::new(storage_cursor, hashed_address);
test_cursor(storage_trie, &expected); test_cursor(storage_trie, &expected);
} }
@ -357,7 +357,7 @@ mod tests {
cursor.upsert(hashed_address, StorageTrieEntry { nibbles: k.into(), node: v }).unwrap(); cursor.upsert(hashed_address, StorageTrieEntry { nibbles: k.into(), node: v }).unwrap();
} }
let mut trie = StorageTrieCursor::new(cursor, hashed_address); let mut trie = DatabaseStorageTrieCursor::new(cursor, hashed_address);
// No changes // No changes
let mut cursor = TrieWalker::new(&mut trie, Default::default()); let mut cursor = TrieWalker::new(&mut trie, Default::default());