mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
perf: trie micro optimizations (#13282)
This commit is contained in:
@ -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 {
|
||||||
|
|||||||
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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");
|
||||||
|
|||||||
@ -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())
|
||||||
|
|||||||
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
11
crates/rpc/rpc-eth-types/src/cache/db.rs
vendored
11
crates/rpc/rpc-eth-types/src/cache/db.rs
vendored
@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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 },
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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()?;
|
||||||
|
|||||||
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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),
|
||||||
|
|||||||
@ -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) }
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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> {
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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))..)?
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 { .. })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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(¤t) {
|
while let Some(node) = self.nodes.remove(¤t) {
|
||||||
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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)?;
|
||||||
|
|||||||
@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user