feat(trie): allow passing intermediate nodes to overlay state root (#9839)

This commit is contained in:
Roman Krasiuk
2024-07-26 08:33:19 -07:00
committed by GitHub
parent 77f5ed1a7b
commit 5688739499
6 changed files with 35 additions and 17 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -260,7 +260,7 @@ impl<'b, TX: DbTx> StateRootProvider for HistoricalStateProviderRef<'b, TX> {
fn hashed_state_root(&self, hashed_state: HashedPostState) -> ProviderResult<B256> {
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()))
}
}

View File

@ -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<B256> {
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()))
}
}

View File

@ -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))| (

View File

@ -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<B256, StateRootError>;
fn overlay_root(
tx: &'a TX,
post_state: HashedPostState,
intermediate_nodes: TrieUpdates,
) -> Result<B256, StateRootError>;
/// 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<B256, StateRootError> {
fn overlay_root(
tx: &'a TX,
post_state: HashedPostState,
intermediate_nodes: TrieUpdates,
) -> Result<B256, 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()
@ -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")
);
}