From 8c4c8c90cfa6045233fd1541155ec2b1fcfc8251 Mon Sep 17 00:00:00 2001 From: Poulav Bhowmick Date: Thu, 6 Feb 2025 17:29:39 +0530 Subject: [PATCH] Moved HashedPostState to trie-common crate (#14230) Co-authored-by: DarkLord017 Co-authored-by: Matthias Seitz --- Cargo.lock | 3 +- crates/trie/common/Cargo.toml | 11 ++++ .../state.rs => common/src/hashedstate.rs} | 60 +++++++++++++++---- crates/trie/common/src/lib.rs | 4 ++ crates/trie/trie/Cargo.toml | 3 +- .../trie/trie/src/hashed_cursor/post_state.rs | 6 +- crates/trie/trie/src/lib.rs | 5 +- crates/trie/trie/src/witness.rs | 3 +- 8 files changed, 71 insertions(+), 24 deletions(-) rename crates/trie/{trie/src/state.rs => common/src/hashedstate.rs} (90%) diff --git a/Cargo.lock b/Cargo.lock index 1ae37d55c..0411703a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9365,7 +9365,6 @@ dependencies = [ "metrics", "proptest", "proptest-arbitrary-interop", - "rayon", "reth-ethereum-primitives", "reth-execution-errors", "reth-metrics", @@ -9402,8 +9401,10 @@ dependencies = [ "plain_hasher", "proptest", "proptest-arbitrary-interop", + "rayon", "reth-codecs", "reth-primitives-traits", + "revm", "serde", "serde_json", "serde_with", diff --git a/crates/trie/common/Cargo.toml b/crates/trie/common/Cargo.toml index 4e0037325..e98d574cd 100644 --- a/crates/trie/common/Cargo.toml +++ b/crates/trie/common/Cargo.toml @@ -28,6 +28,9 @@ derive_more.workspace = true itertools = { workspace = true, features = ["use_alloc"] } nybbles = { workspace = true, features = ["rlp"] } +# reth +revm.workspace = true + # `serde` feature serde = { workspace = true, optional = true } @@ -38,6 +41,9 @@ hash-db = { version = "=0.15.2", optional = true } plain_hasher = { version = "0.2", optional = true } arbitrary = { workspace = true, features = ["derive"], optional = true } +# misc +rayon = { workspace = true, optional = true } + [dev-dependencies] reth-primitives-traits = { workspace = true, features = ["serde"] } reth-codecs.workspace = true @@ -74,6 +80,7 @@ std = [ "serde?/std", "serde_with?/std", "serde_json/std", + "revm/std", ] eip1186 = [ "alloy-rpc-types-eth/serde", @@ -89,6 +96,7 @@ serde = [ "alloy-rpc-types-eth?/serde", "reth-primitives-traits/serde", "reth-codecs?/serde", + "revm/serde", ] reth-codec = [ "dep:reth-codecs", @@ -106,6 +114,7 @@ test-utils = [ "arbitrary", "reth-primitives-traits/test-utils", "reth-codecs/test-utils", + "revm/test-utils", ] arbitrary = [ "std", @@ -119,7 +128,9 @@ arbitrary = [ "nybbles/arbitrary", "reth-codecs/arbitrary", "alloy-rpc-types-eth?/arbitrary", + "revm/arbitrary", ] +rayon = ["dep:rayon"] [[bench]] name = "prefix_set" diff --git a/crates/trie/trie/src/state.rs b/crates/trie/common/src/hashedstate.rs similarity index 90% rename from crates/trie/trie/src/state.rs rename to crates/trie/common/src/hashedstate.rs index 1791bf7b3..120bfdbba 100644 --- a/crates/trie/trie/src/state.rs +++ b/crates/trie/common/src/hashedstate.rs @@ -1,18 +1,22 @@ use crate::{ prefix_set::{PrefixSetMut, TriePrefixSetsMut}, - Nibbles, + KeyHasher, Nibbles, }; +use alloc::{borrow::Cow, vec::Vec}; use alloy_primitives::{ keccak256, map::{hash_map, B256HashMap, B256HashSet, HashMap, HashSet}, Address, B256, U256, }; use itertools::Itertools; -use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use reth_primitives_traits::Account; -use reth_trie_common::KeyHasher; use revm::db::{AccountStatus, BundleAccount}; -use std::borrow::Cow; + +#[cfg(feature = "rayon")] +pub use rayon::*; + +#[cfg(feature = "rayon")] +use rayon::prelude::{IntoParallelIterator, ParallelIterator}; /// Representation of in-memory hashed state. #[derive(PartialEq, Eq, Clone, Default, Debug)] @@ -28,6 +32,7 @@ impl HashedPostState { /// Hashes all changed accounts and storage entries that are currently stored in the bundle /// state. #[inline] + #[cfg(feature = "rayon")] pub fn from_bundle_state<'a, KH: KeyHasher>( state: impl IntoParallelIterator, ) -> Self { @@ -55,6 +60,37 @@ impl HashedPostState { Self { accounts, storages } } + /// Initialize [`HashedPostState`] from bundle state. + /// Hashes all changed accounts and storage entries that are currently stored in the bundle + /// state. + #[cfg(not(feature = "rayon"))] + pub fn from_bundle_state<'a, KH: KeyHasher>( + state: impl IntoIterator, + ) -> Self { + let hashed = state + .into_iter() + .map(|(address, account)| { + let hashed_address = KH::hash_key(address); + let hashed_account = account.info.as_ref().map(Into::into); + let hashed_storage = HashedStorage::from_plain_storage( + account.status, + account.storage.iter().map(|(slot, value)| (slot, &value.present_value)), + ); + (hashed_address, (hashed_account, hashed_storage)) + }) + .collect::, HashedStorage))>>(); + + let mut accounts = HashMap::with_capacity_and_hasher(hashed.len(), Default::default()); + let mut storages = HashMap::with_capacity_and_hasher(hashed.len(), Default::default()); + for (address, (account, storage)) in hashed { + accounts.insert(address, account); + if !storage.is_empty() { + storages.insert(address, storage); + } + } + Self { accounts, storages } + } + /// Construct [`HashedPostState`] from a single [`HashedStorage`]. pub fn from_hashed_storage(hashed_address: B256, storage: HashedStorage) -> Self { Self { @@ -260,9 +296,9 @@ impl HashedStorage { #[derive(PartialEq, Eq, Clone, Default, Debug)] pub struct HashedPostStateSorted { /// Updated state of accounts. - pub(crate) accounts: HashedAccountsSorted, + pub accounts: HashedAccountsSorted, /// Map of hashed addresses to hashed storage. - pub(crate) storages: B256HashMap, + pub storages: B256HashMap, } impl HashedPostStateSorted { @@ -289,9 +325,9 @@ impl HashedPostStateSorted { #[derive(Clone, Eq, PartialEq, Default, Debug)] pub struct HashedAccountsSorted { /// Sorted collection of hashed addresses and their account info. - pub(crate) accounts: Vec<(B256, Account)>, + pub accounts: Vec<(B256, Account)>, /// Set of destroyed account keys. - pub(crate) destroyed_accounts: B256HashSet, + pub destroyed_accounts: B256HashSet, } impl HashedAccountsSorted { @@ -309,11 +345,11 @@ impl HashedAccountsSorted { #[derive(Clone, Eq, PartialEq, Debug)] pub struct HashedStorageSorted { /// Sorted hashed storage slots with non-zero value. - pub(crate) non_zero_valued_slots: Vec<(B256, U256)>, + pub non_zero_valued_slots: Vec<(B256, U256)>, /// Slots that have been zero valued. - pub(crate) zero_valued_slots: B256HashSet, + pub zero_valued_slots: B256HashSet, /// Flag indicating whether the storage was wiped or not. - pub(crate) wiped: bool, + pub wiped: bool, } impl HashedStorageSorted { @@ -335,8 +371,8 @@ impl HashedStorageSorted { #[cfg(test)] mod tests { use super::*; + use crate::KeccakKeyHasher; use alloy_primitives::Bytes; - use reth_trie_common::KeccakKeyHasher; use revm::{ db::{states::StorageSlot, StorageWithOriginalValues}, primitives::{AccountInfo, Bytecode}, diff --git a/crates/trie/common/src/lib.rs b/crates/trie/common/src/lib.rs index 093c2969b..81434d052 100644 --- a/crates/trie/common/src/lib.rs +++ b/crates/trie/common/src/lib.rs @@ -11,6 +11,10 @@ extern crate alloc; +/// In-memory hashed state. +mod hashedstate; +pub use hashedstate::*; + /// The implementation of hash builder. pub mod hash_builder; diff --git a/crates/trie/trie/Cargo.toml b/crates/trie/trie/Cargo.toml index 867474d0f..bc55ddcbe 100644 --- a/crates/trie/trie/Cargo.toml +++ b/crates/trie/trie/Cargo.toml @@ -18,7 +18,7 @@ reth-primitives-traits.workspace = true reth-stages-types.workspace = true reth-storage-errors.workspace = true reth-trie-sparse.workspace = true -reth-trie-common.workspace = true +reth-trie-common = { workspace = true, features = ["rayon"] } revm.workspace = true @@ -33,7 +33,6 @@ alloy-trie.workspace = true tracing.workspace = true # misc -rayon.workspace = true auto_impl.workspace = true itertools.workspace = true diff --git a/crates/trie/trie/src/hashed_cursor/post_state.rs b/crates/trie/trie/src/hashed_cursor/post_state.rs index cf16c26f0..18e58fdba 100644 --- a/crates/trie/trie/src/hashed_cursor/post_state.rs +++ b/crates/trie/trie/src/hashed_cursor/post_state.rs @@ -1,11 +1,9 @@ use super::{HashedCursor, HashedCursorFactory, HashedStorageCursor}; -use crate::{ - forward_cursor::ForwardInMemoryCursor, HashedAccountsSorted, HashedPostStateSorted, - HashedStorageSorted, -}; +use crate::forward_cursor::ForwardInMemoryCursor; use alloy_primitives::{map::B256HashSet, B256, U256}; use reth_primitives_traits::Account; use reth_storage_errors::db::DatabaseError; +use reth_trie_common::{HashedAccountsSorted, HashedPostStateSorted, HashedStorageSorted}; /// The hashed cursor factory for the post state. #[derive(Clone, Debug)] diff --git a/crates/trie/trie/src/lib.rs b/crates/trie/trie/src/lib.rs index 1e7eeb9b5..ce426843a 100644 --- a/crates/trie/trie/src/lib.rs +++ b/crates/trie/trie/src/lib.rs @@ -4,6 +4,7 @@ //! //! ## Feature Flags //! +//! - `rayon`: uses rayon for parallel [`HashedPostState`] creation. //! - `test-utils`: Export utilities for testing #![doc( @@ -28,10 +29,6 @@ pub mod walker; /// The iterators for traversing existing intermediate hashes and updated trie leaves. pub mod node_iter; -/// In-memory hashed state. -mod state; -pub use state::*; - /// Input for trie computation. mod input; pub use input::TrieInput; diff --git a/crates/trie/trie/src/witness.rs b/crates/trie/trie/src/witness.rs index ce3a8f7ac..ba19ffbca 100644 --- a/crates/trie/trie/src/witness.rs +++ b/crates/trie/trie/src/witness.rs @@ -3,8 +3,9 @@ use crate::{ prefix_set::TriePrefixSetsMut, proof::{Proof, ProofBlindedProviderFactory}, trie_cursor::TrieCursorFactory, - HashedPostState, }; +use reth_trie_common::HashedPostState; + use alloy_primitives::{ keccak256, map::{B256HashMap, B256HashSet, Entry, HashMap},