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

feat(storage): implement BundleStateDataProvider for BundleStateWithReceipts #8282

Merged
merged 2 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 5 additions & 1 deletion crates/blockchain-tree/src/bundle.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! [BundleStateDataProvider] implementations used by the tree.

use reth_primitives::{BlockHash, BlockNumber, ForkBlock};
use reth_provider::{BundleStateDataProvider, BundleStateWithReceipts};
use reth_provider::{BundleStateDataProvider, BundleStateForkProvider, BundleStateWithReceipts};
use std::collections::BTreeMap;

/// Structure that combines references of required data to be a [`BundleStateDataProvider`].
Expand Down Expand Up @@ -30,7 +30,9 @@ impl<'a> BundleStateDataProvider for BundleStateDataRef<'a> {

self.canonical_block_hashes.get(&block_number).cloned()
}
}

impl<'a> BundleStateForkProvider for BundleStateDataRef<'a> {
fn canonical_fork(&self) -> ForkBlock {
self.canonical_fork
}
Expand All @@ -57,7 +59,9 @@ impl BundleStateDataProvider for BundleStateData {
fn block_hash(&self, block_number: BlockNumber) -> Option<BlockHash> {
self.parent_block_hashes.get(&block_number).cloned()
}
}

impl BundleStateForkProvider for BundleStateData {
fn canonical_fork(&self) -> ForkBlock {
self.canonical_fork
}
Expand Down
4 changes: 2 additions & 2 deletions crates/blockchain-tree/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use reth_primitives::{
};
use reth_provider::{
providers::{BundleStateProvider, ConsistentDbView},
BundleStateDataProvider, BundleStateWithReceipts, Chain, ProviderError, StateRootProvider,
BundleStateWithReceipts, Chain, FullBundleStateDataProvider, ProviderError, StateRootProvider,
};
use reth_revm::database::StateProviderDatabase;
use reth_trie::updates::TrieUpdates;
Expand Down Expand Up @@ -178,7 +178,7 @@ impl AppendableChain {
block_validation_kind: BlockValidationKind,
) -> RethResult<(BundleStateWithReceipts, Option<TrieUpdates>)>
where
BSDP: BundleStateDataProvider,
BSDP: FullBundleStateDataProvider,
DB: Database + Clone,
E: BlockExecutorProvider,
{
Expand Down
6 changes: 3 additions & 3 deletions crates/blockchain-tree/src/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use reth_primitives::{
SealedHeader,
};
use reth_provider::{
BlockchainTreePendingStateProvider, BundleStateDataProvider, CanonStateNotificationSender,
CanonStateNotifications, CanonStateSubscriptions,
BlockchainTreePendingStateProvider, CanonStateNotificationSender, CanonStateNotifications,
CanonStateSubscriptions, FullBundleStateDataProvider,
};
use std::collections::{BTreeMap, HashSet};

Expand Down Expand Up @@ -138,7 +138,7 @@ impl BlockchainTreePendingStateProvider for NoopBlockchainTree {
fn find_pending_state_provider(
&self,
_block_hash: BlockHash,
) -> Option<Box<dyn BundleStateDataProvider>> {
) -> Option<Box<dyn FullBundleStateDataProvider>> {
None
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/blockchain-tree/src/shareable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use reth_primitives::{
SealedHeader,
};
use reth_provider::{
BlockchainTreePendingStateProvider, BundleStateDataProvider, CanonStateSubscriptions,
BlockchainTreePendingStateProvider, CanonStateSubscriptions, FullBundleStateDataProvider,
ProviderError,
};
use std::{
Expand Down Expand Up @@ -199,7 +199,7 @@ where
fn find_pending_state_provider(
&self,
block_hash: BlockHash,
) -> Option<Box<dyn BundleStateDataProvider>> {
) -> Option<Box<dyn FullBundleStateDataProvider>> {
trace!(target: "blockchain_tree", ?block_hash, "Finding pending state provider");
let provider = self.tree.read().post_state_data(block_hash)?;
Some(Box::new(provider))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{providers::StaticFileProviderRWRefMut, StateChanges, StateReverts, StateWriter};
use crate::{
providers::StaticFileProviderRWRefMut, BundleStateDataProvider, StateChanges, StateReverts,
StateWriter,
};
use reth_db::{
cursor::{DbCursorRO, DbCursorRW},
tables,
Expand All @@ -9,8 +12,8 @@ use reth_interfaces::provider::{ProviderError, ProviderResult};
use reth_primitives::{
logs_bloom,
revm::compat::{into_reth_acc, into_revm_acc},
Account, Address, BlockNumber, Bloom, Bytecode, Log, Receipt, Receipts, StaticFileSegment,
StorageEntry, B256, U256,
Account, Address, BlockHash, BlockNumber, Bloom, Bytecode, Log, Receipt, Receipts,
StaticFileSegment, StorageEntry, B256, U256,
};
use reth_trie::HashedPostState;
pub use revm::db::states::OriginalValuesKnown;
Expand Down Expand Up @@ -365,6 +368,17 @@ impl StateWriter for BundleStateWithReceipts {
}
}

impl BundleStateDataProvider for BundleStateWithReceipts {
fn state(&self) -> &BundleStateWithReceipts {
self
}

/// Always returns [None] because we don't have any information about the block header.
fn block_hash(&self, _block_number: BlockNumber) -> Option<BlockHash> {
None
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
16 changes: 8 additions & 8 deletions crates/storage/provider/src/providers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::{
AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt,
BlockSource, BlockchainTreePendingStateProvider, BundleStateDataProvider, CanonChainTracker,
CanonStateNotifications, CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader,
DatabaseProviderFactory, EvmEnvProvider, HeaderProvider, ProviderError, PruneCheckpointReader,
ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader, StateProviderBox,
StateProviderFactory, StaticFileProviderFactory, TransactionVariant, TransactionsProvider,
TreeViewer, WithdrawalsProvider,
BlockSource, BlockchainTreePendingStateProvider, CanonChainTracker, CanonStateNotifications,
CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader, DatabaseProviderFactory,
EvmEnvProvider, FullBundleStateDataProvider, HeaderProvider, ProviderError,
PruneCheckpointReader, ReceiptProvider, ReceiptProviderIdExt, StageCheckpointReader,
StateProviderBox, StateProviderFactory, StaticFileProviderFactory, TransactionVariant,
TransactionsProvider, TreeViewer, WithdrawalsProvider,
};
use reth_db::{
database::Database,
Expand Down Expand Up @@ -638,7 +638,7 @@ where

fn pending_with_provider(
&self,
bundle_state_data: Box<dyn BundleStateDataProvider>,
bundle_state_data: Box<dyn FullBundleStateDataProvider>,
) -> ProviderResult<StateProviderBox> {
let canonical_fork = bundle_state_data.canonical_fork();
trace!(target: "providers::blockchain", ?canonical_fork, "Returning post state provider");
Expand Down Expand Up @@ -871,7 +871,7 @@ where
fn find_pending_state_provider(
&self,
block_hash: BlockHash,
) -> Option<Box<dyn BundleStateDataProvider>> {
) -> Option<Box<dyn FullBundleStateDataProvider>> {
self.tree.find_pending_state_provider(block_hash)
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/storage/provider/src/test_utils/mock.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::{
traits::{BlockSource, ReceiptProvider},
AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt,
BundleStateDataProvider, ChainSpecProvider, ChangeSetReader, EvmEnvProvider, HeaderProvider,
ReceiptProviderIdExt, StateProvider, StateProviderBox, StateProviderFactory, StateRootProvider,
TransactionVariant, TransactionsProvider, WithdrawalsProvider,
ChainSpecProvider, ChangeSetReader, EvmEnvProvider, FullBundleStateDataProvider,
HeaderProvider, ReceiptProviderIdExt, StateProvider, StateProviderBox, StateProviderFactory,
StateRootProvider, TransactionVariant, TransactionsProvider, WithdrawalsProvider,
};
use parking_lot::Mutex;
use reth_db::models::{AccountBeforeTx, StoredBlockBodyIndices};
Expand Down Expand Up @@ -660,7 +660,7 @@ impl StateProviderFactory for MockEthProvider {

fn pending_with_provider<'a>(
&'a self,
_bundle_state_data: Box<dyn BundleStateDataProvider + 'a>,
_bundle_state_data: Box<dyn FullBundleStateDataProvider + 'a>,
) -> ProviderResult<StateProviderBox> {
Ok(Box::new(self.clone()))
}
Expand Down
2 changes: 1 addition & 1 deletion crates/storage/provider/src/test_utils/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ impl StateProviderFactory for NoopProvider {

fn pending_with_provider<'a>(
&'a self,
_bundle_state_data: Box<dyn crate::BundleStateDataProvider + 'a>,
_bundle_state_data: Box<dyn crate::FullBundleStateDataProvider + 'a>,
) -> ProviderResult<StateProviderBox> {
Ok(Box::new(*self))
}
Expand Down
5 changes: 3 additions & 2 deletions crates/storage/provider/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ pub use receipts::{ReceiptProvider, ReceiptProviderIdExt};

mod state;
pub use state::{
BlockchainTreePendingStateProvider, BundleStateDataProvider, StateProvider, StateProviderBox,
StateProviderFactory, StateWriter,
BlockchainTreePendingStateProvider, BundleStateDataProvider, BundleStateForkProvider,
FullBundleStateDataProvider, StateProvider, StateProviderBox, StateProviderFactory,
StateWriter,
};

mod trie;
Expand Down
34 changes: 26 additions & 8 deletions crates/storage/provider/src/traits/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ pub trait StateProviderFactory: BlockIdReader + Send + Sync {
/// Used to inspect or execute transaction on the pending state.
fn pending_with_provider(
&self,
bundle_state_data: Box<dyn BundleStateDataProvider>,
bundle_state_data: Box<dyn FullBundleStateDataProvider>,
) -> ProviderResult<StateProviderBox>;
}

Expand All @@ -201,7 +201,7 @@ pub trait BlockchainTreePendingStateProvider: Send + Sync {
fn pending_state_provider(
&self,
block_hash: BlockHash,
) -> ProviderResult<Box<dyn BundleStateDataProvider>> {
) -> ProviderResult<Box<dyn FullBundleStateDataProvider>> {
self.find_pending_state_provider(block_hash)
.ok_or(ProviderError::StateForHashNotFound(block_hash))
}
Expand All @@ -210,28 +210,46 @@ pub trait BlockchainTreePendingStateProvider: Send + Sync {
fn find_pending_state_provider(
&self,
block_hash: BlockHash,
) -> Option<Box<dyn BundleStateDataProvider>>;
) -> Option<Box<dyn FullBundleStateDataProvider>>;
}

/// Post state data needs for execution on it.
/// This trait is used to create a state provider over pending state.
/// Post state data needed for execution on it.
///
/// Pending state contains:
/// State contains:
/// * [`BundleStateWithReceipts`] contains all changed of accounts and storage of pending chain
/// * block hashes of pending chain and canonical blocks.
/// * canonical fork, the block on what pending chain was forked from.
#[auto_impl(&, Box)]
pub trait BundleStateDataProvider: Send + Sync {
/// Return post state
fn state(&self) -> &BundleStateWithReceipts;
/// Return block hash by block number of pending or canonical chain.
fn block_hash(&self, block_number: BlockNumber) -> Option<BlockHash>;
/// return canonical fork, the block on what post state was forked from.
}

/// Fork data needed for execution on it.
///
/// It contains a canonical fork, the block on what pending chain was forked from.
#[auto_impl(&, Box)]
pub trait BundleStateForkProvider {
/// Return canonical fork, the block on what post state was forked from.
///
/// Needed to create state provider.
fn canonical_fork(&self) -> BlockNumHash;
}

/// Full post state data needed for execution on it.
/// This trait is used to create a state provider over pending state.
///
/// This trait is a combination of [`BundleStateDataProvider`] and [`BundleStateForkProvider`].
///
/// Pending state contains:
/// * [`BundleStateWithReceipts`] contains all changed of accounts and storage of pending chain
/// * block hashes of pending chain and canonical blocks.
/// * canonical fork, the block on what pending chain was forked from.
pub trait FullBundleStateDataProvider: BundleStateDataProvider + BundleStateForkProvider {}

impl<T> FullBundleStateDataProvider for T where T: BundleStateDataProvider + BundleStateForkProvider {}

/// A helper trait for [BundleStateWithReceipts] to write state and receipts to storage.
pub trait StateWriter {
/// Write the data and receipts to the database or static files if `static_file_producer` is
Expand Down
Loading