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 51851c0b0ad2..f4a86cd3b231 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -21,9 +21,9 @@ use reth_node_api::{NodeTypesWithDB, NodeTypesWithEngine}; use reth_node_ethereum::EthExecutorProvider; use reth_primitives::BlockHashOrNumber; use reth_provider::{ - writer::UnifiedStorageWriter, AccountExtReader, ChainSpecProvider, HashingWriter, - HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderFactory, - StageCheckpointReader, StateWriter, StaticFileProviderFactory, StorageReader, + writer::UnifiedStorageWriter, AccountExtReader, AsLatestStateProviderRef, ChainSpecProvider, + HashingWriter, HeaderProvider, OriginalValuesKnown, ProviderFactory, StageCheckpointReader, + StateWriter, StorageReader, }; use reth_revm::database::StateProviderDatabase; use reth_stages::StageId; @@ -131,10 +131,7 @@ impl> Command { ) .await?; - let db = StateProviderDatabase::new(LatestStateProviderRef::new( - provider.tx_ref(), - provider_factory.static_file_provider(), - )); + let db = StateProviderDatabase::new(provider.latest()); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db); diff --git a/bin/reth/src/commands/debug_cmd/merkle.rs b/bin/reth/src/commands/debug_cmd/merkle.rs index 8e02a52eaf07..62b460ff1c04 100644 --- a/bin/reth/src/commands/debug_cmd/merkle.rs +++ b/bin/reth/src/commands/debug_cmd/merkle.rs @@ -20,9 +20,9 @@ use reth_node_api::{NodeTypesWithDB, NodeTypesWithEngine}; use reth_node_ethereum::EthExecutorProvider; use reth_primitives::BlockHashOrNumber; use reth_provider::{ - writer::UnifiedStorageWriter, BlockNumReader, BlockWriter, ChainSpecProvider, - DatabaseProviderFactory, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, - ProviderError, ProviderFactory, StateWriter, StaticFileProviderFactory, + writer::UnifiedStorageWriter, AsLatestStateProviderRef, BlockNumReader, BlockWriter, + ChainSpecProvider, DatabaseProviderFactory, HeaderProvider, OriginalValuesKnown, ProviderError, + ProviderFactory, StateWriter, }; use reth_revm::database::StateProviderDatabase; use reth_stages::{ @@ -152,12 +152,8 @@ impl> Command { provider_rw.insert_block(sealed_block.clone())?; td += sealed_block.difficulty; - let mut executor = executor_provider.batch_executor(StateProviderDatabase::new( - LatestStateProviderRef::new( - provider_rw.tx_ref(), - provider_rw.static_file_provider().clone(), - ), - )); + let mut executor = + executor_provider.batch_executor(StateProviderDatabase::new(provider_rw.latest())); executor.execute_and_verify_one((&sealed_block.clone().unseal(), td).into())?; let execution_outcome = executor.finalize(); diff --git a/crates/exex/exex/src/backfill/test_utils.rs b/crates/exex/exex/src/backfill/test_utils.rs index 0a8bde242457..243a01f5947a 100644 --- a/crates/exex/exex/src/backfill/test_utils.rs +++ b/crates/exex/exex/src/backfill/test_utils.rs @@ -13,8 +13,8 @@ use reth_primitives::{ Block, BlockBody, BlockWithSenders, Header, Receipt, SealedBlockWithSenders, Transaction, }; use reth_provider::{ - providers::ProviderNodeTypes, BlockWriter as _, ExecutionOutcome, LatestStateProviderRef, - ProviderFactory, StaticFileProviderFactory, + providers::ProviderNodeTypes, AsLatestStateProviderRef, BlockWriter as _, ExecutionOutcome, + ProviderFactory, }; use reth_revm::database::StateProviderDatabase; use reth_testing_utils::generators::sign_tx_with_key_pair; @@ -63,10 +63,7 @@ where // Execute the block to produce a block execution output let mut block_execution_output = EthExecutorProvider::ethereum(chain_spec) - .executor(StateProviderDatabase::new(LatestStateProviderRef::new( - provider.tx_ref(), - provider.static_file_provider(), - ))) + .executor(StateProviderDatabase::new(provider.latest())) .execute(BlockExecutionInput { block, total_difficulty: U256::ZERO })?; block_execution_output.state.reverts.sort(); @@ -191,10 +188,8 @@ where let provider = provider_factory.provider()?; - let executor = - EthExecutorProvider::ethereum(chain_spec).batch_executor(StateProviderDatabase::new( - LatestStateProviderRef::new(provider.tx_ref(), provider.static_file_provider()), - )); + let executor = EthExecutorProvider::ethereum(chain_spec) + .batch_executor(StateProviderDatabase::new(provider.latest())); let mut execution_outcome = executor.execute_and_verify_batch(vec![ (&block1, U256::ZERO).into(), diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index 47cd9d0445a2..d2135a2f1e23 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -15,7 +15,7 @@ use reth_primitives_traits::format_gas_throughput; use reth_provider::{ providers::{StaticFileProvider, StaticFileProviderRWRefMut, StaticFileWriter}, writer::UnifiedStorageWriter, - BlockReader, DBProvider, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, + AsLatestStateProviderRef, BlockReader, DBProvider, HeaderProvider, OriginalValuesKnown, ProviderError, StateChangeWriter, StateWriter, StaticFileProviderFactory, StatsReader, TransactionVariant, }; @@ -45,8 +45,9 @@ use tracing::*; /// - [`tables::BlockBodyIndices`] to get tx number /// - [`tables::Transactions`] to execute /// -/// For state access [`LatestStateProviderRef`] provides us latest state and history state -/// For latest most recent state [`LatestStateProviderRef`] would need (Used for execution Stage): +/// For state access [`reth_provider::LatestStateProviderRef`] provides us latest state and history +/// state For latest most recent state [`reth_provider::LatestStateProviderRef`] would need (Used +/// for execution Stage): /// - [`tables::PlainAccountState`] /// - [`tables::Bytecodes`] /// - [`tables::PlainStorageState`] @@ -174,8 +175,12 @@ impl ExecutionStage { impl Stage for ExecutionStage where E: BlockExecutorProvider, - Provider: - DBProvider + BlockReader + StaticFileProviderFactory + StatsReader + StateChangeWriter, + Provider: DBProvider + + BlockReader + + StaticFileProviderFactory + + StatsReader + + StateChangeWriter + + AsLatestStateProviderRef, for<'a> UnifiedStorageWriter<'a, Provider, StaticFileProviderRWRefMut<'a>>: StateWriter, { /// Return the id of the stage @@ -219,10 +224,7 @@ where None }; - let db = StateProviderDatabase(LatestStateProviderRef::new( - provider.tx_ref(), - provider.static_file_provider(), - )); + let db = StateProviderDatabase(provider.latest()); let mut executor = self.executor_provider.batch_executor(db); executor.set_tip(max_block); executor.set_prune_modes(prune_modes); diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index e6ca1a919324..22e41ac07cb1 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -1,10 +1,10 @@ use super::{DatabaseProviderRO, ProviderFactory, ProviderNodeTypes}; use crate::{ - providers::StaticFileProvider, AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, - BlockReader, BlockReaderIdExt, BlockSource, ChainSpecProvider, ChangeSetReader, EvmEnvProvider, - HeaderProvider, ProviderError, PruneCheckpointReader, ReceiptProvider, ReceiptProviderIdExt, - StageCheckpointReader, StateReader, StaticFileProviderFactory, TransactionVariant, - TransactionsProvider, WithdrawalsProvider, + providers::StaticFileProvider, AccountReader, AsLatestStateProviderRef, BlockHashReader, + BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, BlockSource, ChainSpecProvider, + ChangeSetReader, EvmEnvProvider, HeaderProvider, ProviderError, PruneCheckpointReader, + ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader, StateReader, + StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider, }; use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, HashOrNumber}; use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable, TxHash, TxNumber, B256, U256}; @@ -106,7 +106,7 @@ impl ConsistentProvider { Ok(self.block_state_provider_ref(state)?.boxed()) } else { trace!(target: "providers::blockchain", "Using database state for latest state provider"); - self.storage_provider.latest() + Ok(self.storage_provider.latest()) } } diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 04a30ce90aaa..5d4c413cdfef 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -157,7 +157,10 @@ impl ProviderFactory { #[track_caller] pub fn latest(&self) -> ProviderResult { trace!(target: "providers::db", "Returning latest state provider"); - Ok(Box::new(LatestStateProvider::new(self.db.tx()?, self.static_file_provider()))) + Ok(Box::new(LatestStateProvider::<_, N::StateCommitment>::new( + self.db.tx()?, + self.static_file_provider(), + ))) } /// Storage provider for state at that given block diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 81affa0d804f..8ae0267284f3 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -6,14 +6,15 @@ use crate::{ AccountExtReader, BlockSource, ChangeSetReader, ReceiptProvider, StageCheckpointWriter, }, writer::UnifiedStorageWriter, - AccountReader, BlockExecutionWriter, BlockHashReader, BlockNumReader, BlockReader, BlockWriter, - BundleStateInit, ChainStateBlockReader, ChainStateBlockWriter, DBProvider, EvmEnvProvider, - HashingWriter, HeaderProvider, HeaderSyncGap, HeaderSyncGapProvider, HistoricalStateProvider, - HistoricalStateProviderRef, HistoryWriter, LatestStateProvider, LatestStateProviderRef, - OriginalValuesKnown, ProviderError, PruneCheckpointReader, PruneCheckpointWriter, RevertsInit, - StageCheckpointReader, StateChangeWriter, StateProviderBox, StateReader, StateWriter, - StaticFileProviderFactory, StatsReader, StorageReader, StorageTrieWriter, TransactionVariant, - TransactionsProvider, TransactionsProviderExt, TrieWriter, WithdrawalsProvider, + AccountReader, AsLatestStateProviderRef, BlockExecutionWriter, BlockHashReader, BlockNumReader, + BlockReader, BlockWriter, BundleStateInit, ChainStateBlockReader, ChainStateBlockWriter, + DBProvider, EvmEnvProvider, HashingWriter, HeaderProvider, HeaderSyncGap, + HeaderSyncGapProvider, HistoricalStateProvider, HistoricalStateProviderRef, HistoryWriter, + LatestStateProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderError, + PruneCheckpointReader, PruneCheckpointWriter, RevertsInit, StageCheckpointReader, + StateChangeWriter, StateProviderBox, StateReader, StateWriter, StaticFileProviderFactory, + StatsReader, StorageReader, StorageTrieWriter, TransactionVariant, TransactionsProvider, + TransactionsProviderExt, TrieWriter, WithdrawalsProvider, }; use alloy_eips::BlockHashOrNumber; use alloy_primitives::{keccak256, Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; @@ -146,12 +147,6 @@ impl DatabaseProvider { } impl DatabaseProvider { - /// State provider for latest block - pub fn latest<'a>(&'a self) -> ProviderResult> { - trace!(target: "providers::db", "Returning latest state provider"); - Ok(Box::new(LatestStateProviderRef::new(&self.tx, self.static_file_provider.clone()))) - } - /// Storage provider for state at that given block hash pub fn history_by_block_hash<'a>( &'a self, @@ -162,7 +157,7 @@ impl DatabaseProvider { if block_number == self.best_block_number().unwrap_or_default() && block_number == self.last_block_number().unwrap_or_default() { - return Ok(Box::new(LatestStateProviderRef::new( + return Ok(Box::new(LatestStateProviderRef::<'_, _, N::StateCommitment>::new( &self.tx, self.static_file_provider.clone(), ))) @@ -176,7 +171,7 @@ impl DatabaseProvider { let storage_history_prune_checkpoint = self.get_prune_checkpoint(PruneSegment::StorageHistory)?; - let mut state_provider = HistoricalStateProviderRef::new( + let mut state_provider = HistoricalStateProviderRef::<'_, _, N::StateCommitment>::new( &self.tx, block_number, self.static_file_provider.clone(), @@ -246,7 +241,10 @@ impl TryIntoHistoricalStateProvider for Databa if block_number == self.best_block_number().unwrap_or_default() && block_number == self.last_block_number().unwrap_or_default() { - return Ok(Box::new(LatestStateProvider::new(self.tx, self.static_file_provider))) + return Ok(Box::new(LatestStateProvider::<_, N::StateCommitment>::new( + self.tx, + self.static_file_provider, + ))) } // +1 as the changeset that we want is the one that was applied after this block. @@ -257,8 +255,11 @@ impl TryIntoHistoricalStateProvider for Databa let storage_history_prune_checkpoint = self.get_prune_checkpoint(PruneSegment::StorageHistory)?; - let mut state_provider = - HistoricalStateProvider::new(self.tx, block_number, self.static_file_provider); + let mut state_provider = HistoricalStateProvider::<_, N::StateCommitment>::new( + self.tx, + block_number, + self.static_file_provider, + ); // If we pruned account or storage history, we can't return state on every historical block. // Instead, we should cap it at the latest prune checkpoint for corresponding prune segment. @@ -281,6 +282,17 @@ impl TryIntoHistoricalStateProvider for Databa } } +impl AsLatestStateProviderRef for DatabaseProvider { + /// State provider for latest block + fn latest<'a>(&'a self) -> Box { + trace!(target: "providers::db", "Returning latest state provider"); + Box::new(LatestStateProviderRef::<'_, _, N::StateCommitment>::new( + &self.tx, + self.static_file_provider.clone(), + )) + } +} + impl + 'static> DatabaseProvider { diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index 56a1d057e704..6b25d0082a89 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -25,9 +25,9 @@ use reth_trie::{ }; use reth_trie_db::{ DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, DatabaseStateRoot, - DatabaseStorageProof, DatabaseStorageRoot, DatabaseTrieWitness, + DatabaseStorageProof, DatabaseStorageRoot, DatabaseTrieWitness, StateCommitment, }; -use std::fmt::Debug; +use std::{fmt::Debug, marker::PhantomData}; /// State provider for a given block number which takes a tx reference. /// @@ -41,7 +41,7 @@ use std::fmt::Debug; /// - [`tables::AccountChangeSets`] /// - [`tables::StorageChangeSets`] #[derive(Debug)] -pub struct HistoricalStateProviderRef<'b, TX: DbTx> { +pub struct HistoricalStateProviderRef<'b, TX: DbTx, SC: StateCommitment> { /// Transaction tx: &'b TX, /// Block number is main index for the history state of accounts and storages. @@ -50,6 +50,8 @@ pub struct HistoricalStateProviderRef<'b, TX: DbTx> { lowest_available_blocks: LowestAvailableBlocks, /// Static File provider static_file_provider: StaticFileProvider, + /// Marker to associate the `StateCommitment` type with this provider. + _marker: PhantomData, } #[derive(Debug, Eq, PartialEq)] @@ -60,14 +62,20 @@ pub enum HistoryInfo { MaybeInPlainState, } -impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> { +impl<'b, TX: DbTx, SC: StateCommitment> HistoricalStateProviderRef<'b, TX, SC> { /// Create new `StateProvider` for historical block number pub fn new( tx: &'b TX, block_number: BlockNumber, static_file_provider: StaticFileProvider, ) -> Self { - Self { tx, block_number, lowest_available_blocks: Default::default(), static_file_provider } + Self { + tx, + block_number, + lowest_available_blocks: Default::default(), + static_file_provider, + _marker: PhantomData, + } } /// Create new `StateProvider` for historical block number and lowest block numbers at which @@ -78,7 +86,13 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> { lowest_available_blocks: LowestAvailableBlocks, static_file_provider: StaticFileProvider, ) -> Self { - Self { tx, block_number, lowest_available_blocks, static_file_provider } + Self { + tx, + block_number, + lowest_available_blocks, + static_file_provider, + _marker: PhantomData, + } } /// Lookup an account in the `AccountsHistory` table @@ -248,7 +262,7 @@ impl<'b, TX: DbTx> HistoricalStateProviderRef<'b, TX> { } } -impl AccountReader for HistoricalStateProviderRef<'_, TX> { +impl AccountReader for HistoricalStateProviderRef<'_, TX, SC> { /// Get basic account information. fn basic_account(&self, address: Address) -> ProviderResult> { match self.account_history_lookup(address)? { @@ -270,7 +284,7 @@ impl AccountReader for HistoricalStateProviderRef<'_, TX> { } } -impl BlockHashReader for HistoricalStateProviderRef<'_, TX> { +impl BlockHashReader for HistoricalStateProviderRef<'_, TX, SC> { /// Get block hash by number. fn block_hash(&self, number: u64) -> ProviderResult> { self.static_file_provider.get_with_static_file_or_database( @@ -306,7 +320,7 @@ impl BlockHashReader for HistoricalStateProviderRef<'_, TX> { } } -impl StateRootProvider for HistoricalStateProviderRef<'_, TX> { +impl StateRootProvider for HistoricalStateProviderRef<'_, TX, SC> { fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult { let mut revert_state = self.revert_state()?; revert_state.extend(hashed_state); @@ -340,7 +354,7 @@ impl StateRootProvider for HistoricalStateProviderRef<'_, TX> { } } -impl StorageRootProvider for HistoricalStateProviderRef<'_, TX> { +impl StorageRootProvider for HistoricalStateProviderRef<'_, TX, SC> { fn storage_root( &self, address: Address, @@ -365,7 +379,7 @@ impl StorageRootProvider for HistoricalStateProviderRef<'_, TX> { } } -impl StateProofProvider for HistoricalStateProviderRef<'_, TX> { +impl StateProofProvider for HistoricalStateProviderRef<'_, TX, SC> { /// Get account and storage proofs. fn proof( &self, @@ -397,7 +411,7 @@ impl StateProofProvider for HistoricalStateProviderRef<'_, TX> { } } -impl StateProvider for HistoricalStateProviderRef<'_, TX> { +impl StateProvider for HistoricalStateProviderRef<'_, TX, SC> { /// Get storage. fn storage( &self, @@ -437,7 +451,7 @@ impl StateProvider for HistoricalStateProviderRef<'_, TX> { /// State provider for a given block number. /// For more detailed description, see [`HistoricalStateProviderRef`]. #[derive(Debug)] -pub struct HistoricalStateProvider { +pub struct HistoricalStateProvider { /// Database transaction tx: TX, /// State at the block number is the main indexer of the state. @@ -446,16 +460,24 @@ pub struct HistoricalStateProvider { lowest_available_blocks: LowestAvailableBlocks, /// Static File provider static_file_provider: StaticFileProvider, + /// Marker to associate the `StateCommitment` type with this provider. + _marker: PhantomData, } -impl HistoricalStateProvider { +impl HistoricalStateProvider { /// Create new `StateProvider` for historical block number pub fn new( tx: TX, block_number: BlockNumber, static_file_provider: StaticFileProvider, ) -> Self { - Self { tx, block_number, lowest_available_blocks: Default::default(), static_file_provider } + Self { + tx, + block_number, + lowest_available_blocks: Default::default(), + static_file_provider, + _marker: PhantomData, + } } /// Set the lowest block number at which the account history is available. @@ -478,7 +500,7 @@ impl HistoricalStateProvider { /// Returns a new provider that takes the `TX` as reference #[inline(always)] - fn as_ref(&self) -> HistoricalStateProviderRef<'_, TX> { + fn as_ref(&self) -> HistoricalStateProviderRef<'_, TX, SC> { HistoricalStateProviderRef::new_with_lowest_available_blocks( &self.tx, self.block_number, @@ -489,7 +511,7 @@ impl HistoricalStateProvider { } // Delegates all provider impls to [HistoricalStateProviderRef] -delegate_provider_impls!(HistoricalStateProvider where [TX: DbTx]); +delegate_provider_impls!(HistoricalStateProvider where [TX: DbTx, SC: StateCommitment]); /// Lowest blocks at which different parts of the state are available. /// They may be [Some] if pruning is enabled. @@ -535,6 +557,18 @@ mod tests { }; use reth_primitives::{Account, StorageEntry}; use reth_storage_errors::provider::ProviderError; + use reth_trie_db::{MerklePatriciaTrie, StateCommitment}; + + type TestHistoricalStateProviderRefRO<'a> = HistoricalStateProviderRef< + 'a, + reth_db::mdbx::tx::Tx, + MerklePatriciaTrie, + >; + type TestHistoricalStateProviderRefRW<'a> = HistoricalStateProviderRef< + 'a, + reth_db::mdbx::tx::Tx, + MerklePatriciaTrie, + >; const ADDRESS: Address = address!("0000000000000000000000000000000000000001"); const HIGHER_ADDRESS: Address = address!("0000000000000000000000000000000000000005"); @@ -542,8 +576,8 @@ mod tests { const fn assert_state_provider() {} #[allow(dead_code)] - const fn assert_historical_state_provider() { - assert_state_provider::>(); + const fn assert_historical_state_provider() { + assert_state_provider::>(); } #[test] @@ -614,58 +648,58 @@ mod tests { // run assert_eq!( - HistoricalStateProviderRef::new(&tx, 1, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 1, static_file_provider.clone()) .basic_account(ADDRESS), Ok(None) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 2, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 2, static_file_provider.clone()) .basic_account(ADDRESS), Ok(Some(acc_at3)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 3, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 3, static_file_provider.clone()) .basic_account(ADDRESS), Ok(Some(acc_at3)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 4, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 4, static_file_provider.clone()) .basic_account(ADDRESS), Ok(Some(acc_at7)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 7, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 7, static_file_provider.clone()) .basic_account(ADDRESS), Ok(Some(acc_at7)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 9, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 9, static_file_provider.clone()) .basic_account(ADDRESS), Ok(Some(acc_at10)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 10, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 10, static_file_provider.clone()) .basic_account(ADDRESS), Ok(Some(acc_at10)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 11, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 11, static_file_provider.clone()) .basic_account(ADDRESS), Ok(Some(acc_at15)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 16, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 16, static_file_provider.clone()) .basic_account(ADDRESS), Ok(Some(acc_plain)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 1, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 1, static_file_provider.clone()) .basic_account(HIGHER_ADDRESS), Ok(None) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 1000, static_file_provider) + TestHistoricalStateProviderRefRO::new(&tx, 1000, static_file_provider) .basic_account(HIGHER_ADDRESS), Ok(Some(higher_acc_plain)) ); @@ -726,52 +760,52 @@ mod tests { // run assert_eq!( - HistoricalStateProviderRef::new(&tx, 0, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 0, static_file_provider.clone()) .storage(ADDRESS, STORAGE), Ok(None) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 3, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 3, static_file_provider.clone()) .storage(ADDRESS, STORAGE), Ok(Some(U256::ZERO)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 4, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 4, static_file_provider.clone()) .storage(ADDRESS, STORAGE), Ok(Some(entry_at7.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 7, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 7, static_file_provider.clone()) .storage(ADDRESS, STORAGE), Ok(Some(entry_at7.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 9, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 9, static_file_provider.clone()) .storage(ADDRESS, STORAGE), Ok(Some(entry_at10.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 10, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 10, static_file_provider.clone()) .storage(ADDRESS, STORAGE), Ok(Some(entry_at10.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 11, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 11, static_file_provider.clone()) .storage(ADDRESS, STORAGE), Ok(Some(entry_at15.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 16, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 16, static_file_provider.clone()) .storage(ADDRESS, STORAGE), Ok(Some(entry_plain.value)) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 1, static_file_provider.clone()) + TestHistoricalStateProviderRefRO::new(&tx, 1, static_file_provider.clone()) .storage(HIGHER_ADDRESS, STORAGE), Ok(None) ); assert_eq!( - HistoricalStateProviderRef::new(&tx, 1000, static_file_provider) + TestHistoricalStateProviderRefRO::new(&tx, 1000, static_file_provider) .storage(HIGHER_ADDRESS, STORAGE), Ok(Some(higher_entry_plain.value)) ); @@ -785,7 +819,7 @@ mod tests { // provider block_number < lowest available block number, // i.e. state at provider block is pruned - let provider = HistoricalStateProviderRef::new_with_lowest_available_blocks( + let provider = TestHistoricalStateProviderRefRW::new_with_lowest_available_blocks( &tx, 2, LowestAvailableBlocks { @@ -805,7 +839,7 @@ mod tests { // provider block_number == lowest available block number, // i.e. state at provider block is available - let provider = HistoricalStateProviderRef::new_with_lowest_available_blocks( + let provider = TestHistoricalStateProviderRefRW::new_with_lowest_available_blocks( &tx, 2, LowestAvailableBlocks { @@ -822,7 +856,7 @@ mod tests { // provider block_number == lowest available block number, // i.e. state at provider block is available - let provider = HistoricalStateProviderRef::new_with_lowest_available_blocks( + let provider = TestHistoricalStateProviderRefRW::new_with_lowest_available_blocks( &tx, 2, LowestAvailableBlocks { diff --git a/crates/storage/provider/src/providers/state/latest.rs b/crates/storage/provider/src/providers/state/latest.rs index fdcbfc4937fe..1299db28b911 100644 --- a/crates/storage/provider/src/providers/state/latest.rs +++ b/crates/storage/provider/src/providers/state/latest.rs @@ -22,33 +22,36 @@ use reth_trie::{ }; use reth_trie_db::{ DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot, - DatabaseTrieWitness, + DatabaseTrieWitness, StateCommitment, }; +use std::marker::PhantomData; /// State provider over latest state that takes tx reference. #[derive(Debug)] -pub struct LatestStateProviderRef<'b, TX: DbTx> { +pub struct LatestStateProviderRef<'b, TX: DbTx, SC: StateCommitment> { /// database transaction tx: &'b TX, /// Static File provider static_file_provider: StaticFileProvider, + /// Marker to associate the `StateCommitment` type with this provider. + _marker: PhantomData, } -impl<'b, TX: DbTx> LatestStateProviderRef<'b, TX> { +impl<'b, TX: DbTx, SC: StateCommitment> LatestStateProviderRef<'b, TX, SC> { /// Create new state provider pub const fn new(tx: &'b TX, static_file_provider: StaticFileProvider) -> Self { - Self { tx, static_file_provider } + Self { tx, static_file_provider, _marker: PhantomData } } } -impl AccountReader for LatestStateProviderRef<'_, TX> { +impl AccountReader for LatestStateProviderRef<'_, TX, SC> { /// Get basic account information. fn basic_account(&self, address: Address) -> ProviderResult> { self.tx.get::(address).map_err(Into::into) } } -impl BlockHashReader for LatestStateProviderRef<'_, TX> { +impl BlockHashReader for LatestStateProviderRef<'_, TX, SC> { /// Get block hash by number. fn block_hash(&self, number: u64) -> ProviderResult> { self.static_file_provider.get_with_static_file_or_database( @@ -84,7 +87,7 @@ impl BlockHashReader for LatestStateProviderRef<'_, TX> { } } -impl StateRootProvider for LatestStateProviderRef<'_, TX> { +impl StateRootProvider for LatestStateProviderRef<'_, TX, SC> { fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult { StateRoot::overlay_root(self.tx, hashed_state) .map_err(|err| ProviderError::Database(err.into())) @@ -112,7 +115,7 @@ impl StateRootProvider for LatestStateProviderRef<'_, TX> { } } -impl StorageRootProvider for LatestStateProviderRef<'_, TX> { +impl StorageRootProvider for LatestStateProviderRef<'_, TX, SC> { fn storage_root( &self, address: Address, @@ -133,7 +136,7 @@ impl StorageRootProvider for LatestStateProviderRef<'_, TX> { } } -impl StateProofProvider for LatestStateProviderRef<'_, TX> { +impl StateProofProvider for LatestStateProviderRef<'_, TX, SC> { fn proof( &self, input: TrieInput, @@ -161,7 +164,7 @@ impl StateProofProvider for LatestStateProviderRef<'_, TX> { } } -impl StateProvider for LatestStateProviderRef<'_, TX> { +impl StateProvider for LatestStateProviderRef<'_, TX, SC> { /// Get storage. fn storage( &self, @@ -185,28 +188,30 @@ impl StateProvider for LatestStateProviderRef<'_, TX> { /// State provider for the latest state. #[derive(Debug)] -pub struct LatestStateProvider { +pub struct LatestStateProvider { /// database transaction db: TX, /// Static File provider static_file_provider: StaticFileProvider, + /// Marker to associate the `StateCommitment` type with this provider. + _marker: PhantomData, } -impl LatestStateProvider { +impl LatestStateProvider { /// Create new state provider pub const fn new(db: TX, static_file_provider: StaticFileProvider) -> Self { - Self { db, static_file_provider } + Self { db, static_file_provider, _marker: PhantomData } } /// Returns a new provider that takes the `TX` as reference #[inline(always)] - fn as_ref(&self) -> LatestStateProviderRef<'_, TX> { + fn as_ref(&self) -> LatestStateProviderRef<'_, TX, SC> { LatestStateProviderRef::new(&self.db, self.static_file_provider.clone()) } } // Delegates all provider impls to [LatestStateProviderRef] -delegate_provider_impls!(LatestStateProvider where [TX: DbTx]); +delegate_provider_impls!(LatestStateProvider where [TX: DbTx, SC: StateCommitment]); #[cfg(test)] mod tests { @@ -214,7 +219,7 @@ mod tests { const fn assert_state_provider() {} #[allow(dead_code)] - const fn assert_latest_state_provider() { - assert_state_provider::>(); + const fn assert_latest_state_provider() { + assert_state_provider::>(); } } diff --git a/crates/storage/storage-api/src/state.rs b/crates/storage/storage-api/src/state.rs index d37940f04787..6c9e82cfba3b 100644 --- a/crates/storage/storage-api/src/state.rs +++ b/crates/storage/storage-api/src/state.rs @@ -91,6 +91,13 @@ pub trait TryIntoHistoricalStateProvider { ) -> ProviderResult; } +/// Trait implemented for database providers that can be converted into a latest state provider +/// reference. +pub trait AsLatestStateProviderRef { + /// Returns a [`StateProvider`] for the latest state. + fn latest<'a>(&'a self) -> Box; +} + /// Light wrapper that returns `StateProvider` implementations that correspond to the given /// `BlockNumber`, the latest state, or the pending state. ///