mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-10 15:58:27 -05:00
refactor(trie): prefix sets (#6502)
This commit is contained in:
@@ -1662,12 +1662,9 @@ mod tests {
|
||||
);
|
||||
|
||||
let provider = tree.externals.provider_factory.provider().unwrap();
|
||||
let (acc_prefix_set, storage_prefix_set) = exec5.hash_state_slow().construct_prefix_sets();
|
||||
let state_root = StateRoot::from_tx(provider.tx_ref())
|
||||
.with_changed_account_prefixes(acc_prefix_set)
|
||||
.with_changed_storage_prefixes(storage_prefix_set)
|
||||
.root()
|
||||
.unwrap();
|
||||
let prefix_sets = exec5.hash_state_slow().construct_prefix_sets();
|
||||
let state_root =
|
||||
StateRoot::from_tx(provider.tx_ref()).with_prefix_sets(prefix_sets).root().unwrap();
|
||||
assert_eq!(state_root, block5.state_root);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,11 @@ use reth_primitives::{
|
||||
StorageEntry, TransactionMeta, TransactionSigned, TransactionSignedEcRecovered,
|
||||
TransactionSignedNoHash, TxHash, TxNumber, Withdrawal, Withdrawals, B256, U256,
|
||||
};
|
||||
use reth_trie::{prefix_set::PrefixSetMut, updates::TrieUpdates, HashedPostState, StateRoot};
|
||||
use reth_trie::{
|
||||
prefix_set::{PrefixSet, PrefixSetMut, TriePrefixSets},
|
||||
updates::TrieUpdates,
|
||||
HashedPostState, StateRoot,
|
||||
};
|
||||
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg, SpecId};
|
||||
use std::{
|
||||
collections::{hash_map, BTreeMap, BTreeSet, HashMap, HashSet},
|
||||
@@ -2081,7 +2085,7 @@ impl<TX: DbTxMut + DbTx> HashingWriter for DatabaseProvider<TX> {
|
||||
) -> ProviderResult<()> {
|
||||
// Initialize prefix sets.
|
||||
let mut account_prefix_set = PrefixSetMut::default();
|
||||
let mut storage_prefix_set: HashMap<B256, PrefixSetMut> = HashMap::default();
|
||||
let mut storage_prefix_sets: HashMap<B256, PrefixSetMut> = HashMap::default();
|
||||
let mut destroyed_accounts = HashSet::default();
|
||||
|
||||
let mut durations_recorder = metrics::DurationsRecorder::default();
|
||||
@@ -2094,7 +2098,7 @@ impl<TX: DbTxMut + DbTx> HashingWriter for DatabaseProvider<TX> {
|
||||
for (hashed_address, hashed_slots) in storage_entries {
|
||||
account_prefix_set.insert(Nibbles::unpack(hashed_address));
|
||||
for slot in hashed_slots {
|
||||
storage_prefix_set
|
||||
storage_prefix_sets
|
||||
.entry(hashed_address)
|
||||
.or_default()
|
||||
.insert(Nibbles::unpack(slot));
|
||||
@@ -2121,12 +2125,16 @@ impl<TX: DbTxMut + DbTx> HashingWriter for DatabaseProvider<TX> {
|
||||
{
|
||||
// This is the same as `StateRoot::incremental_root_with_updates`, only the prefix sets
|
||||
// are pre-loaded.
|
||||
let prefix_sets = TriePrefixSets {
|
||||
account_prefix_set: account_prefix_set.freeze(),
|
||||
storage_prefix_sets: storage_prefix_sets
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, v.freeze()))
|
||||
.collect(),
|
||||
destroyed_accounts,
|
||||
};
|
||||
let (state_root, trie_updates) = StateRoot::from_tx(&self.tx)
|
||||
.with_changed_account_prefixes(account_prefix_set.freeze())
|
||||
.with_changed_storage_prefixes(
|
||||
storage_prefix_set.into_iter().map(|(k, v)| (k, v.freeze())).collect(),
|
||||
)
|
||||
.with_destroyed_accounts(destroyed_accounts)
|
||||
.with_prefix_sets(prefix_sets)
|
||||
.root_with_updates()
|
||||
.map_err(Into::<reth_db::DatabaseError>::into)?;
|
||||
if state_root != expected_state_root {
|
||||
@@ -2269,13 +2277,10 @@ impl<TX: DbTxMut + DbTx> BlockExecutionWriter for DatabaseProvider<TX> {
|
||||
if TAKE {
|
||||
let storage_range = BlockNumberAddress::range(range.clone());
|
||||
|
||||
// Initialize prefix sets.
|
||||
let mut account_prefix_set = PrefixSetMut::default();
|
||||
let mut storage_prefix_set: HashMap<B256, PrefixSetMut> = HashMap::default();
|
||||
let mut destroyed_accounts = HashSet::default();
|
||||
|
||||
// Unwind account hashes. Add changed accounts to account prefix set.
|
||||
let hashed_addresses = self.unwind_account_hashing(range.clone())?;
|
||||
let mut account_prefix_set = PrefixSetMut::with_capacity(hashed_addresses.len());
|
||||
let mut destroyed_accounts = HashSet::default();
|
||||
for (hashed_address, account) in hashed_addresses {
|
||||
account_prefix_set.insert(Nibbles::unpack(hashed_address));
|
||||
if account.is_none() {
|
||||
@@ -2288,15 +2293,15 @@ impl<TX: DbTxMut + DbTx> BlockExecutionWriter for DatabaseProvider<TX> {
|
||||
|
||||
// Unwind storage hashes. Add changed account and storage keys to corresponding prefix
|
||||
// sets.
|
||||
let mut storage_prefix_sets = HashMap::<B256, PrefixSet>::default();
|
||||
let storage_entries = self.unwind_storage_hashing(storage_range.clone())?;
|
||||
for (hashed_address, hashed_slots) in storage_entries {
|
||||
account_prefix_set.insert(Nibbles::unpack(hashed_address));
|
||||
let mut storage_prefix_set = PrefixSetMut::with_capacity(hashed_slots.len());
|
||||
for slot in hashed_slots {
|
||||
storage_prefix_set
|
||||
.entry(hashed_address)
|
||||
.or_default()
|
||||
.insert(Nibbles::unpack(slot));
|
||||
storage_prefix_set.insert(Nibbles::unpack(slot));
|
||||
}
|
||||
storage_prefix_sets.insert(hashed_address, storage_prefix_set.freeze());
|
||||
}
|
||||
|
||||
// Unwind storage history indices.
|
||||
@@ -2305,12 +2310,13 @@ impl<TX: DbTxMut + DbTx> BlockExecutionWriter for DatabaseProvider<TX> {
|
||||
// Calculate the reverted merkle root.
|
||||
// This is the same as `StateRoot::incremental_root_with_updates`, only the prefix sets
|
||||
// are pre-loaded.
|
||||
let prefix_sets = TriePrefixSets {
|
||||
account_prefix_set: account_prefix_set.freeze(),
|
||||
storage_prefix_sets,
|
||||
destroyed_accounts,
|
||||
};
|
||||
let (new_state_root, trie_updates) = StateRoot::from_tx(&self.tx)
|
||||
.with_changed_account_prefixes(account_prefix_set.freeze())
|
||||
.with_changed_storage_prefixes(
|
||||
storage_prefix_set.into_iter().map(|(k, v)| (k, v.freeze())).collect(),
|
||||
)
|
||||
.with_destroyed_accounts(destroyed_accounts)
|
||||
.with_prefix_sets(prefix_sets)
|
||||
.root_with_updates()
|
||||
.map_err(Into::<reth_db::DatabaseError>::into)?;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::PrefixSetMut;
|
||||
use super::{PrefixSetMut, TriePrefixSets};
|
||||
use derive_more::Deref;
|
||||
use reth_db::{
|
||||
cursor::DbCursorRO,
|
||||
@@ -13,19 +13,8 @@ use std::{
|
||||
ops::RangeInclusive,
|
||||
};
|
||||
|
||||
/// Loaded prefix sets.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct LoadedPrefixSets {
|
||||
/// The account prefix set
|
||||
pub account_prefix_set: PrefixSetMut,
|
||||
/// The mapping of hashed account key to the corresponding storage prefix set
|
||||
pub storage_prefix_sets: HashMap<B256, PrefixSetMut>,
|
||||
/// The account keys of destroyed accounts
|
||||
pub destroyed_accounts: HashSet<B256>,
|
||||
}
|
||||
|
||||
/// A wrapper around a database transaction that loads prefix sets within a given block range.
|
||||
#[derive(Debug, Deref)]
|
||||
#[derive(Deref, Debug)]
|
||||
pub struct PrefixSetLoader<'a, TX>(&'a TX);
|
||||
|
||||
impl<'a, TX> PrefixSetLoader<'a, TX> {
|
||||
@@ -37,12 +26,11 @@ impl<'a, TX> PrefixSetLoader<'a, TX> {
|
||||
|
||||
impl<'a, TX: DbTx> PrefixSetLoader<'a, TX> {
|
||||
/// Load all account and storage changes for the given block range.
|
||||
pub fn load(
|
||||
self,
|
||||
range: RangeInclusive<BlockNumber>,
|
||||
) -> Result<LoadedPrefixSets, DatabaseError> {
|
||||
pub fn load(self, range: RangeInclusive<BlockNumber>) -> Result<TriePrefixSets, DatabaseError> {
|
||||
// Initialize prefix sets.
|
||||
let mut loaded_prefix_sets = LoadedPrefixSets::default();
|
||||
let mut account_prefix_set = PrefixSetMut::default();
|
||||
let mut storage_prefix_sets = HashMap::<B256, PrefixSetMut>::default();
|
||||
let mut destroyed_accounts = HashSet::default();
|
||||
|
||||
// Walk account changeset and insert account prefixes.
|
||||
let mut account_changeset_cursor = self.cursor_read::<tables::AccountChangeSet>()?;
|
||||
@@ -50,10 +38,10 @@ impl<'a, TX: DbTx> PrefixSetLoader<'a, TX> {
|
||||
for account_entry in account_changeset_cursor.walk_range(range.clone())? {
|
||||
let (_, AccountBeforeTx { address, .. }) = account_entry?;
|
||||
let hashed_address = keccak256(address);
|
||||
loaded_prefix_sets.account_prefix_set.insert(Nibbles::unpack(hashed_address));
|
||||
account_prefix_set.insert(Nibbles::unpack(hashed_address));
|
||||
|
||||
if account_plain_state_cursor.seek_exact(address)?.is_none() {
|
||||
loaded_prefix_sets.destroyed_accounts.insert(hashed_address);
|
||||
destroyed_accounts.insert(hashed_address);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,14 +52,20 @@ impl<'a, TX: DbTx> PrefixSetLoader<'a, TX> {
|
||||
for storage_entry in storage_cursor.walk_range(storage_range)? {
|
||||
let (BlockNumberAddress((_, address)), StorageEntry { key, .. }) = storage_entry?;
|
||||
let hashed_address = keccak256(address);
|
||||
loaded_prefix_sets.account_prefix_set.insert(Nibbles::unpack(hashed_address));
|
||||
loaded_prefix_sets
|
||||
.storage_prefix_sets
|
||||
account_prefix_set.insert(Nibbles::unpack(hashed_address));
|
||||
storage_prefix_sets
|
||||
.entry(hashed_address)
|
||||
.or_default()
|
||||
.insert(Nibbles::unpack(keccak256(key)));
|
||||
}
|
||||
|
||||
Ok(loaded_prefix_sets)
|
||||
Ok(TriePrefixSets {
|
||||
account_prefix_set: account_prefix_set.freeze(),
|
||||
storage_prefix_sets: storage_prefix_sets
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, v.freeze()))
|
||||
.collect(),
|
||||
destroyed_accounts,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
use reth_primitives::trie::Nibbles;
|
||||
use std::rc::Rc;
|
||||
use reth_primitives::{trie::Nibbles, B256};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
mod loader;
|
||||
pub use loader::{LoadedPrefixSets, PrefixSetLoader};
|
||||
pub use loader::PrefixSetLoader;
|
||||
|
||||
/// Collection of trie prefix sets.
|
||||
#[derive(Default, Debug)]
|
||||
pub struct TriePrefixSets {
|
||||
/// A set of account prefixes that have changed.
|
||||
pub account_prefix_set: PrefixSet,
|
||||
/// A map containing storage changes with the hashed address as key and a set of storage key
|
||||
/// prefixes as the value.
|
||||
pub storage_prefix_sets: HashMap<B256, PrefixSet>,
|
||||
/// A set of hashed addresses of destroyed accounts.
|
||||
pub destroyed_accounts: HashSet<B256>,
|
||||
}
|
||||
|
||||
/// A container for efficiently storing and checking for the presence of key prefixes.
|
||||
///
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
hashed_cursor::HashedPostStateCursorFactory,
|
||||
prefix_set::{PrefixSet, PrefixSetMut},
|
||||
prefix_set::{PrefixSetMut, TriePrefixSets},
|
||||
updates::TrieUpdates,
|
||||
StateRoot, StateRootError,
|
||||
};
|
||||
@@ -163,14 +163,19 @@ impl HashedPostState {
|
||||
HashedPostStateSorted { accounts, destroyed_accounts, storages }
|
||||
}
|
||||
|
||||
/// Construct [PrefixSet] from hashed post state.
|
||||
/// Construct [TriePrefixSets] from hashed post state.
|
||||
/// The prefix sets contain the hashed account and storage keys that have been changed in the
|
||||
/// post state.
|
||||
pub fn construct_prefix_sets(&self) -> (PrefixSet, HashMap<B256, PrefixSet>) {
|
||||
pub fn construct_prefix_sets(&self) -> TriePrefixSets {
|
||||
// Populate account prefix set.
|
||||
let mut account_prefix_set = PrefixSetMut::with_capacity(self.accounts.len());
|
||||
for hashed_address in self.accounts.keys() {
|
||||
let mut destroyed_accounts = HashSet::default();
|
||||
for (hashed_address, account) in &self.accounts {
|
||||
account_prefix_set.insert(Nibbles::unpack(hashed_address));
|
||||
|
||||
if account.is_none() {
|
||||
destroyed_accounts.insert(*hashed_address);
|
||||
}
|
||||
}
|
||||
|
||||
// Populate storage prefix sets.
|
||||
@@ -185,7 +190,11 @@ impl HashedPostState {
|
||||
storage_prefix_sets.insert(*hashed_address, prefix_set.freeze());
|
||||
}
|
||||
|
||||
(account_prefix_set.freeze(), storage_prefix_sets)
|
||||
TriePrefixSets {
|
||||
account_prefix_set: account_prefix_set.freeze(),
|
||||
storage_prefix_sets,
|
||||
destroyed_accounts,
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate the state root for this [HashedPostState].
|
||||
@@ -219,11 +228,10 @@ impl HashedPostState {
|
||||
/// The state root for this [HashedPostState].
|
||||
pub fn state_root<TX: DbTx>(&self, tx: &TX) -> Result<B256, StateRootError> {
|
||||
let sorted = self.clone().into_sorted();
|
||||
let (account_prefix_set, storage_prefix_set) = self.construct_prefix_sets();
|
||||
sorted
|
||||
.state_root_calculator(tx)
|
||||
.with_changed_account_prefixes(account_prefix_set)
|
||||
.with_changed_storage_prefixes(storage_prefix_set)
|
||||
let prefix_sets = self.construct_prefix_sets();
|
||||
StateRoot::from_tx(tx)
|
||||
.with_hashed_cursor_factory(HashedPostStateCursorFactory::new(tx, &sorted))
|
||||
.with_prefix_sets(prefix_sets)
|
||||
.root()
|
||||
}
|
||||
|
||||
@@ -234,11 +242,10 @@ impl HashedPostState {
|
||||
tx: &TX,
|
||||
) -> Result<(B256, TrieUpdates), StateRootError> {
|
||||
let sorted = self.clone().into_sorted();
|
||||
let (account_prefix_set, storage_prefix_set) = self.construct_prefix_sets();
|
||||
sorted
|
||||
.state_root_calculator(tx)
|
||||
.with_changed_account_prefixes(account_prefix_set)
|
||||
.with_changed_storage_prefixes(storage_prefix_set)
|
||||
let prefix_sets = self.construct_prefix_sets();
|
||||
StateRoot::from_tx(tx)
|
||||
.with_hashed_cursor_factory(HashedPostStateCursorFactory::new(tx, &sorted))
|
||||
.with_prefix_sets(prefix_sets)
|
||||
.root_with_updates()
|
||||
}
|
||||
}
|
||||
@@ -303,24 +310,6 @@ pub struct HashedPostStateSorted {
|
||||
pub(crate) storages: HashMap<B256, HashedStorageSorted>,
|
||||
}
|
||||
|
||||
impl HashedPostStateSorted {
|
||||
/// Returns all destroyed accounts.
|
||||
pub fn destroyed_accounts(&self) -> HashSet<B256> {
|
||||
self.destroyed_accounts.clone()
|
||||
}
|
||||
|
||||
/// Returns [StateRoot] calculator based on database and in-memory state.
|
||||
fn state_root_calculator<'a, TX: DbTx>(
|
||||
&self,
|
||||
tx: &'a TX,
|
||||
) -> StateRoot<&'a TX, HashedPostStateCursorFactory<'_, &'a TX>> {
|
||||
let hashed_cursor_factory = HashedPostStateCursorFactory::new(tx, self);
|
||||
StateRoot::from_tx(tx)
|
||||
.with_hashed_cursor_factory(hashed_cursor_factory)
|
||||
.with_destroyed_accounts(self.destroyed_accounts())
|
||||
}
|
||||
}
|
||||
|
||||
/// Sorted hashed storage optimized for iterating during state trie calculation.
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub struct HashedStorageSorted {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
hashed_cursor::{HashedCursorFactory, HashedStorageCursor},
|
||||
node_iter::{AccountNode, AccountNodeIter, StorageNode, StorageNodeIter},
|
||||
prefix_set::{PrefixSet, PrefixSetLoader, PrefixSetMut},
|
||||
prefix_set::{PrefixSet, PrefixSetLoader, PrefixSetMut, TriePrefixSets},
|
||||
progress::{IntermediateStateRootState, StateRootProgress},
|
||||
trie_cursor::TrieCursorFactory,
|
||||
updates::{TrieKey, TrieOp, TrieUpdates},
|
||||
@@ -16,10 +16,7 @@ use reth_primitives::{
|
||||
trie::{HashBuilder, Nibbles, TrieAccount},
|
||||
Address, BlockNumber, B256,
|
||||
};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
ops::RangeInclusive,
|
||||
};
|
||||
use std::ops::RangeInclusive;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
/// StateRoot is used to compute the root node of a state trie.
|
||||
@@ -29,13 +26,8 @@ pub struct StateRoot<T, H> {
|
||||
pub trie_cursor_factory: T,
|
||||
/// The factory for hashed cursors.
|
||||
pub hashed_cursor_factory: H,
|
||||
/// A set of account prefixes that have changed.
|
||||
pub changed_account_prefixes: PrefixSet,
|
||||
/// A map containing storage changes with the hashed address as key and a set of storage key
|
||||
/// prefixes as the value.
|
||||
pub changed_storage_prefixes: HashMap<B256, PrefixSet>,
|
||||
/// A map containing keys of accounts that were destroyed.
|
||||
pub destroyed_accounts: HashSet<B256>,
|
||||
/// A set of prefix sets that have changes.
|
||||
pub prefix_sets: TriePrefixSets,
|
||||
/// Previous intermediate state.
|
||||
previous_state: Option<IntermediateStateRootState>,
|
||||
/// The number of updates after which the intermediate progress should be returned.
|
||||
@@ -43,21 +35,9 @@ pub struct StateRoot<T, H> {
|
||||
}
|
||||
|
||||
impl<T, H> StateRoot<T, H> {
|
||||
/// Set the changed account prefixes.
|
||||
pub fn with_changed_account_prefixes(mut self, prefixes: PrefixSet) -> Self {
|
||||
self.changed_account_prefixes = prefixes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the changed storage prefixes.
|
||||
pub fn with_changed_storage_prefixes(mut self, prefixes: HashMap<B256, PrefixSet>) -> Self {
|
||||
self.changed_storage_prefixes = prefixes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the destroyed accounts.
|
||||
pub fn with_destroyed_accounts(mut self, accounts: HashSet<B256>) -> Self {
|
||||
self.destroyed_accounts = accounts;
|
||||
/// Set the prefix sets.
|
||||
pub fn with_prefix_sets(mut self, prefix_sets: TriePrefixSets) -> Self {
|
||||
self.prefix_sets = prefix_sets;
|
||||
self
|
||||
}
|
||||
|
||||
@@ -84,9 +64,7 @@ impl<T, H> StateRoot<T, H> {
|
||||
StateRoot {
|
||||
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,
|
||||
prefix_sets: self.prefix_sets,
|
||||
threshold: self.threshold,
|
||||
previous_state: self.previous_state,
|
||||
}
|
||||
@@ -97,9 +75,7 @@ impl<T, H> StateRoot<T, H> {
|
||||
StateRoot {
|
||||
trie_cursor_factory,
|
||||
hashed_cursor_factory: self.hashed_cursor_factory,
|
||||
changed_account_prefixes: self.changed_account_prefixes,
|
||||
changed_storage_prefixes: self.changed_storage_prefixes,
|
||||
destroyed_accounts: self.destroyed_accounts,
|
||||
prefix_sets: self.prefix_sets,
|
||||
threshold: self.threshold,
|
||||
previous_state: self.previous_state,
|
||||
}
|
||||
@@ -112,9 +88,7 @@ impl<'a, TX: DbTx> StateRoot<&'a TX, &'a TX> {
|
||||
Self {
|
||||
trie_cursor_factory: tx,
|
||||
hashed_cursor_factory: tx,
|
||||
changed_account_prefixes: PrefixSetMut::default().freeze(),
|
||||
changed_storage_prefixes: HashMap::default(),
|
||||
destroyed_accounts: HashSet::default(),
|
||||
prefix_sets: TriePrefixSets::default(),
|
||||
previous_state: None,
|
||||
threshold: 100_000,
|
||||
}
|
||||
@@ -131,16 +105,7 @@ impl<'a, TX: DbTx> StateRoot<&'a TX, &'a TX> {
|
||||
range: RangeInclusive<BlockNumber>,
|
||||
) -> Result<Self, StateRootError> {
|
||||
let loaded_prefix_sets = PrefixSetLoader::new(tx).load(range)?;
|
||||
Ok(Self::from_tx(tx)
|
||||
.with_changed_account_prefixes(loaded_prefix_sets.account_prefix_set.freeze())
|
||||
.with_changed_storage_prefixes(
|
||||
loaded_prefix_sets
|
||||
.storage_prefix_sets
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, v.freeze()))
|
||||
.collect(),
|
||||
)
|
||||
.with_destroyed_accounts(loaded_prefix_sets.destroyed_accounts))
|
||||
Ok(Self::from_tx(tx).with_prefix_sets(loaded_prefix_sets))
|
||||
}
|
||||
|
||||
/// Computes the state root of the trie with the changed account and storage prefixes and
|
||||
@@ -243,7 +208,7 @@ where
|
||||
let walker = TrieWalker::from_stack(
|
||||
trie_cursor,
|
||||
state.walker_stack,
|
||||
self.changed_account_prefixes,
|
||||
self.prefix_sets.account_prefix_set,
|
||||
);
|
||||
(
|
||||
state.hash_builder,
|
||||
@@ -252,7 +217,7 @@ where
|
||||
)
|
||||
}
|
||||
None => {
|
||||
let walker = TrieWalker::new(trie_cursor, self.changed_account_prefixes);
|
||||
let walker = TrieWalker::new(trie_cursor, self.prefix_sets.account_prefix_set);
|
||||
(HashBuilder::default(), AccountNodeIter::new(walker, hashed_account_cursor))
|
||||
}
|
||||
};
|
||||
@@ -282,8 +247,9 @@ where
|
||||
self.hashed_cursor_factory.clone(),
|
||||
hashed_address,
|
||||
)
|
||||
.with_changed_prefixes(
|
||||
self.changed_storage_prefixes
|
||||
.with_prefix_set(
|
||||
self.prefix_sets
|
||||
.storage_prefix_sets
|
||||
.get(&hashed_address)
|
||||
.cloned()
|
||||
.unwrap_or_default(),
|
||||
@@ -340,8 +306,9 @@ where
|
||||
|
||||
trie_updates.extend(walker_updates.into_iter());
|
||||
trie_updates.extend_with_account_updates(hash_builder_updates);
|
||||
trie_updates
|
||||
.extend_with_deletes(self.destroyed_accounts.into_iter().map(TrieKey::StorageTrie));
|
||||
trie_updates.extend_with_deletes(
|
||||
self.prefix_sets.destroyed_accounts.into_iter().map(TrieKey::StorageTrie),
|
||||
);
|
||||
|
||||
Ok(StateRootProgress::Complete(root, hashed_entries_walked, trie_updates))
|
||||
}
|
||||
@@ -357,7 +324,7 @@ pub struct StorageRoot<T, H> {
|
||||
/// The hashed address of an account.
|
||||
pub hashed_address: B256,
|
||||
/// The set of storage slot prefixes that have changed.
|
||||
pub changed_prefixes: PrefixSet,
|
||||
pub prefix_set: PrefixSet,
|
||||
}
|
||||
|
||||
impl<T, H> StorageRoot<T, H> {
|
||||
@@ -376,13 +343,13 @@ impl<T, H> StorageRoot<T, H> {
|
||||
trie_cursor_factory,
|
||||
hashed_cursor_factory,
|
||||
hashed_address,
|
||||
changed_prefixes: PrefixSetMut::default().freeze(),
|
||||
prefix_set: PrefixSetMut::default().freeze(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the changed prefixes.
|
||||
pub fn with_changed_prefixes(mut self, prefixes: PrefixSet) -> Self {
|
||||
self.changed_prefixes = prefixes;
|
||||
pub fn with_prefix_set(mut self, prefix_set: PrefixSet) -> Self {
|
||||
self.prefix_set = prefix_set;
|
||||
self
|
||||
}
|
||||
|
||||
@@ -392,7 +359,7 @@ impl<T, H> StorageRoot<T, H> {
|
||||
trie_cursor_factory: self.trie_cursor_factory,
|
||||
hashed_cursor_factory,
|
||||
hashed_address: self.hashed_address,
|
||||
changed_prefixes: self.changed_prefixes,
|
||||
prefix_set: self.prefix_set,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,7 +369,7 @@ impl<T, H> StorageRoot<T, H> {
|
||||
trie_cursor_factory,
|
||||
hashed_cursor_factory: self.hashed_cursor_factory,
|
||||
hashed_address: self.hashed_address,
|
||||
changed_prefixes: self.changed_prefixes,
|
||||
prefix_set: self.prefix_set,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,7 +396,7 @@ where
|
||||
/// # Returns
|
||||
///
|
||||
/// The storage root and storage trie updates for a given address.
|
||||
pub fn root_with_updates(&self) -> Result<(B256, usize, TrieUpdates), StorageRootError> {
|
||||
pub fn root_with_updates(self) -> Result<(B256, usize, TrieUpdates), StorageRootError> {
|
||||
self.calculate(true)
|
||||
}
|
||||
|
||||
@@ -438,13 +405,13 @@ where
|
||||
/// # Returns
|
||||
///
|
||||
/// The storage root.
|
||||
pub fn root(&self) -> Result<B256, StorageRootError> {
|
||||
pub fn root(self) -> Result<B256, StorageRootError> {
|
||||
let (root, _, _) = self.calculate(false)?;
|
||||
Ok(root)
|
||||
}
|
||||
|
||||
fn calculate(
|
||||
&self,
|
||||
self,
|
||||
retain_updates: bool,
|
||||
) -> Result<(B256, usize, TrieUpdates), StorageRootError> {
|
||||
trace!(target: "trie::storage_root", hashed_address = ?self.hashed_address, "calculating storage root");
|
||||
@@ -460,8 +427,7 @@ where
|
||||
}
|
||||
|
||||
let trie_cursor = self.trie_cursor_factory.storage_tries_cursor(self.hashed_address)?;
|
||||
let walker = TrieWalker::new(trie_cursor, self.changed_prefixes.clone())
|
||||
.with_updates(retain_updates);
|
||||
let walker = TrieWalker::new(trie_cursor, self.prefix_set).with_updates(retain_updates);
|
||||
|
||||
let mut hash_builder = HashBuilder::default().with_updates(retain_updates);
|
||||
|
||||
@@ -586,7 +552,7 @@ mod tests {
|
||||
let mut storage_changes = PrefixSetMut::default();
|
||||
storage_changes.insert(Nibbles::unpack(modified_key));
|
||||
let loader = StorageRoot::from_tx_hashed(tx.tx_ref(), hashed_address)
|
||||
.with_changed_prefixes(storage_changes.freeze());
|
||||
.with_prefix_set(storage_changes.freeze());
|
||||
let incremental_root = loader.root().unwrap();
|
||||
|
||||
assert_eq!(modified_root, incremental_root);
|
||||
@@ -1001,7 +967,10 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let (root, trie_updates) = StateRoot::from_tx(tx.tx_ref())
|
||||
.with_changed_account_prefixes(prefix_set.freeze())
|
||||
.with_prefix_sets(TriePrefixSets {
|
||||
account_prefix_set: prefix_set.freeze(),
|
||||
..Default::default()
|
||||
})
|
||||
.root_with_updates()
|
||||
.unwrap();
|
||||
assert_eq!(root, expected_state_root);
|
||||
@@ -1053,7 +1022,10 @@ mod tests {
|
||||
]);
|
||||
|
||||
let (root, trie_updates) = StateRoot::from_tx(tx.tx_ref())
|
||||
.with_changed_account_prefixes(account_prefix_set.freeze())
|
||||
.with_prefix_sets(TriePrefixSets {
|
||||
account_prefix_set: account_prefix_set.freeze(),
|
||||
..Default::default()
|
||||
})
|
||||
.root_with_updates()
|
||||
.unwrap();
|
||||
assert_eq!(root, computed_expected_root);
|
||||
@@ -1110,7 +1082,10 @@ mod tests {
|
||||
]);
|
||||
|
||||
let (root, trie_updates) = StateRoot::from_tx(tx.tx_ref())
|
||||
.with_changed_account_prefixes(account_prefix_set.freeze())
|
||||
.with_prefix_sets(TriePrefixSets {
|
||||
account_prefix_set: account_prefix_set.freeze(),
|
||||
..Default::default()
|
||||
})
|
||||
.root_with_updates()
|
||||
.unwrap();
|
||||
assert_eq!(root, computed_expected_root);
|
||||
@@ -1205,14 +1180,14 @@ mod tests {
|
||||
let should_generate_changeset = !state.is_empty();
|
||||
let mut changes = PrefixSetMut::default();
|
||||
for (hashed_address, balance) in accounts.clone() {
|
||||
hashed_account_cursor.upsert(hashed_address, Account { balance,..Default::default() }).unwrap();
|
||||
hashed_account_cursor.upsert(hashed_address, Account { balance, ..Default::default() }).unwrap();
|
||||
if should_generate_changeset {
|
||||
changes.insert(Nibbles::unpack(hashed_address));
|
||||
}
|
||||
}
|
||||
|
||||
let (state_root, trie_updates) = StateRoot::from_tx(tx.tx_ref())
|
||||
.with_changed_account_prefixes(changes.freeze())
|
||||
.with_prefix_sets(TriePrefixSets { account_prefix_set: changes.freeze(), ..Default::default() })
|
||||
.root_with_updates()
|
||||
.unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user