diff --git a/Cargo.lock b/Cargo.lock index 27581ba3a8008..d0a47eedc8cd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6378,7 +6378,6 @@ dependencies = [ "reth-stages-api", "reth-tokio-util", "reth-transaction-pool", - "reth-trie", "revm-primitives", "tokio", "tokio-stream", @@ -7397,7 +7396,6 @@ dependencies = [ "reth-provider", "reth-revm", "reth-transaction-pool", - "reth-trie", "revm", "revm-primitives", "tracing", @@ -8284,7 +8282,6 @@ dependencies = [ "reth-revm", "reth-rpc-types-compat", "reth-transaction-pool", - "reth-trie", "revm", "sha2 0.10.8", "thiserror", @@ -8824,7 +8821,6 @@ dependencies = [ "reth-rpc-types-compat", "reth-tasks", "reth-transaction-pool", - "reth-trie", "revm", "revm-inspectors", "revm-primitives", diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index a2dfb5ab3eaad..c13c315316241 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -34,7 +34,7 @@ use reth_primitives::{ }; use reth_provider::{ providers::BlockchainProvider, BlockHashReader, BlockReader, BlockWriter, ChainSpecProvider, - ProviderFactory, StageCheckpointReader, StateProviderFactory, + HashedPostStateProvider, ProviderFactory, StageCheckpointReader, StateProviderFactory, }; use reth_revm::{database::StateProviderDatabase, primitives::EnvKzgSettings}; use reth_stages::StageId; @@ -270,7 +270,8 @@ impl> Command { ExecutionOutcome::from((block_execution_output, block.number)); debug!(target: "reth::cli", ?execution_outcome, "Executed block"); - let hashed_post_state = execution_outcome.hash_state_slow(); + let hashed_post_state = + provider_factory.hashed_post_state_from_bundle_state(execution_outcome.state()); let (state_root, trie_updates) = StateRoot::overlay_root_with_updates( provider_factory.provider()?.tx_ref(), hashed_post_state.clone(), diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index f4a86cd3b231e..634a872b95770 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -22,8 +22,8 @@ use reth_node_ethereum::EthExecutorProvider; use reth_primitives::BlockHashOrNumber; use reth_provider::{ writer::UnifiedStorageWriter, AccountExtReader, AsLatestStateProviderRef, ChainSpecProvider, - HashingWriter, HeaderProvider, OriginalValuesKnown, ProviderFactory, StageCheckpointReader, - StateWriter, StorageReader, + HashedPostStateProvider, HashingWriter, HeaderProvider, OriginalValuesKnown, ProviderFactory, + StageCheckpointReader, StateWriter, StorageReader, }; use reth_revm::database::StateProviderDatabase; use reth_stages::StageId; @@ -153,7 +153,7 @@ impl> Command { // Unpacked `BundleState::state_root_slow` function let (in_memory_state_root, in_memory_updates) = StateRoot::overlay_root_with_updates( provider.tx_ref(), - execution_outcome.hash_state_slow(), + provider.hashed_post_state_from_bundle_state(execution_outcome.state()), )?; if in_memory_state_root == block.state_root { diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 4468d82052c83..172a9d8ffbb72 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -23,8 +23,8 @@ use reth_primitives::{ use reth_provider::{ providers::ProviderNodeTypes, BlockExecutionWriter, BlockNumReader, BlockWriter, CanonStateNotification, CanonStateNotificationSender, CanonStateNotifications, - ChainSpecProvider, ChainSplit, ChainSplitTarget, DisplayBlocksChain, HeaderProvider, - ProviderError, StaticFileProviderFactory, + ChainSpecProvider, ChainSplit, ChainSplitTarget, DisplayBlocksChain, HashedPostStateProvider, + HeaderProvider, ProviderError, StaticFileProviderFactory, }; use reth_stages_api::{MetricEvent, MetricEventsSender}; use reth_storage_errors::provider::{ProviderResult, RootMismatch}; @@ -1214,7 +1214,8 @@ where recorder: &mut MakeCanonicalDurationsRecorder, ) -> Result<(), CanonicalError> { let (blocks, state, chain_trie_updates) = chain.into_inner(); - let hashed_state = state.hash_state_slow(); + let hashed_state = + self.externals.provider_factory.hashed_post_state_from_bundle_state(state.state()); let prefix_sets = hashed_state.construct_prefix_sets().freeze(); let hashed_state_sorted = hashed_state.into_sorted(); @@ -1872,7 +1873,12 @@ mod tests { ); let provider = tree.externals.provider_factory.provider().unwrap(); - let prefix_sets = exec5.hash_state_slow().construct_prefix_sets().freeze(); + let prefix_sets = tree + .externals + .provider_factory + .hashed_post_state_from_bundle_state(exec5.state()) + .construct_prefix_sets() + .freeze(); let state_root = StateRoot::from_tx(provider.tx_ref()).with_prefix_sets(prefix_sets).root().unwrap(); assert_eq!(state_root, block5.state_root); diff --git a/crates/blockchain-tree/src/chain.rs b/crates/blockchain-tree/src/chain.rs index 393e525d5ae20..db350e0185b27 100644 --- a/crates/blockchain-tree/src/chain.rs +++ b/crates/blockchain-tree/src/chain.rs @@ -18,10 +18,11 @@ use reth_execution_types::{Chain, ExecutionOutcome}; use reth_primitives::{GotExpected, SealedBlockWithSenders, SealedHeader}; use reth_provider::{ providers::{BundleStateProvider, ConsistentDbView, ProviderNodeTypes}, - FullExecutionDataProvider, ProviderError, StateRootProvider, TryIntoHistoricalStateProvider, + FullExecutionDataProvider, HashedPostStateProvider, ProviderError, StateRootProvider, + TryIntoHistoricalStateProvider, }; use reth_revm::database::StateProviderDatabase; -use reth_trie::{updates::TrieUpdates, HashedPostState, TrieInput}; +use reth_trie::{updates::TrieUpdates, TrieInput}; use reth_trie_parallel::parallel_root::ParallelStateRoot; use std::{ collections::BTreeMap, @@ -227,14 +228,19 @@ impl AppendableChain { execution_outcome.extend(initial_execution_outcome.clone()); ParallelStateRoot::new( consistent_view, - TrieInput::from_state(execution_outcome.hash_state_slow()), + TrieInput::from_state( + externals + .provider_factory + .hashed_post_state_from_bundle_state(execution_outcome.state()), + ), ) .incremental_root_with_updates() .map(|(root, updates)| (root, Some(updates))) .map_err(ProviderError::from)? } else { - let hashed_state = - HashedPostState::from_bundle_state(&initial_execution_outcome.state().state); + let hashed_state = externals + .provider_factory + .hashed_post_state_from_bundle_state(initial_execution_outcome.state()); let state_root = provider.state_root(hashed_state)?; (state_root, None) }; diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index 6bef197bea984..bd5447d248b8e 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -918,8 +918,8 @@ mod tests { use reth_errors::ProviderResult; use reth_primitives::{Account, Bytecode, Receipt}; use reth_storage_api::{ - AccountReader, BlockHashReader, StateProofProvider, StateProvider, StateRootProvider, - StorageRootProvider, + AccountReader, BlockHashReader, HashedPostStateProvider, StateProofProvider, StateProvider, + StateRootProvider, StorageRootProvider, }; use reth_trie::{AccountProof, HashedStorage, MultiProof, StorageProof, TrieInput}; @@ -1060,6 +1060,22 @@ mod tests { } } + impl HashedPostStateProvider for MockStateProvider { + fn hashed_post_state_from_bundle_state( + &self, + _bundle_state: &reth_execution_types::BundleState, + ) -> HashedPostState { + HashedPostState::default() + } + + fn hashed_post_state_from_reverts( + &self, + _block_number: BlockNumber, + ) -> ProviderResult { + Ok(HashedPostState::default()) + } + } + #[test] fn test_in_memory_state_impl_state_by_hash() { let mut state_by_hash = HashMap::default(); diff --git a/crates/chain-state/src/memory_overlay.rs b/crates/chain-state/src/memory_overlay.rs index ada0faee4907f..5de2ded6e4bf5 100644 --- a/crates/chain-state/src/memory_overlay.rs +++ b/crates/chain-state/src/memory_overlay.rs @@ -7,8 +7,8 @@ use alloy_primitives::{ use reth_errors::ProviderResult; use reth_primitives::{Account, Bytecode}; use reth_storage_api::{ - AccountReader, BlockHashReader, StateProofProvider, StateProvider, StateRootProvider, - StorageRootProvider, + AccountReader, BlockHashReader, HashedPostStateProvider, StateProofProvider, StateProvider, + StateRootProvider, StorageRootProvider, }; use reth_trie::{ updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, TrieInput, @@ -202,6 +202,22 @@ macro_rules! impl_state_provider { } } + impl $($tokens)* HashedPostStateProvider for $type { + fn hashed_post_state_from_bundle_state( + &self, + bundle_state: &reth_execution_types::BundleState, + ) -> HashedPostState { + self.historical.hashed_post_state_from_bundle_state(bundle_state) + } + + fn hashed_post_state_from_reverts( + &self, + block_number: BlockNumber, + ) -> ProviderResult { + self.historical.hashed_post_state_from_reverts(block_number) + } + } + impl $($tokens)* StateProvider for $type { fn storage( &self, diff --git a/crates/consensus/auto-seal/Cargo.toml b/crates/consensus/auto-seal/Cargo.toml index f2bfb43bccedf..00390323f73f9 100644 --- a/crates/consensus/auto-seal/Cargo.toml +++ b/crates/consensus/auto-seal/Cargo.toml @@ -28,7 +28,6 @@ reth-engine-primitives.workspace = true reth-consensus.workspace = true reth-network-peers.workspace = true reth-tokio-util.workspace = true -reth-trie.workspace = true # ethereum alloy-eips.workspace = true diff --git a/crates/consensus/auto-seal/src/lib.rs b/crates/consensus/auto-seal/src/lib.rs index 16299e19ba459..aac75b39f8e72 100644 --- a/crates/consensus/auto-seal/src/lib.rs +++ b/crates/consensus/auto-seal/src/lib.rs @@ -32,7 +32,6 @@ use reth_primitives::{ use reth_provider::{BlockReaderIdExt, StateProviderFactory, StateRootProvider}; use reth_revm::database::StateProviderDatabase; use reth_transaction_pool::TransactionPool; -use reth_trie::HashedPostState; use revm_primitives::calc_excess_blob_gas; use std::{ collections::HashMap, @@ -383,7 +382,7 @@ impl StorageInner { executor.executor(&mut db).execute((&block, U256::ZERO).into())?; let gas_used = block_execution_output.gas_used; let execution_outcome = ExecutionOutcome::from((block_execution_output, block.number)); - let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); + let hashed_state = db.0.hashed_post_state_from_bundle_state(execution_outcome.state()); // todo(onbjerg): we should not pass requests around as this is building a block, which // means we need to extract the requests from the execution output and compute the requests diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index 416c4adb40f8a..8b6018f17d260 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -19,7 +19,7 @@ use reth_revm::{ }; use reth_rpc_api::DebugApiClient; use reth_tracing::tracing::warn; -use reth_trie::{updates::TrieUpdates, HashedPostState, HashedStorage}; +use reth_trie::{updates::TrieUpdates, HashedStorage}; use serde::Serialize; /// Generates a witness for the given block and saves it to a file. @@ -129,7 +129,7 @@ where // // Note: We grab *all* accounts in the cache here, as the `BundleState` prunes // referenced accounts + storage slots. - let mut hashed_state = HashedPostState::from_bundle_state(&bundle_state.state); + let mut hashed_state = db.database.hashed_post_state_from_bundle_state(&bundle_state); for (address, account) in db.cache.accounts { let hashed_address = keccak256(address); hashed_state diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index bc070d87345e7..750a6bc36df86 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -37,8 +37,8 @@ use reth_primitives::{ }; use reth_provider::{ providers::ConsistentDbView, BlockReader, DatabaseProviderFactory, ExecutionOutcome, - ProviderError, StateProviderBox, StateProviderFactory, StateReader, StateRootProvider, - TransactionVariant, + HashedPostStateProvider, ProviderError, StateProviderBox, StateProviderFactory, StateReader, + StateRootProvider, TransactionVariant, }; use reth_revm::database::StateProviderDatabase; use reth_stages_api::ControlFlow; @@ -532,8 +532,14 @@ impl std::fmt::Debug impl EngineApiTreeHandler where - P: DatabaseProviderFactory + BlockReader + StateProviderFactory + StateReader + Clone + 'static, -

::Provider: BlockReader, + P: DatabaseProviderFactory + + BlockReader + + StateProviderFactory + + StateReader + + HashedPostStateProvider + + Clone + + 'static, +

::Provider: BlockReader + HashedPostStateProvider, E: BlockExecutorProvider, T: EngineTypes, Spec: Send + Sync + EthereumHardforks + 'static, @@ -1537,7 +1543,8 @@ where .provider .get_state(block.number)? .ok_or_else(|| ProviderError::StateForNumberNotFound(block.number))?; - let hashed_state = execution_output.hash_state_slow(); + let hashed_state = + self.provider.hashed_post_state_from_bundle_state(execution_output.state()); Ok(Some(ExecutedBlock { block: Arc::new(block), @@ -2202,7 +2209,7 @@ where return Err(err.into()) } - let hashed_state = HashedPostState::from_bundle_state(&output.state.state); + let hashed_state = self.provider.hashed_post_state_from_bundle_state(&output.state); trace!(target: "engine::tree", block=?sealed_block.num_hash(), "Calculating block state root"); let root_time = Instant::now(); diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 0d51d2dfab6f8..293bbb792c270 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -24,7 +24,6 @@ use reth_revm::{ DatabaseCommit, }; use reth_rpc_types_compat::engine::payload::block_to_payload; -use reth_trie::HashedPostState; use revm_primitives::{ calc_excess_blob_gas, BlockEnv, CfgEnvWithHandlerCfg, EVMError, EnvWithHandlerCfg, }; @@ -381,7 +380,7 @@ where reorg_target.number, Default::default(), ); - let hashed_state = HashedPostState::from_bundle_state(&outcome.state().state); + let hashed_state = state_provider.hashed_post_state_from_bundle_state(outcome.state()); let (blob_gas_used, excess_blob_gas) = if chain_spec.is_cancun_active_at_timestamp(reorg_target.timestamp) { diff --git a/crates/ethereum/payload/Cargo.toml b/crates/ethereum/payload/Cargo.toml index 443e837b2ed12..0205ba9312ac6 100644 --- a/crates/ethereum/payload/Cargo.toml +++ b/crates/ethereum/payload/Cargo.toml @@ -24,7 +24,6 @@ reth-basic-payload-builder.workspace = true reth-evm.workspace = true reth-evm-ethereum.workspace = true reth-errors.workspace = true -reth-trie.workspace = true reth-chain-state.workspace = true reth-chainspec.workspace = true diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 8e188f890fd98..20b049f4bb4c6 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -35,7 +35,6 @@ use reth_transaction_pool::{ noop::NoopTransactionPool, BestTransactions, BestTransactionsAttributes, TransactionPool, ValidPoolTransaction, }; -use reth_trie::HashedPostState; use revm::{ db::{states::bundle_state::BundleRetention, State}, primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState}, @@ -366,16 +365,20 @@ where let logs_bloom = execution_outcome.block_logs_bloom(block_number).expect("Number is in range"); // calculate the state root - let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); - let (state_root, trie_output) = { + + let (state_root, trie_output, hashed_state) = { let state_provider = db.database.0.inner.borrow_mut(); - state_provider.db.state_root_with_updates(hashed_state.clone()).inspect_err(|err| { - warn!(target: "payload_builder", - parent_hash=%parent_header.hash(), - %err, - "failed to calculate state root for payload" - ); - })? + let hashed_state = + state_provider.db.hashed_post_state_from_bundle_state(execution_outcome.state()); + let (state_root, trie_output) = + state_provider.db.state_root_with_updates(hashed_state.clone()).inspect_err(|err| { + warn!(target: "payload_builder", + parent_hash=%parent_header.hash(), + %err, + "failed to calculate state root for payload" + ); + })?; + (state_root, trie_output, hashed_state) }; // create the block header diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index 026e6b37c42cb..9b9d857102cc0 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -2,7 +2,7 @@ use crate::BlockExecutionOutput; use alloy_eips::eip7685::Requests; use alloy_primitives::{Address, BlockNumber, Bloom, Log, B256, U256}; use reth_primitives::{logs_bloom, Account, Bytecode, Receipt, Receipts, StorageEntry}; -use reth_trie::HashedPostState; +use reth_trie::{HashedPostState, KeyHasher}; use revm::{ db::{states::BundleState, BundleAccount}, primitives::AccountInfo, @@ -163,8 +163,8 @@ impl ExecutionOutcome { /// Returns [`HashedPostState`] for this execution outcome. /// See [`HashedPostState::from_bundle_state`] for more info. - pub fn hash_state_slow(&self) -> HashedPostState { - HashedPostState::from_bundle_state(&self.bundle.state) + pub fn hash_state_slow(&self) -> HashedPostState { + HashedPostState::from_bundle_state::(&self.bundle.state) } /// Transform block number to the index of block. diff --git a/crates/evm/execution-types/src/lib.rs b/crates/evm/execution-types/src/lib.rs index f98ebfe73a5f0..c5adafecb1da1 100644 --- a/crates/evm/execution-types/src/lib.rs +++ b/crates/evm/execution-types/src/lib.rs @@ -19,6 +19,9 @@ pub use execute::*; mod execution_outcome; pub use execution_outcome::*; +// Re-export commonly used execution types from `revm`. +pub use revm::db::{BundleAccount, BundleState}; + /// Bincode-compatible serde implementations for commonly used types for (EVM) block execution. /// /// `bincode` crate doesn't work with optionally serializable serde fields, but some of the diff --git a/crates/optimism/payload/Cargo.toml b/crates/optimism/payload/Cargo.toml index 4b8e64f2dba3c..cf4fe80547ed4 100644 --- a/crates/optimism/payload/Cargo.toml +++ b/crates/optimism/payload/Cargo.toml @@ -24,7 +24,6 @@ reth-execution-types.workspace = true reth-payload-builder.workspace = true reth-payload-primitives.workspace = true reth-basic-payload-builder.workspace = true -reth-trie.workspace = true reth-chain-state.workspace = true # op-reth diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 0550adeaa8d54..4b71f9cb37b64 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -24,7 +24,6 @@ use reth_revm::database::StateProviderDatabase; use reth_transaction_pool::{ noop::NoopTransactionPool, BestTransactionsAttributes, TransactionPool, }; -use reth_trie::HashedPostState; use revm::{ db::{states::bundle_state::BundleRetention, State}, primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState}, @@ -445,16 +444,19 @@ where let logs_bloom = execution_outcome.block_logs_bloom(block_number).expect("Number is in range"); // calculate the state root - let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); - let (state_root, trie_output) = { + let (state_root, trie_output, hashed_state) = { let state_provider = db.database.0.inner.borrow_mut(); - state_provider.db.state_root_with_updates(hashed_state.clone()).inspect_err(|err| { - warn!(target: "payload_builder", - parent_header=%parent_header.hash(), - %err, - "failed to calculate state root for payload" - ); - })? + let hashed_state = + state_provider.db.hashed_post_state_from_bundle_state(execution_outcome.state()); + let (state_root, trie_output) = + state_provider.db.state_root_with_updates(hashed_state.clone()).inspect_err(|err| { + warn!(target: "payload_builder", + parent_header=%parent_header.hash(), + %err, + "failed to calculate state root for payload" + ); + })?; + (state_root, trie_output, hashed_state) }; // create the block header diff --git a/crates/revm/src/test_utils.rs b/crates/revm/src/test_utils.rs index 813997c72d11b..f15398a81cfa0 100644 --- a/crates/revm/src/test_utils.rs +++ b/crates/revm/src/test_utils.rs @@ -6,14 +6,15 @@ use alloy_primitives::{ }; use reth_primitives::{Account, Bytecode}; use reth_storage_api::{ - AccountReader, BlockHashReader, StateProofProvider, StateProvider, StateRootProvider, - StorageRootProvider, + AccountReader, BlockHashReader, HashedPostStateProvider, StateProofProvider, StateProvider, + StateRootProvider, StorageRootProvider, }; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ - updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, StorageProof, - TrieInput, + updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, KeccakKeyHasher, + MultiProof, StorageProof, TrieInput, }; +use revm::db::BundleState; /// Mock state for testing #[derive(Debug, Default, Clone, Eq, PartialEq)] @@ -141,6 +142,19 @@ impl StateProofProvider for StateProviderTest { } } +impl HashedPostStateProvider for StateProviderTest { + fn hashed_post_state_from_bundle_state(&self, bundle_state: &BundleState) -> HashedPostState { + HashedPostState::from_bundle_state::(&bundle_state.state) + } + + fn hashed_post_state_from_reverts( + &self, + _block_number: BlockNumber, + ) -> ProviderResult { + unimplemented!("reverts are not supported") + } +} + impl StateProvider for StateProviderTest { fn storage( &self, diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml index edfd57b201d9b..6e32f29f9494b 100644 --- a/crates/rpc/rpc-eth-api/Cargo.toml +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -29,7 +29,6 @@ reth-execution-types.workspace = true reth-rpc-eth-types.workspace = true reth-rpc-server-types.workspace = true reth-network-api.workspace = true -reth-trie.workspace = true reth-node-api.workspace = true # ethereum diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index f2d1416139b8c..570b395548031 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -34,7 +34,6 @@ use reth_provider::{ use reth_revm::database::StateProviderDatabase; use reth_rpc_eth_types::{EthApiError, PendingBlock, PendingBlockEnv, PendingBlockEnvOrigin}; use reth_transaction_pool::{BestTransactionsAttributes, TransactionPool}; -use reth_trie::HashedPostState; use revm::{db::states::bundle_state::BundleRetention, DatabaseCommit, State}; use tokio::sync::Mutex; use tracing::debug; @@ -391,7 +390,10 @@ pub trait LoadPendingBlock: block_number, Vec::new(), ); - let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state); + + let state_provider = &db.database; + let hashed_state = + state_provider.hashed_post_state_from_bundle_state(execution_outcome.state()); let receipts_root = self.receipts_root(&block_env, &execution_outcome, block_number); @@ -399,7 +401,6 @@ pub trait LoadPendingBlock: execution_outcome.block_logs_bloom(block_number).expect("Block is present"); // calculate the state root - let state_provider = &db.database; let state_root = state_provider.state_root(hashed_state).map_err(Self::Error::from_eth_err)?; diff --git a/crates/rpc/rpc-eth-types/src/cache/db.rs b/crates/rpc/rpc-eth-types/src/cache/db.rs index 627fd2b2df729..8162471792098 100644 --- a/crates/rpc/rpc-eth-types/src/cache/db.rs +++ b/crates/rpc/rpc-eth-types/src/cache/db.rs @@ -130,6 +130,22 @@ impl reth_storage_api::BlockHashReader for StateProviderTraitObjWrapper<'_> { } } +impl reth_storage_api::HashedPostStateProvider for StateProviderTraitObjWrapper<'_> { + fn hashed_post_state_from_bundle_state( + &self, + bundle_state: &reth_execution_types::BundleState, + ) -> reth_trie::HashedPostState { + self.0.hashed_post_state_from_bundle_state(bundle_state) + } + + fn hashed_post_state_from_reverts( + &self, + block_number: alloy_primitives::BlockNumber, + ) -> ProviderResult { + self.0.hashed_post_state_from_reverts(block_number) + } +} + impl StateProvider for StateProviderTraitObjWrapper<'_> { fn storage( &self, diff --git a/crates/stages/stages/benches/criterion.rs b/crates/stages/stages/benches/criterion.rs index 481ec75f87ee6..0f876dd7011a1 100644 --- a/crates/stages/stages/benches/criterion.rs +++ b/crates/stages/stages/benches/criterion.rs @@ -13,7 +13,6 @@ use reth_stages::{ StageCheckpoint, }; use reth_stages_api::{ExecInput, Stage, StageExt, UnwindInput}; -use reth_trie_db::MerklePatriciaTrie; use std::ops::RangeInclusive; use tokio::runtime::Runtime; diff --git a/crates/stages/stages/benches/setup/mod.rs b/crates/stages/stages/benches/setup/mod.rs index 37d28a3324c09..e6ae33f9c2997 100644 --- a/crates/stages/stages/benches/setup/mod.rs +++ b/crates/stages/stages/benches/setup/mod.rs @@ -27,7 +27,7 @@ mod constants; mod account_hashing; pub use account_hashing::*; use reth_stages_api::{ExecInput, Stage, UnwindInput}; -use reth_trie_db::{DatabaseStateRoot, MerklePatriciaTrie}; +use reth_trie_db::DatabaseStateRoot; pub(crate) type StageRange = (ExecInput, UnwindInput); diff --git a/crates/stages/stages/src/test_utils/runner.rs b/crates/stages/stages/src/test_utils/runner.rs index b4d2508df8b0c..c3d25b99536ae 100644 --- a/crates/stages/stages/src/test_utils/runner.rs +++ b/crates/stages/stages/src/test_utils/runner.rs @@ -5,7 +5,6 @@ use reth_stages_api::{ ExecInput, ExecOutput, Stage, StageError, StageExt, UnwindInput, UnwindOutput, }; use reth_storage_errors::db::DatabaseError; -use reth_trie_db::MerklePatriciaTrie; use tokio::sync::oneshot; #[derive(thiserror::Error, Debug)] diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 64a8a204a3299..2f546f249f5c2 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -29,7 +29,7 @@ use reth_primitives::{ }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; -use reth_storage_api::{DBProvider, StorageChangeSetReader}; +use reth_storage_api::{DBProvider, HashedPostStateProvider, StorageChangeSetReader}; use reth_storage_errors::provider::ProviderResult; use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use std::{ @@ -750,6 +750,22 @@ impl StateReader for BlockchainProvider2 { } } +impl HashedPostStateProvider for BlockchainProvider2 { + fn hashed_post_state_from_bundle_state( + &self, + bundle_state: &reth_execution_types::BundleState, + ) -> reth_trie::HashedPostState { + self.database.hashed_post_state_from_bundle_state(bundle_state) + } + + fn hashed_post_state_from_reverts( + &self, + block_number: BlockNumber, + ) -> ProviderResult { + self.database.hashed_post_state_from_reverts(block_number) + } +} + #[cfg(test)] mod tests { use std::{ diff --git a/crates/storage/provider/src/providers/bundle_state_provider.rs b/crates/storage/provider/src/providers/bundle_state_provider.rs index be6549033cde4..8c45a01330934 100644 --- a/crates/storage/provider/src/providers/bundle_state_provider.rs +++ b/crates/storage/provider/src/providers/bundle_state_provider.rs @@ -6,7 +6,7 @@ use alloy_primitives::{ Address, BlockNumber, Bytes, B256, }; use reth_primitives::{Account, Bytecode}; -use reth_storage_api::{StateProofProvider, StorageRootProvider}; +use reth_storage_api::{HashedPostStateProvider, StateProofProvider, StorageRootProvider}; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, TrieInput, @@ -86,7 +86,7 @@ impl StateRootProvider { fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - let mut state = HashedPostState::from_bundle_state(&bundle_state.state); + let mut state = self.state_provider.hashed_post_state_from_bundle_state(bundle_state); state.extend(hashed_state); self.state_provider.state_root(state) } @@ -100,7 +100,7 @@ impl StateRootProvider hashed_state: HashedPostState, ) -> ProviderResult<(B256, TrieUpdates)> { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - let mut state = HashedPostState::from_bundle_state(&bundle_state.state); + let mut state = self.state_provider.hashed_post_state_from_bundle_state(bundle_state); state.extend(hashed_state); self.state_provider.state_root_with_updates(state) } @@ -110,7 +110,7 @@ impl StateRootProvider mut input: TrieInput, ) -> ProviderResult<(B256, TrieUpdates)> { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - input.prepend(HashedPostState::from_bundle_state(&bundle_state.state)); + input.prepend(self.state_provider.hashed_post_state_from_bundle_state(bundle_state)); self.state_provider.state_root_from_nodes_with_updates(input) } } @@ -150,7 +150,7 @@ impl StateProofProvider slots: &[B256], ) -> ProviderResult { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - input.prepend(HashedPostState::from_bundle_state(&bundle_state.state)); + input.prepend(self.state_provider.hashed_post_state_from_bundle_state(bundle_state)); self.state_provider.proof(input, address, slots) } @@ -160,7 +160,7 @@ impl StateProofProvider targets: HashMap>, ) -> ProviderResult { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - input.prepend(HashedPostState::from_bundle_state(&bundle_state.state)); + input.prepend(self.state_provider.hashed_post_state_from_bundle_state(bundle_state)); self.state_provider.multiproof(input, targets) } @@ -170,11 +170,29 @@ impl StateProofProvider target: HashedPostState, ) -> ProviderResult> { let bundle_state = self.block_execution_data_provider.execution_outcome().state(); - input.prepend(HashedPostState::from_bundle_state(&bundle_state.state)); + input.prepend(self.state_provider.hashed_post_state_from_bundle_state(bundle_state)); self.state_provider.witness(input, target) } } +impl HashedPostStateProvider + for BundleStateProvider +{ + fn hashed_post_state_from_bundle_state( + &self, + bundle_state: &reth_execution_types::BundleState, + ) -> HashedPostState { + self.state_provider.hashed_post_state_from_bundle_state(bundle_state) + } + + fn hashed_post_state_from_reverts( + &self, + block_number: BlockNumber, + ) -> ProviderResult { + self.state_provider.hashed_post_state_from_reverts(block_number) + } +} + impl StateProvider for BundleStateProvider { fn storage( &self, diff --git a/crates/storage/provider/src/providers/consistent_view.rs b/crates/storage/provider/src/providers/consistent_view.rs index 4640f46033540..330b3abba3cda 100644 --- a/crates/storage/provider/src/providers/consistent_view.rs +++ b/crates/storage/provider/src/providers/consistent_view.rs @@ -2,11 +2,10 @@ use crate::{BlockNumReader, DatabaseProviderFactory, HeaderProvider}; use alloy_primitives::B256; use reth_errors::ProviderError; use reth_primitives::GotExpected; -use reth_storage_api::{BlockReader, DBProvider}; +use reth_storage_api::{BlockReader, HashedPostStateProvider}; use reth_storage_errors::provider::ProviderResult; use reth_trie::HashedPostState; -use reth_trie_db::DatabaseHashedPostState; pub use reth_storage_errors::provider::ConsistentViewError; @@ -33,7 +32,7 @@ pub struct ConsistentDbView { impl ConsistentDbView where - Factory: DatabaseProviderFactory, + Factory: DatabaseProviderFactory, { /// Creates new consistent database view. pub const fn new(factory: Factory, tip: Option) -> Self { @@ -59,7 +58,7 @@ where { Ok(HashedPostState::default()) } else { - Ok(HashedPostState::from_reverts(provider.tx_ref(), block_number + 1)?) + Ok(provider.hashed_post_state_from_reverts(block_number + 1)?) } } diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 5d4c413cdfef4..4f96e20de2baf 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -23,8 +23,10 @@ use reth_primitives::{ }; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; -use reth_storage_api::TryIntoHistoricalStateProvider; +use reth_storage_api::{HashedPostStateProvider, TryIntoHistoricalStateProvider}; use reth_storage_errors::provider::ProviderResult; +use reth_trie::HashedPostState; +use reth_trie_db::{DatabaseHashedPostState, StateCommitment}; use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use std::{ ops::{RangeBounds, RangeInclusive}, @@ -608,6 +610,28 @@ impl PruneCheckpointReader for ProviderFactory { } } +impl HashedPostStateProvider for ProviderFactory { + fn hashed_post_state_from_bundle_state( + &self, + bundle_state: &reth_execution_types::BundleState, + ) -> reth_trie::HashedPostState { + HashedPostState::from_bundle_state::<::KeyHasher>( + &bundle_state.state, + ) + } + + fn hashed_post_state_from_reverts( + &self, + block_number: BlockNumber, + ) -> ProviderResult { + HashedPostState::from_reverts::<::KeyHasher>( + &self.db.tx().map_err(Into::::into)?, + block_number, + ) + .map_err(Into::into) + } +} + impl Clone for ProviderFactory { fn clone(&self) -> Self { Self { diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index d13526c84c3b6..a6c88a644f5f1 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -48,14 +48,18 @@ use reth_primitives::{ }; use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; -use reth_storage_api::{StateProvider, StorageChangeSetReader, TryIntoHistoricalStateProvider}; +use reth_storage_api::{ + HashedPostStateProvider, StateProvider, StorageChangeSetReader, TryIntoHistoricalStateProvider, +}; use reth_storage_errors::provider::{ProviderResult, RootMismatch}; use reth_trie::{ prefix_set::{PrefixSet, PrefixSetMut, TriePrefixSets}, updates::{StorageTrieUpdates, TrieUpdates}, - HashedPostStateSorted, Nibbles, StateRoot, StoredNibbles, + HashedPostState, HashedPostStateSorted, Nibbles, StateRoot, StoredNibbles, +}; +use reth_trie_db::{ + DatabaseHashedPostState, DatabaseStateRoot, DatabaseStorageTrieCursor, StateCommitment, }; -use reth_trie_db::{DatabaseStateRoot, DatabaseStorageTrieCursor, StateCommitment}; use revm::{ db::states::{PlainStateReverts, PlainStorageChangeset, PlainStorageRevert, StateChangeset}, primitives::{BlockEnv, CfgEnvWithHandlerCfg}, @@ -64,7 +68,6 @@ use std::{ cmp::Ordering, collections::{hash_map, BTreeMap, BTreeSet, HashMap, HashSet}, fmt::Debug, - marker::PhantomData, ops::{Bound, Deref, DerefMut, Range, RangeBounds, RangeInclusive}, sync::{mpsc, Arc}, time::{Duration, Instant}, @@ -138,8 +141,6 @@ pub struct DatabaseProvider { static_file_provider: StaticFileProvider, /// Pruning configuration prune_modes: PruneModes, - /// Marker to associate the `StateCommitment` type with this provider. - _marker: std::marker::PhantomData, } impl DatabaseProvider { @@ -226,7 +227,7 @@ impl DatabaseProvider { static_file_provider: StaticFileProvider, prune_modes: PruneModes, ) -> Self { - Self { tx, chain_spec, static_file_provider, prune_modes, _marker: PhantomData } + Self { tx, chain_spec, static_file_provider, prune_modes } } } @@ -387,7 +388,7 @@ impl DatabaseProvider { static_file_provider: StaticFileProvider, prune_modes: PruneModes, ) -> Self { - Self { tx, chain_spec, static_file_provider, prune_modes, _marker: PhantomData } + Self { tx, chain_spec, static_file_provider, prune_modes } } /// Consume `DbTx` or `DbTxMut`. @@ -3512,6 +3513,28 @@ impl ChainStateBlockWriter for DatabaseProvider HashedPostStateProvider for DatabaseProvider { + fn hashed_post_state_from_bundle_state( + &self, + bundle_state: &reth_execution_types::BundleState, + ) -> reth_trie::HashedPostState { + HashedPostState::from_bundle_state::<::KeyHasher>( + &bundle_state.state, + ) + } + + fn hashed_post_state_from_reverts( + &self, + block_number: BlockNumber, + ) -> ProviderResult { + HashedPostState::from_reverts::<::KeyHasher>( + self.tx_ref(), + block_number, + ) + .map_err(Into::into) + } +} + impl DBProvider for DatabaseProvider { type Tx = TX; diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index 6b25d0082a897..80fd762b3c53c 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -15,7 +15,7 @@ use reth_db_api::{ transaction::DbTx, }; use reth_primitives::{Account, Bytecode, StaticFileSegment}; -use reth_storage_api::{StateProofProvider, StorageRootProvider}; +use reth_storage_api::{HashedPostStateProvider, StateProofProvider, StorageRootProvider}; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ proof::{Proof, StorageProof}, @@ -160,7 +160,7 @@ impl<'b, TX: DbTx, SC: StateCommitment> HistoricalStateProviderRef<'b, TX, SC> { ); } - Ok(HashedPostState::from_reverts(self.tx, self.block_number)?) + Ok(HashedPostState::from_reverts::(self.tx, self.block_number)?) } /// Retrieve revert hashed storage for this history provider and target address. @@ -411,6 +411,24 @@ impl StateProofProvider for HistoricalStateProvid } } +impl HashedPostStateProvider + for HistoricalStateProviderRef<'_, TX, SC> +{ + fn hashed_post_state_from_bundle_state( + &self, + bundle_state: &reth_execution_types::BundleState, + ) -> HashedPostState { + HashedPostState::from_bundle_state::(&bundle_state.state) + } + + fn hashed_post_state_from_reverts( + &self, + block_number: BlockNumber, + ) -> ProviderResult { + HashedPostState::from_reverts::(self.tx, block_number).map_err(Into::into) + } +} + impl StateProvider for HistoricalStateProviderRef<'_, TX, SC> { /// Get storage. fn storage( diff --git a/crates/storage/provider/src/providers/state/latest.rs b/crates/storage/provider/src/providers/state/latest.rs index 1299db28b9113..f20f00954faba 100644 --- a/crates/storage/provider/src/providers/state/latest.rs +++ b/crates/storage/provider/src/providers/state/latest.rs @@ -12,7 +12,7 @@ use reth_db_api::{ transaction::DbTx, }; use reth_primitives::{Account, Bytecode, StaticFileSegment}; -use reth_storage_api::{StateProofProvider, StorageRootProvider}; +use reth_storage_api::{HashedPostStateProvider, StateProofProvider, StorageRootProvider}; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use reth_trie::{ proof::{Proof, StorageProof}, @@ -21,8 +21,8 @@ use reth_trie::{ AccountProof, HashedPostState, HashedStorage, MultiProof, StateRoot, StorageRoot, TrieInput, }; use reth_trie_db::{ - DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot, - DatabaseTrieWitness, StateCommitment, + DatabaseHashedPostState, DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, + DatabaseStorageRoot, DatabaseTrieWitness, StateCommitment, }; use std::marker::PhantomData; @@ -164,6 +164,22 @@ impl StateProofProvider for LatestStateProviderRe } } +impl HashedPostStateProvider for LatestStateProviderRef<'_, TX, SC> { + fn hashed_post_state_from_bundle_state( + &self, + bundle_state: &reth_execution_types::BundleState, + ) -> HashedPostState { + HashedPostState::from_bundle_state::(&bundle_state.state) + } + + fn hashed_post_state_from_reverts( + &self, + block_number: BlockNumber, + ) -> ProviderResult { + HashedPostState::from_reverts::(self.tx, block_number).map_err(Into::into) + } +} + impl StateProvider for LatestStateProviderRef<'_, TX, SC> { /// Get storage. fn storage( diff --git a/crates/storage/provider/src/providers/state/macros.rs b/crates/storage/provider/src/providers/state/macros.rs index b90924354c434..424565340b117 100644 --- a/crates/storage/provider/src/providers/state/macros.rs +++ b/crates/storage/provider/src/providers/state/macros.rs @@ -56,6 +56,10 @@ macro_rules! delegate_provider_impls { fn multiproof(&self, input: reth_trie::TrieInput, targets: alloy_primitives::map::HashMap>) -> reth_storage_errors::provider::ProviderResult; fn witness(&self, input: reth_trie::TrieInput, target: reth_trie::HashedPostState) -> reth_storage_errors::provider::ProviderResult>; } + HashedPostStateProvider $(where [$($generics)*])? { + fn hashed_post_state_from_reverts(&self, block_number: alloy_primitives::BlockNumber) -> reth_storage_errors::provider::ProviderResult; + fn hashed_post_state_from_bundle_state(&self, bundle_state: &revm::db::BundleState) -> reth_trie::HashedPostState; + } ); } } diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index 9295a14cb6de6..cacb71b351de6 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -14,7 +14,6 @@ use reth_primitives::{ Signature, Transaction, TransactionSigned, TxType, Withdrawal, Withdrawals, }; use reth_trie::root::{state_root_unhashed, storage_root_unhashed}; -use reth_trie_db::StateCommitment; use revm::{db::BundleState, primitives::AccountInfo}; use std::{str::FromStr, sync::LazyLock}; diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index e2e08e61a86f3..6a5d45875687a 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -27,12 +27,13 @@ use reth_primitives::{ }; use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_api::{ - DatabaseProviderFactory, StageCheckpointReader, StateProofProvider, StorageRootProvider, + DatabaseProviderFactory, HashedPostStateProvider, StageCheckpointReader, StateProofProvider, + StorageRootProvider, }; use reth_storage_errors::provider::{ConsistentViewError, ProviderError, ProviderResult}; use reth_trie::{ - updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, StorageProof, - TrieInput, + updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, KeccakKeyHasher, + MultiProof, StorageProof, TrieInput, }; use reth_trie_db::MerklePatriciaTrie; use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; @@ -680,6 +681,22 @@ impl StateProofProvider for MockEthProvider { } } +impl HashedPostStateProvider for MockEthProvider { + fn hashed_post_state_from_bundle_state( + &self, + bundle_state: &reth_execution_types::BundleState, + ) -> HashedPostState { + HashedPostState::from_bundle_state::(&bundle_state.state) + } + + fn hashed_post_state_from_reverts( + &self, + _block_number: BlockNumber, + ) -> ProviderResult { + unimplemented!("hashed_post_state_from_reverts not supported for MockEthProvider") + } +} + impl StateProvider for MockEthProvider { fn storage( &self, diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index f6f7e185de639..e84bb0552b390 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -24,7 +24,7 @@ use reth_primitives::{ }; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; -use reth_storage_api::{StateProofProvider, StorageRootProvider}; +use reth_storage_api::{HashedPostStateProvider, StateProofProvider, StorageRootProvider}; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, TrieInput, @@ -394,6 +394,22 @@ impl StateProofProvider for NoopProvider { } } +impl HashedPostStateProvider for NoopProvider { + fn hashed_post_state_from_bundle_state( + &self, + _bundle_state: &reth_execution_types::BundleState, + ) -> HashedPostState { + HashedPostState::default() + } + + fn hashed_post_state_from_reverts( + &self, + _block_number: BlockNumber, + ) -> ProviderResult { + Ok(HashedPostState::default()) + } +} + impl StateProvider for NoopProvider { fn storage( &self, diff --git a/crates/storage/provider/src/writer/mod.rs b/crates/storage/provider/src/writer/mod.rs index 5b16b2da4e5a2..562f777887351 100644 --- a/crates/storage/provider/src/writer/mod.rs +++ b/crates/storage/provider/src/writer/mod.rs @@ -555,7 +555,7 @@ mod tests { use reth_storage_api::DatabaseProviderFactory; use reth_trie::{ test_utils::{state_root, storage_root_prehashed}, - HashedPostState, HashedStorage, StateRoot, StorageRoot, + HashedPostState, HashedStorage, KeccakKeyHasher, StateRoot, StorageRoot, }; use reth_trie_db::{DatabaseStateRoot, DatabaseStorageRoot}; use revm::{ @@ -1447,7 +1447,7 @@ mod tests { 0, Vec::new() ) - .hash_state_slow(), + .hash_state_slow::(), ) .unwrap(), state_root(expected.clone().into_iter().map(|(address, (account, storage))| ( diff --git a/crates/storage/storage-api/src/state.rs b/crates/storage/storage-api/src/state.rs index 6c9e82cfba3b0..8288aed96d82b 100644 --- a/crates/storage/storage-api/src/state.rs +++ b/crates/storage/storage-api/src/state.rs @@ -6,9 +6,10 @@ use alloy_consensus::constants::KECCAK_EMPTY; use alloy_eips::{BlockId, BlockNumHash, BlockNumberOrTag}; use alloy_primitives::{Address, BlockHash, BlockNumber, StorageKey, StorageValue, B256, U256}; use auto_impl::auto_impl; -use reth_execution_types::ExecutionOutcome; +use reth_execution_types::{BundleState, ExecutionOutcome}; use reth_primitives::Bytecode; use reth_storage_errors::provider::{ProviderError, ProviderResult}; +use reth_trie::HashedPostState; /// Type alias of boxed [`StateProvider`]. pub type StateProviderBox = Box; @@ -21,6 +22,7 @@ pub trait StateProvider: + StateRootProvider + StorageRootProvider + StateProofProvider + + HashedPostStateProvider + Send + Sync { @@ -175,6 +177,19 @@ pub trait StateProviderFactory: BlockIdReader + Send + Sync { fn pending_state_by_hash(&self, block_hash: B256) -> ProviderResult>; } +/// Trait that provides the hashed state from various sources. +#[auto_impl::auto_impl(&, Box, Arc)] +pub trait HashedPostStateProvider { + /// Returns the `HashedPostState` of the provided `BundleState`. + fn hashed_post_state_from_bundle_state(&self, bundle_state: &BundleState) -> HashedPostState; + + /// Returns the `HashedPostState` for the given block number. + fn hashed_post_state_from_reverts( + &self, + block_number: BlockNumber, + ) -> ProviderResult; +} + /// Blockchain trait provider that gives access to the blockchain state that is not yet committed /// (pending). pub trait BlockchainTreePendingStateProvider: Send + Sync { diff --git a/crates/trie/db/src/state.rs b/crates/trie/db/src/state.rs index 4d46183dfda48..0a1aa5fbce957 100644 --- a/crates/trie/db/src/state.rs +++ b/crates/trie/db/src/state.rs @@ -1,5 +1,5 @@ use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory, PrefixSetLoader}; -use alloy_primitives::{keccak256, Address, BlockNumber, B256, U256}; +use alloy_primitives::{Address, BlockNumber, B256, U256}; use reth_db::tables; use reth_db_api::{ cursor::DbCursorRO, @@ -11,7 +11,8 @@ use reth_primitives::Account; use reth_storage_errors::db::DatabaseError; use reth_trie::{ hashed_cursor::HashedPostStateCursorFactory, trie_cursor::InMemoryTrieCursorFactory, - updates::TrieUpdates, HashedPostState, HashedStorage, StateRoot, StateRootProgress, TrieInput, + updates::TrieUpdates, HashedPostState, HashedStorage, KeyHasher, StateRoot, StateRootProgress, + TrieInput, }; use std::{ collections::{hash_map, HashMap}, @@ -126,7 +127,7 @@ pub trait DatabaseStateRoot<'a, TX>: Sized { pub trait DatabaseHashedPostState: Sized { /// Initializes [`HashedPostState`] from reverts. Iterates over state reverts from the specified /// block up to the current tip and aggregates them into hashed state in reverse. - fn from_reverts(tx: &TX, from: BlockNumber) -> Result; + fn from_reverts(tx: &TX, from: BlockNumber) -> Result; } impl<'a, TX: DbTx> DatabaseStateRoot<'a, TX> @@ -220,7 +221,7 @@ impl<'a, TX: DbTx> DatabaseStateRoot<'a, TX> } impl DatabaseHashedPostState for HashedPostState { - fn from_reverts(tx: &TX, from: BlockNumber) -> Result { + fn from_reverts(tx: &TX, from: BlockNumber) -> Result { // Iterate over account changesets and record value before first occurring account change. let mut accounts = HashMap::>::default(); let mut account_changesets_cursor = tx.cursor_read::()?; @@ -245,19 +246,19 @@ impl DatabaseHashedPostState for HashedPostState { } let hashed_accounts = - accounts.into_iter().map(|(address, info)| (keccak256(address), info)).collect(); + accounts.into_iter().map(|(address, info)| (KH::hash_key(address), info)).collect(); let hashed_storages = storages .into_iter() .map(|(address, storage)| { ( - keccak256(address), + KH::hash_key(address), HashedStorage::from_iter( // The `wiped` flag indicates only whether previous storage entries // should be looked up in db or not. For reverts it's a noop since all // wiped changes had been written as storage reverts. false, - storage.into_iter().map(|(slot, value)| (keccak256(slot), value)), + storage.into_iter().map(|(slot, value)| (KH::hash_key(slot), value)), ), ) }) @@ -274,6 +275,7 @@ mod tests { use reth_db::test_utils::create_test_rw_db; use reth_db_api::database::Database; use reth_primitives::revm_primitives::AccountInfo; + use reth_trie::KeccakKeyHasher; use revm::db::BundleState; #[test] @@ -294,7 +296,7 @@ mod tests { .build(); assert_eq!(bundle_state.reverts.len(), 1); - let post_state = HashedPostState::from_bundle_state(&bundle_state.state); + let post_state = HashedPostState::from_bundle_state::(&bundle_state.state); assert_eq!(post_state.accounts.len(), 2); assert_eq!(post_state.storages.len(), 2); diff --git a/crates/trie/parallel/src/parallel_root.rs b/crates/trie/parallel/src/parallel_root.rs index e432b91062ca8..3ac976b5ca98e 100644 --- a/crates/trie/parallel/src/parallel_root.rs +++ b/crates/trie/parallel/src/parallel_root.rs @@ -6,7 +6,8 @@ use alloy_rlp::{BufMut, Encodable}; use itertools::Itertools; use reth_execution_errors::StorageRootError; use reth_provider::{ - providers::ConsistentDbView, BlockReader, DBProvider, DatabaseProviderFactory, ProviderError, + providers::ConsistentDbView, BlockReader, DBProvider, DatabaseProviderFactory, + HashedPostStateProvider, ProviderError, }; use reth_trie::{ hashed_cursor::{HashedCursorFactory, HashedPostStateCursorFactory}, @@ -57,7 +58,11 @@ impl ParallelStateRoot { impl ParallelStateRoot where - Factory: DatabaseProviderFactory + Clone + Send + Sync + 'static, + Factory: DatabaseProviderFactory + + Clone + + Send + + Sync + + 'static, { /// Calculate incremental state root in parallel. pub fn incremental_root(self) -> Result { diff --git a/crates/trie/trie/benches/hash_post_state.rs b/crates/trie/trie/benches/hash_post_state.rs index 6e913ef78a3cb..7111a785f4699 100644 --- a/crates/trie/trie/benches/hash_post_state.rs +++ b/crates/trie/trie/benches/hash_post_state.rs @@ -2,7 +2,7 @@ use alloy_primitives::{keccak256, map::HashMap, Address, B256, U256}; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use proptest::{prelude::*, strategy::ValueTree, test_runner::TestRunner}; -use reth_trie::{HashedPostState, HashedStorage}; +use reth_trie::{HashedPostState, HashedStorage, KeccakKeyHasher}; use revm::db::{states::BundleBuilder, BundleAccount}; pub fn hash_post_state(c: &mut Criterion) { @@ -19,7 +19,7 @@ pub fn hash_post_state(c: &mut Criterion) { // parallel group.bench_function(BenchmarkId::new("parallel hashing", size), |b| { - b.iter(|| HashedPostState::from_bundle_state(&state)) + b.iter(|| HashedPostState::from_bundle_state::(&state)) }); } } diff --git a/crates/trie/trie/src/state.rs b/crates/trie/trie/src/state.rs index 2af48dfff7983..c53d2fd71aa81 100644 --- a/crates/trie/trie/src/state.rs +++ b/crates/trie/trie/src/state.rs @@ -6,6 +6,7 @@ use alloy_primitives::{keccak256, Address, B256, U256}; use itertools::Itertools; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use reth_primitives::Account; +use reth_trie_common::KeyHasher; use revm::db::{states::CacheAccount, AccountStatus, BundleAccount}; use std::{ borrow::Cow, @@ -25,13 +26,13 @@ impl HashedPostState { /// Initialize [`HashedPostState`] from bundle state. /// Hashes all changed accounts and storage entries that are currently stored in the bundle /// state. - pub fn from_bundle_state<'a>( + pub fn from_bundle_state<'a, KH: KeyHasher>( state: impl IntoParallelIterator, ) -> Self { let hashed = state .into_par_iter() .map(|(address, account)| { - let hashed_address = keccak256(address); + let hashed_address = KH::hash_key(address); let hashed_account = account.info.clone().map(Into::into); let hashed_storage = HashedStorage::from_plain_storage( account.status, @@ -52,13 +53,13 @@ impl HashedPostState { /// Initialize [`HashedPostState`] from cached state. /// Hashes all changed accounts and storage entries that are currently stored in cache. - pub fn from_cache_state<'a>( + pub fn from_cache_state<'a, KH: KeyHasher>( state: impl IntoParallelIterator, ) -> Self { let hashed = state .into_par_iter() .map(|(address, account)| { - let hashed_address = keccak256(address); + let hashed_address = KH::hash_key(address); let hashed_account = account.account.as_ref().map(|a| a.info.clone().into()); let hashed_storage = HashedStorage::from_plain_storage( account.status, @@ -347,7 +348,8 @@ impl HashedStorageSorted { #[cfg(test)] mod tests { - use alloy_primitives::Bytes; + use alloy_primitives::{keccak256, Bytes}; + use reth_trie_common::KeccakKeyHasher; use revm::{ db::{ states::{plain_account::PlainStorage, StorageSlot}, @@ -463,7 +465,7 @@ mod tests { let state = vec![(&address, &account)]; // Convert the bundle state into a hashed post state. - let hashed_state = HashedPostState::from_bundle_state(state); + let hashed_state = HashedPostState::from_bundle_state::(state); // Validate the hashed post state. assert_eq!(hashed_state.accounts.len(), 1); @@ -502,7 +504,7 @@ mod tests { let state = vec![(&address, &account)]; // Convert the cache state into a hashed post state. - let hashed_state = HashedPostState::from_cache_state(state); + let hashed_state = HashedPostState::from_cache_state::(state); // Validate the hashed post state. assert_eq!(hashed_state.accounts.len(), 1);