Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce StateCommitment in StateProviders #12602

Merged
merged 5 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions crates/stages/stages/src/stages/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use reth_provider::{
providers::{StaticFileProvider, StaticFileProviderRWRefMut, StaticFileWriter},
writer::UnifiedStorageWriter,
BlockHashReader, BlockReader, DBProvider, HeaderProvider, LatestStateProviderRef,
OriginalValuesKnown, ProviderError, StateChangeWriter, StateWriter, StaticFileProviderFactory,
StatsReader, TransactionVariant,
OriginalValuesKnown, ProviderError, StateChangeWriter, StateCommitmentProvider, StateWriter,
StaticFileProviderFactory, StatsReader, TransactionVariant,
};
use reth_prune_types::PruneModes;
use reth_revm::database::StateProviderDatabase;
Expand Down Expand Up @@ -180,7 +180,8 @@ where
+ StaticFileProviderFactory
+ StatsReader
+ StateChangeWriter
+ BlockHashReader,
+ BlockHashReader
+ StateCommitmentProvider,
for<'a> UnifiedStorageWriter<'a, Provider, StaticFileProviderRWRefMut<'a, Provider::Primitives>>:
StateWriter,
{
Expand Down
2 changes: 1 addition & 1 deletion crates/storage/provider/src/providers/consistent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
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())
}
}

Expand Down
17 changes: 11 additions & 6 deletions crates/storage/provider/src/providers/database/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ use crate::{
HeaderSyncGapProvider, HistoricalStateProvider, HistoricalStateProviderRef, HistoryWriter,
LatestStateProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderError,
PruneCheckpointReader, PruneCheckpointWriter, RevertsInit, StageCheckpointReader,
StateChangeWriter, StateProviderBox, StateReader, StateWriter, StaticFileProviderFactory,
StatsReader, StorageLocation, StorageReader, StorageTrieWriter, TransactionVariant,
TransactionsProvider, TransactionsProviderExt, TrieWriter, WithdrawalsProvider,
StateChangeWriter, StateCommitmentProvider, StateProviderBox, StateReader, StateWriter,
StaticFileProviderFactory, StatsReader, StorageLocation, StorageReader, StorageTrieWriter,
TransactionVariant, TransactionsProvider, TransactionsProviderExt, TrieWriter,
WithdrawalsProvider,
};
use alloy_consensus::Header;
use alloy_eips::{
Expand Down Expand Up @@ -155,10 +156,10 @@ impl<TX, N: NodeTypes> DatabaseProvider<TX, N> {
}

impl<TX: DbTx + 'static, N: NodeTypes> DatabaseProvider<TX, N> {
/// State provider for latest block
pub fn latest<'a>(&'a self) -> ProviderResult<Box<dyn StateProvider + 'a>> {
/// State provider for latest state
pub fn latest<'a>(&'a self) -> Box<dyn StateProvider + 'a> {
trace!(target: "providers::db", "Returning latest state provider");
Ok(Box::new(LatestStateProviderRef::new(self)))
Box::new(LatestStateProviderRef::new(self))
}

/// Storage provider for state at that given block hash
Expand Down Expand Up @@ -374,6 +375,10 @@ impl<TX: DbTx + 'static, N: NodeTypes> TryIntoHistoricalStateProvider for Databa
}
}

impl<TX: DbTx + 'static, N: NodeTypes> StateCommitmentProvider for DatabaseProvider<TX, N> {
type StateCommitment = N::StateCommitment;
}

