Skip to content

Commit

Permalink
feat: introduce StateCommitment in StateProviders
Browse files Browse the repository at this point in the history
  • Loading branch information
frisitano committed Oct 29, 2024
1 parent 928bcaa commit 27f08e0
Show file tree
Hide file tree
Showing 13 changed files with 165 additions and 112 deletions.
9 changes: 3 additions & 6 deletions bin/reth/src/commands/debug_cmd/in_memory_merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ 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,
HeaderProvider, OriginalValuesKnown, ProviderFactory, StageCheckpointReader, StateWriter,
StorageReader, ToLatestStateProviderRef,
};
use reth_revm::database::StateProviderDatabase;
use reth_stages::StageId;
Expand Down Expand Up @@ -131,10 +131,7 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
)
.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);

Expand Down
12 changes: 4 additions & 8 deletions bin/reth/src/commands/debug_cmd/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ 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,
DatabaseProviderFactory, HeaderProvider, OriginalValuesKnown, ProviderError, ProviderFactory,
StateWriter, ToLatestStateProviderRef,
};
use reth_revm::database::StateProviderDatabase;
use reth_stages::{
Expand Down Expand Up @@ -152,12 +152,8 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
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();

Expand Down
15 changes: 5 additions & 10 deletions crates/exex/exex/src/backfill/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, BlockWriter as _, ExecutionOutcome, ProviderFactory,
ToLatestStateProviderRef,
};
use reth_revm::database::StateProviderDatabase;
use reth_testing_utils::generators::sign_tx_with_key_pair;
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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(),
Expand Down
1 change: 1 addition & 0 deletions crates/stages/stages/benches/criterion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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;

Expand Down
2 changes: 1 addition & 1 deletion crates/stages/stages/benches/setup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
use reth_trie_db::{DatabaseStateRoot, MerklePatriciaTrie};

pub(crate) type StageRange = (ExecInput, UnwindInput);

Expand Down
22 changes: 12 additions & 10 deletions crates/stages/stages/src/stages/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use reth_primitives_traits::format_gas_throughput;
use reth_provider::{
providers::{StaticFileProvider, StaticFileProviderRWRefMut, StaticFileWriter},
writer::UnifiedStorageWriter,
BlockReader, DBProvider, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown,
ProviderError, StateChangeWriter, StateWriter, StaticFileProviderFactory, StatsReader,
BlockReader, DBProvider, HeaderProvider, OriginalValuesKnown, ProviderError, StateChangeWriter,
StateWriter, StaticFileProviderFactory, StatsReader, ToLatestStateProviderRef,
TransactionVariant,
};
use reth_prune_types::PruneModes;
Expand Down Expand Up @@ -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`]
Expand Down Expand Up @@ -174,8 +175,12 @@ impl<E> ExecutionStage<E> {
impl<E, Provider> Stage<Provider> for ExecutionStage<E>
where
E: BlockExecutorProvider,
Provider:
DBProvider + BlockReader + StaticFileProviderFactory + StatsReader + StateChangeWriter,
Provider: DBProvider
+ BlockReader
+ StaticFileProviderFactory
+ StatsReader
+ StateChangeWriter
+ ToLatestStateProviderRef,
for<'a> UnifiedStorageWriter<'a, Provider, StaticFileProviderRWRefMut<'a>>: StateWriter,
{
/// Return the id of the stage
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions crates/stages/stages/src/test_utils/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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)]
Expand Down
6 changes: 3 additions & 3 deletions crates/storage/provider/src/providers/consistent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ 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,
StageCheckpointReader, StateReader, StaticFileProviderFactory, ToLatestStateProviderRef,
TransactionVariant, TransactionsProvider, WithdrawalsProvider,
};
use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, HashOrNumber};
use alloy_primitives::{Address, BlockHash, BlockNumber, Sealable, TxHash, TxNumber, B256, U256};
Expand Down Expand Up @@ -106,7 +106,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
5 changes: 4 additions & 1 deletion crates/storage/provider/src/providers/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,10 @@ impl<N: ProviderNodeTypes> ProviderFactory<N> {
#[track_caller]
pub fn latest(&self) -> ProviderResult<StateProviderBox> {
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
Expand Down
38 changes: 25 additions & 13 deletions crates/storage/provider/src/providers/database/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ use crate::{
HistoricalStateProviderRef, HistoryWriter, LatestStateProvider, LatestStateProviderRef,
OriginalValuesKnown, ProviderError, PruneCheckpointReader, PruneCheckpointWriter, RevertsInit,
StageCheckpointReader, StateChangeWriter, StateProviderBox, StateReader, StateWriter,
StaticFileProviderFactory, StatsReader, StorageReader, StorageTrieWriter, TransactionVariant,
TransactionsProvider, TransactionsProviderExt, TrieWriter, WithdrawalsProvider,
StaticFileProviderFactory, StatsReader, StorageReader, StorageTrieWriter,
ToLatestStateProviderRef, TransactionVariant, TransactionsProvider, TransactionsProviderExt,
TrieWriter, WithdrawalsProvider,
};
use alloy_eips::BlockHashOrNumber;
use alloy_primitives::{keccak256, Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256};
Expand Down Expand Up @@ -146,12 +147,6 @@ impl<TX, N: NodeTypes> DatabaseProvider<TX, N> {
}

impl<TX: DbTx, N: NodeTypes> DatabaseProvider<TX, N> {
/// State provider for latest block
pub fn latest<'a>(&'a self) -> ProviderResult<Box<dyn StateProvider + 'a>> {
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,
Expand All @@ -162,7 +157,7 @@ impl<TX: DbTx, N: NodeTypes> DatabaseProvider<TX, N> {
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(),
)))
Expand All @@ -176,7 +171,7 @@ impl<TX: DbTx, N: NodeTypes> DatabaseProvider<TX, N> {
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(),
Expand Down Expand Up @@ -246,7 +241,10 @@ impl<TX: DbTx + 'static, N: NodeTypes> 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.
Expand All @@ -257,8 +255,11 @@ impl<TX: DbTx + 'static, N: NodeTypes> 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.
Expand All @@ -281,6 +282,17 @@ impl<TX: DbTx + 'static, N: NodeTypes> TryIntoHistoricalStateProvider for Databa
}
}

impl<TX: DbTx, N: NodeTypes> ToLatestStateProviderRef for DatabaseProvider<TX, N> {
/// State provider for latest block
fn latest<'a>(&'a self) -> Box<dyn StateProvider + 'a> {
trace!(target: "providers::db", "Returning latest state provider");
Box::new(LatestStateProviderRef::<'_, _, N::StateCommitment>::new(
&self.tx,
self.static_file_provider.clone(),
))
}
}

impl<Tx: DbTx + DbTxMut + 'static, N: NodeTypes<ChainSpec: EthereumHardforks> + 'static>
DatabaseProvider<Tx, N>
{
Expand Down
Loading

0 comments on commit 27f08e0

Please sign in to comment.