mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
refactor: use DBProvider in LatestStateProvider (#12557)
This commit is contained in:
@ -24,7 +24,7 @@ use reth_node_ethereum::EthExecutorProvider;
|
||||
use reth_provider::{
|
||||
writer::UnifiedStorageWriter, AccountExtReader, ChainSpecProvider, HashingWriter,
|
||||
HeaderProvider, LatestStateProviderRef, OriginalValuesKnown, ProviderFactory,
|
||||
StageCheckpointReader, StateWriter, StaticFileProviderFactory, StorageReader,
|
||||
StageCheckpointReader, StateWriter, StorageReader,
|
||||
};
|
||||
use reth_revm::database::StateProviderDatabase;
|
||||
use reth_stages::StageId;
|
||||
@ -133,10 +133,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(LatestStateProviderRef::new(&provider));
|
||||
|
||||
let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()).executor(db);
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ use reth_node_ethereum::EthExecutorProvider;
|
||||
use reth_provider::{
|
||||
writer::UnifiedStorageWriter, BlockNumReader, BlockWriter, ChainSpecProvider,
|
||||
DatabaseProviderFactory, HeaderProvider, LatestStateProviderRef, OriginalValuesKnown,
|
||||
ProviderError, ProviderFactory, StateWriter, StaticFileProviderFactory,
|
||||
ProviderError, ProviderFactory, StateWriter,
|
||||
};
|
||||
use reth_revm::database::StateProviderDatabase;
|
||||
use reth_stages::{
|
||||
@ -153,10 +153,7 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
|
||||
|
||||
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(),
|
||||
),
|
||||
LatestStateProviderRef::new(&provider_rw),
|
||||
));
|
||||
executor.execute_and_verify_one((&sealed_block.clone().unseal(), td).into())?;
|
||||
let execution_outcome = executor.finalize();
|
||||
|
||||
@ -14,7 +14,7 @@ use reth_primitives::{
|
||||
};
|
||||
use reth_provider::{
|
||||
providers::ProviderNodeTypes, BlockWriter as _, ExecutionOutcome, LatestStateProviderRef,
|
||||
ProviderFactory, StaticFileProviderFactory,
|
||||
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(LatestStateProviderRef::new(&provider)))
|
||||
.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(LatestStateProviderRef::new(&provider)));
|
||||
|
||||
let mut execution_outcome = executor.execute_and_verify_batch(vec![
|
||||
(&block1, U256::ZERO).into(),
|
||||
|
||||
@ -16,9 +16,9 @@ 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,
|
||||
TransactionVariant,
|
||||
BlockHashReader, BlockReader, DBProvider, HeaderProvider, LatestStateProviderRef,
|
||||
OriginalValuesKnown, ProviderError, StateChangeWriter, StateWriter, StaticFileProviderFactory,
|
||||
StatsReader, TransactionVariant,
|
||||
};
|
||||
use reth_prune_types::PruneModes;
|
||||
use reth_revm::database::StateProviderDatabase;
|
||||
@ -175,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
|
||||
+ BlockHashReader,
|
||||
for<'a> UnifiedStorageWriter<'a, Provider, StaticFileProviderRWRefMut<'a>>: StateWriter,
|
||||
{
|
||||
/// Return the id of the stage
|
||||
@ -220,10 +224,7 @@ where
|
||||
None
|
||||
};
|
||||
|
||||
let db = StateProviderDatabase(LatestStateProviderRef::new(
|
||||
provider.tx_ref(),
|
||||
provider.static_file_provider(),
|
||||
));
|
||||
let db = StateProviderDatabase(LatestStateProviderRef::new(provider));
|
||||
let mut executor = self.executor_provider.batch_executor(db);
|
||||
executor.set_tip(max_block);
|
||||
executor.set_prune_modes(prune_modes);
|
||||
|
||||
@ -160,7 +160,7 @@ 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::new(self.database_provider_ro()?)))
|
||||
}
|
||||
|
||||
/// Storage provider for state at that given block
|
||||
|
||||
@ -151,7 +151,7 @@ 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>> {
|
||||
trace!(target: "providers::db", "Returning latest state provider");
|
||||
Ok(Box::new(LatestStateProviderRef::new(&self.tx, self.static_file_provider.clone())))
|
||||
Ok(Box::new(LatestStateProviderRef::new(self)))
|
||||
}
|
||||
|
||||
/// Storage provider for state at that given block hash
|
||||
@ -164,10 +164,7 @@ impl<TX: DbTx + 'static, 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(
|
||||
&self.tx,
|
||||
self.static_file_provider.clone(),
|
||||
)))
|
||||
return Ok(Box::new(LatestStateProviderRef::new(self)))
|
||||
}
|
||||
|
||||
// +1 as the changeset that we want is the one that was applied after this block.
|
||||
@ -244,7 +241,7 @@ 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::new(self)))
|
||||
}
|
||||
|
||||
// +1 as the changeset that we want is the one that was applied after this block.
|
||||
|
||||
@ -1,18 +1,15 @@
|
||||
use crate::{
|
||||
providers::{state::macros::delegate_provider_impls, StaticFileProvider},
|
||||
AccountReader, BlockHashReader, StateProvider, StateRootProvider,
|
||||
providers::state::macros::delegate_provider_impls, AccountReader, BlockHashReader,
|
||||
StateProvider, StateRootProvider,
|
||||
};
|
||||
use alloy_primitives::{
|
||||
map::{HashMap, HashSet},
|
||||
Address, BlockNumber, Bytes, StorageKey, StorageValue, B256,
|
||||
};
|
||||
use reth_db::tables;
|
||||
use reth_db_api::{
|
||||
cursor::{DbCursorRO, DbDupCursorRO},
|
||||
transaction::DbTx,
|
||||
};
|
||||
use reth_primitives::{Account, Bytecode, StaticFileSegment};
|
||||
use reth_storage_api::{StateProofProvider, StorageRootProvider};
|
||||
use reth_db_api::{cursor::DbDupCursorRO, transaction::DbTx};
|
||||
use reth_primitives::{Account, Bytecode};
|
||||
use reth_storage_api::{DBProvider, StateProofProvider, StorageRootProvider};
|
||||
use reth_storage_errors::provider::{ProviderError, ProviderResult};
|
||||
use reth_trie::{
|
||||
proof::{Proof, StorageProof},
|
||||
@ -26,37 +23,33 @@ use reth_trie_db::{
|
||||
};
|
||||
|
||||
/// State provider over latest state that takes tx reference.
|
||||
///
|
||||
/// Wraps a [`DBProvider`] to get access to database.
|
||||
#[derive(Debug)]
|
||||
pub struct LatestStateProviderRef<'b, TX: DbTx> {
|
||||
/// database transaction
|
||||
tx: &'b TX,
|
||||
/// Static File provider
|
||||
static_file_provider: StaticFileProvider,
|
||||
}
|
||||
pub struct LatestStateProviderRef<'b, Provider>(&'b Provider);
|
||||
|
||||
impl<'b, TX: DbTx> LatestStateProviderRef<'b, TX> {
|
||||
impl<'b, Provider: DBProvider> LatestStateProviderRef<'b, Provider> {
|
||||
/// Create new state provider
|
||||
pub const fn new(tx: &'b TX, static_file_provider: StaticFileProvider) -> Self {
|
||||
Self { tx, static_file_provider }
|
||||
pub const fn new(provider: &'b Provider) -> Self {
|
||||
Self(provider)
|
||||
}
|
||||
|
||||
fn tx(&self) -> &Provider::Tx {
|
||||
self.0.tx_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<TX: DbTx> AccountReader for LatestStateProviderRef<'_, TX> {
|
||||
impl<Provider: DBProvider> AccountReader for LatestStateProviderRef<'_, Provider> {
|
||||
/// Get basic account information.
|
||||
fn basic_account(&self, address: Address) -> ProviderResult<Option<Account>> {
|
||||
self.tx.get::<tables::PlainAccountState>(address).map_err(Into::into)
|
||||
self.tx().get::<tables::PlainAccountState>(address).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl<TX: DbTx> BlockHashReader for LatestStateProviderRef<'_, TX> {
|
||||
impl<Provider: BlockHashReader> BlockHashReader for LatestStateProviderRef<'_, Provider> {
|
||||
/// Get block hash by number.
|
||||
fn block_hash(&self, number: u64) -> ProviderResult<Option<B256>> {
|
||||
self.static_file_provider.get_with_static_file_or_database(
|
||||
StaticFileSegment::Headers,
|
||||
number,
|
||||
|static_file| static_file.block_hash(number),
|
||||
|| Ok(self.tx.get::<tables::CanonicalHeaders>(number)?),
|
||||
)
|
||||
self.0.block_hash(number)
|
||||
}
|
||||
|
||||
fn canonical_hashes_range(
|
||||
@ -64,34 +57,18 @@ impl<TX: DbTx> BlockHashReader for LatestStateProviderRef<'_, TX> {
|
||||
start: BlockNumber,
|
||||
end: BlockNumber,
|
||||
) -> ProviderResult<Vec<B256>> {
|
||||
self.static_file_provider.get_range_with_static_file_or_database(
|
||||
StaticFileSegment::Headers,
|
||||
start..end,
|
||||
|static_file, range, _| static_file.canonical_hashes_range(range.start, range.end),
|
||||
|range, _| {
|
||||
self.tx
|
||||
.cursor_read::<tables::CanonicalHeaders>()
|
||||
.map(|mut cursor| {
|
||||
cursor
|
||||
.walk_range(range)?
|
||||
.map(|result| result.map(|(_, hash)| hash).map_err(Into::into))
|
||||
.collect::<ProviderResult<Vec<_>>>()
|
||||
})?
|
||||
.map_err(Into::into)
|
||||
},
|
||||
|_| true,
|
||||
)
|
||||
self.0.canonical_hashes_range(start, end)
|
||||
}
|
||||
}
|
||||
|
||||
impl<TX: DbTx> StateRootProvider for LatestStateProviderRef<'_, TX> {
|
||||
impl<Provider: DBProvider> StateRootProvider for LatestStateProviderRef<'_, Provider> {
|
||||
fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult<B256> {
|
||||
StateRoot::overlay_root(self.tx, hashed_state)
|
||||
StateRoot::overlay_root(self.tx(), hashed_state)
|
||||
.map_err(|err| ProviderError::Database(err.into()))
|
||||
}
|
||||
|
||||
fn state_root_from_nodes(&self, input: TrieInput) -> ProviderResult<B256> {
|
||||
StateRoot::overlay_root_from_nodes(self.tx, input)
|
||||
StateRoot::overlay_root_from_nodes(self.tx(), input)
|
||||
.map_err(|err| ProviderError::Database(err.into()))
|
||||
}
|
||||
|
||||
@ -99,7 +76,7 @@ impl<TX: DbTx> StateRootProvider for LatestStateProviderRef<'_, TX> {
|
||||
&self,
|
||||
hashed_state: HashedPostState,
|
||||
) -> ProviderResult<(B256, TrieUpdates)> {
|
||||
StateRoot::overlay_root_with_updates(self.tx, hashed_state)
|
||||
StateRoot::overlay_root_with_updates(self.tx(), hashed_state)
|
||||
.map_err(|err| ProviderError::Database(err.into()))
|
||||
}
|
||||
|
||||
@ -107,18 +84,18 @@ impl<TX: DbTx> StateRootProvider for LatestStateProviderRef<'_, TX> {
|
||||
&self,
|
||||
input: TrieInput,
|
||||
) -> ProviderResult<(B256, TrieUpdates)> {
|
||||
StateRoot::overlay_root_from_nodes_with_updates(self.tx, input)
|
||||
StateRoot::overlay_root_from_nodes_with_updates(self.tx(), input)
|
||||
.map_err(|err| ProviderError::Database(err.into()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<TX: DbTx> StorageRootProvider for LatestStateProviderRef<'_, TX> {
|
||||
impl<Provider: DBProvider> StorageRootProvider for LatestStateProviderRef<'_, Provider> {
|
||||
fn storage_root(
|
||||
&self,
|
||||
address: Address,
|
||||
hashed_storage: HashedStorage,
|
||||
) -> ProviderResult<B256> {
|
||||
StorageRoot::overlay_root(self.tx, address, hashed_storage)
|
||||
StorageRoot::overlay_root(self.tx(), address, hashed_storage)
|
||||
.map_err(|err| ProviderError::Database(err.into()))
|
||||
}
|
||||
|
||||
@ -128,19 +105,19 @@ impl<TX: DbTx> StorageRootProvider for LatestStateProviderRef<'_, TX> {
|
||||
slot: B256,
|
||||
hashed_storage: HashedStorage,
|
||||
) -> ProviderResult<reth_trie::StorageProof> {
|
||||
StorageProof::overlay_storage_proof(self.tx, address, slot, hashed_storage)
|
||||
StorageProof::overlay_storage_proof(self.tx(), address, slot, hashed_storage)
|
||||
.map_err(Into::<ProviderError>::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl<TX: DbTx> StateProofProvider for LatestStateProviderRef<'_, TX> {
|
||||
impl<Provider: DBProvider> StateProofProvider for LatestStateProviderRef<'_, Provider> {
|
||||
fn proof(
|
||||
&self,
|
||||
input: TrieInput,
|
||||
address: Address,
|
||||
slots: &[B256],
|
||||
) -> ProviderResult<AccountProof> {
|
||||
Proof::overlay_account_proof(self.tx, input, address, slots)
|
||||
Proof::overlay_account_proof(self.tx(), input, address, slots)
|
||||
.map_err(Into::<ProviderError>::into)
|
||||
}
|
||||
|
||||
@ -149,7 +126,7 @@ impl<TX: DbTx> StateProofProvider for LatestStateProviderRef<'_, TX> {
|
||||
input: TrieInput,
|
||||
targets: HashMap<B256, HashSet<B256>>,
|
||||
) -> ProviderResult<MultiProof> {
|
||||
Proof::overlay_multiproof(self.tx, input, targets).map_err(Into::<ProviderError>::into)
|
||||
Proof::overlay_multiproof(self.tx(), input, targets).map_err(Into::<ProviderError>::into)
|
||||
}
|
||||
|
||||
fn witness(
|
||||
@ -157,18 +134,20 @@ impl<TX: DbTx> StateProofProvider for LatestStateProviderRef<'_, TX> {
|
||||
input: TrieInput,
|
||||
target: HashedPostState,
|
||||
) -> ProviderResult<HashMap<B256, Bytes>> {
|
||||
TrieWitness::overlay_witness(self.tx, input, target).map_err(Into::<ProviderError>::into)
|
||||
TrieWitness::overlay_witness(self.tx(), input, target).map_err(Into::<ProviderError>::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl<TX: DbTx> StateProvider for LatestStateProviderRef<'_, TX> {
|
||||
impl<Provider: DBProvider + BlockHashReader> StateProvider
|
||||
for LatestStateProviderRef<'_, Provider>
|
||||
{
|
||||
/// Get storage.
|
||||
fn storage(
|
||||
&self,
|
||||
account: Address,
|
||||
storage_key: StorageKey,
|
||||
) -> ProviderResult<Option<StorageValue>> {
|
||||
let mut cursor = self.tx.cursor_dup_read::<tables::PlainStorageState>()?;
|
||||
let mut cursor = self.tx().cursor_dup_read::<tables::PlainStorageState>()?;
|
||||
if let Some(entry) = cursor.seek_by_key_subkey(account, storage_key)? {
|
||||
if entry.key == storage_key {
|
||||
return Ok(Some(entry.value))
|
||||
@ -179,34 +158,29 @@ impl<TX: DbTx> StateProvider for LatestStateProviderRef<'_, TX> {
|
||||
|
||||
/// Get account code by its hash
|
||||
fn bytecode_by_hash(&self, code_hash: B256) -> ProviderResult<Option<Bytecode>> {
|
||||
self.tx.get::<tables::Bytecodes>(code_hash).map_err(Into::into)
|
||||
self.tx().get::<tables::Bytecodes>(code_hash).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
/// State provider for the latest state.
|
||||
#[derive(Debug)]
|
||||
pub struct LatestStateProvider<TX: DbTx> {
|
||||
/// database transaction
|
||||
db: TX,
|
||||
/// Static File provider
|
||||
static_file_provider: StaticFileProvider,
|
||||
}
|
||||
pub struct LatestStateProvider<Provider>(Provider);
|
||||
|
||||
impl<TX: DbTx> LatestStateProvider<TX> {
|
||||
impl<Provider: DBProvider> LatestStateProvider<Provider> {
|
||||
/// Create new state provider
|
||||
pub const fn new(db: TX, static_file_provider: StaticFileProvider) -> Self {
|
||||
Self { db, static_file_provider }
|
||||
pub const fn new(db: Provider) -> Self {
|
||||
Self(db)
|
||||
}
|
||||
|
||||
/// Returns a new provider that takes the `TX` as reference
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> LatestStateProviderRef<'_, TX> {
|
||||
LatestStateProviderRef::new(&self.db, self.static_file_provider.clone())
|
||||
const fn as_ref(&self) -> LatestStateProviderRef<'_, Provider> {
|
||||
LatestStateProviderRef::new(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
// Delegates all provider impls to [LatestStateProviderRef]
|
||||
delegate_provider_impls!(LatestStateProvider<TX> where [TX: DbTx]);
|
||||
delegate_provider_impls!(LatestStateProvider<Provider> where [Provider: DBProvider + BlockHashReader]);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@ -214,7 +188,7 @@ mod tests {
|
||||
|
||||
const fn assert_state_provider<T: StateProvider>() {}
|
||||
#[allow(dead_code)]
|
||||
const fn assert_latest_state_provider<T: DbTx>() {
|
||||
const fn assert_latest_state_provider<T: DBProvider + BlockHashReader>() {
|
||||
assert_state_provider::<LatestStateProvider<T>>();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user