impl<Tx: DbTx + DbTxMut + 'static, N: NodeTypesForProvider + 'static> DatabaseProvider<Tx, N> {
// TODO: uncomment below, once `reth debug_cmd` has been feature gated with dev.
// #[cfg(any(test, feature = "test-utils"))]
Expand Down
35 changes: 23 additions & 12 deletions crates/storage/provider/src/providers/state/historical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ use reth_db_api::{
transaction::DbTx,
};
use reth_primitives::{Account, Bytecode};
use reth_storage_api::{BlockNumReader, DBProvider, StateProofProvider, StorageRootProvider};
use reth_storage_api::{
BlockNumReader, DBProvider, StateCommitmentProvider, StateProofProvider, StorageRootProvider,
};
use reth_storage_errors::provider::ProviderResult;
use reth_trie::{
proof::{Proof, StorageProof},
Expand Down Expand Up @@ -58,7 +60,9 @@ pub enum HistoryInfo {
MaybeInPlainState,
}

impl<'b, Provider: DBProvider + BlockNumReader> HistoricalStateProviderRef<'b, Provider> {
impl<'b, Provider: DBProvider + BlockNumReader + StateCommitmentProvider>
HistoricalStateProviderRef<'b, Provider>
{
/// Create new `StateProvider` for historical block number
pub fn new(provider: &'b Provider, block_number: BlockNumber) -> Self {
Self { provider, block_number, lowest_available_blocks: Default::default() }
Expand Down Expand Up @@ -239,7 +243,7 @@ impl<Provider: DBProvider + BlockNumReader> HistoricalStateProviderRef<'_, Provi
}
}

impl<Provider: DBProvider + BlockNumReader> AccountReader
impl<Provider: DBProvider + BlockNumReader + StateCommitmentProvider> AccountReader
for HistoricalStateProviderRef<'_, Provider>
{
/// Get basic account information.
Expand Down Expand Up @@ -280,7 +284,7 @@ impl<Provider: DBProvider + BlockNumReader + BlockHashReader> BlockHashReader
}
}

impl<Provider: DBProvider + BlockNumReader> StateRootProvider
impl<Provider: DBProvider + BlockNumReader + StateCommitmentProvider> StateRootProvider
for HistoricalStateProviderRef<'_, Provider>
{
fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult<B256> {
Expand Down Expand Up @@ -316,7 +320,7 @@ impl<Provider: DBProvider + BlockNumReader> StateRootProvider
}
}

impl<Provider: DBProvider + BlockNumReader> StorageRootProvider
impl<Provider: DBProvider + BlockNumReader + StateCommitmentProvider> StorageRootProvider
for HistoricalStateProviderRef<'_, Provider>
{
fn storage_root(
Expand All @@ -343,7 +347,7 @@ impl<Provider: DBProvider + BlockNumReader> StorageRootProvider
}
}

impl<Provider: DBProvider + BlockNumReader> StateProofProvider
impl<Provider: DBProvider + BlockNumReader + StateCommitmentProvider> StateProofProvider
for HistoricalStateProviderRef<'_, Provider>
{
/// Get account and storage proofs.
Expand Down Expand Up @@ -377,8 +381,8 @@ impl<Provider: DBProvider + BlockNumReader> StateProofProvider
}
}

impl<Provider: DBProvider + BlockNumReader + BlockHashReader> StateProvider
for HistoricalStateProviderRef<'_, Provider>
impl<Provider: DBProvider + BlockNumReader + BlockHashReader + StateCommitmentProvider>
StateProvider for HistoricalStateProviderRef<'_, Provider>
{
/// Get storage.
fn storage(
Expand Down Expand Up @@ -428,7 +432,9 @@ pub struct HistoricalStateProvider<Provider> {
lowest_available_blocks: LowestAvailableBlocks,
}

impl<Provider: DBProvider + BlockNumReader> HistoricalStateProvider<Provider> {
impl<Provider: DBProvider + BlockNumReader + StateCommitmentProvider>
HistoricalStateProvider<Provider>
{
/// Create new `StateProvider` for historical block number
pub fn new(provider: Provider, block_number: BlockNumber) -> Self {
Self { provider, block_number, lowest_available_blocks: Default::default() }
Expand Down Expand Up @@ -464,7 +470,7 @@ impl<Provider: DBProvider + BlockNumReader> HistoricalStateProvider<Provider> {
}

// Delegates all provider impls to [HistoricalStateProviderRef]
delegate_provider_impls!(HistoricalStateProvider<Provider> where [Provider: DBProvider + BlockNumReader + BlockHashReader]);
delegate_provider_impls!(HistoricalStateProvider<Provider> where [Provider: DBProvider + BlockNumReader + BlockHashReader + StateCommitmentProvider]);

/// Lowest blocks at which different parts of the state are available.
/// They may be [Some] if pruning is enabled.
Expand Down Expand Up @@ -508,7 +514,10 @@ mod tests {
transaction::{DbTx, DbTxMut},
};
use reth_primitives::{Account, StorageEntry};
use reth_storage_api::{BlockHashReader, BlockNumReader, DBProvider, DatabaseProviderFactory};
use reth_storage_api::{
BlockHashReader, BlockNumReader, DBProvider, DatabaseProviderFactory,
StateCommitmentProvider,
};
use reth_storage_errors::provider::ProviderError;

const ADDRESS: Address = address!("0000000000000000000000000000000000000001");
Expand All @@ -517,7 +526,9 @@ mod tests {

const fn assert_state_provider<T: StateProvider>() {}
#[allow(dead_code)]
const fn assert_historical_state_provider<T: DBProvider + BlockNumReader + BlockHashReader>() {
const fn assert_historical_state_provider<
T: DBProvider + BlockNumReader + BlockHashReader + StateCommitmentProvider,
>() {
assert_state_provider::<HistoricalStateProvider<T>>();
}

Expand Down
24 changes: 17 additions & 7 deletions crates/storage/provider/src/providers/state/latest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use alloy_primitives::{
use reth_db::tables;
use reth_db_api::{cursor::DbDupCursorRO, transaction::DbTx};
use reth_primitives::{Account, Bytecode};
use reth_storage_api::{DBProvider, StateProofProvider, StorageRootProvider};
use reth_storage_api::{
DBProvider, StateCommitmentProvider, StateProofProvider, StorageRootProvider,
};
use reth_storage_errors::provider::{ProviderError, ProviderResult};
use reth_trie::{
proof::{Proof, StorageProof},
Expand Down Expand Up @@ -61,7 +63,9 @@ impl<Provider: BlockHashReader> BlockHashReader for LatestStateProviderRef<'_, P
}
}

impl<Provider: DBProvider> StateRootProvider for LatestStateProviderRef<'_, Provider> {
impl<Provider: DBProvider + StateCommitmentProvider> StateRootProvider
for LatestStateProviderRef<'_, Provider>
{
fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult<B256> {
StateRoot::overlay_root(self.tx(), hashed_state)
.map_err(|err| ProviderError::Database(err.into()))
Expand Down Expand Up @@ -89,7 +93,9 @@ impl<Provider: DBProvider> StateRootProvider for LatestStateProviderRef<'_, Prov
}
}

impl<Provider: DBProvider> StorageRootProvider for LatestStateProviderRef<'_, Provider> {
impl<Provider: DBProvider + StateCommitmentProvider> StorageRootProvider
for LatestStateProviderRef<'_, Provider>
{
fn storage_root(
&self,
address: Address,
Expand All @@ -110,7 +116,9 @@ impl<Provider: DBProvider> StorageRootProvider for LatestStateProviderRef<'_, Pr
}
}

impl<Provider: DBProvider> StateProofProvider for LatestStateProviderRef<'_, Provider> {
impl<Provider: DBProvider + StateCommitmentProvider> StateProofProvider
for LatestStateProviderRef<'_, Provider>
{
fn proof(
&self,
input: TrieInput,
Expand Down Expand Up @@ -138,7 +146,7 @@ impl<Provider: DBProvider> StateProofProvider for LatestStateProviderRef<'_, Pro
}
}

impl<Provider: DBProvider + BlockHashReader> StateProvider
impl<Provider: DBProvider + BlockHashReader + StateCommitmentProvider> StateProvider
for LatestStateProviderRef<'_, Provider>
{
/// Get storage.
Expand Down Expand Up @@ -180,15 +188,17 @@ impl<Provider: DBProvider> LatestStateProvider<Provider> {
}

// Delegates all provider impls to [LatestStateProviderRef]
delegate_provider_impls!(LatestStateProvider<Provider> where [Provider: DBProvider + BlockHashReader]);
delegate_provider_impls!(LatestStateProvider<Provider> where [Provider: DBProvider + BlockHashReader + StateCommitmentProvider]);

#[cfg(test)]
mod tests {
use super::*;

const fn assert_state_provider<T: StateProvider>() {}
#[allow(dead_code)]
const fn assert_latest_state_provider<T: DBProvider + BlockHashReader>() {
const fn assert_latest_state_provider<
T: DBProvider + BlockHashReader + StateCommitmentProvider,
>() {
assert_state_provider::<LatestStateProvider<T>>();
}
}
1 change: 1 addition & 0 deletions crates/storage/storage-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ reth-prune-types.workspace = true
reth-stages-types.workspace = true
reth-storage-errors.workspace = true
reth-trie.workspace = true
reth-trie-db.workspace = true
reth-db.workspace = true

# ethereum
Expand Down
7 changes: 7 additions & 0 deletions crates/storage/storage-api/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use alloy_primitives::{Address, BlockHash, BlockNumber, StorageKey, StorageValue
use auto_impl::auto_impl;
use reth_primitives::Bytecode;
use reth_storage_errors::provider::ProviderResult;
use reth_trie_db::StateCommitment;

/// Type alias of boxed [`StateProvider`].
pub type StateProviderBox = Box<dyn StateProvider>;
Expand Down Expand Up @@ -81,6 +82,12 @@ pub trait StateProvider:
}
}

/// Trait implemented for database providers that can provide the [`StateCommitment`] type.
pub trait StateCommitmentProvider {
/// The [`StateCommitment`] type that can be used to perform state commitment operations.
type StateCommitment: StateCommitment;
}

/// 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.
Expand Down
Loading