perf: trie micro optimizations (#13282)

This commit is contained in:
DaniPopes
2024-12-11 05:52:42 +01:00
committed by GitHub
parent 0144a433df
commit 0494ca01d5
37 changed files with 306 additions and 246 deletions

View File

@ -1244,7 +1244,7 @@ where
)) ))
.with_prefix_sets(prefix_sets) .with_prefix_sets(prefix_sets)
.root_with_updates() .root_with_updates()
.map_err(Into::<BlockValidationError>::into)?; .map_err(BlockValidationError::from)?;
let tip = blocks.tip(); let tip = blocks.tip();
if state_root != tip.state_root { if state_root != tip.state_root {
return Err(ProviderError::StateRootMismatch(Box::new(RootMismatch { return Err(ProviderError::StateRootMismatch(Box::new(RootMismatch {

View File

@ -944,7 +944,7 @@ mod tests {
use super::*; use super::*;
use crate::test_utils::TestBlockBuilder; use crate::test_utils::TestBlockBuilder;
use alloy_eips::eip7685::Requests; use alloy_eips::eip7685::Requests;
use alloy_primitives::{map::HashSet, BlockNumber, Bytes, StorageKey, StorageValue}; use alloy_primitives::{map::B256HashMap, BlockNumber, Bytes, StorageKey, StorageValue};
use rand::Rng; use rand::Rng;
use reth_errors::ProviderResult; use reth_errors::ProviderResult;
use reth_primitives::{Account, Bytecode, EthPrimitives, Receipt}; use reth_primitives::{Account, Bytecode, EthPrimitives, Receipt};
@ -953,7 +953,8 @@ mod tests {
StateRootProvider, StorageRootProvider, StateRootProvider, StorageRootProvider,
}; };
use reth_trie::{ use reth_trie::{
AccountProof, HashedStorage, MultiProof, StorageMultiProof, StorageProof, TrieInput, AccountProof, HashedStorage, MultiProof, MultiProofTargets, StorageMultiProof,
StorageProof, TrieInput,
}; };
fn create_mock_state( fn create_mock_state(
@ -1094,7 +1095,7 @@ mod tests {
fn multiproof( fn multiproof(
&self, &self,
_input: TrieInput, _input: TrieInput,
_targets: HashMap<B256, HashSet<B256>>, _targets: MultiProofTargets,
) -> ProviderResult<MultiProof> { ) -> ProviderResult<MultiProof> {
Ok(MultiProof::default()) Ok(MultiProof::default())
} }
@ -1103,7 +1104,7 @@ mod tests {
&self, &self,
_input: TrieInput, _input: TrieInput,
_target: HashedPostState, _target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>> { ) -> ProviderResult<B256HashMap<Bytes>> {
Ok(HashMap::default()) Ok(HashMap::default())
} }
} }

View File

@ -1,9 +1,7 @@
use super::ExecutedBlock; use super::ExecutedBlock;
use alloy_consensus::BlockHeader; use alloy_consensus::BlockHeader;
use alloy_primitives::{ use alloy_primitives::{
keccak256, keccak256, map::B256HashMap, Address, BlockNumber, Bytes, StorageKey, StorageValue, B256,
map::{HashMap, HashSet},
Address, BlockNumber, Bytes, StorageKey, StorageValue, B256,
}; };
use reth_errors::ProviderResult; use reth_errors::ProviderResult;
use reth_primitives::{Account, Bytecode, NodePrimitives}; use reth_primitives::{Account, Bytecode, NodePrimitives};
@ -13,7 +11,7 @@ use reth_storage_api::{
}; };
use reth_trie::{ use reth_trie::{
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
StorageMultiProof, TrieInput, MultiProofTargets, StorageMultiProof, TrieInput,
}; };
use revm::db::BundleState; use revm::db::BundleState;
use std::sync::OnceLock; use std::sync::OnceLock;
@ -201,7 +199,7 @@ macro_rules! impl_state_provider {
fn multiproof( fn multiproof(
&self, &self,
mut input: TrieInput, mut input: TrieInput,
targets: HashMap<B256, HashSet<B256>>, targets: MultiProofTargets,
) -> ProviderResult<MultiProof> { ) -> ProviderResult<MultiProof> {
let MemoryOverlayTrieState { nodes, state } = self.trie_state().clone(); let MemoryOverlayTrieState { nodes, state } = self.trie_state().clone();
input.prepend_cached(nodes, state); input.prepend_cached(nodes, state);
@ -212,7 +210,7 @@ macro_rules! impl_state_provider {
&self, &self,
mut input: TrieInput, mut input: TrieInput,
target: HashedPostState, target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>> { ) -> ProviderResult<B256HashMap<Bytes>> {
let MemoryOverlayTrieState { nodes, state } = self.trie_state().clone(); let MemoryOverlayTrieState { nodes, state } = self.trie_state().clone();
input.prepend_cached(nodes, state); input.prepend_cached(nodes, state);
self.historical.witness(input, target) self.historical.witness(input, target)

View File

@ -8,13 +8,13 @@ use reth_provider::{
StateCommitmentProvider, StateCommitmentProvider,
}; };
use reth_trie::{ use reth_trie::{
proof::Proof, updates::TrieUpdates, HashedPostState, HashedStorage, MultiProof, Nibbles, proof::Proof, updates::TrieUpdates, HashedPostState, HashedStorage, MultiProof,
TrieInput, MultiProofTargets, Nibbles, TrieInput,
}; };
use reth_trie_db::DatabaseProof; use reth_trie_db::DatabaseProof;
use reth_trie_parallel::root::ParallelStateRootError; use reth_trie_parallel::root::ParallelStateRootError;
use reth_trie_sparse::{ use reth_trie_sparse::{
errors::{SparseStateTrieResult, SparseTrieError}, errors::{SparseStateTrieResult, SparseTrieErrorKind},
SparseStateTrie, SparseStateTrie,
}; };
use revm_primitives::{keccak256, EvmState, B256}; use revm_primitives::{keccak256, EvmState, B256};
@ -232,7 +232,7 @@ pub struct StateRootTask<Factory> {
/// Sender for state root related messages. /// Sender for state root related messages.
tx: Sender<StateRootMessage>, tx: Sender<StateRootMessage>,
/// Proof targets that have been already fetched. /// Proof targets that have been already fetched.
fetched_proof_targets: HashMap<B256, HashSet<B256>>, fetched_proof_targets: MultiProofTargets,
/// Proof sequencing handler. /// Proof sequencing handler.
proof_sequencer: ProofSequencer, proof_sequencer: ProofSequencer,
/// The sparse trie used for the state root calculation. If [`None`], then update is in /// The sparse trie used for the state root calculation. If [`None`], then update is in
@ -297,7 +297,7 @@ where
view: ConsistentDbView<Factory>, view: ConsistentDbView<Factory>,
input: Arc<TrieInput>, input: Arc<TrieInput>,
update: EvmState, update: EvmState,
fetched_proof_targets: &mut HashMap<B256, HashSet<B256>>, fetched_proof_targets: &mut MultiProofTargets,
proof_sequence_number: u64, proof_sequence_number: u64,
state_root_message_sender: Sender<StateRootMessage>, state_root_message_sender: Sender<StateRootMessage>,
) { ) {
@ -525,8 +525,8 @@ where
/// account shouldn't be included. /// account shouldn't be included.
fn get_proof_targets( fn get_proof_targets(
state_update: &HashedPostState, state_update: &HashedPostState,
fetched_proof_targets: &HashMap<B256, HashSet<B256>>, fetched_proof_targets: &MultiProofTargets,
) -> HashMap<B256, HashSet<B256>> { ) -> MultiProofTargets {
let mut targets = HashMap::default(); let mut targets = HashMap::default();
// first collect all new accounts (not previously fetched) // first collect all new accounts (not previously fetched)
@ -558,7 +558,7 @@ fn get_proof_targets(
fn update_sparse_trie( fn update_sparse_trie(
mut trie: Box<SparseStateTrie>, mut trie: Box<SparseStateTrie>,
multiproof: MultiProof, multiproof: MultiProof,
targets: HashMap<B256, HashSet<B256>>, targets: MultiProofTargets,
state: HashedPostState, state: HashedPostState,
) -> SparseStateTrieResult<(Box<SparseStateTrie>, Duration)> { ) -> SparseStateTrieResult<(Box<SparseStateTrie>, Duration)> {
trace!(target: "engine::root::sparse", "Updating sparse trie"); trace!(target: "engine::root::sparse", "Updating sparse trie");
@ -576,7 +576,7 @@ fn update_sparse_trie(
.par_bridge() .par_bridge()
.map(|(address, storage, storage_trie)| { .map(|(address, storage, storage_trie)| {
trace!(target: "engine::root::sparse", ?address, "Updating storage"); trace!(target: "engine::root::sparse", ?address, "Updating storage");
let mut storage_trie = storage_trie.ok_or(SparseTrieError::Blind)?; let mut storage_trie = storage_trie.ok_or(SparseTrieErrorKind::Blind)?;
if storage.wiped { if storage.wiped {
trace!(target: "engine::root::sparse", ?address, "Wiping storage"); trace!(target: "engine::root::sparse", ?address, "Wiping storage");

View File

@ -67,7 +67,38 @@ pub type SparseStateTrieResult<Ok> = Result<Ok, SparseStateTrieError>;
/// Error encountered in `SparseStateTrie`. /// Error encountered in `SparseStateTrie`.
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum SparseStateTrieError { #[error(transparent)]
pub struct SparseStateTrieError(#[from] Box<SparseStateTrieErrorKind>);
impl<T: Into<SparseStateTrieErrorKind>> From<T> for SparseStateTrieError {
#[cold]
fn from(value: T) -> Self {
Self(Box::new(value.into()))
}
}
impl From<SparseTrieError> for SparseStateTrieErrorKind {
#[cold]
fn from(value: SparseTrieError) -> Self {
Self::Sparse(*value.0)
}
}
impl SparseStateTrieError {
/// Returns the error kind.
pub const fn kind(&self) -> &SparseStateTrieErrorKind {
&self.0
}
/// Consumes the error and returns the error kind.
pub fn into_kind(self) -> SparseStateTrieErrorKind {
*self.0
}
}
/// Error encountered in `SparseStateTrie`.
#[derive(Error, Debug)]
pub enum SparseStateTrieErrorKind {
/// Encountered invalid root node. /// Encountered invalid root node.
#[error("invalid root node at {path:?}: {node:?}")] #[error("invalid root node at {path:?}: {node:?}")]
InvalidRootNode { InvalidRootNode {
@ -78,7 +109,7 @@ pub enum SparseStateTrieError {
}, },
/// Sparse trie error. /// Sparse trie error.
#[error(transparent)] #[error(transparent)]
Sparse(#[from] SparseTrieError), Sparse(#[from] SparseTrieErrorKind),
/// RLP error. /// RLP error.
#[error(transparent)] #[error(transparent)]
Rlp(#[from] alloy_rlp::Error), Rlp(#[from] alloy_rlp::Error),
@ -89,7 +120,31 @@ pub type SparseTrieResult<Ok> = Result<Ok, SparseTrieError>;
/// Error encountered in `SparseTrie`. /// Error encountered in `SparseTrie`.
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum SparseTrieError { #[error(transparent)]
pub struct SparseTrieError(#[from] Box<SparseTrieErrorKind>);
impl<T: Into<SparseTrieErrorKind>> From<T> for SparseTrieError {
#[cold]
fn from(value: T) -> Self {
Self(Box::new(value.into()))
}
}
impl SparseTrieError {
/// Returns the error kind.
pub const fn kind(&self) -> &SparseTrieErrorKind {
&self.0
}
/// Consumes the error and returns the error kind.
pub fn into_kind(self) -> SparseTrieErrorKind {
*self.0
}
}
/// [`SparseTrieError`] kind.
#[derive(Error, Debug)]
pub enum SparseTrieErrorKind {
/// Sparse trie is still blind. Thrown on attempt to update it. /// Sparse trie is still blind. Thrown on attempt to update it.
#[error("sparse trie is blind")] #[error("sparse trie is blind")]
Blind, Blind,
@ -134,6 +189,12 @@ pub enum TrieWitnessError {
MissingAccount(B256), MissingAccount(B256),
} }
impl From<SparseStateTrieErrorKind> for TrieWitnessError {
fn from(error: SparseStateTrieErrorKind) -> Self {
Self::Sparse(error.into())
}
}
impl From<TrieWitnessError> for ProviderError { impl From<TrieWitnessError> for ProviderError {
fn from(error: TrieWitnessError) -> Self { fn from(error: TrieWitnessError) -> Self {
Self::TrieWitnessError(error.to_string()) Self::TrieWitnessError(error.to_string())

View File

@ -1,7 +1,7 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use alloy_primitives::{ use alloy_primitives::{
keccak256, keccak256,
map::{HashMap, HashSet}, map::{B256HashMap, HashMap},
Address, BlockNumber, Bytes, StorageKey, B256, U256, Address, BlockNumber, Bytes, StorageKey, B256, U256,
}; };
use reth_primitives::{Account, Bytecode}; use reth_primitives::{Account, Bytecode};
@ -12,7 +12,7 @@ use reth_storage_api::{
use reth_storage_errors::provider::ProviderResult; use reth_storage_errors::provider::ProviderResult;
use reth_trie::{ use reth_trie::{
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, KeccakKeyHasher, updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, KeccakKeyHasher,
MultiProof, StorageMultiProof, StorageProof, TrieInput, MultiProof, MultiProofTargets, StorageMultiProof, StorageProof, TrieInput,
}; };
/// Mock state for testing /// Mock state for testing
@ -136,7 +136,7 @@ impl StateProofProvider for StateProviderTest {
fn multiproof( fn multiproof(
&self, &self,
_input: TrieInput, _input: TrieInput,
_targets: HashMap<B256, HashSet<B256>>, _targets: MultiProofTargets,
) -> ProviderResult<MultiProof> { ) -> ProviderResult<MultiProof> {
unimplemented!("proof generation is not supported") unimplemented!("proof generation is not supported")
} }
@ -145,7 +145,7 @@ impl StateProofProvider for StateProviderTest {
&self, &self,
_input: TrieInput, _input: TrieInput,
_target: HashedPostState, _target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>> { ) -> ProviderResult<B256HashMap<Bytes>> {
unimplemented!("witness generation is not supported") unimplemented!("witness generation is not supported")
} }
} }

View File

@ -253,7 +253,7 @@ mod tests {
fn test_rpc_gas_cap() { fn test_rpc_gas_cap() {
let args = CommandParser::<RpcServerArgs>::parse_from(["reth"]).args; let args = CommandParser::<RpcServerArgs>::parse_from(["reth"]).args;
let config = args.eth_config(); let config = args.eth_config();
assert_eq!(config.rpc_gas_cap, Into::<u64>::into(RPC_DEFAULT_GAS_CAP)); assert_eq!(config.rpc_gas_cap, u64::from(RPC_DEFAULT_GAS_CAP));
let args = let args =
CommandParser::<RpcServerArgs>::parse_from(["reth", "--rpc.gascap", "1000"]).args; CommandParser::<RpcServerArgs>::parse_from(["reth", "--rpc.gascap", "1000"]).args;

View File

@ -2,14 +2,11 @@
//! <https://github.com/rust-lang/rust/issues/100013> in default implementation of //! <https://github.com/rust-lang/rust/issues/100013> in default implementation of
//! `reth_rpc_eth_api::helpers::Call`. //! `reth_rpc_eth_api::helpers::Call`.
use alloy_primitives::{ use alloy_primitives::{Address, B256, U256};
map::{HashMap, HashSet},
Address, B256, U256,
};
use reth_errors::ProviderResult; use reth_errors::ProviderResult;
use reth_revm::{database::StateProviderDatabase, db::CacheDB, DatabaseRef}; use reth_revm::{database::StateProviderDatabase, db::CacheDB, DatabaseRef};
use reth_storage_api::{HashedPostStateProvider, StateProvider}; use reth_storage_api::{HashedPostStateProvider, StateProvider};
use reth_trie::HashedStorage; use reth_trie::{HashedStorage, MultiProofTargets};
use revm::Database; use revm::Database;
/// Helper alias type for the state's [`CacheDB`] /// Helper alias type for the state's [`CacheDB`]
@ -91,7 +88,7 @@ impl reth_storage_api::StateProofProvider for StateProviderTraitObjWrapper<'_> {
fn multiproof( fn multiproof(
&self, &self,
input: reth_trie::TrieInput, input: reth_trie::TrieInput,
targets: HashMap<B256, HashSet<B256>>, targets: MultiProofTargets,
) -> ProviderResult<reth_trie::MultiProof> { ) -> ProviderResult<reth_trie::MultiProof> {
self.0.multiproof(input, targets) self.0.multiproof(input, targets)
} }
@ -100,7 +97,7 @@ impl reth_storage_api::StateProofProvider for StateProviderTraitObjWrapper<'_> {
&self, &self,
input: reth_trie::TrieInput, input: reth_trie::TrieInput,
target: reth_trie::HashedPostState, target: reth_trie::HashedPostState,
) -> reth_errors::ProviderResult<alloy_primitives::map::HashMap<B256, alloy_primitives::Bytes>> ) -> reth_errors::ProviderResult<alloy_primitives::map::B256HashMap<alloy_primitives::Bytes>>
{ {
self.0.witness(input, target) self.0.witness(input, target)
} }

View File

@ -1,16 +1,13 @@
use crate::{ use crate::{
AccountReader, BlockHashReader, ExecutionDataProvider, StateProvider, StateRootProvider, AccountReader, BlockHashReader, ExecutionDataProvider, StateProvider, StateRootProvider,
}; };
use alloy_primitives::{ use alloy_primitives::{map::B256HashMap, Address, BlockNumber, Bytes, B256};
map::{HashMap, HashSet},
Address, BlockNumber, Bytes, B256,
};
use reth_primitives::{Account, Bytecode}; use reth_primitives::{Account, Bytecode};
use reth_storage_api::{HashedPostStateProvider, StateProofProvider, StorageRootProvider}; use reth_storage_api::{HashedPostStateProvider, StateProofProvider, StorageRootProvider};
use reth_storage_errors::provider::ProviderResult; use reth_storage_errors::provider::ProviderResult;
use reth_trie::{ use reth_trie::{
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
StorageMultiProof, TrieInput, MultiProofTargets, StorageMultiProof, TrieInput,
}; };
/// A state provider that resolves to data from either a wrapped [`crate::ExecutionOutcome`] /// A state provider that resolves to data from either a wrapped [`crate::ExecutionOutcome`]
@ -169,7 +166,7 @@ impl<SP: StateProvider, EDP: ExecutionDataProvider> StateProofProvider
fn multiproof( fn multiproof(
&self, &self,
mut input: reth_trie::TrieInput, mut input: reth_trie::TrieInput,
targets: HashMap<B256, HashSet<B256>>, targets: MultiProofTargets,
) -> ProviderResult<MultiProof> { ) -> ProviderResult<MultiProof> {
let bundle_state = self.block_execution_data_provider.execution_outcome().state(); let bundle_state = self.block_execution_data_provider.execution_outcome().state();
input.prepend(self.hashed_post_state(bundle_state)); input.prepend(self.hashed_post_state(bundle_state));
@ -180,7 +177,7 @@ impl<SP: StateProvider, EDP: ExecutionDataProvider> StateProofProvider
&self, &self,
mut input: TrieInput, mut input: TrieInput,
target: HashedPostState, target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>> { ) -> ProviderResult<B256HashMap<Bytes>> {
let bundle_state = self.block_execution_data_provider.execution_outcome().state(); let bundle_state = self.block_execution_data_provider.execution_outcome().state();
input.prepend(self.hashed_post_state(bundle_state)); input.prepend(self.hashed_post_state(bundle_state));
self.state_provider.witness(input, target) self.state_provider.witness(input, target)

View File

@ -27,7 +27,7 @@ use alloy_eips::{
}; };
use alloy_primitives::{ use alloy_primitives::{
keccak256, keccak256,
map::{hash_map, HashMap, HashSet}, map::{hash_map, B256HashMap, HashMap, HashSet},
Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256, Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256,
}; };
use itertools::Itertools; use itertools::Itertools;
@ -296,7 +296,7 @@ impl<TX: DbTx + DbTxMut + 'static, N: NodeTypesForProvider> DatabaseProvider<TX,
// Unwind storage hashes. Add changed account and storage keys to corresponding prefix // Unwind storage hashes. Add changed account and storage keys to corresponding prefix
// sets. // sets.
let mut storage_prefix_sets = HashMap::<B256, PrefixSet>::default(); let mut storage_prefix_sets = B256HashMap::<PrefixSet>::default();
let storage_entries = self.unwind_storage_hashing(changed_storages.iter().copied())?; let storage_entries = self.unwind_storage_hashing(changed_storages.iter().copied())?;
for (hashed_address, hashed_slots) in storage_entries { for (hashed_address, hashed_slots) in storage_entries {
account_prefix_set.insert(Nibbles::unpack(hashed_address)); account_prefix_set.insert(Nibbles::unpack(hashed_address));
@ -321,7 +321,7 @@ impl<TX: DbTx + DbTxMut + 'static, N: NodeTypesForProvider> DatabaseProvider<TX,
let (new_state_root, trie_updates) = StateRoot::from_tx(&self.tx) let (new_state_root, trie_updates) = StateRoot::from_tx(&self.tx)
.with_prefix_sets(prefix_sets) .with_prefix_sets(prefix_sets)
.root_with_updates() .root_with_updates()
.map_err(Into::<reth_db::DatabaseError>::into)?; .map_err(reth_db::DatabaseError::from)?;
let parent_number = range.start().saturating_sub(1); let parent_number = range.start().saturating_sub(1);
let parent_state_root = self let parent_state_root = self
@ -2310,7 +2310,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> StorageTrieWriter for DatabaseP
/// updates by the hashed address, writing in sorted order. /// updates by the hashed address, writing in sorted order.
fn write_storage_trie_updates( fn write_storage_trie_updates(
&self, &self,
storage_tries: &HashMap<B256, StorageTrieUpdates>, storage_tries: &B256HashMap<StorageTrieUpdates>,
) -> ProviderResult<usize> { ) -> ProviderResult<usize> {
let mut num_entries = 0; let mut num_entries = 0;
let mut storage_tries = Vec::from_iter(storage_tries); let mut storage_tries = Vec::from_iter(storage_tries);
@ -2549,7 +2549,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypes> HashingWriter for DatabaseProvi
let (state_root, trie_updates) = StateRoot::from_tx(&self.tx) let (state_root, trie_updates) = StateRoot::from_tx(&self.tx)
.with_prefix_sets(prefix_sets) .with_prefix_sets(prefix_sets)
.root_with_updates() .root_with_updates()
.map_err(Into::<reth_db::DatabaseError>::into)?; .map_err(reth_db::DatabaseError::from)?;
if state_root != expected_state_root { if state_root != expected_state_root {
return Err(ProviderError::StateRootMismatch(Box::new(RootMismatch { return Err(ProviderError::StateRootMismatch(Box::new(RootMismatch {
root: GotExpected { got: state_root, expected: expected_state_root }, root: GotExpected { got: state_root, expected: expected_state_root },

View File

@ -4,8 +4,7 @@ use crate::{
}; };
use alloy_eips::merge::EPOCH_SLOTS; use alloy_eips::merge::EPOCH_SLOTS;
use alloy_primitives::{ use alloy_primitives::{
map::{HashMap, HashSet}, map::B256HashMap, Address, BlockNumber, Bytes, StorageKey, StorageValue, B256,
Address, BlockNumber, Bytes, StorageKey, StorageValue, B256,
}; };
use reth_db::{tables, BlockNumberList}; use reth_db::{tables, BlockNumberList};
use reth_db_api::{ use reth_db_api::{
@ -23,8 +22,8 @@ use reth_trie::{
proof::{Proof, StorageProof}, proof::{Proof, StorageProof},
updates::TrieUpdates, updates::TrieUpdates,
witness::TrieWitness, witness::TrieWitness,
AccountProof, HashedPostState, HashedStorage, MultiProof, StateRoot, StorageMultiProof, AccountProof, HashedPostState, HashedStorage, MultiProof, MultiProofTargets, StateRoot,
StorageRoot, TrieInput, StorageMultiProof, StorageRoot, TrieInput,
}; };
use reth_trie_db::{ use reth_trie_db::{
DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, DatabaseStateRoot, DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, DatabaseStateRoot,
@ -346,7 +345,7 @@ impl<Provider: DBProvider + BlockNumReader + StateCommitmentProvider> StorageRoo
let mut revert_storage = self.revert_storage(address)?; let mut revert_storage = self.revert_storage(address)?;
revert_storage.extend(&hashed_storage); revert_storage.extend(&hashed_storage);
StorageProof::overlay_storage_proof(self.tx(), address, slot, revert_storage) StorageProof::overlay_storage_proof(self.tx(), address, slot, revert_storage)
.map_err(Into::<ProviderError>::into) .map_err(ProviderError::from)
} }
fn storage_multiproof( fn storage_multiproof(
@ -358,7 +357,7 @@ impl<Provider: DBProvider + BlockNumReader + StateCommitmentProvider> StorageRoo
let mut revert_storage = self.revert_storage(address)?; let mut revert_storage = self.revert_storage(address)?;
revert_storage.extend(&hashed_storage); revert_storage.extend(&hashed_storage);
StorageProof::overlay_storage_multiproof(self.tx(), address, slots, revert_storage) StorageProof::overlay_storage_multiproof(self.tx(), address, slots, revert_storage)
.map_err(Into::<ProviderError>::into) .map_err(ProviderError::from)
} }
} }
@ -373,26 +372,25 @@ impl<Provider: DBProvider + BlockNumReader + StateCommitmentProvider> StateProof
slots: &[B256], slots: &[B256],
) -> ProviderResult<AccountProof> { ) -> ProviderResult<AccountProof> {
input.prepend(self.revert_state()?); input.prepend(self.revert_state()?);
Proof::overlay_account_proof(self.tx(), input, address, slots) Proof::overlay_account_proof(self.tx(), input, address, slots).map_err(ProviderError::from)
.map_err(Into::<ProviderError>::into)
} }
fn multiproof( fn multiproof(
&self, &self,
mut input: TrieInput, mut input: TrieInput,
targets: HashMap<B256, HashSet<B256>>, targets: MultiProofTargets,
) -> ProviderResult<MultiProof> { ) -> ProviderResult<MultiProof> {
input.prepend(self.revert_state()?); input.prepend(self.revert_state()?);
Proof::overlay_multiproof(self.tx(), input, targets).map_err(Into::<ProviderError>::into) Proof::overlay_multiproof(self.tx(), input, targets).map_err(ProviderError::from)
} }
fn witness( fn witness(
&self, &self,
mut input: TrieInput, mut input: TrieInput,
target: HashedPostState, target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>> { ) -> ProviderResult<B256HashMap<Bytes>> {
input.prepend(self.revert_state()?); input.prepend(self.revert_state()?);
TrieWitness::overlay_witness(self.tx(), input, target).map_err(Into::<ProviderError>::into) TrieWitness::overlay_witness(self.tx(), input, target).map_err(ProviderError::from)
} }
} }

View File

@ -3,8 +3,7 @@ use crate::{
HashedPostStateProvider, StateProvider, StateRootProvider, HashedPostStateProvider, StateProvider, StateRootProvider,
}; };
use alloy_primitives::{ use alloy_primitives::{
map::{HashMap, HashSet}, map::B256HashMap, Address, BlockNumber, Bytes, StorageKey, StorageValue, B256,
Address, BlockNumber, Bytes, StorageKey, StorageValue, B256,
}; };
use reth_db::tables; use reth_db::tables;
use reth_db_api::{cursor::DbDupCursorRO, transaction::DbTx}; use reth_db_api::{cursor::DbDupCursorRO, transaction::DbTx};
@ -17,8 +16,8 @@ use reth_trie::{
proof::{Proof, StorageProof}, proof::{Proof, StorageProof},
updates::TrieUpdates, updates::TrieUpdates,
witness::TrieWitness, witness::TrieWitness,
AccountProof, HashedPostState, HashedStorage, MultiProof, StateRoot, StorageMultiProof, AccountProof, HashedPostState, HashedStorage, MultiProof, MultiProofTargets, StateRoot,
StorageRoot, TrieInput, StorageMultiProof, StorageRoot, TrieInput,
}; };
use reth_trie_db::{ use reth_trie_db::{
DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot, DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot,
@ -113,7 +112,7 @@ impl<Provider: DBProvider + StateCommitmentProvider> StorageRootProvider
hashed_storage: HashedStorage, hashed_storage: HashedStorage,
) -> ProviderResult<reth_trie::StorageProof> { ) -> ProviderResult<reth_trie::StorageProof> {
StorageProof::overlay_storage_proof(self.tx(), address, slot, hashed_storage) StorageProof::overlay_storage_proof(self.tx(), address, slot, hashed_storage)
.map_err(Into::<ProviderError>::into) .map_err(ProviderError::from)
} }
fn storage_multiproof( fn storage_multiproof(
@ -123,7 +122,7 @@ impl<Provider: DBProvider + StateCommitmentProvider> StorageRootProvider
hashed_storage: HashedStorage, hashed_storage: HashedStorage,
) -> ProviderResult<StorageMultiProof> { ) -> ProviderResult<StorageMultiProof> {
StorageProof::overlay_storage_multiproof(self.tx(), address, slots, hashed_storage) StorageProof::overlay_storage_multiproof(self.tx(), address, slots, hashed_storage)
.map_err(Into::<ProviderError>::into) .map_err(ProviderError::from)
} }
} }
@ -136,24 +135,23 @@ impl<Provider: DBProvider + StateCommitmentProvider> StateProofProvider
address: Address, address: Address,
slots: &[B256], slots: &[B256],
) -> ProviderResult<AccountProof> { ) -> ProviderResult<AccountProof> {
Proof::overlay_account_proof(self.tx(), input, address, slots) Proof::overlay_account_proof(self.tx(), input, address, slots).map_err(ProviderError::from)
.map_err(Into::<ProviderError>::into)
} }
fn multiproof( fn multiproof(
&self, &self,
input: TrieInput, input: TrieInput,
targets: HashMap<B256, HashSet<B256>>, targets: MultiProofTargets,
) -> ProviderResult<MultiProof> { ) -> ProviderResult<MultiProof> {
Proof::overlay_multiproof(self.tx(), input, targets).map_err(Into::<ProviderError>::into) Proof::overlay_multiproof(self.tx(), input, targets).map_err(ProviderError::from)
} }
fn witness( fn witness(
&self, &self,
input: TrieInput, input: TrieInput,
target: HashedPostState, target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>> { ) -> ProviderResult<B256HashMap<Bytes>> {
TrieWitness::overlay_witness(self.tx(), input, target).map_err(Into::<ProviderError>::into) TrieWitness::overlay_witness(self.tx(), input, target).map_err(ProviderError::from)
} }
} }

View File

@ -54,8 +54,8 @@ macro_rules! delegate_provider_impls {
} }
StateProofProvider $(where [$($generics)*])? { StateProofProvider $(where [$($generics)*])? {
fn proof(&self, input: reth_trie::TrieInput, address: alloy_primitives::Address, slots: &[alloy_primitives::B256]) -> reth_storage_errors::provider::ProviderResult<reth_trie::AccountProof>; fn proof(&self, input: reth_trie::TrieInput, address: alloy_primitives::Address, slots: &[alloy_primitives::B256]) -> reth_storage_errors::provider::ProviderResult<reth_trie::AccountProof>;
fn multiproof(&self, input: reth_trie::TrieInput, targets: alloy_primitives::map::HashMap<alloy_primitives::B256, alloy_primitives::map::HashSet<alloy_primitives::B256>>) -> reth_storage_errors::provider::ProviderResult<reth_trie::MultiProof>; fn multiproof(&self, input: reth_trie::TrieInput, targets: reth_trie::MultiProofTargets) -> reth_storage_errors::provider::ProviderResult<reth_trie::MultiProof>;
fn witness(&self, input: reth_trie::TrieInput, target: reth_trie::HashedPostState) -> reth_storage_errors::provider::ProviderResult<alloy_primitives::map::HashMap<alloy_primitives::B256, alloy_primitives::Bytes>>; fn witness(&self, input: reth_trie::TrieInput, target: reth_trie::HashedPostState) -> reth_storage_errors::provider::ProviderResult<alloy_primitives::map::B256HashMap<alloy_primitives::Bytes>>;
} }
HashedPostStateProvider $(where [$($generics)*])? { HashedPostStateProvider $(where [$($generics)*])? {
fn hashed_post_state(&self, bundle_state: &revm::db::BundleState) -> reth_trie::HashedPostState; fn hashed_post_state(&self, bundle_state: &revm::db::BundleState) -> reth_trie::HashedPostState;

View File

@ -171,7 +171,7 @@ fn bundle_state_root(execution_outcome: &ExecutionOutcome) -> B256 {
( (
address, address,
( (
Into::<Account>::into(info), Account::from(info),
storage_root_unhashed( storage_root_unhashed(
account account
.storage .storage

View File

@ -12,7 +12,7 @@ use alloy_eips::{
}; };
use alloy_primitives::{ use alloy_primitives::{
keccak256, keccak256,
map::{HashMap, HashSet}, map::{B256HashMap, HashMap},
Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256,
}; };
use parking_lot::Mutex; use parking_lot::Mutex;
@ -35,7 +35,7 @@ use reth_storage_api::{
use reth_storage_errors::provider::{ConsistentViewError, ProviderError, ProviderResult}; use reth_storage_errors::provider::{ConsistentViewError, ProviderError, ProviderResult};
use reth_trie::{ use reth_trie::{
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
StorageMultiProof, StorageProof, TrieInput, MultiProofTargets, StorageMultiProof, StorageProof, TrieInput,
}; };
use reth_trie_db::MerklePatriciaTrie; use reth_trie_db::MerklePatriciaTrie;
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
@ -673,7 +673,7 @@ impl StateProofProvider for MockEthProvider {
fn multiproof( fn multiproof(
&self, &self,
_input: TrieInput, _input: TrieInput,
_targets: HashMap<B256, HashSet<B256>>, _targets: MultiProofTargets,
) -> ProviderResult<MultiProof> { ) -> ProviderResult<MultiProof> {
Ok(MultiProof::default()) Ok(MultiProof::default())
} }
@ -682,7 +682,7 @@ impl StateProofProvider for MockEthProvider {
&self, &self,
_input: TrieInput, _input: TrieInput,
_target: HashedPostState, _target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>> { ) -> ProviderResult<B256HashMap<Bytes>> {
Ok(HashMap::default()) Ok(HashMap::default())
} }
} }

View File

@ -80,7 +80,7 @@ pub fn insert_genesis<N: ProviderNodeTypes<ChainSpec = ChainSpec>>(
let (root, updates) = StateRoot::from_tx(provider.tx_ref()) let (root, updates) = StateRoot::from_tx(provider.tx_ref())
.root_with_updates() .root_with_updates()
.map_err(Into::<reth_db::DatabaseError>::into)?; .map_err(reth_db::DatabaseError::from)?;
provider.write_trie_updates(&updates).unwrap(); provider.write_trie_updates(&updates).unwrap();
provider.commit()?; provider.commit()?;

View File

@ -10,7 +10,7 @@ use alloy_eips::{
BlockHashOrNumber, BlockId, BlockNumberOrTag, BlockHashOrNumber, BlockId, BlockNumberOrTag,
}; };
use alloy_primitives::{ use alloy_primitives::{
map::{HashMap, HashSet}, map::{B256HashMap, HashMap},
Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256,
}; };
use reth_chain_state::{ use reth_chain_state::{
@ -32,7 +32,8 @@ use reth_storage_api::{
}; };
use reth_storage_errors::provider::ProviderResult; use reth_storage_errors::provider::ProviderResult;
use reth_trie::{ use reth_trie::{
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, TrieInput, updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
MultiProofTargets, TrieInput,
}; };
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
use tokio::sync::{broadcast, watch}; use tokio::sync::{broadcast, watch};
@ -401,7 +402,7 @@ impl StateProofProvider for NoopProvider {
fn multiproof( fn multiproof(
&self, &self,
_input: TrieInput, _input: TrieInput,
_targets: HashMap<B256, HashSet<B256>>, _targets: MultiProofTargets,
) -> ProviderResult<MultiProof> { ) -> ProviderResult<MultiProof> {
Ok(MultiProof::default()) Ok(MultiProof::default())
} }
@ -410,7 +411,7 @@ impl StateProofProvider for NoopProvider {
&self, &self,
_input: TrieInput, _input: TrieInput,
_target: HashedPostState, _target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>> { ) -> ProviderResult<B256HashMap<Bytes>> {
Ok(HashMap::default()) Ok(HashMap::default())
} }
} }

View File

@ -12,7 +12,7 @@ use alloy_eips::{
BlockHashOrNumber, BlockId, BlockNumberOrTag, BlockHashOrNumber, BlockId, BlockNumberOrTag,
}; };
use alloy_primitives::{ use alloy_primitives::{
map::{HashMap, HashSet}, map::{B256HashMap, HashMap},
Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256,
}; };
use reth_chainspec::{ChainInfo, ChainSpecProvider, EthChainSpec, MAINNET}; use reth_chainspec::{ChainInfo, ChainSpecProvider, EthChainSpec, MAINNET};
@ -25,7 +25,8 @@ use reth_prune_types::{PruneCheckpoint, PruneSegment};
use reth_stages_types::{StageCheckpoint, StageId}; use reth_stages_types::{StageCheckpoint, StageId};
use reth_storage_errors::provider::{ProviderError, ProviderResult}; use reth_storage_errors::provider::{ProviderError, ProviderResult};
use reth_trie::{ use reth_trie::{
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, TrieInput, updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
MultiProofTargets, TrieInput,
}; };
use std::{ use std::{
marker::PhantomData, marker::PhantomData,
@ -442,7 +443,7 @@ impl<C: Send + Sync, N: NodePrimitives> StateProofProvider for NoopProvider<C, N
fn multiproof( fn multiproof(
&self, &self,
_input: TrieInput, _input: TrieInput,
_targets: HashMap<B256, HashSet<B256>>, _targets: MultiProofTargets,
) -> ProviderResult<MultiProof> { ) -> ProviderResult<MultiProof> {
Ok(MultiProof::default()) Ok(MultiProof::default())
} }
@ -451,7 +452,7 @@ impl<C: Send + Sync, N: NodePrimitives> StateProofProvider for NoopProvider<C, N
&self, &self,
_input: TrieInput, _input: TrieInput,
_target: HashedPostState, _target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>> { ) -> ProviderResult<B256HashMap<Bytes>> {
Ok(HashMap::default()) Ok(HashMap::default())
} }
} }

View File

@ -1,12 +1,9 @@
use alloy_primitives::{ use alloy_primitives::{map::B256HashMap, Address, Bytes, B256};
map::{HashMap, HashSet},
Address, Bytes, B256,
};
use reth_storage_errors::provider::ProviderResult; use reth_storage_errors::provider::ProviderResult;
use reth_trie::{ use reth_trie::{
updates::{StorageTrieUpdates, TrieUpdates}, updates::{StorageTrieUpdates, TrieUpdates},
AccountProof, HashedPostState, HashedStorage, MultiProof, StorageMultiProof, StorageProof, AccountProof, HashedPostState, HashedStorage, MultiProof, MultiProofTargets, StorageMultiProof,
TrieInput, StorageProof, TrieInput,
}; };
/// A type that can compute the state root of a given post state. /// A type that can compute the state root of a given post state.
@ -84,7 +81,7 @@ pub trait StateProofProvider: Send + Sync {
fn multiproof( fn multiproof(
&self, &self,
input: TrieInput, input: TrieInput,
targets: HashMap<B256, HashSet<B256>>, targets: MultiProofTargets,
) -> ProviderResult<MultiProof>; ) -> ProviderResult<MultiProof>;
/// Get trie witness for provided state. /// Get trie witness for provided state.
@ -92,7 +89,7 @@ pub trait StateProofProvider: Send + Sync {
&self, &self,
input: TrieInput, input: TrieInput,
target: HashedPostState, target: HashedPostState,
) -> ProviderResult<HashMap<B256, Bytes>>; ) -> ProviderResult<B256HashMap<Bytes>>;
} }
/// Trie Writer /// Trie Writer
@ -114,7 +111,7 @@ pub trait StorageTrieWriter: Send + Sync {
/// Returns the number of entries modified. /// Returns the number of entries modified.
fn write_storage_trie_updates( fn write_storage_trie_updates(
&self, &self,
storage_tries: &HashMap<B256, StorageTrieUpdates>, storage_tries: &B256HashMap<StorageTrieUpdates>,
) -> ProviderResult<usize>; ) -> ProviderResult<usize>;
/// Writes storage trie updates for the given hashed address. /// Writes storage trie updates for the given hashed address.

View File

@ -92,13 +92,10 @@ mod tests {
assert_eq!(trie_account.code_hash, KECCAK_EMPTY); assert_eq!(trie_account.code_hash, KECCAK_EMPTY);
// Check that the default Account converts to the same TrieAccount // Check that the default Account converts to the same TrieAccount
assert_eq!(Into::<TrieAccount>::into((Account::default(), EMPTY_ROOT_HASH)), trie_account); assert_eq!(TrieAccount::from((Account::default(), EMPTY_ROOT_HASH)), trie_account);
// Check that the default AccountInfo converts to the same TrieAccount // Check that the default AccountInfo converts to the same TrieAccount
assert_eq!( assert_eq!(TrieAccount::from((AccountInfo::default(), EMPTY_ROOT_HASH)), trie_account);
Into::<TrieAccount>::into((AccountInfo::default(), EMPTY_ROOT_HASH)),
trie_account
);
} }
#[test] #[test]
@ -131,7 +128,7 @@ mod tests {
// Check that the Account converts to the same TrieAccount // Check that the Account converts to the same TrieAccount
assert_eq!( assert_eq!(
Into::<TrieAccount>::into(( TrieAccount::from((
Account { Account {
nonce: 10, nonce: 10,
balance: U256::from(1000), balance: U256::from(1000),
@ -144,7 +141,7 @@ mod tests {
// Check that the AccountInfo converts to the same TrieAccount // Check that the AccountInfo converts to the same TrieAccount
assert_eq!( assert_eq!(
Into::<TrieAccount>::into(( TrieAccount::from((
AccountInfo { AccountInfo {
nonce: 10, nonce: 10,
balance: U256::from(1000), balance: U256::from(1000),

View File

@ -1,8 +1,5 @@
use crate::Nibbles; use crate::Nibbles;
use alloy_primitives::{ use alloy_primitives::map::{B256HashMap, B256HashSet};
map::{HashMap, HashSet},
B256,
};
use std::sync::Arc; use std::sync::Arc;
/// Collection of mutable prefix sets. /// Collection of mutable prefix sets.
@ -12,9 +9,9 @@ pub struct TriePrefixSetsMut {
pub account_prefix_set: PrefixSetMut, pub account_prefix_set: PrefixSetMut,
/// A map containing storage changes with the hashed address as key and a set of storage key /// A map containing storage changes with the hashed address as key and a set of storage key
/// prefixes as the value. /// prefixes as the value.
pub storage_prefix_sets: HashMap<B256, PrefixSetMut>, pub storage_prefix_sets: B256HashMap<PrefixSetMut>,
/// A set of hashed addresses of destroyed accounts. /// A set of hashed addresses of destroyed accounts.
pub destroyed_accounts: HashSet<B256>, pub destroyed_accounts: B256HashSet,
} }
impl TriePrefixSetsMut { impl TriePrefixSetsMut {
@ -50,9 +47,9 @@ pub struct TriePrefixSets {
pub account_prefix_set: PrefixSet, pub account_prefix_set: PrefixSet,
/// A map containing storage changes with the hashed address as key and a set of storage key /// A map containing storage changes with the hashed address as key and a set of storage key
/// prefixes as the value. /// prefixes as the value.
pub storage_prefix_sets: HashMap<B256, PrefixSet>, pub storage_prefix_sets: B256HashMap<PrefixSet>,
/// A set of hashed addresses of destroyed accounts. /// A set of hashed addresses of destroyed accounts.
pub destroyed_accounts: HashSet<B256>, pub destroyed_accounts: B256HashSet,
} }
/// A container for efficiently storing and checking for the presence of key prefixes. /// A container for efficiently storing and checking for the presence of key prefixes.
@ -146,9 +143,9 @@ impl PrefixSetMut {
if self.all { if self.all {
PrefixSet { index: 0, all: true, keys: Arc::new(Vec::new()) } PrefixSet { index: 0, all: true, keys: Arc::new(Vec::new()) }
} else { } else {
self.keys.sort(); self.keys.sort_unstable();
self.keys.dedup(); self.keys.dedup();
// we need to shrink in both the sorted and non-sorted cases because deduping may have // We need to shrink in both the sorted and non-sorted cases because deduping may have
// occurred either on `freeze`, or during `contains`. // occurred either on `freeze`, or during `contains`.
self.keys.shrink_to_fit(); self.keys.shrink_to_fit();
PrefixSet { index: 0, all: false, keys: Arc::new(self.keys) } PrefixSet { index: 0, all: false, keys: Arc::new(self.keys) }

View File

@ -4,7 +4,7 @@ use crate::{Nibbles, TrieAccount};
use alloy_consensus::constants::KECCAK_EMPTY; use alloy_consensus::constants::KECCAK_EMPTY;
use alloy_primitives::{ use alloy_primitives::{
keccak256, keccak256,
map::{hash_map, HashMap}, map::{hash_map, B256HashMap, B256HashSet, HashMap},
Address, Bytes, B256, U256, Address, Bytes, B256, U256,
}; };
use alloy_rlp::{encode_fixed_size, Decodable, EMPTY_STRING_CODE}; use alloy_rlp::{encode_fixed_size, Decodable, EMPTY_STRING_CODE};
@ -16,6 +16,9 @@ use alloy_trie::{
use itertools::Itertools; use itertools::Itertools;
use reth_primitives_traits::Account; use reth_primitives_traits::Account;
/// Proof targets map.
pub type MultiProofTargets = B256HashMap<B256HashSet>;
/// The state multiproof of target accounts and multiproofs of their storage tries. /// The state multiproof of target accounts and multiproofs of their storage tries.
/// Multiproof is effectively a state subtrie that only contains the nodes /// Multiproof is effectively a state subtrie that only contains the nodes
/// in the paths of target accounts. /// in the paths of target accounts.
@ -26,7 +29,7 @@ pub struct MultiProof {
/// The hash masks of the branch nodes in the account proof. /// The hash masks of the branch nodes in the account proof.
pub branch_node_hash_masks: HashMap<Nibbles, TrieMask>, pub branch_node_hash_masks: HashMap<Nibbles, TrieMask>,
/// Storage trie multiproofs. /// Storage trie multiproofs.
pub storages: HashMap<B256, StorageMultiProof>, pub storages: B256HashMap<StorageMultiProof>,
} }
impl MultiProof { impl MultiProof {

View File

@ -1,6 +1,6 @@
use crate::{BranchNodeCompact, HashBuilder, Nibbles}; use crate::{BranchNodeCompact, HashBuilder, Nibbles};
use alloy_primitives::{ use alloy_primitives::{
map::{HashMap, HashSet}, map::{B256HashMap, B256HashSet, HashMap, HashSet},
B256, B256,
}; };
@ -15,7 +15,7 @@ pub struct TrieUpdates {
#[cfg_attr(any(test, feature = "serde"), serde(with = "serde_nibbles_set"))] #[cfg_attr(any(test, feature = "serde"), serde(with = "serde_nibbles_set"))]
pub removed_nodes: HashSet<Nibbles>, pub removed_nodes: HashSet<Nibbles>,
/// Collection of updated storage tries indexed by the hashed address. /// Collection of updated storage tries indexed by the hashed address.
pub storage_tries: HashMap<B256, StorageTrieUpdates>, pub storage_tries: B256HashMap<StorageTrieUpdates>,
} }
impl TrieUpdates { impl TrieUpdates {
@ -37,7 +37,7 @@ impl TrieUpdates {
} }
/// Returns a reference to updated storage tries. /// Returns a reference to updated storage tries.
pub const fn storage_tries_ref(&self) -> &HashMap<B256, StorageTrieUpdates> { pub const fn storage_tries_ref(&self) -> &B256HashMap<StorageTrieUpdates> {
&self.storage_tries &self.storage_tries
} }
@ -84,7 +84,7 @@ impl TrieUpdates {
&mut self, &mut self,
hash_builder: HashBuilder, hash_builder: HashBuilder,
removed_keys: HashSet<Nibbles>, removed_keys: HashSet<Nibbles>,
destroyed_accounts: HashSet<B256>, destroyed_accounts: B256HashSet,
) { ) {
// Retrieve updated nodes from hash builder. // Retrieve updated nodes from hash builder.
let (_, updated_nodes) = hash_builder.split(); let (_, updated_nodes) = hash_builder.split();
@ -347,7 +347,7 @@ pub struct TrieUpdatesSorted {
pub removed_nodes: HashSet<Nibbles>, pub removed_nodes: HashSet<Nibbles>,
/// Storage tries storage stored by hashed address of the account /// Storage tries storage stored by hashed address of the account
/// the trie belongs to. /// the trie belongs to.
pub storage_tries: HashMap<B256, StorageTrieUpdatesSorted>, pub storage_tries: B256HashMap<StorageTrieUpdatesSorted>,
} }
impl TrieUpdatesSorted { impl TrieUpdatesSorted {
@ -362,7 +362,7 @@ impl TrieUpdatesSorted {
} }
/// Returns reference to updated storage tries. /// Returns reference to updated storage tries.
pub const fn storage_tries_ref(&self) -> &HashMap<B256, StorageTrieUpdatesSorted> { pub const fn storage_tries_ref(&self) -> &B256HashMap<StorageTrieUpdatesSorted> {
&self.storage_tries &self.storage_tries
} }
} }
@ -411,10 +411,7 @@ fn exclude_empty_from_pair<V>(
#[cfg(feature = "serde-bincode-compat")] #[cfg(feature = "serde-bincode-compat")]
pub mod serde_bincode_compat { pub mod serde_bincode_compat {
use crate::{BranchNodeCompact, Nibbles}; use crate::{BranchNodeCompact, Nibbles};
use alloy_primitives::{ use alloy_primitives::map::{B256HashMap, HashMap, HashSet};
map::{HashMap, HashSet},
B256,
};
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_with::{DeserializeAs, SerializeAs}; use serde_with::{DeserializeAs, SerializeAs};
use std::borrow::Cow; use std::borrow::Cow;
@ -438,7 +435,7 @@ pub mod serde_bincode_compat {
pub struct TrieUpdates<'a> { pub struct TrieUpdates<'a> {
account_nodes: Cow<'a, HashMap<Nibbles, BranchNodeCompact>>, account_nodes: Cow<'a, HashMap<Nibbles, BranchNodeCompact>>,
removed_nodes: Cow<'a, HashSet<Nibbles>>, removed_nodes: Cow<'a, HashSet<Nibbles>>,
storage_tries: HashMap<B256, StorageTrieUpdates<'a>>, storage_tries: B256HashMap<StorageTrieUpdates<'a>>,
} }
impl<'a> From<&'a super::TrieUpdates> for TrieUpdates<'a> { impl<'a> From<&'a super::TrieUpdates> for TrieUpdates<'a> {

View File

@ -1,7 +1,7 @@
use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory};
use alloy_primitives::{ use alloy_primitives::{
keccak256, keccak256,
map::{HashMap, HashSet}, map::{B256HashMap, B256HashSet, HashMap},
Address, B256, Address, B256,
}; };
use reth_db_api::transaction::DbTx; use reth_db_api::transaction::DbTx;
@ -30,7 +30,7 @@ pub trait DatabaseProof<'a, TX> {
fn overlay_multiproof( fn overlay_multiproof(
tx: &'a TX, tx: &'a TX,
input: TrieInput, input: TrieInput,
targets: HashMap<B256, HashSet<B256>>, targets: B256HashMap<B256HashSet>,
) -> Result<MultiProof, StateProofError>; ) -> Result<MultiProof, StateProofError>;
} }
@ -66,7 +66,7 @@ impl<'a, TX: DbTx> DatabaseProof<'a, TX>
fn overlay_multiproof( fn overlay_multiproof(
tx: &'a TX, tx: &'a TX,
input: TrieInput, input: TrieInput,
targets: HashMap<B256, HashSet<B256>>, targets: B256HashMap<B256HashSet>,
) -> Result<MultiProof, StateProofError> { ) -> Result<MultiProof, StateProofError> {
let nodes_sorted = input.nodes.into_sorted(); let nodes_sorted = input.nodes.into_sorted();
let state_sorted = input.state.into_sorted(); let state_sorted = input.state.into_sorted();

View File

@ -1,5 +1,8 @@
use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory, PrefixSetLoader}; use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory, PrefixSetLoader};
use alloy_primitives::{Address, BlockNumber, B256, U256}; use alloy_primitives::{
map::{AddressHashMap, B256HashMap},
Address, BlockNumber, B256, U256,
};
use reth_db::tables; use reth_db::tables;
use reth_db_api::{ use reth_db_api::{
cursor::DbCursorRO, cursor::DbCursorRO,
@ -227,7 +230,7 @@ impl<TX: DbTx> DatabaseHashedPostState<TX> for HashedPostState {
} }
// Iterate over storage changesets and record value before first occurring storage change. // Iterate over storage changesets and record value before first occurring storage change.
let mut storages = HashMap::<Address, HashMap<B256, U256>>::default(); let mut storages = AddressHashMap::<B256HashMap<U256>>::default();
let mut storage_changesets_cursor = tx.cursor_read::<tables::StorageChangeSets>()?; let mut storage_changesets_cursor = tx.cursor_read::<tables::StorageChangeSets>()?;
for entry in for entry in
storage_changesets_cursor.walk_range(BlockNumberAddress((from, Address::ZERO))..)? storage_changesets_cursor.walk_range(BlockNumberAddress((from, Address::ZERO))..)?

View File

@ -1,5 +1,5 @@
use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory};
use alloy_primitives::{map::HashMap, Bytes, B256}; use alloy_primitives::{map::B256HashMap, Bytes};
use reth_db_api::transaction::DbTx; use reth_db_api::transaction::DbTx;
use reth_execution_errors::TrieWitnessError; use reth_execution_errors::TrieWitnessError;
use reth_trie::{ use reth_trie::{
@ -17,7 +17,7 @@ pub trait DatabaseTrieWitness<'a, TX> {
tx: &'a TX, tx: &'a TX,
input: TrieInput, input: TrieInput,
target: HashedPostState, target: HashedPostState,
) -> Result<HashMap<B256, Bytes>, TrieWitnessError>; ) -> Result<B256HashMap<Bytes>, TrieWitnessError>;
} }
impl<'a, TX: DbTx> DatabaseTrieWitness<'a, TX> impl<'a, TX: DbTx> DatabaseTrieWitness<'a, TX>
@ -31,7 +31,7 @@ impl<'a, TX: DbTx> DatabaseTrieWitness<'a, TX>
tx: &'a TX, tx: &'a TX,
input: TrieInput, input: TrieInput,
target: HashedPostState, target: HashedPostState,
) -> Result<HashMap<B256, Bytes>, TrieWitnessError> { ) -> Result<B256HashMap<Bytes>, TrieWitnessError> {
let nodes_sorted = input.nodes.into_sorted(); let nodes_sorted = input.nodes.into_sorted();
let state_sorted = input.state.into_sorted(); let state_sorted = input.state.into_sorted();
Self::from_tx(tx) Self::from_tx(tx)

View File

@ -1,8 +1,5 @@
use crate::{root::ParallelStateRootError, stats::ParallelTrieTracker, StorageRootTargets}; use crate::{root::ParallelStateRootError, stats::ParallelTrieTracker, StorageRootTargets};
use alloy_primitives::{ use alloy_primitives::{map::HashMap, B256};
map::{HashMap, HashSet},
B256,
};
use alloy_rlp::{BufMut, Encodable}; use alloy_rlp::{BufMut, Encodable};
use itertools::Itertools; use itertools::Itertools;
use reth_db::DatabaseError; use reth_db::DatabaseError;
@ -18,7 +15,8 @@ use reth_trie::{
proof::StorageProof, proof::StorageProof,
trie_cursor::{InMemoryTrieCursorFactory, TrieCursorFactory}, trie_cursor::{InMemoryTrieCursorFactory, TrieCursorFactory},
walker::TrieWalker, walker::TrieWalker,
HashBuilder, MultiProof, Nibbles, TrieAccount, TrieInput, TRIE_ACCOUNT_RLP_MAX_SIZE, HashBuilder, MultiProof, MultiProofTargets, Nibbles, TrieAccount, TrieInput,
TRIE_ACCOUNT_RLP_MAX_SIZE,
}; };
use reth_trie_common::proof::ProofRetainer; use reth_trie_common::proof::ProofRetainer;
use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory}; use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory};
@ -73,7 +71,7 @@ where
/// Generate a state multiproof according to specified targets. /// Generate a state multiproof according to specified targets.
pub fn multiproof( pub fn multiproof(
self, self,
targets: HashMap<B256, HashSet<B256>>, targets: MultiProofTargets,
) -> Result<MultiProof, ParallelStateRootError> { ) -> Result<MultiProof, ParallelStateRootError> {
let mut tracker = ParallelTrieTracker::default(); let mut tracker = ParallelTrieTracker::default();
@ -108,8 +106,7 @@ where
storage_root_targets.into_iter().sorted_unstable_by_key(|(address, _)| *address) storage_root_targets.into_iter().sorted_unstable_by_key(|(address, _)| *address)
{ {
let view = self.view.clone(); let view = self.view.clone();
let target_slots: HashSet<B256> = let target_slots = targets.get(&hashed_address).cloned().unwrap_or_default();
targets.get(&hashed_address).cloned().unwrap_or_default();
let trie_nodes_sorted = trie_nodes_sorted.clone(); let trie_nodes_sorted = trie_nodes_sorted.clone();
let hashed_state_sorted = hashed_state_sorted.clone(); let hashed_state_sorted = hashed_state_sorted.clone();
@ -249,7 +246,11 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use alloy_primitives::{keccak256, map::DefaultHashBuilder, Address, U256}; use alloy_primitives::{
keccak256,
map::{B256HashSet, DefaultHashBuilder},
Address, U256,
};
use rand::Rng; use rand::Rng;
use reth_primitives::{Account, StorageEntry}; use reth_primitives::{Account, StorageEntry};
use reth_provider::{test_utils::create_test_provider_factory, HashingWriter}; use reth_provider::{test_utils::create_test_provider_factory, HashingWriter};
@ -300,11 +301,10 @@ mod tests {
provider_rw.commit().unwrap(); provider_rw.commit().unwrap();
} }
let mut targets = let mut targets = MultiProofTargets::default();
HashMap::<B256, HashSet<B256, DefaultHashBuilder>, DefaultHashBuilder>::default();
for (address, (_, storage)) in state.iter().take(10) { for (address, (_, storage)) in state.iter().take(10) {
let hashed_address = keccak256(*address); let hashed_address = keccak256(*address);
let mut target_slots = HashSet::<B256, DefaultHashBuilder>::default(); let mut target_slots = B256HashSet::default();
for (slot, _) in storage.iter().take(5) { for (slot, _) in storage.iter().take(5) {
target_slots.insert(*slot); target_slots.insert(*slot);

View File

@ -1,11 +1,10 @@
use alloy_primitives::B256; use alloy_primitives::{map::B256HashMap, B256};
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
use reth_trie::prefix_set::PrefixSet; use reth_trie::prefix_set::PrefixSet;
use std::collections::HashMap;
/// Target accounts with corresponding prefix sets for storage root calculation. /// Target accounts with corresponding prefix sets for storage root calculation.
#[derive(Deref, DerefMut, Debug)] #[derive(Deref, DerefMut, Debug)]
pub struct StorageRootTargets(HashMap<B256, PrefixSet>); pub struct StorageRootTargets(B256HashMap<PrefixSet>);
impl StorageRootTargets { impl StorageRootTargets {
/// Create new storage root targets from updated post state accounts /// Create new storage root targets from updated post state accounts

View File

@ -1,6 +1,6 @@
#![allow(missing_docs, unreachable_pub)] #![allow(missing_docs, unreachable_pub)]
use alloy_primitives::{map::HashMap, B256, U256}; use alloy_primitives::{map::B256HashMap, B256, U256};
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use itertools::Itertools; use itertools::Itertools;
use proptest::{prelude::*, strategy::ValueTree, test_runner::TestRunner}; use proptest::{prelude::*, strategy::ValueTree, test_runner::TestRunner};
@ -193,7 +193,7 @@ pub fn calculate_root_from_leaves_repeated(c: &mut Criterion) {
} }
} }
fn generate_test_data(size: usize) -> HashMap<B256, U256> { fn generate_test_data(size: usize) -> B256HashMap<U256> {
let mut runner = TestRunner::new(ProptestConfig::default()); let mut runner = TestRunner::new(ProptestConfig::default());
proptest::collection::hash_map(any::<B256>(), any::<U256>(), size) proptest::collection::hash_map(any::<B256>(), any::<U256>(), size)
.new_tree(&mut runner) .new_tree(&mut runner)

View File

@ -11,6 +11,7 @@ pub mod blinded;
/// Re-export sparse trie error types. /// Re-export sparse trie error types.
pub mod errors { pub mod errors {
pub use reth_execution_errors::{ pub use reth_execution_errors::{
SparseStateTrieError, SparseStateTrieResult, SparseTrieError, SparseTrieResult, SparseStateTrieError, SparseStateTrieErrorKind, SparseStateTrieResult, SparseTrieError,
SparseTrieErrorKind, SparseTrieResult,
}; };
} }

View File

@ -4,11 +4,13 @@ use crate::{
}; };
use alloy_primitives::{ use alloy_primitives::{
hex, hex,
map::{HashMap, HashSet}, map::{B256HashMap, B256HashSet},
Bytes, B256, Bytes, B256,
}; };
use alloy_rlp::{Decodable, Encodable}; use alloy_rlp::{Decodable, Encodable};
use reth_execution_errors::{SparseStateTrieError, SparseStateTrieResult, SparseTrieError}; use reth_execution_errors::{
SparseStateTrieErrorKind, SparseStateTrieResult, SparseTrieError, SparseTrieErrorKind,
};
use reth_primitives_traits::Account; use reth_primitives_traits::Account;
use reth_tracing::tracing::trace; use reth_tracing::tracing::trace;
use reth_trie_common::{ use reth_trie_common::{
@ -24,9 +26,9 @@ pub struct SparseStateTrie<F: BlindedProviderFactory = DefaultBlindedProviderFac
/// Sparse account trie. /// Sparse account trie.
state: SparseTrie<F::AccountNodeProvider>, state: SparseTrie<F::AccountNodeProvider>,
/// Sparse storage tries. /// Sparse storage tries.
storages: HashMap<B256, SparseTrie<F::StorageNodeProvider>>, storages: B256HashMap<SparseTrie<F::StorageNodeProvider>>,
/// Collection of revealed account and storage keys. /// Collection of revealed account and storage keys.
revealed: HashMap<B256, HashSet<B256>>, revealed: B256HashMap<B256HashSet>,
/// Flag indicating whether trie updates should be retained. /// Flag indicating whether trie updates should be retained.
retain_updates: bool, retain_updates: bool,
/// Reusable buffer for RLP encoding of trie accounts. /// Reusable buffer for RLP encoding of trie accounts.
@ -204,7 +206,7 @@ impl<F: BlindedProviderFactory> SparseStateTrie<F> {
/// NOTE: This method does not extensively validate the proof. /// NOTE: This method does not extensively validate the proof.
pub fn reveal_multiproof( pub fn reveal_multiproof(
&mut self, &mut self,
targets: HashMap<B256, HashSet<B256>>, targets: B256HashMap<B256HashSet>,
multiproof: MultiProof, multiproof: MultiProof,
) -> SparseStateTrieResult<()> { ) -> SparseStateTrieResult<()> {
let account_subtree = multiproof.account_subtree.into_nodes_sorted(); let account_subtree = multiproof.account_subtree.into_nodes_sorted();
@ -278,13 +280,13 @@ impl<F: BlindedProviderFactory> SparseStateTrie<F> {
// Validate root node. // Validate root node.
let Some((path, node)) = proof.next() else { return Ok(None) }; let Some((path, node)) = proof.next() else { return Ok(None) };
if !path.is_empty() { if !path.is_empty() {
return Err(SparseStateTrieError::InvalidRootNode { path, node }) return Err(SparseStateTrieErrorKind::InvalidRootNode { path, node }.into())
} }
// Decode root node and perform sanity check. // Decode root node and perform sanity check.
let root_node = TrieNode::decode(&mut &node[..])?; let root_node = TrieNode::decode(&mut &node[..])?;
if matches!(root_node, TrieNode::EmptyRoot) && proof.peek().is_some() { if matches!(root_node, TrieNode::EmptyRoot) && proof.peek().is_some() {
return Err(SparseStateTrieError::InvalidRootNode { path, node }) return Err(SparseStateTrieErrorKind::InvalidRootNode { path, node }.into())
} }
Ok(Some(root_node)) Ok(Some(root_node))
@ -364,11 +366,9 @@ where
slot: Nibbles, slot: Nibbles,
value: Vec<u8>, value: Vec<u8>,
) -> SparseStateTrieResult<()> { ) -> SparseStateTrieResult<()> {
if let Some(storage_trie) = self.storages.get_mut(&address) { let storage_trie = self.storages.get_mut(&address).ok_or(SparseTrieErrorKind::Blind)?;
Ok(storage_trie.update_leaf(slot, value)?) storage_trie.update_leaf(slot, value)?;
} else { Ok(())
Err(SparseStateTrieError::Sparse(SparseTrieError::Blind))
}
} }
/// Update or remove trie account based on new account info. This method will either recompute /// Update or remove trie account based on new account info. This method will either recompute
@ -379,10 +379,10 @@ where
let nibbles = Nibbles::unpack(address); let nibbles = Nibbles::unpack(address);
let storage_root = if let Some(storage_trie) = self.storages.get_mut(&address) { let storage_root = if let Some(storage_trie) = self.storages.get_mut(&address) {
trace!(target: "trie::sparse", ?address, "Calculating storage root to update account"); trace!(target: "trie::sparse", ?address, "Calculating storage root to update account");
storage_trie.root().ok_or(SparseTrieError::Blind)? storage_trie.root().ok_or(SparseTrieErrorKind::Blind)?
} else if self.revealed.contains_key(&address) { } else if self.revealed.contains_key(&address) {
trace!(target: "trie::sparse", ?address, "Retrieving storage root from account leaf to update account"); trace!(target: "trie::sparse", ?address, "Retrieving storage root from account leaf to update account");
let state = self.state.as_revealed_mut().ok_or(SparseTrieError::Blind)?; let state = self.state.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
// The account was revealed, either... // The account was revealed, either...
if let Some(value) = state.get_leaf_value(&nibbles) { if let Some(value) = state.get_leaf_value(&nibbles) {
// ..it exists and we should take it's current storage root or... // ..it exists and we should take it's current storage root or...
@ -392,7 +392,7 @@ where
EMPTY_ROOT_HASH EMPTY_ROOT_HASH
} }
} else { } else {
return Err(SparseTrieError::Blind.into()) return Err(SparseTrieErrorKind::Blind.into())
}; };
if account.is_empty() && storage_root == EMPTY_ROOT_HASH { if account.is_empty() && storage_root == EMPTY_ROOT_HASH {
@ -418,18 +418,20 @@ where
address: B256, address: B256,
slot: &Nibbles, slot: &Nibbles,
) -> SparseStateTrieResult<()> { ) -> SparseStateTrieResult<()> {
if let Some(storage_trie) = self.storages.get_mut(&address) { let storage_trie = self.storages.get_mut(&address).ok_or(SparseTrieErrorKind::Blind)?;
Ok(storage_trie.remove_leaf(slot)?) storage_trie.remove_leaf(slot)?;
} else { Ok(())
Err(SparseStateTrieError::Sparse(SparseTrieError::Blind))
}
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use alloy_primitives::{b256, Bytes, U256}; use alloy_primitives::{
b256,
map::{HashMap, HashSet},
Bytes, U256,
};
use alloy_rlp::EMPTY_STRING_CODE; use alloy_rlp::EMPTY_STRING_CODE;
use arbitrary::Arbitrary; use arbitrary::Arbitrary;
use assert_matches::assert_matches; use assert_matches::assert_matches;
@ -443,8 +445,8 @@ mod tests {
let sparse = SparseStateTrie::default(); let sparse = SparseStateTrie::default();
let proof = [(Nibbles::from_nibbles([0x1]), Bytes::from([EMPTY_STRING_CODE]))]; let proof = [(Nibbles::from_nibbles([0x1]), Bytes::from([EMPTY_STRING_CODE]))];
assert_matches!( assert_matches!(
sparse.validate_root_node(&mut proof.into_iter().peekable(),), sparse.validate_root_node(&mut proof.into_iter().peekable()).map_err(|e| e.into_kind()),
Err(SparseStateTrieError::InvalidRootNode { .. }) Err(SparseStateTrieErrorKind::InvalidRootNode { .. })
); );
} }
@ -456,8 +458,8 @@ mod tests {
(Nibbles::from_nibbles([0x1]), Bytes::new()), (Nibbles::from_nibbles([0x1]), Bytes::new()),
]; ];
assert_matches!( assert_matches!(
sparse.validate_root_node(&mut proof.into_iter().peekable(),), sparse.validate_root_node(&mut proof.into_iter().peekable()).map_err(|e| e.into_kind()),
Err(SparseStateTrieError::InvalidRootNode { .. }) Err(SparseStateTrieErrorKind::InvalidRootNode { .. })
); );
} }

View File

@ -5,7 +5,7 @@ use alloy_primitives::{
B256, B256,
}; };
use alloy_rlp::Decodable; use alloy_rlp::Decodable;
use reth_execution_errors::{SparseTrieError, SparseTrieResult}; use reth_execution_errors::{SparseTrieError, SparseTrieErrorKind, SparseTrieResult};
use reth_tracing::tracing::trace; use reth_tracing::tracing::trace;
use reth_trie_common::{ use reth_trie_common::{
prefix_set::{PrefixSet, PrefixSetMut}, prefix_set::{PrefixSet, PrefixSetMut},
@ -106,7 +106,7 @@ impl<P> SparseTrie<P> {
/// Wipe the trie, removing all values and nodes, and replacing the root with an empty node. /// Wipe the trie, removing all values and nodes, and replacing the root with an empty node.
pub fn wipe(&mut self) -> SparseTrieResult<()> { pub fn wipe(&mut self) -> SparseTrieResult<()> {
let revealed = self.as_revealed_mut().ok_or(SparseTrieError::Blind)?; let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
revealed.wipe(); revealed.wipe();
Ok(()) Ok(())
} }
@ -129,14 +129,14 @@ where
{ {
/// Update the leaf node. /// Update the leaf node.
pub fn update_leaf(&mut self, path: Nibbles, value: Vec<u8>) -> SparseTrieResult<()> { pub fn update_leaf(&mut self, path: Nibbles, value: Vec<u8>) -> SparseTrieResult<()> {
let revealed = self.as_revealed_mut().ok_or(SparseTrieError::Blind)?; let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
revealed.update_leaf(path, value)?; revealed.update_leaf(path, value)?;
Ok(()) Ok(())
} }
/// Remove the leaf node. /// Remove the leaf node.
pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> { pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> {
let revealed = self.as_revealed_mut().ok_or(SparseTrieError::Blind)?; let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
revealed.remove_leaf(path)?; revealed.remove_leaf(path)?;
Ok(()) Ok(())
} }
@ -313,10 +313,11 @@ impl<P> RevealedSparseTrie<P> {
SparseNode::Branch { .. } | SparseNode::Extension { .. } => {} SparseNode::Branch { .. } | SparseNode::Extension { .. } => {}
// All other node types can't be handled. // All other node types can't be handled.
node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => { node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => {
return Err(SparseTrieError::Reveal { return Err(SparseTrieErrorKind::Reveal {
path: entry.key().clone(), path: entry.key().clone(),
node: Box::new(node.clone()), node: Box::new(node.clone()),
}) }
.into())
} }
}, },
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
@ -337,10 +338,11 @@ impl<P> RevealedSparseTrie<P> {
SparseNode::Extension { .. } | SparseNode::Branch { .. } => {} SparseNode::Extension { .. } | SparseNode::Branch { .. } => {}
// All other node types can't be handled. // All other node types can't be handled.
node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => { node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => {
return Err(SparseTrieError::Reveal { return Err(SparseTrieErrorKind::Reveal {
path: entry.key().clone(), path: entry.key().clone(),
node: Box::new(node.clone()), node: Box::new(node.clone()),
}) }
.into())
} }
}, },
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
@ -364,10 +366,11 @@ impl<P> RevealedSparseTrie<P> {
node @ (SparseNode::Empty | node @ (SparseNode::Empty |
SparseNode::Extension { .. } | SparseNode::Extension { .. } |
SparseNode::Branch { .. }) => { SparseNode::Branch { .. }) => {
return Err(SparseTrieError::Reveal { return Err(SparseTrieErrorKind::Reveal {
path: entry.key().clone(), path: entry.key().clone(),
node: Box::new(node.clone()), node: Box::new(node.clone()),
}) }
.into())
} }
}, },
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
@ -389,10 +392,11 @@ impl<P> RevealedSparseTrie<P> {
Entry::Occupied(entry) => match entry.get() { Entry::Occupied(entry) => match entry.get() {
// Hash node with a different hash can't be handled. // Hash node with a different hash can't be handled.
SparseNode::Hash(previous_hash) if previous_hash != &hash => { SparseNode::Hash(previous_hash) if previous_hash != &hash => {
return Err(SparseTrieError::Reveal { return Err(SparseTrieErrorKind::Reveal {
path: entry.key().clone(), path: entry.key().clone(),
node: Box::new(SparseNode::Hash(hash)), node: Box::new(SparseNode::Hash(hash)),
}) }
.into())
} }
_ => {} _ => {}
}, },
@ -413,9 +417,9 @@ impl<P> RevealedSparseTrie<P> {
while let Some(node) = self.nodes.remove(&current) { while let Some(node) = self.nodes.remove(&current) {
match &node { match &node {
SparseNode::Empty => return Err(SparseTrieError::Blind), SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
SparseNode::Hash(hash) => { &SparseNode::Hash(hash) => {
return Err(SparseTrieError::BlindedNode { path: current, hash: *hash }) return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into())
} }
SparseNode::Leaf { key: _key, .. } => { SparseNode::Leaf { key: _key, .. } => {
// Leaf node is always the one that we're deleting, and no other leaf nodes can // Leaf node is always the one that we're deleting, and no other leaf nodes can
@ -603,13 +607,13 @@ impl<P> RevealedSparseTrie<P> {
} }
SparseNode::Hash(hash) => (RlpNode::word_rlp(hash), false, SparseNodeType::Hash), SparseNode::Hash(hash) => (RlpNode::word_rlp(hash), false, SparseNodeType::Hash),
SparseNode::Leaf { key, hash } => { SparseNode::Leaf { key, hash } => {
self.rlp_buf.clear();
let mut path = path.clone(); let mut path = path.clone();
path.extend_from_slice_unchecked(key); path.extend_from_slice_unchecked(key);
if let Some(hash) = hash.filter(|_| !prefix_set_contains(&path)) { if let Some(hash) = hash.filter(|_| !prefix_set_contains(&path)) {
(RlpNode::word_rlp(&hash), false, SparseNodeType::Leaf) (RlpNode::word_rlp(&hash), false, SparseNodeType::Leaf)
} else { } else {
let value = self.values.get(&path).unwrap(); let value = self.values.get(&path).unwrap();
self.rlp_buf.clear();
let rlp_node = LeafNodeRef { key, value }.rlp(&mut self.rlp_buf); let rlp_node = LeafNodeRef { key, value }.rlp(&mut self.rlp_buf);
*hash = rlp_node.as_hash(); *hash = rlp_node.as_hash();
(rlp_node, true, SparseNodeType::Leaf) (rlp_node, true, SparseNodeType::Leaf)
@ -825,8 +829,8 @@ where
*node = SparseNode::new_leaf(path); *node = SparseNode::new_leaf(path);
break break
} }
SparseNode::Hash(hash) => { &mut SparseNode::Hash(hash) => {
return Err(SparseTrieError::BlindedNode { path: current, hash: *hash }) return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into())
} }
SparseNode::Leaf { key: current_key, .. } => { SparseNode::Leaf { key: current_key, .. } => {
current.extend_from_slice_unchecked(current_key); current.extend_from_slice_unchecked(current_key);
@ -844,6 +848,7 @@ where
*node = SparseNode::new_ext(new_ext_key); *node = SparseNode::new_ext(new_ext_key);
// create a branch node and corresponding leaves // create a branch node and corresponding leaves
self.nodes.reserve(3);
self.nodes.insert( self.nodes.insert(
current.slice(..common), current.slice(..common),
SparseNode::new_split_branch(current[common], path[common]), SparseNode::new_split_branch(current[common], path[common]),
@ -887,6 +892,7 @@ where
// create state mask for new branch node // create state mask for new branch node
// NOTE: this might overwrite the current extension node // NOTE: this might overwrite the current extension node
self.nodes.reserve(3);
let branch = SparseNode::new_split_branch(current[common], path[common]); let branch = SparseNode::new_split_branch(current[common], path[common]);
self.nodes.insert(current.slice(..common), branch); self.nodes.insert(current.slice(..common), branch);
@ -922,9 +928,9 @@ where
/// Remove leaf node from the trie. /// Remove leaf node from the trie.
pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> { pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> {
if self.values.remove(path).is_none() { if self.values.remove(path).is_none() {
if let Some(SparseNode::Hash(hash)) = self.nodes.get(path) { if let Some(&SparseNode::Hash(hash)) = self.nodes.get(path) {
// Leaf is present in the trie, but it's blinded. // Leaf is present in the trie, but it's blinded.
return Err(SparseTrieError::BlindedNode { path: path.clone(), hash: *hash }) return Err(SparseTrieErrorKind::BlindedNode { path: path.clone(), hash }.into())
} }
// Leaf is not present in the trie. // Leaf is not present in the trie.
@ -962,9 +968,9 @@ where
let removed_path = removed_node.path; let removed_path = removed_node.path;
let new_node = match &removed_node.node { let new_node = match &removed_node.node {
SparseNode::Empty => return Err(SparseTrieError::Blind), SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
SparseNode::Hash(hash) => { &SparseNode::Hash(hash) => {
return Err(SparseTrieError::BlindedNode { path: removed_path, hash: *hash }) return Err(SparseTrieErrorKind::BlindedNode { path: removed_path, hash }.into())
} }
SparseNode::Leaf { .. } => { SparseNode::Leaf { .. } => {
unreachable!("we already popped the leaf node") unreachable!("we already popped the leaf node")
@ -973,12 +979,11 @@ where
// If the node is an extension node, we need to look at its child to see if we // If the node is an extension node, we need to look at its child to see if we
// need to merge them. // need to merge them.
match &child.node { match &child.node {
SparseNode::Empty => return Err(SparseTrieError::Blind), SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
SparseNode::Hash(hash) => { &SparseNode::Hash(hash) => {
return Err(SparseTrieError::BlindedNode { return Err(
path: child.path, SparseTrieErrorKind::BlindedNode { path: child.path, hash }.into()
hash: *hash, )
})
} }
// For a leaf node, we collapse the extension node into a leaf node, // For a leaf node, we collapse the extension node into a leaf node,
// extending the key. While it's impossible to encounter an extension node // extending the key. While it's impossible to encounter an extension node
@ -1041,12 +1046,13 @@ where
let mut delete_child = false; let mut delete_child = false;
let new_node = match child { let new_node = match child {
SparseNode::Empty => return Err(SparseTrieError::Blind), SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
SparseNode::Hash(hash) => { &SparseNode::Hash(hash) => {
return Err(SparseTrieError::BlindedNode { return Err(SparseTrieErrorKind::BlindedNode {
path: child_path, path: child_path,
hash: *hash, hash,
}) }
.into())
} }
// If the only child is a leaf node, we downgrade the branch node into a // If the only child is a leaf node, we downgrade the branch node into a
// leaf node, prepending the nibble to the key, and delete the old // leaf node, prepending the nibble to the key, and delete the old
@ -1273,7 +1279,10 @@ impl SparseTrieUpdates {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use alloy_primitives::{map::HashSet, U256}; use alloy_primitives::{
map::{B256HashSet, HashSet},
U256,
};
use alloy_rlp::Encodable; use alloy_rlp::Encodable;
use assert_matches::assert_matches; use assert_matches::assert_matches;
use itertools::Itertools; use itertools::Itertools;
@ -1316,7 +1325,7 @@ mod tests {
/// Returns the state root and the retained proof nodes. /// Returns the state root and the retained proof nodes.
fn run_hash_builder( fn run_hash_builder(
state: impl IntoIterator<Item = (Nibbles, Account)> + Clone, state: impl IntoIterator<Item = (Nibbles, Account)> + Clone,
destroyed_accounts: HashSet<B256>, destroyed_accounts: B256HashSet,
proof_targets: impl IntoIterator<Item = Nibbles>, proof_targets: impl IntoIterator<Item = Nibbles>,
) -> (B256, TrieUpdates, ProofNodes, HashMap<Nibbles, TrieMask>) { ) -> (B256, TrieUpdates, ProofNodes, HashMap<Nibbles, TrieMask>) {
let mut account_rlp = Vec::new(); let mut account_rlp = Vec::new();
@ -1866,8 +1875,8 @@ mod tests {
// Removing a blinded leaf should result in an error // Removing a blinded leaf should result in an error
assert_matches!( assert_matches!(
sparse.remove_leaf(&Nibbles::from_nibbles([0x0])), sparse.remove_leaf(&Nibbles::from_nibbles([0x0])).map_err(|e| e.into_kind()),
Err(SparseTrieError::BlindedNode { path, hash }) if path == Nibbles::from_nibbles([0x0]) && hash == B256::repeat_byte(1) Err(SparseTrieErrorKind::BlindedNode { path, hash }) if path == Nibbles::from_nibbles([0x0]) && hash == B256::repeat_byte(1)
); );
} }

View File

@ -3,7 +3,7 @@ use crate::{
forward_cursor::ForwardInMemoryCursor, HashedAccountsSorted, HashedPostStateSorted, forward_cursor::ForwardInMemoryCursor, HashedAccountsSorted, HashedPostStateSorted,
HashedStorageSorted, HashedStorageSorted,
}; };
use alloy_primitives::{map::HashSet, B256, U256}; use alloy_primitives::{map::B256HashSet, B256, U256};
use reth_primitives::Account; use reth_primitives::Account;
use reth_storage_errors::db::DatabaseError; use reth_storage_errors::db::DatabaseError;
@ -48,7 +48,7 @@ pub struct HashedPostStateAccountCursor<'a, C> {
/// Forward-only in-memory cursor over accounts. /// Forward-only in-memory cursor over accounts.
post_state_cursor: ForwardInMemoryCursor<'a, B256, Account>, post_state_cursor: ForwardInMemoryCursor<'a, B256, Account>,
/// Reference to the collection of account keys that were destroyed. /// Reference to the collection of account keys that were destroyed.
destroyed_accounts: &'a HashSet<B256>, destroyed_accounts: &'a B256HashSet,
/// The last hashed account that was returned by the cursor. /// The last hashed account that was returned by the cursor.
/// De facto, this is a current cursor position. /// De facto, this is a current cursor position.
last_account: Option<B256>, last_account: Option<B256>,
@ -182,7 +182,7 @@ pub struct HashedPostStateStorageCursor<'a, C> {
/// Forward-only in-memory cursor over non zero-valued account storage slots. /// Forward-only in-memory cursor over non zero-valued account storage slots.
post_state_cursor: Option<ForwardInMemoryCursor<'a, B256, U256>>, post_state_cursor: Option<ForwardInMemoryCursor<'a, B256, U256>>,
/// Reference to the collection of storage slot keys that were cleared. /// Reference to the collection of storage slot keys that were cleared.
cleared_slots: Option<&'a HashSet<B256>>, cleared_slots: Option<&'a B256HashSet>,
/// Flag indicating whether database storage was wiped. /// Flag indicating whether database storage was wiped.
storage_wiped: bool, storage_wiped: bool,
/// The last slot that has been returned by the cursor. /// The last slot that has been returned by the cursor.

View File

@ -4,7 +4,7 @@ use alloy_primitives::{
map::{HashMap, HashSet}, map::{HashMap, HashSet},
Bytes, B256, Bytes, B256,
}; };
use reth_execution_errors::SparseTrieError; use reth_execution_errors::{SparseTrieError, SparseTrieErrorKind};
use reth_trie_common::{prefix_set::TriePrefixSetsMut, Nibbles}; use reth_trie_common::{prefix_set::TriePrefixSetsMut, Nibbles};
use reth_trie_sparse::blinded::{pad_path_to_key, BlindedProvider, BlindedProviderFactory}; use reth_trie_sparse::blinded::{pad_path_to_key, BlindedProvider, BlindedProviderFactory};
use std::sync::Arc; use std::sync::Arc;
@ -92,7 +92,7 @@ where
Proof::new(self.trie_cursor_factory.clone(), self.hashed_cursor_factory.clone()) Proof::new(self.trie_cursor_factory.clone(), self.hashed_cursor_factory.clone())
.with_prefix_sets_mut(self.prefix_sets.as_ref().clone()) .with_prefix_sets_mut(self.prefix_sets.as_ref().clone())
.multiproof(targets) .multiproof(targets)
.map_err(|error| SparseTrieError::Other(Box::new(error)))?; .map_err(|error| SparseTrieErrorKind::Other(Box::new(error)))?;
Ok(proof.account_subtree.into_inner().remove(&path)) Ok(proof.account_subtree.into_inner().remove(&path))
} }
@ -141,7 +141,7 @@ where
) )
.with_prefix_set_mut(storage_prefix_set) .with_prefix_set_mut(storage_prefix_set)
.storage_multiproof(targets) .storage_multiproof(targets)
.map_err(|error| SparseTrieError::Other(Box::new(error)))?; .map_err(|error| SparseTrieErrorKind::Other(Box::new(error)))?;
Ok(proof.subtree.into_inner().remove(&path)) Ok(proof.subtree.into_inner().remove(&path))
} }

View File

@ -8,7 +8,7 @@ use crate::{
}; };
use alloy_primitives::{ use alloy_primitives::{
keccak256, keccak256,
map::{HashMap, HashSet}, map::{B256HashMap, B256HashSet, HashMap, HashSet},
Address, B256, Address, B256,
}; };
use alloy_rlp::{BufMut, Encodable}; use alloy_rlp::{BufMut, Encodable};
@ -103,7 +103,7 @@ where
/// Generate a state multiproof according to specified targets. /// Generate a state multiproof according to specified targets.
pub fn multiproof( pub fn multiproof(
mut self, mut self,
mut targets: HashMap<B256, HashSet<B256>>, mut targets: B256HashMap<B256HashSet>,
) -> Result<MultiProof, StateProofError> { ) -> Result<MultiProof, StateProofError> {
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 = self.trie_cursor_factory.account_trie_cursor()?; let trie_cursor = self.trie_cursor_factory.account_trie_cursor()?;
@ -121,7 +121,7 @@ where
// Initialize all storage multiproofs as empty. // Initialize all storage multiproofs as empty.
// Storage multiproofs for non empty tries will be overwritten if necessary. // Storage multiproofs for non empty tries will be overwritten if necessary.
let mut storages: HashMap<_, _> = let mut storages: B256HashMap<_> =
targets.keys().map(|key| (*key, StorageMultiProof::empty())).collect(); targets.keys().map(|key| (*key, StorageMultiProof::empty())).collect();
let mut account_rlp = Vec::with_capacity(TRIE_ACCOUNT_RLP_MAX_SIZE); let mut account_rlp = Vec::with_capacity(TRIE_ACCOUNT_RLP_MAX_SIZE);
let mut account_node_iter = TrieNodeIter::new(walker, hashed_account_cursor); let mut account_node_iter = TrieNodeIter::new(walker, hashed_account_cursor);
@ -263,7 +263,7 @@ where
/// Generate storage proof. /// Generate storage proof.
pub fn storage_multiproof( pub fn storage_multiproof(
mut self, mut self,
targets: HashSet<B256>, targets: B256HashSet,
) -> Result<StorageMultiProof, StateProofError> { ) -> Result<StorageMultiProof, StateProofError> {
let mut hashed_storage_cursor = let mut hashed_storage_cursor =
self.hashed_cursor_factory.hashed_storage_cursor(self.hashed_address)?; self.hashed_cursor_factory.hashed_storage_cursor(self.hashed_address)?;

View File

@ -4,7 +4,7 @@ use crate::{
}; };
use alloy_primitives::{ use alloy_primitives::{
keccak256, keccak256,
map::{hash_map, HashMap, HashSet}, map::{hash_map, B256HashMap, B256HashSet, HashMap, HashSet},
Address, B256, U256, Address, B256, U256,
}; };
use itertools::Itertools; use itertools::Itertools;
@ -18,9 +18,9 @@ use std::borrow::Cow;
#[derive(PartialEq, Eq, Clone, Default, Debug)] #[derive(PartialEq, Eq, Clone, Default, Debug)]
pub struct HashedPostState { pub struct HashedPostState {
/// Mapping of hashed address to account info, `None` if destroyed. /// Mapping of hashed address to account info, `None` if destroyed.
pub accounts: HashMap<B256, Option<Account>>, pub accounts: B256HashMap<Option<Account>>,
/// Mapping of hashed address to hashed storage. /// Mapping of hashed address to hashed storage.
pub storages: HashMap<B256, HashedStorage>, pub storages: B256HashMap<HashedStorage>,
} }
impl HashedPostState { impl HashedPostState {
@ -210,7 +210,7 @@ pub struct HashedStorage {
/// Flag indicating whether the storage was wiped or not. /// Flag indicating whether the storage was wiped or not.
pub wiped: bool, pub wiped: bool,
/// Mapping of hashed storage slot to storage value. /// Mapping of hashed storage slot to storage value.
pub storage: HashMap<B256, U256>, pub storage: B256HashMap<U256>,
} }
impl HashedStorage { impl HashedStorage {
@ -281,14 +281,14 @@ pub struct HashedPostStateSorted {
/// Updated state of accounts. /// Updated state of accounts.
pub(crate) accounts: HashedAccountsSorted, pub(crate) accounts: HashedAccountsSorted,
/// Map of hashed addresses to hashed storage. /// Map of hashed addresses to hashed storage.
pub(crate) storages: HashMap<B256, HashedStorageSorted>, pub(crate) storages: B256HashMap<HashedStorageSorted>,
} }
impl HashedPostStateSorted { impl HashedPostStateSorted {
/// Create new instance of [`HashedPostStateSorted`] /// Create new instance of [`HashedPostStateSorted`]
pub const fn new( pub const fn new(
accounts: HashedAccountsSorted, accounts: HashedAccountsSorted,
storages: HashMap<B256, HashedStorageSorted>, storages: B256HashMap<HashedStorageSorted>,
) -> Self { ) -> Self {
Self { accounts, storages } Self { accounts, storages }
} }
@ -299,7 +299,7 @@ impl HashedPostStateSorted {
} }
/// Returns reference to hashed account storages. /// Returns reference to hashed account storages.
pub const fn account_storages(&self) -> &HashMap<B256, HashedStorageSorted> { pub const fn account_storages(&self) -> &B256HashMap<HashedStorageSorted> {
&self.storages &self.storages
} }
} }
@ -310,7 +310,7 @@ pub struct HashedAccountsSorted {
/// Sorted collection of hashed addresses and their account info. /// Sorted collection of hashed addresses and their account info.
pub(crate) accounts: Vec<(B256, Account)>, pub(crate) accounts: Vec<(B256, Account)>,
/// Set of destroyed account keys. /// Set of destroyed account keys.
pub(crate) destroyed_accounts: HashSet<B256>, pub(crate) destroyed_accounts: B256HashSet,
} }
impl HashedAccountsSorted { impl HashedAccountsSorted {
@ -330,7 +330,7 @@ pub struct HashedStorageSorted {
/// Sorted hashed storage slots with non-zero value. /// Sorted hashed storage slots with non-zero value.
pub(crate) non_zero_valued_slots: Vec<(B256, U256)>, pub(crate) non_zero_valued_slots: Vec<(B256, U256)>,
/// Slots that have been zero valued. /// Slots that have been zero valued.
pub(crate) zero_valued_slots: HashSet<B256>, pub(crate) zero_valued_slots: B256HashSet,
/// Flag indicating whether the storage was wiped or not. /// Flag indicating whether the storage was wiped or not.
pub(crate) wiped: bool, pub(crate) wiped: bool,
} }

View File

@ -7,12 +7,13 @@ use crate::{
}; };
use alloy_primitives::{ use alloy_primitives::{
keccak256, keccak256,
map::{Entry, HashMap, HashSet}, map::{B256HashMap, B256HashSet, Entry, HashMap},
Bytes, B256, Bytes, B256,
}; };
use itertools::Itertools; use itertools::Itertools;
use reth_execution_errors::{ use reth_execution_errors::{
SparseStateTrieError, SparseTrieError, StateProofError, TrieWitnessError, SparseStateTrieError, SparseStateTrieErrorKind, SparseTrieError, SparseTrieErrorKind,
StateProofError, TrieWitnessError,
}; };
use reth_trie_common::Nibbles; use reth_trie_common::Nibbles;
use reth_trie_sparse::{ use reth_trie_sparse::{
@ -31,7 +32,7 @@ pub struct TrieWitness<T, H> {
/// A set of prefix sets that have changes. /// A set of prefix sets that have changes.
prefix_sets: TriePrefixSetsMut, prefix_sets: TriePrefixSetsMut,
/// Recorded witness. /// Recorded witness.
witness: HashMap<B256, Bytes>, witness: B256HashMap<Bytes>,
} }
impl<T, H> TrieWitness<T, H> { impl<T, H> TrieWitness<T, H> {
@ -86,7 +87,7 @@ where
pub fn compute( pub fn compute(
mut self, mut self,
state: HashedPostState, state: HashedPostState,
) -> Result<HashMap<B256, Bytes>, TrieWitnessError> { ) -> Result<B256HashMap<Bytes>, TrieWitnessError> {
if state.is_empty() { if state.is_empty() {
return Ok(self.witness) return Ok(self.witness)
} }
@ -127,7 +128,7 @@ where
let storage = state.storages.get(&hashed_address); let storage = state.storages.get(&hashed_address);
let storage_trie = sparse_trie let storage_trie = sparse_trie
.storage_trie_mut(&hashed_address) .storage_trie_mut(&hashed_address)
.ok_or(SparseStateTrieError::Sparse(SparseTrieError::Blind))?; .ok_or(SparseStateTrieErrorKind::Sparse(SparseTrieErrorKind::Blind))?;
for hashed_slot in hashed_slots.into_iter().sorted_unstable() { for hashed_slot in hashed_slots.into_iter().sorted_unstable() {
let storage_nibbles = Nibbles::unpack(hashed_slot); let storage_nibbles = Nibbles::unpack(hashed_slot);
let maybe_leaf_value = storage let maybe_leaf_value = storage
@ -138,11 +139,11 @@ where
if let Some(value) = maybe_leaf_value { if let Some(value) = maybe_leaf_value {
storage_trie storage_trie
.update_leaf(storage_nibbles, value) .update_leaf(storage_nibbles, value)
.map_err(SparseStateTrieError::Sparse)?; .map_err(SparseStateTrieError::from)?;
} else { } else {
storage_trie storage_trie
.remove_leaf(&storage_nibbles) .remove_leaf(&storage_nibbles)
.map_err(SparseStateTrieError::Sparse)?; .map_err(SparseStateTrieError::from)?;
} }
} }
@ -170,13 +171,13 @@ where
fn get_proof_targets( fn get_proof_targets(
&self, &self,
state: &HashedPostState, state: &HashedPostState,
) -> Result<HashMap<B256, HashSet<B256>>, StateProofError> { ) -> Result<B256HashMap<B256HashSet>, StateProofError> {
let mut proof_targets = HashMap::default(); let mut proof_targets = B256HashMap::default();
for hashed_address in state.accounts.keys() { for hashed_address in state.accounts.keys() {
proof_targets.insert(*hashed_address, HashSet::default()); proof_targets.insert(*hashed_address, B256HashSet::default());
} }
for (hashed_address, storage) in &state.storages { for (hashed_address, storage) in &state.storages {
let mut storage_keys = storage.storage.keys().copied().collect::<HashSet<_>>(); let mut storage_keys = storage.storage.keys().copied().collect::<B256HashSet>();
if storage.wiped { if storage.wiped {
// storage for this account was destroyed, gather all slots from the current state // storage for this account was destroyed, gather all slots from the current state
let mut storage_cursor = let mut storage_cursor =
@ -251,7 +252,9 @@ where
fn blinded_node(&mut self, path: Nibbles) -> Result<Option<Bytes>, Self::Error> { fn blinded_node(&mut self, path: Nibbles) -> Result<Option<Bytes>, Self::Error> {
let maybe_node = self.provider.blinded_node(path)?; let maybe_node = self.provider.blinded_node(path)?;
if let Some(node) = &maybe_node { if let Some(node) = &maybe_node {
self.tx.send(node.clone()).map_err(|error| SparseTrieError::Other(Box::new(error)))?; self.tx
.send(node.clone())
.map_err(|error| SparseTrieErrorKind::Other(Box::new(error)))?;
} }
Ok(maybe_node) Ok(maybe_node)
} }