Compare commits

...

10 Commits

Author SHA1 Message Date
Alexey Shekhirin
f5f666039d wip 2025-12-19 12:44:55 +00:00
Brian Picciano
b81cab5d28 WIP 2025-12-19 12:23:12 +01:00
Brian Picciano
9aefd9d144 doc fix 2025-12-19 11:09:30 +01:00
Brian Picciano
59c04b1c91 Final clippy fixes 2025-12-19 10:56:19 +01:00
Brian Picciano
43b37776f7 Got rid of extra state provider in payload building 2025-12-18 19:18:35 +01:00
Brian Picciano
866739394b Compiling 2025-12-18 19:09:20 +01:00
Brian Picciano
0946449b67 WIP 2025-12-18 18:48:50 +01:00
Brian Picciano
e06e6f3d25 InMemoryOverlayProvider 2025-12-18 17:36:31 +01:00
Brian Picciano
5673865fb7 WIP 2025-12-18 16:52:46 +01:00
Brian Picciano
60f0e968b8 reth-provider compiles 2025-12-18 16:25:05 +01:00
47 changed files with 399 additions and 182 deletions

View File

@@ -5,14 +5,14 @@ use reth_errors::ProviderResult;
use reth_primitives_traits::{Account, Bytecode, NodePrimitives};
use reth_storage_api::{
AccountReader, BlockHashReader, BytecodeReader, HashedPostStateProvider, StateProofProvider,
StateProvider, StateRootProvider, StorageRootProvider,
StateProvider, StateProviderBox, StateRootProvider, StorageRootProvider,
};
use reth_trie::{
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
MultiProofTargets, StorageMultiProof, TrieInput,
};
use revm_database::BundleState;
use std::sync::OnceLock;
use std::{borrow::Cow, sync::OnceLock};
/// A state provider that stores references to in-memory blocks along with their state as well as a
/// reference of the historical state provider for fallback lookups.
@@ -24,15 +24,11 @@ pub struct MemoryOverlayStateProviderRef<
/// Historical state provider for state lookups that are not found in memory blocks.
pub(crate) historical: Box<dyn StateProvider + 'a>,
/// The collection of executed parent blocks. Expected order is newest to oldest.
pub(crate) in_memory: Vec<ExecutedBlock<N>>,
pub(crate) in_memory: Cow<'a, [ExecutedBlock<N>]>,
/// Lazy-loaded in-memory trie data.
pub(crate) trie_input: OnceLock<TrieInput>,
}
/// A state provider that stores references to in-memory blocks along with their state as well as
/// the historical state provider for fallback lookups.
pub type MemoryOverlayStateProvider<N> = MemoryOverlayStateProviderRef<'static, N>;
impl<'a, N: NodePrimitives> MemoryOverlayStateProviderRef<'a, N> {
/// Create new memory overlay state provider.
///
@@ -42,7 +38,7 @@ impl<'a, N: NodePrimitives> MemoryOverlayStateProviderRef<'a, N> {
/// - `historical` - a historical state provider for the latest ancestor block stored in the
/// database.
pub fn new(historical: Box<dyn StateProvider + 'a>, in_memory: Vec<ExecutedBlock<N>>) -> Self {
Self { historical, in_memory, trie_input: OnceLock::new() }
Self { historical, in_memory: Cow::Owned(in_memory), trie_input: OnceLock::new() }
}
/// Turn this state provider into a state provider
@@ -71,7 +67,7 @@ impl<'a, N: NodePrimitives> MemoryOverlayStateProviderRef<'a, N> {
impl<N: NodePrimitives> BlockHashReader for MemoryOverlayStateProviderRef<'_, N> {
fn block_hash(&self, number: BlockNumber) -> ProviderResult<Option<B256>> {
for block in &self.in_memory {
for block in self.in_memory.iter() {
if block.recovered_block().number() == number {
return Ok(Some(block.recovered_block().hash()));
}
@@ -90,7 +86,7 @@ impl<N: NodePrimitives> BlockHashReader for MemoryOverlayStateProviderRef<'_, N>
let mut in_memory_hashes = Vec::with_capacity(range.size_hint().0);
// iterate in ascending order (oldest to newest = low to high)
for block in &self.in_memory {
for block in self.in_memory.iter() {
let block_num = block.recovered_block().number();
if range.contains(&block_num) {
in_memory_hashes.push(block.recovered_block().hash());
@@ -112,7 +108,7 @@ impl<N: NodePrimitives> BlockHashReader for MemoryOverlayStateProviderRef<'_, N>
impl<N: NodePrimitives> AccountReader for MemoryOverlayStateProviderRef<'_, N> {
fn basic_account(&self, address: &Address) -> ProviderResult<Option<Account>> {
for block in &self.in_memory {
for block in self.in_memory.iter() {
if let Some(account) = block.execution_output.account(address) {
return Ok(account);
}
@@ -216,7 +212,7 @@ impl<N: NodePrimitives> StateProvider for MemoryOverlayStateProviderRef<'_, N> {
address: Address,
storage_key: StorageKey,
) -> ProviderResult<Option<StorageValue>> {
for block in &self.in_memory {
for block in self.in_memory.iter() {
if let Some(value) = block.execution_output.storage(&address, storage_key.into()) {
return Ok(Some(value));
}
@@ -228,7 +224,7 @@ impl<N: NodePrimitives> StateProvider for MemoryOverlayStateProviderRef<'_, N> {
impl<N: NodePrimitives> BytecodeReader for MemoryOverlayStateProviderRef<'_, N> {
fn bytecode_by_hash(&self, code_hash: &B256) -> ProviderResult<Option<Bytecode>> {
for block in &self.in_memory {
for block in self.in_memory.iter() {
if let Some(contract) = block.execution_output.bytecode(code_hash) {
return Ok(Some(contract));
}
@@ -237,3 +233,46 @@ impl<N: NodePrimitives> BytecodeReader for MemoryOverlayStateProviderRef<'_, N>
self.historical.bytecode_by_hash(code_hash)
}
}
/// An owned state provider that stores references to in-memory blocks along with their state as
/// well as a reference of the historical state provider for fallback lookups.
#[expect(missing_debug_implementations)]
pub struct MemoryOverlayStateProvider<N: NodePrimitives = reth_ethereum_primitives::EthPrimitives> {
/// Historical state provider for state lookups that are not found in memory blocks.
pub(crate) historical: StateProviderBox,
/// The collection of executed parent blocks. Expected order is newest to oldest.
pub(crate) in_memory: Vec<ExecutedBlock<N>>,
/// Lazy-loaded in-memory trie data.
pub(crate) trie_input: OnceLock<TrieInput>,
}
impl<N: NodePrimitives> MemoryOverlayStateProvider<N> {
/// Create new memory overlay state provider.
///
/// ## Arguments
///
/// - `in_memory` - the collection of executed ancestor blocks in reverse.
/// - `historical` - a historical state provider for the latest ancestor block stored in the
/// database.
pub fn new(historical: StateProviderBox, in_memory: Vec<ExecutedBlock<N>>) -> Self {
Self { historical, in_memory, trie_input: OnceLock::new() }
}
/// Returns a new provider that takes the `TX` as reference
#[inline(always)]
fn as_ref(&self) -> MemoryOverlayStateProviderRef<'_, N> {
MemoryOverlayStateProviderRef {
historical: Box::new(self.historical.as_ref()),
in_memory: Cow::Borrowed(&self.in_memory),
trie_input: self.trie_input.clone(),
}
}
/// Wraps the [`Self`] in a `Box`.
pub fn boxed(self) -> StateProviderBox {
Box::new(self)
}
}
// Delegates all provider impls to [`MemoryOverlayStateProviderRef`]
reth_storage_api::macros::delegate_provider_impls!(MemoryOverlayStateProvider<N> where [N: NodePrimitives]);

View File

@@ -970,7 +970,7 @@ impl<H: BlockHeader> EthereumHardforks for ChainSpec<H> {
/// A trait for reading the current chainspec.
#[auto_impl::auto_impl(&, Arc)]
pub trait ChainSpecProvider: Debug + Send + Sync {
pub trait ChainSpecProvider: Debug + Send {
/// The chain spec type.
type ChainSpec: EthChainSpec + 'static;

View File

@@ -5,7 +5,7 @@ use pretty_assertions::Comparison;
use reth_engine_primitives::InvalidBlockHook;
use reth_evm::{execute::Executor, ConfigureEvm};
use reth_primitives_traits::{NodePrimitives, RecoveredBlock, SealedHeader};
use reth_provider::{BlockExecutionOutput, StateProvider, StateProviderFactory};
use reth_provider::{BlockExecutionOutput, StateProvider, StateProviderBox, StateProviderFactory};
use reth_revm::{
database::StateProviderDatabase,
db::{BundleState, State},
@@ -114,7 +114,7 @@ fn sort_bundle_state_for_comparison(bundle_state: &BundleState) -> BundleStateSo
/// Extracts execution data including codes, preimages, and hashed state from database
fn collect_execution_data(
mut db: State<StateProviderDatabase<Box<dyn StateProvider>>>,
mut db: State<StateProviderDatabase<StateProviderBox>>,
) -> eyre::Result<CollectionResult> {
let bundle_state = db.take_bundle();
let mut codes = BTreeMap::new();
@@ -530,9 +530,7 @@ mod tests {
// Create a State with StateProviderTest
let state_provider = StateProviderTest::default();
let mut state = State::builder()
.with_database(StateProviderDatabase::new(
Box::new(state_provider) as Box<dyn StateProvider>
))
.with_database(StateProviderDatabase::new(Box::new(state_provider) as StateProviderBox))
.with_bundle_update()
.build();

View File

@@ -47,7 +47,7 @@ impl BackfillSyncState {
}
/// Backfill sync mode functionality.
pub trait BackfillSync: Send + Sync {
pub trait BackfillSync: Send {
/// Performs a backfill action.
fn on_action(&mut self, action: BackfillAction);

View File

@@ -435,8 +435,7 @@ where
}
// Execute the block and handle any execution errors
let (output, senders) = match self.execute_block(&state_provider, env, &input, &mut handle)
{
let (output, senders) = match self.execute_block(state_provider, env, &input, &mut handle) {
Ok(output) => output,
Err(err) => return self.handle_execution_error(input, err, &parent_block),
};
@@ -603,7 +602,7 @@ where
handle: &mut PayloadHandle<impl ExecutableTxFor<Evm>, Err, N::Receipt>,
) -> Result<(BlockExecutionOutput<N::Receipt>, Vec<Address>), InsertBlockErrorKind>
where
S: StateProvider,
S: StateProvider + Send,
Err: core::error::Error + Send + Sync + 'static,
V: PayloadValidator<T, Block = N::Block>,
T: PayloadTypes<BuiltPayload: BuiltPayload<Primitives = N>>,

View File

@@ -116,7 +116,7 @@ where
/// these stages that this work has already been done. Otherwise, there might be some conflict with
/// database integrity.
pub fn save_stage_checkpoints<P>(
provider: &P,
provider: P,
from: BlockNumber,
to: BlockNumber,
processed: u64,

View File

@@ -153,9 +153,9 @@ where
let PayloadConfig { parent_header, attributes } = config;
let state_provider = client.state_by_block_hash(parent_header.hash())?;
let state = StateProviderDatabase::new(&state_provider);
let state = StateProviderDatabase::new(state_provider.as_ref());
let mut db =
State::builder().with_database(cached_reads.as_db_mut(state)).with_bundle_update().build();
State::builder().with_database_ref(cached_reads.as_db(state)).with_bundle_update().build();
let mut builder = evm_config
.builder_for_next_block(
@@ -358,7 +358,8 @@ where
return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads })
}
let BlockBuilderOutcome { execution_result, block, .. } = builder.finish(&state_provider)?;
let BlockBuilderOutcome { execution_result, block, .. } =
builder.finish(state_provider.as_ref())?;
let requests = chain_spec
.is_prague_active_at_timestamp(attributes.timestamp)

View File

@@ -13,7 +13,7 @@ use reth_evm_ethereum::EthEvmConfig;
use reth_node_api::NodePrimitives;
use reth_primitives_traits::{Block as _, RecoveredBlock};
use reth_provider::{
providers::ProviderNodeTypes, BlockWriter as _, ExecutionOutcome, LatestStateProviderRef,
providers::ProviderNodeTypes, BlockWriter as _, ExecutionOutcome, LatestStateProvider,
ProviderFactory,
};
use reth_revm::database::StateProviderDatabase;
@@ -69,7 +69,7 @@ where
// Execute the block to produce a block execution output
let mut block_execution_output = EthEvmConfig::ethereum(chain_spec)
.batch_executor(StateProviderDatabase::new(LatestStateProviderRef::new(&provider)))
.batch_executor(StateProviderDatabase::new(LatestStateProvider::new(provider)))
.execute(block)?;
block_execution_output.state.reverts.sort();
@@ -203,8 +203,8 @@ where
let provider = provider_factory.provider()?;
let evm_config = EthEvmConfig::new(chain_spec);
let executor = evm_config
.batch_executor(StateProviderDatabase::new(LatestStateProviderRef::new(&provider)));
let executor =
evm_config.batch_executor(StateProviderDatabase::new(LatestStateProvider::new(provider)));
let mut execution_outcome = executor.execute_batch(vec![&block1, &block2])?;
execution_outcome.state_mut().reverts.sort();

View File

@@ -13,9 +13,7 @@ pub type BodyDownloaderResult<B> = DownloadResult<Vec<BlockResponse<B>>>;
/// A downloader represents a distinct strategy for submitting requests to download block bodies,
/// while a [`BodiesClient`][crate::bodies::client::BodiesClient] represents a client capable of
/// fulfilling these requests.
pub trait BodyDownloader:
Send + Sync + Stream<Item = BodyDownloaderResult<Self::Block>> + Unpin
{
pub trait BodyDownloader: Send + Stream<Item = BodyDownloaderResult<Self::Block>> + Unpin {
/// The Block type this downloader supports
type Block: Block + 'static;

View File

@@ -88,7 +88,8 @@ impl<Client, Tx> OpTransactionValidator<Client, Tx> {
impl<Client, Tx> OpTransactionValidator<Client, Tx>
where
Client: ChainSpecProvider<ChainSpec: OpHardforks> + StateProviderFactory + BlockReaderIdExt,
Client:
ChainSpecProvider<ChainSpec: OpHardforks> + StateProviderFactory + BlockReaderIdExt + Sync,
Tx: EthPoolTransaction + OpPooledTx,
{
/// Create a new [`OpTransactionValidator`].
@@ -177,7 +178,7 @@ where
&self,
origin: TransactionOrigin,
transaction: Tx,
state: &mut Option<Box<dyn AccountInfoReader>>,
state: &mut Option<Box<dyn AccountInfoReader + Send>>,
) -> TransactionValidationOutcome<Tx> {
if transaction.is_eip4844() {
return TransactionValidationOutcome::Invalid(
@@ -289,7 +290,8 @@ where
impl<Client, Tx> TransactionValidator for OpTransactionValidator<Client, Tx>
where
Client: ChainSpecProvider<ChainSpec: OpHardforks> + StateProviderFactory + BlockReaderIdExt,
Client:
ChainSpecProvider<ChainSpec: OpHardforks> + StateProviderFactory + BlockReaderIdExt + Sync,
Tx: EthPoolTransaction + OpPooledTx,
{
type Transaction = Tx;

View File

@@ -9,7 +9,7 @@ use revm::{bytecode::Bytecode, state::AccountInfo, Database, DatabaseRef};
/// A helper trait responsible for providing state necessary for EVM execution.
///
/// This serves as the data layer for [`Database`].
pub trait EvmStateProvider: Send + Sync {
pub trait EvmStateProvider {
/// Get basic account information.
///
/// Returns [`None`] if the account doesn't exist.

View File

@@ -33,7 +33,7 @@ use reth_rpc_eth_types::{
simulate::{self, EthSimulateError},
EthApiError, StateCacheDb,
};
use reth_storage_api::{BlockIdReader, ProviderTx, StateProvider};
use reth_storage_api::{BlockIdReader, ProviderTx, StateProviderBox};
use revm::{
context::Block,
context_interface::{result::ResultAndState, Transaction},
@@ -491,11 +491,11 @@ pub trait Call:
) -> impl Future<Output = Result<R, Self::Error>> + Send
where
R: Send + 'static,
F: FnOnce(Self, &dyn StateProvider) -> Result<R, Self::Error> + Send + 'static,
F: FnOnce(Self, StateProviderBox) -> Result<R, Self::Error> + Send + 'static,
{
self.spawn_blocking_io_fut(move |this| async move {
let state = this.state_at_block_id(at).await?;
f(this, &state)
f(this, state)
})
}

View File

@@ -235,7 +235,7 @@ pub trait LoadPendingBlock:
.provider()
.history_by_block_hash(parent.hash())
.map_err(Self::Error::from_eth_err)?;
let state = StateProviderDatabase::new(&state_provider);
let state = StateProviderDatabase::new(state_provider);
let mut db = State::builder().with_database(state).with_bundle_update().build();
let mut builder = self

View File

@@ -238,7 +238,7 @@ pub struct UnwindOutput {
///
/// Stages receive [`DBProvider`](reth_provider::DBProvider).
#[auto_impl::auto_impl(Box)]
pub trait Stage<Provider>: Send + Sync {
pub trait Stage<Provider>: Send {
/// Get the ID of the stage.
///
/// Stage IDs must be unique.

View File

@@ -195,7 +195,7 @@ where
}
era::save_stage_checkpoints(
&provider,
provider,
input.checkpoint().block_number,
height,
height,

View File

@@ -1,4 +1,5 @@
use std::{
cell::RefCell,
fmt,
ops::{Bound, RangeBounds},
};
@@ -369,3 +370,42 @@ impl<T: DupSort, CURSOR: DbDupCursorRO<T>> Iterator for DupWalker<'_, T, CURSOR>
self.cursor.next_dup().transpose()
}
}
/// A guard that returns a cursor to its slot on drop.
pub struct CursorGuard<'a, C> {
cursor: Option<C>,
slot: &'a RefCell<Option<C>>,
}
impl<C: fmt::Debug> fmt::Debug for CursorGuard<'_, C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("CursorGuard").field("cursor", &self.cursor).finish()
}
}
impl<C> CursorGuard<'_, C> {
/// Creates a new `CursorGuard` from a cursor and a slot to return it to.
pub const fn new(cursor: C, slot: &RefCell<Option<C>>) -> CursorGuard<'_, C> {
CursorGuard { cursor: Some(cursor), slot }
}
}
impl<C> Drop for CursorGuard<'_, C> {
fn drop(&mut self) {
*self.slot.borrow_mut() = self.cursor.take();
}
}
impl<C> std::ops::Deref for CursorGuard<'_, C> {
type Target = C;
fn deref(&self) -> &Self::Target {
self.cursor.as_ref().expect("cursor is always Some until drop")
}
}
impl<C> std::ops::DerefMut for CursorGuard<'_, C> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.cursor.as_mut().expect("cursor is always Some until drop")
}
}

View File

@@ -12,7 +12,7 @@ pub type CursorTy<TX, T> = <TX as DbTx>::Cursor<T>;
pub type CursorMutTy<TX, T> = <TX as DbTxMut>::CursorMut<T>;
/// Read only transaction
pub trait DbTx: Debug + Send + Sync {
pub trait DbTx: Debug + Send {
/// Cursor type for this read-only transaction
type Cursor<T: Table>: DbCursorRO<T> + Send + Sync;
/// `DupCursor` type for this read-only transaction
@@ -43,7 +43,7 @@ pub trait DbTx: Debug + Send + Sync {
}
/// Read write transaction that allows writing to database
pub trait DbTxMut: Send + Sync {
pub trait DbTxMut: Send {
/// Read-Write Cursor type
type CursorMut<T: Table>: DbCursorRW<T> + DbCursorRO<T> + Send + Sync;
/// Read-Write `DupCursor` type

View File

@@ -26,7 +26,7 @@ use reth_stages_types::{StageCheckpoint, StageId};
use reth_static_file_types::StaticFileSegment;
use reth_storage_api::{
BlockBodyIndicesProvider, DatabaseProviderFactory, NodePrimitivesProvider, StateProvider,
StorageChangeSetReader, TryIntoHistoricalStateProvider,
StateProviderBox, StorageChangeSetReader, TryIntoHistoricalStateProvider,
};
use reth_storage_errors::provider::ProviderResult;
use reth_trie::updates::TrieUpdatesSorted;
@@ -596,9 +596,9 @@ impl<N: ProviderNodeTypes> ConsistentProvider<N> {
pub(crate) fn into_state_provider_at_block_hash(
self,
block_hash: BlockHash,
) -> ProviderResult<Box<dyn StateProvider>> {
) -> ProviderResult<StateProviderBox> {
let Self { storage_provider, head_block, .. } = self;
let into_history_at_block_hash = |block_hash| -> ProviderResult<Box<dyn StateProvider>> {
let into_history_at_block_hash = |block_hash| -> ProviderResult<StateProviderBox> {
let block_number = storage_provider
.block_number(block_hash)?
.ok_or(ProviderError::BlockHashNotFound(block_hash))?;

View File

@@ -261,7 +261,7 @@ impl<TX, N: NodeTypes> RocksDBProviderFactory for DatabaseProvider<TX, N> {
}
}
impl<TX: Debug + Send + Sync, N: NodeTypes<ChainSpec: EthChainSpec + 'static>> ChainSpecProvider
impl<TX: Debug + Send, N: NodeTypes<ChainSpec: EthChainSpec + 'static>> ChainSpecProvider
for DatabaseProvider<TX, N>
{
type ChainSpec = N::ChainSpec;
@@ -3208,7 +3208,7 @@ impl<TX: DbTxMut, N: NodeTypes> MetadataWriter for DatabaseProvider<TX, N> {
}
}
impl<TX: Send + Sync, N: NodeTypes> StorageSettingsCache for DatabaseProvider<TX, N> {
impl<TX: Send, N: NodeTypes> StorageSettingsCache for DatabaseProvider<TX, N> {
fn cached_storage_settings(&self) -> StorageSettings {
*self.storage_settings.read()
}

View File

@@ -0,0 +1,114 @@
use reth_db_api::{
cursor::{CursorGuard, DbCursorRO, DbDupCursorRO},
tables::{AccountsHistory, PlainStorageState, StorageChangeSets, StoragesHistory},
transaction::DbTx,
DatabaseError,
};
use std::cell::RefCell;
/// Container for reusable database cursors.
///
/// Holds optional cached cursors for frequently accessed tables. When a cursor is requested,
/// it returns a cached cursor if available, otherwise creates a new one. The cursor is
/// automatically returned to the cache when dropped via the `CursorGuard` wrapper.
///
/// This reduces cursor allocation overhead for state providers that perform many sequential
/// database operations.
pub(crate) struct ReusableStateCursors<TX: DbTx> {
storage_changesets: RefCell<Option<TX::DupCursor<StorageChangeSets>>>,
plain_storage_state: RefCell<Option<TX::DupCursor<PlainStorageState>>>,
accounts_history: RefCell<Option<TX::Cursor<AccountsHistory>>>,
storages_history: RefCell<Option<TX::Cursor<StoragesHistory>>>,
}
impl<TX: DbTx> std::fmt::Debug for ReusableStateCursors<TX> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ReusableStateCursors").finish_non_exhaustive()
}
}
impl<TX: DbTx> ReusableStateCursors<TX> {
/// Creates a new `ReusableStateCursors` with empty cursor slots.
pub(crate) const fn new() -> Self {
Self {
storage_changesets: RefCell::new(None),
plain_storage_state: RefCell::new(None),
accounts_history: RefCell::new(None),
storages_history: RefCell::new(None),
}
}
/// Gets a reusable cursor for the `StorageChangeSets` table.
pub(crate) fn storage_changesets(
&self,
tx: &TX,
) -> Result<CursorGuard<'_, TX::DupCursor<StorageChangeSets>>, DatabaseError>
where
TX::DupCursor<StorageChangeSets>: DbDupCursorRO<StorageChangeSets>,
{
let cursor = self
.storage_changesets
.borrow_mut()
.take()
.map(Ok)
.unwrap_or_else(|| tx.cursor_dup_read())?;
Ok(CursorGuard::new(cursor, &self.storage_changesets))
}
/// Gets a reusable cursor for the `PlainStorageState` table.
pub(crate) fn plain_storage_state(
&self,
tx: &TX,
) -> Result<CursorGuard<'_, TX::DupCursor<PlainStorageState>>, DatabaseError>
where
TX::DupCursor<PlainStorageState>: DbDupCursorRO<PlainStorageState>,
{
let cursor = self
.plain_storage_state
.borrow_mut()
.take()
.map(Ok)
.unwrap_or_else(|| tx.cursor_dup_read())?;
Ok(CursorGuard::new(cursor, &self.plain_storage_state))
}
/// Gets a reusable cursor for the `AccountsHistory` table.
pub(crate) fn accounts_history(
&self,
tx: &TX,
) -> Result<CursorGuard<'_, TX::Cursor<AccountsHistory>>, DatabaseError>
where
TX::Cursor<AccountsHistory>: DbCursorRO<AccountsHistory>,
{
let cursor = self
.accounts_history
.borrow_mut()
.take()
.map(Ok)
.unwrap_or_else(|| tx.cursor_read())?;
Ok(CursorGuard::new(cursor, &self.accounts_history))
}
/// Gets a reusable cursor for the `StoragesHistory` table.
pub(crate) fn storages_history(
&self,
tx: &TX,
) -> Result<CursorGuard<'_, TX::Cursor<StoragesHistory>>, DatabaseError>
where
TX::Cursor<StoragesHistory>: DbCursorRO<StoragesHistory>,
{
let cursor = self
.storages_history
.borrow_mut()
.take()
.map(Ok)
.unwrap_or_else(|| tx.cursor_read())?;
Ok(CursorGuard::new(cursor, &self.storages_history))
}
}
impl<TX: DbTx> Default for ReusableStateCursors<TX> {
fn default() -> Self {
Self::new()
}
}

View File

@@ -1,5 +1,5 @@
use crate::{
providers::state::macros::delegate_provider_impls, AccountReader, BlockHashReader,
providers::state::cursor_reuse::ReusableStateCursors, AccountReader, BlockHashReader,
ChangeSetReader, HashedPostStateProvider, ProviderError, StateProvider, StateRootProvider,
};
use alloy_eips::merge::EPOCH_SLOTS;
@@ -44,13 +44,15 @@ use std::fmt::Debug;
/// - [`tables::AccountChangeSets`]
/// - [`tables::StorageChangeSets`]
#[derive(Debug)]
pub struct HistoricalStateProviderRef<'b, Provider> {
pub struct HistoricalStateProviderRef<'b, Provider: DBProvider> {
/// Database provider
provider: &'b Provider,
/// Block number is main index for the history state of accounts and storages.
block_number: BlockNumber,
/// Lowest blocks at which different parts of the state are available.
lowest_available_blocks: LowestAvailableBlocks,
/// Reusable cursors for state lookups
cursors: ReusableStateCursors<Provider::Tx>,
}
#[derive(Debug, Eq, PartialEq)]
@@ -64,7 +66,12 @@ pub enum HistoryInfo {
impl<'b, Provider: DBProvider + BlockNumReader> 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() }
Self {
provider,
block_number,
lowest_available_blocks: Default::default(),
cursors: ReusableStateCursors::new(),
}
}
/// Create new `StateProvider` for historical block number and lowest block numbers at which
@@ -74,7 +81,12 @@ impl<'b, Provider: DBProvider + BlockNumReader> HistoricalStateProviderRef<'b, P
block_number: BlockNumber,
lowest_available_blocks: LowestAvailableBlocks,
) -> Self {
Self { provider, block_number, lowest_available_blocks }
Self {
provider,
block_number,
lowest_available_blocks,
cursors: ReusableStateCursors::new(),
}
}
/// Lookup an account in the `AccountsHistory` table
@@ -85,7 +97,9 @@ impl<'b, Provider: DBProvider + BlockNumReader> HistoricalStateProviderRef<'b, P
// history key to search IntegerList of block number changesets.
let history_key = ShardedKey::new(address, self.block_number);
self.history_info::<tables::AccountsHistory, _>(
let mut cursor = self.cursors.accounts_history(self.tx())?;
self.history_info::<tables::AccountsHistory, _, _>(
&mut *cursor,
history_key,
|key| key.key == address,
self.lowest_available_blocks.account_history_block_number,
@@ -104,7 +118,9 @@ impl<'b, Provider: DBProvider + BlockNumReader> HistoricalStateProviderRef<'b, P
// history key to search IntegerList of block number changesets.
let history_key = StorageShardedKey::new(address, storage_key, self.block_number);
self.history_info::<tables::StoragesHistory, _>(
let mut cursor = self.cursors.storages_history(self.tx())?;
self.history_info::<tables::StoragesHistory, _, _>(
&mut *cursor,
history_key,
|key| key.address == address && key.sharded_key.key == storage_key,
self.lowest_available_blocks.storage_history_block_number,
@@ -155,17 +171,17 @@ impl<'b, Provider: DBProvider + BlockNumReader> HistoricalStateProviderRef<'b, P
Ok(HashedStorage::from_reverts(self.tx(), address, self.block_number)?)
}
fn history_info<T, K>(
fn history_info<T, K, C>(
&self,
cursor: &mut C,
key: K,
key_filter: impl Fn(&K) -> bool,
lowest_available_block_number: Option<BlockNumber>,
) -> ProviderResult<HistoryInfo>
where
T: Table<Key = K, Value = BlockNumberList>,
C: DbCursorRO<T>,
{
let mut cursor = self.tx().cursor_read::<T>()?;
// Lookup the history chunk in the history index. If they key does not appear in the
// index, the first chunk for the next key will be returned so we filter out chunks that
// have a different key.
@@ -397,7 +413,7 @@ impl<Provider: DBProvider + BlockNumReader> StateProofProvider
}
}
impl<Provider: Sync> HashedPostStateProvider for HistoricalStateProviderRef<'_, Provider> {
impl<Provider: DBProvider> HashedPostStateProvider for HistoricalStateProviderRef<'_, Provider> {
fn hashed_post_state(&self, bundle_state: &revm_database::BundleState) -> HashedPostState {
HashedPostState::from_bundle_state::<KeccakKeyHasher>(bundle_state.state())
}
@@ -414,25 +430,28 @@ impl<Provider: DBProvider + BlockNumReader + BlockHashReader + ChangeSetReader>
) -> ProviderResult<Option<StorageValue>> {
match self.storage_history_lookup(address, storage_key)? {
HistoryInfo::NotYetWritten => Ok(None),
HistoryInfo::InChangeset(changeset_block_number) => Ok(Some(
self.tx()
.cursor_dup_read::<tables::StorageChangeSets>()?
.seek_by_key_subkey((changeset_block_number, address).into(), storage_key)?
HistoryInfo::InChangeset(changeset_block_number) => {
let mut cursor = self.cursors.storage_changesets(self.tx())?;
Ok(Some(
cursor
.seek_by_key_subkey((changeset_block_number, address).into(), storage_key)?
.filter(|entry| entry.key == storage_key)
.ok_or_else(|| ProviderError::StorageChangesetNotFound {
block_number: changeset_block_number,
address,
storage_key: Box::new(storage_key),
})?
.value,
))
}
HistoryInfo::InPlainState | HistoryInfo::MaybeInPlainState => {
let mut cursor = self.cursors.plain_storage_state(self.tx())?;
Ok(cursor
.seek_by_key_subkey(address, storage_key)?
.filter(|entry| entry.key == storage_key)
.ok_or_else(|| ProviderError::StorageChangesetNotFound {
block_number: changeset_block_number,
address,
storage_key: Box::new(storage_key),
})?
.value,
)),
HistoryInfo::InPlainState | HistoryInfo::MaybeInPlainState => Ok(self
.tx()
.cursor_dup_read::<tables::PlainStorageState>()?
.seek_by_key_subkey(address, storage_key)?
.filter(|entry| entry.key == storage_key)
.map(|entry| entry.value)
.or(Some(StorageValue::ZERO))),
.map(|entry| entry.value)
.or(Some(StorageValue::ZERO)))
}
}
}
}
@@ -494,7 +513,7 @@ impl<Provider: DBProvider + BlockNumReader> HistoricalStateProvider<Provider> {
}
// Delegates all provider impls to [HistoricalStateProviderRef]
delegate_provider_impls!(HistoricalStateProvider<Provider> where [Provider: DBProvider + BlockNumReader + BlockHashReader + ChangeSetReader]);
reth_storage_api::macros::delegate_provider_impls!(HistoricalStateProvider<Provider> where [Provider: DBProvider + BlockNumReader + BlockHashReader + ChangeSetReader]);
/// Lowest blocks at which different parts of the state are available.
/// They may be [Some] if pruning is enabled.

View File

@@ -1,5 +1,5 @@
use crate::{
providers::state::macros::delegate_provider_impls, AccountReader, BlockHashReader,
providers::state::cursor_reuse::ReusableStateCursors, AccountReader, BlockHashReader,
HashedPostStateProvider, StateProvider, StateRootProvider,
};
use alloy_primitives::{Address, BlockNumber, Bytes, StorageKey, StorageValue, B256};
@@ -23,16 +23,20 @@ use reth_trie_db::{
///
/// Wraps a [`DBProvider`] to get access to database.
#[derive(Debug)]
pub struct LatestStateProviderRef<'b, Provider>(&'b Provider);
pub struct LatestStateProviderRef<'b, Provider: DBProvider> {
provider: &'b Provider,
/// Reusable cursors for state lookups
cursors: ReusableStateCursors<Provider::Tx>,
}
impl<'b, Provider: DBProvider> LatestStateProviderRef<'b, Provider> {
/// Create new state provider
pub const fn new(provider: &'b Provider) -> Self {
Self(provider)
Self { provider, cursors: ReusableStateCursors::new() }
}
fn tx(&self) -> &Provider::Tx {
self.0.tx_ref()
self.provider.tx_ref()
}
}
@@ -43,10 +47,12 @@ impl<Provider: DBProvider> AccountReader for LatestStateProviderRef<'_, Provider
}
}
impl<Provider: BlockHashReader> BlockHashReader for LatestStateProviderRef<'_, Provider> {
impl<Provider: DBProvider + BlockHashReader> BlockHashReader
for LatestStateProviderRef<'_, Provider>
{
/// Get block hash by number.
fn block_hash(&self, number: u64) -> ProviderResult<Option<B256>> {
self.0.block_hash(number)
self.provider.block_hash(number)
}
fn canonical_hashes_range(
@@ -54,11 +60,11 @@ impl<Provider: BlockHashReader> BlockHashReader for LatestStateProviderRef<'_, P
start: BlockNumber,
end: BlockNumber,
) -> ProviderResult<Vec<B256>> {
self.0.canonical_hashes_range(start, end)
self.provider.canonical_hashes_range(start, end)
}
}
impl<Provider: DBProvider + Sync> StateRootProvider for LatestStateProviderRef<'_, Provider> {
impl<Provider: DBProvider> StateRootProvider for LatestStateProviderRef<'_, Provider> {
fn state_root(&self, hashed_state: HashedPostState) -> ProviderResult<B256> {
StateRoot::overlay_root(self.tx(), &hashed_state.into_sorted())
.map_err(|err| ProviderError::Database(err.into()))
@@ -89,7 +95,7 @@ impl<Provider: DBProvider + Sync> StateRootProvider for LatestStateProviderRef<'
}
}
impl<Provider: DBProvider + Sync> StorageRootProvider for LatestStateProviderRef<'_, Provider> {
impl<Provider: DBProvider> StorageRootProvider for LatestStateProviderRef<'_, Provider> {
fn storage_root(
&self,
address: Address,
@@ -120,7 +126,7 @@ impl<Provider: DBProvider + Sync> StorageRootProvider for LatestStateProviderRef
}
}
impl<Provider: DBProvider + Sync> StateProofProvider for LatestStateProviderRef<'_, Provider> {
impl<Provider: DBProvider> StateProofProvider for LatestStateProviderRef<'_, Provider> {
fn proof(
&self,
input: TrieInput,
@@ -147,7 +153,7 @@ impl<Provider: DBProvider + Sync> StateProofProvider for LatestStateProviderRef<
}
}
impl<Provider: DBProvider + Sync> HashedPostStateProvider for LatestStateProviderRef<'_, Provider> {
impl<Provider: DBProvider> HashedPostStateProvider for LatestStateProviderRef<'_, Provider> {
fn hashed_post_state(&self, bundle_state: &revm_database::BundleState) -> HashedPostState {
HashedPostState::from_bundle_state::<KeccakKeyHasher>(bundle_state.state())
}
@@ -162,7 +168,7 @@ impl<Provider: DBProvider + BlockHashReader> StateProvider
account: Address,
storage_key: StorageKey,
) -> ProviderResult<Option<StorageValue>> {
let mut cursor = self.tx().cursor_dup_read::<tables::PlainStorageState>()?;
let mut cursor = self.cursors.plain_storage_state(self.tx())?;
if let Some(entry) = cursor.seek_by_key_subkey(account, storage_key)? &&
entry.key == storage_key
{
@@ -199,7 +205,7 @@ impl<Provider: DBProvider> LatestStateProvider<Provider> {
}
// Delegates all provider impls to [LatestStateProviderRef]
delegate_provider_impls!(LatestStateProvider<Provider> where [Provider: DBProvider + BlockHashReader ]);
reth_storage_api::macros::delegate_provider_impls!(LatestStateProvider<Provider> where [Provider: DBProvider + BlockHashReader ]);
#[cfg(test)]
mod tests {

View File

@@ -1,5 +1,5 @@
//! [`StateProvider`](crate::StateProvider) implementations
pub(crate) mod cursor_reuse;
pub(crate) mod historical;
pub(crate) mod latest;
pub(crate) mod macros;
pub(crate) mod overlay;

View File

@@ -54,7 +54,6 @@ pub trait BlockReader:
+ TransactionsProvider
+ ReceiptProvider
+ Send
+ Sync
{
/// The block type this provider reads.
type Block: reth_primitives_traits::Block<
@@ -149,7 +148,7 @@ pub trait BlockReader:
fn block_by_transaction_id(&self, id: TxNumber) -> ProviderResult<Option<BlockNumber>>;
}
impl<T: BlockReader> BlockReader for Arc<T> {
impl<T: BlockReader + Send + Sync> BlockReader for Arc<T> {
type Block = T::Block;
fn find_block_by_hash(
@@ -210,7 +209,7 @@ impl<T: BlockReader> BlockReader for Arc<T> {
}
}
impl<T: BlockReader> BlockReader for &T {
impl<T: BlockReader + Send + Sync> BlockReader for &T {
type Block = T::Block;
fn find_block_by_hash(
@@ -382,7 +381,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt {
}
/// Functionality to read the last known chain blocks from the database.
pub trait ChainStateBlockReader: Send + Sync {
pub trait ChainStateBlockReader: Send {
/// Returns the last finalized block number.
///
/// If no finalized block has been written yet, this returns `None`.
@@ -394,7 +393,7 @@ pub trait ChainStateBlockReader: Send + Sync {
}
/// Functionality to write the last known chain blocks to the database.
pub trait ChainStateBlockWriter: Send + Sync {
pub trait ChainStateBlockWriter: Send {
/// Saves the given finalized block number in the DB.
fn save_finalized_block_number(&self, block_number: BlockNumber) -> ProviderResult<()>;

View File

@@ -4,8 +4,8 @@ use alloy_primitives::{BlockNumber, B256};
use reth_storage_errors::provider::ProviderResult;
/// Client trait for fetching block hashes by number.
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait BlockHashReader: Send + Sync {
#[auto_impl::auto_impl(&, Box, Arc)]
pub trait BlockHashReader {
/// Get the hash of the block with the given number. Returns `None` if no block with this number
/// exists.
fn block_hash(&self, number: BlockNumber) -> ProviderResult<Option<B256>>;

View File

@@ -9,7 +9,7 @@ use reth_storage_errors::provider::{ProviderError, ProviderResult};
///
/// This trait also supports fetching block hashes and block numbers from a [`BlockHashOrNumber`].
#[auto_impl::auto_impl(&, Arc)]
pub trait BlockNumReader: BlockHashReader + Send + Sync {
pub trait BlockNumReader: BlockHashReader + Send {
/// Returns the current info for the chain.
fn chain_info(&self) -> ProviderResult<ChainInfo>;

View File

@@ -6,7 +6,7 @@ use reth_storage_errors::provider::ProviderResult;
/// Client trait for fetching block body indices related data.
#[auto_impl::auto_impl(&, Arc)]
pub trait BlockBodyIndicesProvider: Send + Sync {
pub trait BlockBodyIndicesProvider: Send {
/// Returns the block body indices with matching number from database.
///
/// Returns `None` if block is not found.

View File

@@ -9,7 +9,7 @@ use reth_trie_common::HashedPostStateSorted;
/// `BlockExecution` Writer
pub trait BlockExecutionWriter:
NodePrimitivesProvider<Primitives: NodePrimitives<Block = Self::Block>> + BlockWriter + Send + Sync
NodePrimitivesProvider<Primitives: NodePrimitives<Block = Self::Block>> + BlockWriter
{
/// Take all of the blocks above the provided number and their execution result
///
@@ -39,8 +39,8 @@ impl<T: BlockExecutionWriter> BlockExecutionWriter for &T {
}
/// Block Writer
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait BlockWriter: Send + Sync {
#[auto_impl::auto_impl(&, Box)]
pub trait BlockWriter {
/// The body this writer can write.
type Block: Block;
/// The receipt type for [`ExecutionOutcome`].

View File

@@ -8,8 +8,8 @@ use reth_primitives_traits::{Account, StorageEntry};
use reth_storage_errors::provider::ProviderResult;
/// Hashing Writer
#[auto_impl(&, Arc, Box)]
pub trait HashingWriter: Send + Sync {
#[auto_impl(&, Box)]
pub trait HashingWriter: Send {
/// Unwind and clear account hashing.
///
/// # Returns

View File

@@ -10,7 +10,7 @@ pub type ProviderHeader<P> = <P as HeaderProvider>::Header;
/// Client trait for fetching `Header` related data.
#[auto_impl::auto_impl(&, Arc)]
pub trait HeaderProvider: Send + Sync {
pub trait HeaderProvider: Send {
/// The header type this provider supports.
type Header: BlockHeader;

View File

@@ -3,7 +3,7 @@ use reth_primitives_traits::{BlockHeader, SealedHeader};
use reth_storage_errors::provider::ProviderResult;
/// Provider for getting the local tip header for sync gap calculation.
pub trait HeaderSyncGapProvider: Send + Sync {
pub trait HeaderSyncGapProvider: Send {
/// The header type.
type Header: BlockHeader;

View File

@@ -7,8 +7,8 @@ use reth_primitives_traits::StorageEntry;
use reth_storage_errors::provider::ProviderResult;
/// History Writer
#[auto_impl(&, Arc, Box)]
pub trait HistoryWriter: Send + Sync {
#[auto_impl(&, Box)]
pub trait HistoryWriter: Send {
/// Unwind and clear account history indices.
///
/// Returns number of changesets walked.

View File

@@ -103,3 +103,5 @@ pub use reth_db_api::models::StorageSettings;
mod full;
pub use full::*;
pub mod macros;

View File

@@ -1,9 +1,10 @@
//! Helper macros for implementing traits for various [`StateProvider`](crate::StateProvider)
//! Helper macros for implementing traits for various `StateProvider`
//! implementations
/// A macro that delegates trait implementations to the `as_ref` function of the type.
///
/// Used to implement provider traits.
#[macro_export]
macro_rules! delegate_impls_to_as_ref {
(for $target:ty => $($trait:ident $(where [$($generics:tt)*])? { $(fn $func:ident$(<$($generic_arg:ident: $generic_arg_ty:path),*>)?(&self, $($arg:ident: $argty:ty),*) -> $ret:path;)* })* ) => {
@@ -19,45 +20,46 @@ macro_rules! delegate_impls_to_as_ref {
};
}
pub(crate) use delegate_impls_to_as_ref;
pub use delegate_impls_to_as_ref;
/// Delegates the provider trait implementations to the `as_ref` function of the type:
///
/// [`AccountReader`](crate::AccountReader)
/// [`BlockHashReader`](crate::BlockHashReader)
/// [`StateProvider`](crate::StateProvider)
#[macro_export]
macro_rules! delegate_provider_impls {
($target:ty $(where [$($generics:tt)*])?) => {
$crate::providers::state::macros::delegate_impls_to_as_ref!(
$crate::macros::delegate_impls_to_as_ref!(
for $target =>
AccountReader $(where [$($generics)*])? {
fn basic_account(&self, address: &alloy_primitives::Address) -> reth_storage_errors::provider::ProviderResult<Option<reth_primitives_traits::Account>>;
fn basic_account(&self, address: &alloy_primitives::Address) -> reth_storage_api::errors::provider::ProviderResult<Option<reth_primitives_traits::Account>>;
}
BlockHashReader $(where [$($generics)*])? {
fn block_hash(&self, number: u64) -> reth_storage_errors::provider::ProviderResult<Option<alloy_primitives::B256>>;
fn canonical_hashes_range(&self, start: alloy_primitives::BlockNumber, end: alloy_primitives::BlockNumber) -> reth_storage_errors::provider::ProviderResult<Vec<alloy_primitives::B256>>;
fn block_hash(&self, number: u64) -> reth_storage_api::errors::provider::ProviderResult<Option<alloy_primitives::B256>>;
fn canonical_hashes_range(&self, start: alloy_primitives::BlockNumber, end: alloy_primitives::BlockNumber) -> reth_storage_api::errors::provider::ProviderResult<Vec<alloy_primitives::B256>>;
}
StateProvider $(where [$($generics)*])? {
fn storage(&self, account: alloy_primitives::Address, storage_key: alloy_primitives::StorageKey) -> reth_storage_errors::provider::ProviderResult<Option<alloy_primitives::StorageValue>>;
fn storage(&self, account: alloy_primitives::Address, storage_key: alloy_primitives::StorageKey) -> reth_storage_api::errors::provider::ProviderResult<Option<alloy_primitives::StorageValue>>;
}
BytecodeReader $(where [$($generics)*])? {
fn bytecode_by_hash(&self, code_hash: &alloy_primitives::B256) -> reth_storage_errors::provider::ProviderResult<Option<reth_primitives_traits::Bytecode>>;
fn bytecode_by_hash(&self, code_hash: &alloy_primitives::B256) -> reth_storage_api::errors::provider::ProviderResult<Option<reth_primitives_traits::Bytecode>>;
}
StateRootProvider $(where [$($generics)*])? {
fn state_root(&self, state: reth_trie::HashedPostState) -> reth_storage_errors::provider::ProviderResult<alloy_primitives::B256>;
fn state_root_from_nodes(&self, input: reth_trie::TrieInput) -> reth_storage_errors::provider::ProviderResult<alloy_primitives::B256>;
fn state_root_with_updates(&self, state: reth_trie::HashedPostState) -> reth_storage_errors::provider::ProviderResult<(alloy_primitives::B256, reth_trie::updates::TrieUpdates)>;
fn state_root_from_nodes_with_updates(&self, input: reth_trie::TrieInput) -> reth_storage_errors::provider::ProviderResult<(alloy_primitives::B256, reth_trie::updates::TrieUpdates)>;
fn state_root(&self, state: reth_trie::HashedPostState) -> reth_storage_api::errors::provider::ProviderResult<alloy_primitives::B256>;
fn state_root_from_nodes(&self, input: reth_trie::TrieInput) -> reth_storage_api::errors::provider::ProviderResult<alloy_primitives::B256>;
fn state_root_with_updates(&self, state: reth_trie::HashedPostState) -> reth_storage_api::errors::provider::ProviderResult<(alloy_primitives::B256, reth_trie::updates::TrieUpdates)>;
fn state_root_from_nodes_with_updates(&self, input: reth_trie::TrieInput) -> reth_storage_api::errors::provider::ProviderResult<(alloy_primitives::B256, reth_trie::updates::TrieUpdates)>;
}
StorageRootProvider $(where [$($generics)*])? {
fn storage_root(&self, address: alloy_primitives::Address, storage: reth_trie::HashedStorage) -> reth_storage_errors::provider::ProviderResult<alloy_primitives::B256>;
fn storage_proof(&self, address: alloy_primitives::Address, slot: alloy_primitives::B256, storage: reth_trie::HashedStorage) -> reth_storage_errors::provider::ProviderResult<reth_trie::StorageProof>;
fn storage_multiproof(&self, address: alloy_primitives::Address, slots: &[alloy_primitives::B256], storage: reth_trie::HashedStorage) -> reth_storage_errors::provider::ProviderResult<reth_trie::StorageMultiProof>;
fn storage_root(&self, address: alloy_primitives::Address, storage: reth_trie::HashedStorage) -> reth_storage_api::errors::provider::ProviderResult<alloy_primitives::B256>;
fn storage_proof(&self, address: alloy_primitives::Address, slot: alloy_primitives::B256, storage: reth_trie::HashedStorage) -> reth_storage_api::errors::provider::ProviderResult<reth_trie::StorageProof>;
fn storage_multiproof(&self, address: alloy_primitives::Address, slots: &[alloy_primitives::B256], storage: reth_trie::HashedStorage) -> reth_storage_api::errors::provider::ProviderResult<reth_trie::StorageMultiProof>;
}
StateProofProvider $(where [$($generics)*])? {
fn proof(&self, input: reth_trie::TrieInput, address: alloy_primitives::Address, slots: &[alloy_primitives::B256]) -> reth_storage_errors::provider::ProviderResult<reth_trie::AccountProof>;
fn multiproof(&self, input: reth_trie::TrieInput, targets: reth_trie::MultiProofTargets) -> reth_storage_errors::provider::ProviderResult<reth_trie::MultiProof>;
fn witness(&self, input: reth_trie::TrieInput, target: reth_trie::HashedPostState) -> reth_storage_errors::provider::ProviderResult<Vec<alloy_primitives::Bytes>>;
fn proof(&self, input: reth_trie::TrieInput, address: alloy_primitives::Address, slots: &[alloy_primitives::B256]) -> reth_storage_api::errors::provider::ProviderResult<reth_trie::AccountProof>;
fn multiproof(&self, input: reth_trie::TrieInput, targets: reth_trie::MultiProofTargets) -> reth_storage_api::errors::provider::ProviderResult<reth_trie::MultiProof>;
fn witness(&self, input: reth_trie::TrieInput, target: reth_trie::HashedPostState) -> reth_storage_api::errors::provider::ProviderResult<Vec<alloy_primitives::Bytes>>;
}
HashedPostStateProvider $(where [$($generics)*])? {
fn hashed_post_state(&self, bundle_state: &revm_database::BundleState) -> reth_trie::HashedPostState;
@@ -66,4 +68,4 @@ macro_rules! delegate_provider_impls {
}
}
pub(crate) use delegate_provider_impls;
pub use delegate_provider_impls;

View File

@@ -10,8 +10,8 @@ pub mod keys {
}
/// Client trait for reading node metadata from the database.
#[auto_impl::auto_impl(&, Arc)]
pub trait MetadataProvider: Send + Sync {
#[auto_impl::auto_impl(&)]
pub trait MetadataProvider: Send {
/// Get a metadata value by key
fn get_metadata(&self, key: &str) -> ProviderResult<Option<Vec<u8>>>;
@@ -24,7 +24,7 @@ pub trait MetadataProvider: Send + Sync {
}
/// Client trait for writing node metadata to the database.
pub trait MetadataWriter: Send + Sync {
pub trait MetadataWriter: Send {
/// Write a metadata value
fn write_metadata(&self, key: &str, value: Vec<u8>) -> ProviderResult<()>;
@@ -41,7 +41,7 @@ pub trait MetadataWriter: Send + Sync {
}
/// Trait for caching storage settings on a provider factory.
pub trait StorageSettingsCache: Send + Sync {
pub trait StorageSettingsCache: Send {
/// Gets the cached storage settings.
fn cached_storage_settings(&self) -> StorageSettings;

View File

@@ -3,8 +3,8 @@ use reth_prune_types::{PruneCheckpoint, PruneSegment};
use reth_storage_errors::provider::ProviderResult;
/// The trait for fetching prune checkpoint related data.
#[auto_impl::auto_impl(&, Arc)]
pub trait PruneCheckpointReader: Send + Sync {
#[auto_impl::auto_impl(&)]
pub trait PruneCheckpointReader: Send {
/// Fetch the prune checkpoint for the given segment.
fn get_prune_checkpoint(
&self,
@@ -16,8 +16,8 @@ pub trait PruneCheckpointReader: Send + Sync {
}
/// The trait for updating prune checkpoint related data.
#[auto_impl::auto_impl(&, Arc)]
pub trait PruneCheckpointWriter: Send + Sync {
#[auto_impl::auto_impl(&)]
pub trait PruneCheckpointWriter {
/// Save prune checkpoint.
fn save_prune_checkpoint(
&self,

View File

@@ -11,7 +11,7 @@ pub type ProviderReceipt<P> = <P as ReceiptProvider>::Receipt;
/// Client trait for fetching receipt data.
#[auto_impl::auto_impl(&, Arc)]
pub trait ReceiptProvider: Send + Sync {
pub trait ReceiptProvider {
/// The receipt type.
type Receipt: Receipt;

View File

@@ -4,8 +4,8 @@ use reth_stages_types::{StageCheckpoint, StageId};
use reth_storage_errors::provider::ProviderResult;
/// The trait for fetching stage checkpoint related data.
#[auto_impl::auto_impl(&, Arc)]
pub trait StageCheckpointReader: Send + Sync {
#[auto_impl::auto_impl(&)]
pub trait StageCheckpointReader: Send {
/// Fetch the checkpoint for the given stage.
fn get_stage_checkpoint(&self, id: StageId) -> ProviderResult<Option<StageCheckpoint>>;
@@ -18,8 +18,8 @@ pub trait StageCheckpointReader: Send + Sync {
}
/// The trait for updating stage checkpoint related data.
#[auto_impl::auto_impl(&, Arc)]
pub trait StageCheckpointWriter: Send + Sync {
#[auto_impl::auto_impl(&)]
pub trait StageCheckpointWriter {
/// Save stage checkpoint.
fn save_stage_checkpoint(&self, id: StageId, checkpoint: StageCheckpoint)
-> ProviderResult<()>;

View File

@@ -14,8 +14,8 @@ use reth_trie_common::HashedPostState;
use revm_database::BundleState;
/// This just receives state, or [`ExecutionOutcome`], from the provider
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait StateReader: Send + Sync {
#[auto_impl::auto_impl(&, Box)]
pub trait StateReader: Send {
/// Receipt type in [`ExecutionOutcome`].
type Receipt: Send + Sync;
@@ -27,10 +27,10 @@ pub trait StateReader: Send + Sync {
}
/// Type alias of boxed [`StateProvider`].
pub type StateProviderBox = Box<dyn StateProvider>;
pub type StateProviderBox = Box<dyn StateProvider + Send + 'static>;
/// An abstraction for a type that provides state data.
#[auto_impl(&, Arc, Box)]
#[auto_impl(&, Box)]
pub trait StateProvider:
BlockHashReader
+ AccountReader
@@ -39,8 +39,6 @@ pub trait StateProvider:
+ StorageRootProvider
+ StateProofProvider
+ HashedPostStateProvider
+ Send
+ Sync
{
/// Get storage of given account.
fn storage(
@@ -97,15 +95,15 @@ pub trait AccountInfoReader: AccountReader + BytecodeReader {}
impl<T: AccountReader + BytecodeReader> AccountInfoReader for T {}
/// Trait that provides the hashed state from various sources.
#[auto_impl(&, Arc, Box)]
pub trait HashedPostStateProvider: Send + Sync {
#[auto_impl(&, Box)]
pub trait HashedPostStateProvider {
/// Returns the `HashedPostState` of the provided [`BundleState`].
fn hashed_post_state(&self, bundle_state: &BundleState) -> HashedPostState;
}
/// Trait for reading bytecode associated with a given code hash.
#[auto_impl(&, Arc, Box)]
pub trait BytecodeReader: Send + Sync {
#[auto_impl(&, Box)]
pub trait BytecodeReader {
/// Get account code by its hash
fn bytecode_by_hash(&self, code_hash: &B256) -> ProviderResult<Option<Bytecode>>;
}
@@ -142,8 +140,8 @@ pub trait TryIntoHistoricalStateProvider {
/// This affects tracing, or replaying blocks, which will need to be executed on top of the state of
/// the parent block. For example, in order to trace block `n`, the state after block `n - 1` needs
/// to be used, since block `n` was executed on its parent block's state.
#[auto_impl(&, Arc, Box)]
pub trait StateProviderFactory: BlockIdReader + Send + Sync {
#[auto_impl(&, Box, Arc)]
pub trait StateProviderFactory: BlockIdReader + Send {
/// Storage provider for latest block.
fn latest(&self) -> ProviderResult<StateProviderBox>;

View File

@@ -1,8 +1,8 @@
use reth_db_api::table::Table;
/// The trait for fetching provider statistics.
#[auto_impl::auto_impl(&, Arc)]
pub trait StatsReader: Send + Sync {
#[auto_impl::auto_impl(&)]
pub trait StatsReader {
/// Fetch the number of entries in the corresponding [Table]. Depending on the provider, it may
/// route to different data sources other than [Table].
fn count_entries<T: Table>(&self) -> reth_storage_errors::provider::ProviderResult<usize>;

View File

@@ -8,8 +8,8 @@ use reth_primitives_traits::StorageEntry;
use reth_storage_errors::provider::ProviderResult;
/// Storage reader
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait StorageReader: Send + Sync {
#[auto_impl::auto_impl(&, Box)]
pub trait StorageReader: Send {
/// Get plainstate storages for addresses and storage keys.
fn plain_state_storages(
&self,
@@ -34,8 +34,8 @@ pub trait StorageReader: Send + Sync {
/// Storage `ChangeSet` reader
#[cfg(feature = "db-api")]
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait StorageChangeSetReader: Send + Sync {
#[auto_impl::auto_impl(&, Box)]
pub trait StorageChangeSetReader: Send {
/// Iterate over storage changesets and return the storage state from before this block.
fn storage_changeset(
&self,

View File

@@ -22,7 +22,7 @@ pub enum TransactionVariant {
/// Client trait for fetching transactions related data.
#[auto_impl::auto_impl(&, Arc)]
pub trait TransactionsProvider: BlockNumReader + Send + Sync {
pub trait TransactionsProvider: BlockNumReader + Send {
/// The transaction type this provider reads.
type Transaction: Send + Sync + SignedTransaction;

View File

@@ -9,7 +9,7 @@ use reth_trie_common::{
/// A type that can compute the state root of a given post state.
#[auto_impl::auto_impl(&, Box, Arc)]
pub trait StateRootProvider: Send + Sync {
pub trait StateRootProvider {
/// Returns the state root of the `BundleState` on top of the current state.
///
/// # Note
@@ -40,8 +40,8 @@ pub trait StateRootProvider: Send + Sync {
}
/// A type that can compute the storage root for a given account.
#[auto_impl::auto_impl(&, Box, Arc)]
pub trait StorageRootProvider: Send + Sync {
#[auto_impl::auto_impl(&, Box)]
pub trait StorageRootProvider {
/// Returns the storage root of the `HashedStorage` for target address on top of the current
/// state.
fn storage_root(&self, address: Address, hashed_storage: HashedStorage)
@@ -66,8 +66,8 @@ pub trait StorageRootProvider: Send + Sync {
}
/// A type that can generate state proof on top of a given post state.
#[auto_impl::auto_impl(&, Box, Arc)]
pub trait StateProofProvider: Send + Sync {
#[auto_impl::auto_impl(&, Box)]
pub trait StateProofProvider {
/// Get account and storage proofs of target keys in the `HashedPostState`
/// on top of the current state.
fn proof(
@@ -90,8 +90,8 @@ pub trait StateProofProvider: Send + Sync {
}
/// Trie Reader
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait TrieReader: Send + Sync {
#[auto_impl::auto_impl(&, Box)]
pub trait TrieReader: Send {
/// Returns the [`TrieUpdatesSorted`] for reverting the trie database to its state prior to the
/// given block and onwards having been processed.
fn trie_reverts(&self, from: BlockNumber) -> ProviderResult<TrieUpdatesSorted>;
@@ -104,8 +104,8 @@ pub trait TrieReader: Send + Sync {
}
/// Trie Writer
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait TrieWriter: Send + Sync {
#[auto_impl::auto_impl(&, Box)]
pub trait TrieWriter: Send {
/// Writes trie updates to the database.
///
/// Returns the number of entries modified.
@@ -146,8 +146,8 @@ pub trait TrieWriter: Send + Sync {
}
/// Storage Trie Writer
#[auto_impl::auto_impl(&, Arc, Box)]
pub trait StorageTrieWriter: Send + Sync {
#[auto_impl::auto_impl(&, Box)]
pub trait StorageTrieWriter: Send {
/// Writes storage trie updates from the given storage trie map with already sorted updates.
///
/// Expects the storage trie updates to already be sorted by the hashed address key.

View File

@@ -207,7 +207,7 @@ where
&self,
origin: TransactionOrigin,
transaction: Tx,
state: &mut Option<Box<dyn AccountInfoReader>>,
state: &mut Option<Box<dyn AccountInfoReader + Send>>,
) -> TransactionValidationOutcome<Tx> {
self.validate_one_with_provider(origin, transaction, state)
}
@@ -219,7 +219,7 @@ where
&self,
origin: TransactionOrigin,
transaction: Tx,
maybe_state: &mut Option<Box<dyn AccountInfoReader>>,
maybe_state: &mut Option<Box<dyn AccountInfoReader + Send>>,
) -> TransactionValidationOutcome<Tx> {
match self.validate_one_no_state(origin, transaction) {
Ok(transaction) => {

View File

@@ -27,8 +27,8 @@ impl<T, H> ProofTrieNodeProviderFactory<T, H> {
impl<T, H> TrieNodeProviderFactory for ProofTrieNodeProviderFactory<T, H>
where
T: TrieCursorFactory + Clone + Send + Sync,
H: HashedCursorFactory + Clone + Send + Sync,
T: TrieCursorFactory + Clone,
H: HashedCursorFactory + Clone,
{
type AccountNodeProvider = ProofBlindedAccountProvider<T, H>;
type StorageNodeProvider = ProofBlindedStorageProvider<T, H>;

View File

@@ -95,8 +95,8 @@ impl<T, H> TrieWitness<T, H> {
impl<T, H> TrieWitness<T, H>
where
T: TrieCursorFactory + Clone + Send + Sync,
H: HashedCursorFactory + Clone + Send + Sync,
T: TrieCursorFactory + Clone,
H: HashedCursorFactory + Clone,
{
/// Compute the state transition witness for the trie. Gather all required nodes
/// to apply `state` on top of the current trie state.

View File

@@ -65,7 +65,7 @@ where
impl<Provider, T> ImportService<Provider, T>
where
Provider: BlockNumReader + Clone + 'static,
Provider: BlockNumReader + Sync + Clone + 'static,
T: PayloadTypes,
{
/// Create a new block import service
@@ -198,7 +198,7 @@ where
impl<Provider, T> Future for ImportService<Provider, T>
where
Provider: BlockNumReader + BlockHashReader + Clone + 'static + Unpin,
Provider: BlockNumReader + BlockHashReader + Sync + Clone + 'static + Unpin,
T: PayloadTypes,
{
type Output = Result<(), Box<dyn std::error::Error>>;