From 59a1ccdcf914c8bd94a98dc5f3b7a0d1d4385058 Mon Sep 17 00:00:00 2001 From: frisitano <35734660+frisitano@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:06:41 +0800 Subject: [PATCH] Introduce `KeyHasherProvider` (#47) * feat: introduce StateCommitment in StateProviders * refactor: introduce StateCommimentProvider * feat: introduce HashedPostStateProvider * feat: HashedPostState from reverts * feat: introduce HashedStorageProvider * lint: revm/test-utils feature propogation * fix: add Send + Sync bound on introduced storage state api methods * feat: introduce KeyHasherProvider * fix: add merge files * fix lint * fix lint * fmt * add KeyHasher generic to DatabaseHashedStorage::from_reverts trait * add merge files * lint: minimise diff with upstream --- Cargo.lock | 8 ++-- crates/chain-state/src/in_memory.rs | 12 +++++- crates/chain-state/src/memory_overlay.rs | 15 ++++--- .../engine/invalid-block-hooks/src/witness.rs | 10 ++--- crates/revm/src/test_utils.rs | 10 ++++- crates/rpc/rpc-eth-types/src/cache/db.rs | 10 ++++- .../stages/src/stages/hashing_account.rs | 25 +++++++++--- .../stages/src/stages/hashing_storage.rs | 25 +++++++++--- .../src/providers/bundle_state_provider.rs | 11 +++++- .../src/providers/database/provider.rs | 39 ++++++++++++------- .../src/providers/state/historical.rs | 18 ++++++--- .../provider/src/providers/state/latest.rs | 14 +++++-- .../provider/src/providers/state/macros.rs | 3 ++ .../storage/provider/src/test_utils/mock.rs | 10 ++++- .../storage/provider/src/test_utils/noop.rs | 10 ++++- crates/storage/storage-api/src/state.rs | 8 ++++ 16 files changed, 171 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b69aef5ab400..8180e83e4069 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4606,9 +4606,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.165" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb4d3d38eab6c5239a362fa8bae48c03baf980a6e7079f063942d563ef3533e" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libloading" @@ -4617,7 +4617,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -11354,7 +11354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3637e734239e12ab152cd269302500bd063f37624ee210cd04b4936ed671f3b1" dependencies = [ "cc", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index f698a5b7b2f9..1453f8543a18 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -950,10 +950,12 @@ mod tests { use reth_primitives::{Account, Bytecode, EthPrimitives, Receipt}; use reth_storage_api::{ AccountReader, BlockHashReader, HashedPostStateProvider, HashedStorageProvider, - StateProofProvider, StateProvider, StateRootProvider, StorageRootProvider, + KeyHasherProvider, StateProofProvider, StateProvider, StateRootProvider, + StorageRootProvider, }; use reth_trie::{ - AccountProof, HashedStorage, MultiProof, StorageMultiProof, StorageProof, TrieInput, + AccountProof, HashedStorage, KeccakKeyHasher, KeyHasher, MultiProof, StorageMultiProof, + StorageProof, TrieInput, }; use revm::db::BundleAccount; @@ -1060,6 +1062,12 @@ mod tests { } } + impl KeyHasherProvider for MockStateProvider { + fn hash_key(&self, bytes: &[u8]) -> B256 { + KeccakKeyHasher::hash_key(bytes) + } + } + impl StorageRootProvider for MockStateProvider { fn storage_root( &self, diff --git a/crates/chain-state/src/memory_overlay.rs b/crates/chain-state/src/memory_overlay.rs index a901190143da..b39c4e57b97d 100644 --- a/crates/chain-state/src/memory_overlay.rs +++ b/crates/chain-state/src/memory_overlay.rs @@ -1,7 +1,6 @@ use super::ExecutedBlock; use alloy_consensus::BlockHeader; use alloy_primitives::{ - keccak256, map::{HashMap, HashSet}, Address, BlockNumber, Bytes, StorageKey, StorageValue, B256, }; @@ -9,7 +8,7 @@ use reth_errors::ProviderResult; use reth_primitives::{Account, Bytecode, NodePrimitives}; use reth_storage_api::{ AccountReader, BlockHashReader, HashedPostStateProvider, HashedStorageProvider, - StateProofProvider, StateProvider, StateRootProvider, StorageRootProvider, + KeyHasherProvider, StateProofProvider, StateProvider, StateRootProvider, StorageRootProvider, }; use reth_trie::{ updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, @@ -152,7 +151,7 @@ macro_rules! impl_state_provider { fn storage_root(&self, address: Address, storage: HashedStorage) -> ProviderResult { let state = &self.trie_state().state; let mut hashed_storage = - state.storages.get(&keccak256(address)).cloned().unwrap_or_default(); + state.storages.get(&self.hash_key(address.as_ref())).cloned().unwrap_or_default(); hashed_storage.extend(&storage); self.historical.storage_root(address, hashed_storage) } @@ -166,7 +165,7 @@ macro_rules! impl_state_provider { ) -> ProviderResult { let state = &self.trie_state().state; let mut hashed_storage = - state.storages.get(&keccak256(address)).cloned().unwrap_or_default(); + state.storages.get(&self.hash_key(address.as_ref())).cloned().unwrap_or_default(); hashed_storage.extend(&storage); self.historical.storage_proof(address, slot, hashed_storage) } @@ -180,7 +179,7 @@ macro_rules! impl_state_provider { ) -> ProviderResult { let state = &self.trie_state().state; let mut hashed_storage = - state.storages.get(&keccak256(address)).cloned().unwrap_or_default(); + state.storages.get(&self.hash_key(address.as_ref())).cloned().unwrap_or_default(); hashed_storage.extend(&storage); self.historical.storage_multiproof(address, slots, hashed_storage) } @@ -231,6 +230,12 @@ macro_rules! impl_state_provider { } } + impl $($tokens)* KeyHasherProvider for $type { + fn hash_key(&self, bytes: &[u8]) -> B256 { + self.historical.hash_key(bytes) + } + } + impl $($tokens)* StateProvider for $type { fn storage( &self, diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index df60103c32f2..e86d84fcbd6b 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -1,5 +1,5 @@ use alloy_consensus::Header; -use alloy_primitives::{keccak256, B256, U256}; +use alloy_primitives::{B256, U256}; use alloy_rpc_types_debug::ExecutionWitness; use eyre::OptionExt; use pretty_assertions::Comparison; @@ -69,9 +69,9 @@ where // Setup database. let provider = self.provider.state_by_block_hash(parent_header.hash())?; #[cfg(not(feature = "scroll"))] - let state = reth_revm::database::StateProviderDatabase::new(provider); + let state = reth_revm::database::StateProviderDatabase::new(&provider); #[cfg(feature = "scroll")] - let state = reth_scroll_storage::ScrollStateProviderDatabase::new(provider); + let state = reth_scroll_storage::ScrollStateProviderDatabase::new(&provider); let mut db = StateBuilder::new().with_database(state).with_bundle_update().build(); // Setup environment for the execution. @@ -129,7 +129,7 @@ where // referenced accounts + storage slots. let mut hashed_state = db.database.hashed_post_state(&bundle_state); for (address, account) in db.cache.accounts { - let hashed_address = keccak256(address); + let hashed_address = provider.hash_key(address.as_ref()); #[cfg(feature = "scroll")] let hashed_account = account.account.as_ref().map(|a| { Into::::into(( @@ -152,7 +152,7 @@ where for (slot, value) in account.storage { let slot = B256::from(slot); - let hashed_slot = keccak256(slot); + let hashed_slot = provider.hash_key(slot.as_ref()); storage.storage.insert(hashed_slot, value); state_preimages.insert(hashed_slot, alloy_rlp::encode(slot).into()); diff --git a/crates/revm/src/test_utils.rs b/crates/revm/src/test_utils.rs index 698b08b3db9d..d290421309f2 100644 --- a/crates/revm/src/test_utils.rs +++ b/crates/revm/src/test_utils.rs @@ -7,11 +7,11 @@ use alloy_primitives::{ use reth_primitives::{Account, Bytecode}; use reth_storage_api::{ AccountReader, BlockHashReader, HashedPostStateProvider, HashedStorageProvider, - StateProofProvider, StateProvider, StateRootProvider, StorageRootProvider, + KeyHasherProvider, StateProofProvider, StateProvider, StateRootProvider, StorageRootProvider, }; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ - updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, KeccakKeyHasher, + updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, KeccakKeyHasher, KeyHasher, MultiProof, StorageMultiProof, StorageProof, TrieInput, }; @@ -162,6 +162,12 @@ impl HashedStorageProvider for StateProviderTest { } } +impl KeyHasherProvider for StateProviderTest { + fn hash_key(&self, bytes: &[u8]) -> B256 { + KeccakKeyHasher::hash_key(bytes) + } +} + impl StateProvider for StateProviderTest { fn storage( &self, diff --git a/crates/rpc/rpc-eth-types/src/cache/db.rs b/crates/rpc/rpc-eth-types/src/cache/db.rs index a3d987596e61..c5e322677fac 100644 --- a/crates/rpc/rpc-eth-types/src/cache/db.rs +++ b/crates/rpc/rpc-eth-types/src/cache/db.rs @@ -8,7 +8,9 @@ use alloy_primitives::{ }; use reth_errors::ProviderResult; use reth_revm::{database::StateProviderDatabase, db::CacheDB, DatabaseRef}; -use reth_storage_api::{HashedPostStateProvider, HashedStorageProvider, StateProvider}; +use reth_storage_api::{ + HashedPostStateProvider, HashedStorageProvider, KeyHasherProvider, StateProvider, +}; use reth_trie::HashedStorage; use revm::Database; @@ -154,6 +156,12 @@ impl HashedStorageProvider for StateProviderTraitObjWrapper<'_> { } } +impl KeyHasherProvider for StateProviderTraitObjWrapper<'_> { + fn hash_key(&self, bytes: &[u8]) -> B256 { + self.0.hash_key(bytes) + } +} + impl StateProvider for StateProviderTraitObjWrapper<'_> { fn storage( &self, diff --git a/crates/stages/stages/src/stages/hashing_account.rs b/crates/stages/stages/src/stages/hashing_account.rs index 895943b83a92..320972542a24 100644 --- a/crates/stages/stages/src/stages/hashing_account.rs +++ b/crates/stages/stages/src/stages/hashing_account.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{keccak256, B256}; +use alloy_primitives::B256; use itertools::Itertools; use reth_config::config::{EtlConfig, HashingConfig}; use reth_db::{tables, RawKey, RawTable, RawValue}; @@ -8,12 +8,16 @@ use reth_db_api::{ }; use reth_etl::Collector; use reth_primitives::Account; -use reth_provider::{AccountExtReader, DBProvider, HashingWriter, StatsReader}; +use reth_provider::{ + AccountExtReader, DBProvider, HashingWriter, StateCommitmentProvider, StatsReader, +}; use reth_stages_api::{ AccountHashingCheckpoint, EntitiesCheckpoint, ExecInput, ExecOutput, Stage, StageCheckpoint, StageError, StageId, UnwindInput, UnwindOutput, }; use reth_storage_errors::provider::ProviderResult; +use reth_trie::KeyHasher; +use reth_trie_db::StateCommitment; use std::{ fmt::Debug, ops::{Range, RangeInclusive}, @@ -133,7 +137,11 @@ impl Default for AccountHashingStage { impl Stage for AccountHashingStage where - Provider: DBProvider + HashingWriter + AccountExtReader + StatsReader, + Provider: DBProvider + + HashingWriter + + AccountExtReader + + StatsReader + + StateCommitmentProvider, { /// Return the id of the stage fn id(&self) -> StageId { @@ -174,7 +182,14 @@ where rayon::spawn(move || { for (address, account) in chunk { let address = address.key().unwrap(); - let _ = tx.send((RawKey::new(keccak256(address)), account)); + let _ = tx.send(( + RawKey::new( + <::KeyHasher as KeyHasher>::hash_key( + address, + ), + ), + account, + )); } }); @@ -301,7 +316,7 @@ mod tests { stage_test_suite_ext, ExecuteStageTestRunner, StageTestRunner, TestRunnerError, UnwindStageTestRunner, }; - use alloy_primitives::U256; + use alloy_primitives::{keccak256, U256}; use assert_matches::assert_matches; use reth_primitives::Account; use reth_provider::providers::StaticFileWriter; diff --git a/crates/stages/stages/src/stages/hashing_storage.rs b/crates/stages/stages/src/stages/hashing_storage.rs index dcabbe83ee64..3208113140ee 100644 --- a/crates/stages/stages/src/stages/hashing_storage.rs +++ b/crates/stages/stages/src/stages/hashing_storage.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{bytes::BufMut, keccak256, B256}; +use alloy_primitives::{bytes::BufMut, B256}; use itertools::Itertools; use reth_config::config::{EtlConfig, HashingConfig}; use reth_db::tables; @@ -10,12 +10,16 @@ use reth_db_api::{ }; use reth_etl::Collector; use reth_primitives::StorageEntry; -use reth_provider::{DBProvider, HashingWriter, StatsReader, StorageReader}; +use reth_provider::{ + DBProvider, HashingWriter, StateCommitmentProvider, StatsReader, StorageReader, +}; use reth_stages_api::{ EntitiesCheckpoint, ExecInput, ExecOutput, Stage, StageCheckpoint, StageError, StageId, StorageHashingCheckpoint, UnwindInput, UnwindOutput, }; use reth_storage_errors::provider::ProviderResult; +use reth_trie::KeyHasher; +use reth_trie_db::StateCommitment; use std::{ fmt::Debug, sync::mpsc::{self, Receiver}, @@ -64,7 +68,11 @@ impl Default for StorageHashingStage { impl Stage for StorageHashingStage where - Provider: DBProvider + StorageReader + HashingWriter + StatsReader, + Provider: DBProvider + + StorageReader + + HashingWriter + + StatsReader + + StateCommitmentProvider, { /// Return the id of the stage fn id(&self) -> StageId { @@ -103,8 +111,13 @@ where rayon::spawn(move || { for (address, slot) in chunk { let mut addr_key = Vec::with_capacity(64); - addr_key.put_slice(keccak256(address).as_slice()); - addr_key.put_slice(keccak256(slot.key).as_slice()); + addr_key.put_slice( + <::KeyHasher as KeyHasher>::hash_key( + address, + ) + .as_slice(), + ); + addr_key.put_slice(<::KeyHasher as KeyHasher>::hash_key(slot.key).as_slice()); let _ = tx.send((addr_key, CompactU256::from(slot.value))); } }); @@ -212,7 +225,7 @@ mod tests { stage_test_suite_ext, ExecuteStageTestRunner, StageTestRunner, TestRunnerError, TestStageDB, UnwindStageTestRunner, }; - use alloy_primitives::{Address, U256}; + use alloy_primitives::{keccak256, Address, U256}; use assert_matches::assert_matches; use rand::Rng; use reth_db_api::{ diff --git a/crates/storage/provider/src/providers/bundle_state_provider.rs b/crates/storage/provider/src/providers/bundle_state_provider.rs index 2b8682fc9bc9..3bbef6aaf744 100644 --- a/crates/storage/provider/src/providers/bundle_state_provider.rs +++ b/crates/storage/provider/src/providers/bundle_state_provider.rs @@ -7,7 +7,8 @@ use alloy_primitives::{ }; use reth_primitives::{Account, Bytecode}; use reth_storage_api::{ - HashedPostStateProvider, HashedStorageProvider, StateProofProvider, StorageRootProvider, + HashedPostStateProvider, HashedStorageProvider, KeyHasherProvider, StateProofProvider, + StorageRootProvider, }; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ @@ -200,6 +201,14 @@ impl HashedStorageProvider } } +impl KeyHasherProvider + for BundleStateProvider +{ + fn hash_key(&self, bytes: &[u8]) -> B256 { + self.state_provider.hash_key(bytes) + } +} + impl StateProvider for BundleStateProvider { fn storage( &self, diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index cfbe20cf4b44..8a081eb16bcc 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -13,11 +13,12 @@ use crate::{ BlockReader, BlockWriter, BundleStateInit, ChainStateBlockReader, ChainStateBlockWriter, DBProvider, EvmEnvProvider, HashingWriter, HeaderProvider, HeaderSyncGap, HeaderSyncGapProvider, HistoricalStateProvider, HistoricalStateProviderRef, HistoryWriter, - LatestStateProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderError, - PruneCheckpointReader, PruneCheckpointWriter, RevertsInit, StageCheckpointReader, - StateCommitmentProvider, StateProviderBox, StateWriter, StaticFileProviderFactory, StatsReader, - StorageLocation, StorageReader, StorageTrieWriter, TransactionVariant, TransactionsProvider, - TransactionsProviderExt, TrieWriter, WithdrawalsProvider, + KeyHasherProvider, LatestStateProvider, LatestStateProviderRef, OriginalValuesKnown, + ProviderError, PruneCheckpointReader, PruneCheckpointWriter, RevertsInit, + StageCheckpointReader, StateCommitmentProvider, StateProviderBox, StateWriter, + StaticFileProviderFactory, StatsReader, StorageLocation, StorageReader, StorageTrieWriter, + TransactionVariant, TransactionsProvider, TransactionsProviderExt, TrieWriter, + WithdrawalsProvider, }; use alloy_consensus::Header; use alloy_eips::{ @@ -66,9 +67,9 @@ use reth_storage_errors::provider::{ProviderResult, RootMismatch}; use reth_trie::{ prefix_set::{PrefixSet, PrefixSetMut, TriePrefixSets}, updates::{StorageTrieUpdates, TrieUpdates}, - HashedPostStateSorted, Nibbles, StateRoot, StoredNibbles, + HashedPostStateSorted, KeyHasher, Nibbles, StateRoot, StoredNibbles, }; -use reth_trie_db::{DatabaseStateRoot, DatabaseStorageTrieCursor}; +use reth_trie_db::{DatabaseStateRoot, DatabaseStorageTrieCursor, StateCommitment}; use revm::{ db::states::{PlainStateReverts, PlainStorageChangeset, PlainStorageRevert, StateChangeset}, primitives::{BlockEnv, CfgEnvWithHandlerCfg}, @@ -420,6 +421,12 @@ impl StateCommitmentProvider for DatabaseProvi type StateCommitment = N::StateCommitment; } +impl KeyHasherProvider for DatabaseProvider { + fn hash_key(&self, bytes: &[u8]) -> B256 { + <::KeyHasher as KeyHasher>::hash_key(bytes) + } +} + impl DatabaseProvider { // TODO: uncomment below, once `reth debug_cmd` has been feature gated with dev. // #[cfg(any(test, feature = "test-utils"))] @@ -2383,7 +2390,7 @@ impl HashingWriter for DatabaseProvi // changes are applied in the correct order. let hashed_accounts = changesets .into_iter() - .map(|(_, e)| (keccak256(e.address), e.info)) + .map(|(_, e)| (self.hash_key(e.address.as_ref()), e.info)) .collect::>() .into_iter() .rev() @@ -2419,8 +2426,10 @@ impl HashingWriter for DatabaseProvi changesets: impl IntoIterator)>, ) -> ProviderResult>> { let mut hashed_accounts_cursor = self.tx.cursor_write::()?; - let hashed_accounts = - changesets.into_iter().map(|(ad, ac)| (keccak256(ad), ac)).collect::>(); + let hashed_accounts = changesets + .into_iter() + .map(|(ad, ac)| (self.hash_key(ad.as_ref()), ac)) + .collect::>(); for (hashed_address, account) in &hashed_accounts { if let Some(account) = account { hashed_accounts_cursor.upsert(*hashed_address, *account)?; @@ -2439,7 +2448,11 @@ impl HashingWriter for DatabaseProvi let mut hashed_storages = changesets .into_iter() .map(|(BlockNumberAddress((_, address)), storage_entry)| { - (keccak256(address), keccak256(storage_entry.key), storage_entry.value) + ( + self.hash_key(address.as_ref()), + self.hash_key(storage_entry.key.as_ref()), + storage_entry.value, + ) }) .collect::>(); hashed_storages.sort_by_key(|(ha, hk, _)| (*ha, *hk)); @@ -2486,10 +2499,10 @@ impl HashingWriter for DatabaseProvi let hashed_storages = storages.into_iter().fold(BTreeMap::new(), |mut map, (address, storage)| { let storage = storage.into_iter().fold(BTreeMap::new(), |mut map, entry| { - map.insert(keccak256(entry.key), entry.value); + map.insert(self.hash_key(entry.key.as_ref()), entry.value); map }); - map.insert(keccak256(address), storage); + map.insert(self.hash_key(address.as_ref()), storage); map }); diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index cba511aad03b..b2b63ef4a4f6 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -16,16 +16,16 @@ use reth_db_api::{ }; use reth_primitives::{Account, Bytecode}; use reth_storage_api::{ - BlockNumReader, DBProvider, HashedStorageProvider, StateCommitmentProvider, StateProofProvider, - StorageRootProvider, + BlockNumReader, DBProvider, HashedStorageProvider, KeyHasherProvider, StateCommitmentProvider, + StateProofProvider, StorageRootProvider, }; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ proof::{Proof, StorageProof}, updates::TrieUpdates, witness::TrieWitness, - AccountProof, HashedPostState, HashedStorage, MultiProof, StateRoot, StorageMultiProof, - StorageRoot, TrieInput, + AccountProof, HashedPostState, HashedStorage, KeyHasher, MultiProof, StateRoot, + StorageMultiProof, StorageRoot, TrieInput, }; use reth_trie_db::{ DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, DatabaseStateRoot, @@ -413,7 +413,7 @@ impl HashedPostStateProvider } } -impl HashedStorageProvider +impl HashedStorageProvider for HistoricalStateProviderRef<'_, Provider> { fn hashed_storage(&self, account: &revm::db::BundleAccount) -> HashedStorage { @@ -423,6 +423,14 @@ impl HashedStorageProvider } } +impl KeyHasherProvider + for HistoricalStateProviderRef<'_, Provider> +{ + fn hash_key(&self, bytes: &[u8]) -> B256 { + <::KeyHasher as KeyHasher>::hash_key(bytes) + } +} + impl StateProvider for HistoricalStateProviderRef<'_, Provider> { diff --git a/crates/storage/provider/src/providers/state/latest.rs b/crates/storage/provider/src/providers/state/latest.rs index 6d701defa13e..e9b844b0d2c3 100644 --- a/crates/storage/provider/src/providers/state/latest.rs +++ b/crates/storage/provider/src/providers/state/latest.rs @@ -10,16 +10,16 @@ use reth_db::tables; use reth_db_api::{cursor::DbDupCursorRO, transaction::DbTx}; use reth_primitives::{Account, Bytecode}; use reth_storage_api::{ - DBProvider, HashedStorageProvider, StateCommitmentProvider, StateProofProvider, - StorageRootProvider, + DBProvider, HashedStorageProvider, KeyHasherProvider, StateCommitmentProvider, + StateProofProvider, StorageRootProvider, }; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use reth_trie::{ proof::{Proof, StorageProof}, updates::TrieUpdates, witness::TrieWitness, - AccountProof, HashedPostState, HashedStorage, MultiProof, StateRoot, StorageMultiProof, - StorageRoot, TrieInput, + AccountProof, HashedPostState, HashedStorage, KeyHasher, MultiProof, StateRoot, + StorageMultiProof, StorageRoot, TrieInput, }; use reth_trie_db::{ DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot, @@ -178,6 +178,12 @@ impl HashedStorageProvider } } +impl KeyHasherProvider for LatestStateProviderRef<'_, Provider> { + fn hash_key(&self, bytes: &[u8]) -> B256 { + <::KeyHasher as KeyHasher>::hash_key(bytes) + } +} + impl StateProvider for LatestStateProviderRef<'_, Provider> { diff --git a/crates/storage/provider/src/providers/state/macros.rs b/crates/storage/provider/src/providers/state/macros.rs index 994d760dc9cf..2646e6e05536 100644 --- a/crates/storage/provider/src/providers/state/macros.rs +++ b/crates/storage/provider/src/providers/state/macros.rs @@ -63,6 +63,9 @@ macro_rules! delegate_provider_impls { HashedStorageProvider $(where [$($generics)*])? { fn hashed_storage(&self, bundle_state: &revm::db::BundleAccount) -> reth_trie::HashedStorage; } + KeyHasherProvider $(where [$($generics)*])? { + fn hash_key(&self, bytes: &[u8]) -> alloy_primitives::B256; + } ); } } diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 442e6df073bd..06972099e8bc 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -29,8 +29,8 @@ use reth_primitives::{ use reth_primitives_traits::SignedTransaction; use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_api::{ - DatabaseProviderFactory, HashedPostStateProvider, HashedStorageProvider, StageCheckpointReader, - StateCommitmentProvider, StateProofProvider, StorageRootProvider, + DatabaseProviderFactory, HashedPostStateProvider, HashedStorageProvider, KeyHasherProvider, + StageCheckpointReader, StateCommitmentProvider, StateProofProvider, StorageRootProvider, }; use reth_storage_errors::provider::{ConsistentViewError, ProviderError, ProviderResult}; use reth_trie::{ @@ -708,6 +708,12 @@ impl HashedStorageProvider for MockEthProvider { } } +impl KeyHasherProvider for MockEthProvider { + fn hash_key(&self, _bytes: &[u8]) -> B256 { + B256::default() + } +} + 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 2aeeb36a94fd..3833fdae44a8 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -28,8 +28,8 @@ use reth_primitives::{ use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_api::{ - HashedPostStateProvider, HashedStorageProvider, NodePrimitivesProvider, StateProofProvider, - StorageRootProvider, + HashedPostStateProvider, HashedStorageProvider, KeyHasherProvider, NodePrimitivesProvider, + StateProofProvider, StorageRootProvider, }; use reth_storage_errors::provider::ProviderResult; use reth_trie::{ @@ -426,6 +426,12 @@ impl HashedStorageProvider for NoopProvider { } } +impl KeyHasherProvider for NoopProvider { + fn hash_key(&self, _bytes: &[u8]) -> B256 { + B256::default() + } +} + impl StateProvider for NoopProvider { fn storage( &self, diff --git a/crates/storage/storage-api/src/state.rs b/crates/storage/storage-api/src/state.rs index 59b47221588e..859e73eb61e9 100644 --- a/crates/storage/storage-api/src/state.rs +++ b/crates/storage/storage-api/src/state.rs @@ -25,6 +25,7 @@ pub trait StateProvider: + StateProofProvider + HashedPostStateProvider + HashedStorageProvider + + KeyHasherProvider + Send + Sync { @@ -99,6 +100,13 @@ pub trait HashedPostStateProvider: Send + Sync { fn hashed_post_state(&self, bundle_state: &BundleState) -> HashedPostState; } +/// Trait that provides a method to hash bytes to produce a [`B256`] hash. +#[auto_impl(&, Arc, Box)] +pub trait KeyHasherProvider: Send + Sync { + /// Hashes the provided bytes into a 256-bit hash. + fn hash_key(&self, bytes: &[u8]) -> B256; +} + /// Trait implemented for database providers that can be converted into a historical state provider. pub trait TryIntoHistoricalStateProvider { /// Returns a historical [`StateProvider`] indexed by the given historic block number.