From fa0c85474dd608a6009dba908d337a77565e284e Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Tue, 25 Jun 2024 10:28:51 +0200 Subject: [PATCH 1/2] chore(trie): hold direct reference to hashed accounts in cursor --- .../trie/trie/src/hashed_cursor/post_state.rs | 10 +++++----- crates/trie/trie/src/state.rs | 20 +++++++++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/crates/trie/trie/src/hashed_cursor/post_state.rs b/crates/trie/trie/src/hashed_cursor/post_state.rs index 4eb98169760e..de28265b87c6 100644 --- a/crates/trie/trie/src/hashed_cursor/post_state.rs +++ b/crates/trie/trie/src/hashed_cursor/post_state.rs @@ -1,5 +1,5 @@ use super::{HashedCursor, HashedCursorFactory, HashedStorageCursor}; -use crate::{state::HashedPostStateSorted, HashedStorageSorted}; +use crate::{HashedAccountsSorted, HashedPostStateSorted, HashedStorageSorted}; use reth_primitives::{Account, B256, U256}; /// The hashed cursor factory for the post state. @@ -22,7 +22,7 @@ impl<'a, CF: HashedCursorFactory> HashedCursorFactory for HashedPostStateCursorF fn hashed_account_cursor(&self) -> Result { let cursor = self.cursor_factory.hashed_account_cursor()?; - Ok(HashedPostStateAccountCursor::new(cursor, self.post_state)) + Ok(HashedPostStateAccountCursor::new(cursor, &self.post_state.accounts)) } fn hashed_storage_cursor( @@ -40,8 +40,8 @@ impl<'a, CF: HashedCursorFactory> HashedCursorFactory for HashedPostStateCursorF pub struct HashedPostStateAccountCursor<'a, C> { /// The database cursor. cursor: C, - /// The reference to the in-memory [`HashedPostStateSorted`]. - post_state: &'a HashedPostStateSorted, + /// The reference to the in-memory [`HashedAccountsSorted`]. + post_state: &'a HashedAccountsSorted, /// The post state account index where the cursor is currently at. post_state_account_index: usize, /// The last hashed account that was returned by the cursor. @@ -51,7 +51,7 @@ pub struct HashedPostStateAccountCursor<'a, C> { impl<'a, C> HashedPostStateAccountCursor<'a, C> { /// Create new instance of [`HashedPostStateAccountCursor`]. - pub const fn new(cursor: C, post_state: &'a HashedPostStateSorted) -> Self { + pub const fn new(cursor: C, post_state: &'a HashedAccountsSorted) -> Self { Self { cursor, post_state, last_account: None, post_state_account_index: 0 } } diff --git a/crates/trie/trie/src/state.rs b/crates/trie/trie/src/state.rs index 821dcc971b62..de7ecc236dbe 100644 --- a/crates/trie/trie/src/state.rs +++ b/crates/trie/trie/src/state.rs @@ -149,16 +149,17 @@ impl HashedPostState { /// Converts hashed post state into [`HashedPostStateSorted`]. pub fn into_sorted(self) -> HashedPostStateSorted { - let mut accounts = Vec::new(); + let mut updated_accounts = Vec::new(); let mut destroyed_accounts = HashSet::default(); for (hashed_address, info) in self.accounts { if let Some(info) = info { - accounts.push((hashed_address, info)); + updated_accounts.push((hashed_address, info)); } else { destroyed_accounts.insert(hashed_address); } } - accounts.sort_unstable_by_key(|(address, _)| *address); + updated_accounts.sort_unstable_by_key(|(address, _)| *address); + let accounts = HashedAccountsSorted { accounts: updated_accounts, destroyed_accounts }; let storages = self .storages @@ -166,7 +167,7 @@ impl HashedPostState { .map(|(hashed_address, storage)| (hashed_address, storage.into_sorted())) .collect(); - HashedPostStateSorted { accounts, destroyed_accounts, storages } + HashedPostStateSorted { accounts, storages } } /// Construct [`TriePrefixSets`] from hashed post state. @@ -309,12 +310,19 @@ impl HashedStorage { /// Sorted hashed post state optimized for iterating during state trie calculation. #[derive(PartialEq, Eq, Clone, Debug)] pub struct HashedPostStateSorted { + /// Updated state of accounts. + pub(crate) accounts: HashedAccountsSorted, + /// Map of hashed addresses to hashed storage. + pub(crate) storages: HashMap, +} + +/// Sorted account state optimized for iterating during state trie calculation. +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct HashedAccountsSorted { /// Sorted collection of hashed addresses and their account info. pub(crate) accounts: Vec<(B256, Account)>, /// Set of destroyed account keys. pub(crate) destroyed_accounts: HashSet, - /// Map of hashed addresses to hashed storage. - pub(crate) storages: HashMap, } /// Sorted hashed storage optimized for iterating during state trie calculation. From 7640b85112eb8c83ac7d963e2c54d3d42d2ed1e3 Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Tue, 25 Jun 2024 13:46:47 +0200 Subject: [PATCH 2/2] fix naming --- .../trie/trie/src/hashed_cursor/post_state.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/crates/trie/trie/src/hashed_cursor/post_state.rs b/crates/trie/trie/src/hashed_cursor/post_state.rs index de28265b87c6..b609048fafa9 100644 --- a/crates/trie/trie/src/hashed_cursor/post_state.rs +++ b/crates/trie/trie/src/hashed_cursor/post_state.rs @@ -41,7 +41,7 @@ pub struct HashedPostStateAccountCursor<'a, C> { /// The database cursor. cursor: C, /// The reference to the in-memory [`HashedAccountsSorted`]. - post_state: &'a HashedAccountsSorted, + post_state_accounts: &'a HashedAccountsSorted, /// The post state account index where the cursor is currently at. post_state_account_index: usize, /// The last hashed account that was returned by the cursor. @@ -51,8 +51,8 @@ pub struct HashedPostStateAccountCursor<'a, C> { impl<'a, C> HashedPostStateAccountCursor<'a, C> { /// Create new instance of [`HashedPostStateAccountCursor`]. - pub const fn new(cursor: C, post_state: &'a HashedAccountsSorted) -> Self { - Self { cursor, post_state, last_account: None, post_state_account_index: 0 } + pub const fn new(cursor: C, post_state_accounts: &'a HashedAccountsSorted) -> Self { + Self { cursor, post_state_accounts, last_account: None, post_state_account_index: 0 } } /// Returns `true` if the account has been destroyed. @@ -61,7 +61,7 @@ impl<'a, C> HashedPostStateAccountCursor<'a, C> { /// This function only checks the post state, not the database, because the latter does not /// store destroyed accounts. fn is_account_cleared(&self, account: &B256) -> bool { - self.post_state.destroyed_accounts.contains(account) + self.post_state_accounts.destroyed_accounts.contains(account) } /// Return the account with the lowest hashed account key. @@ -107,10 +107,11 @@ where // Take the next account from the post state with the key greater than or equal to the // sought key. - let mut post_state_entry = self.post_state.accounts.get(self.post_state_account_index); + let mut post_state_entry = + self.post_state_accounts.accounts.get(self.post_state_account_index); while post_state_entry.map(|(k, _)| k < &key).unwrap_or_default() { self.post_state_account_index += 1; - post_state_entry = self.post_state.accounts.get(self.post_state_account_index); + post_state_entry = self.post_state_accounts.accounts.get(self.post_state_account_index); } // It's an exact match, return the account from post state without looking up in the @@ -163,10 +164,11 @@ where } // Take the next account from the post state with the key greater than the last sought key. - let mut post_state_entry = self.post_state.accounts.get(self.post_state_account_index); + let mut post_state_entry = + self.post_state_accounts.accounts.get(self.post_state_account_index); while post_state_entry.map(|(k, _)| k <= last_account).unwrap_or_default() { self.post_state_account_index += 1; - post_state_entry = self.post_state.accounts.get(self.post_state_account_index); + post_state_entry = self.post_state_accounts.accounts.get(self.post_state_account_index); } // Compare two entries and return the lowest.