From 2f94aeebedcb3c3faf38f199d272121eca216d31 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 8 Jan 2025 13:35:07 +0100 Subject: [PATCH] chore!: rm legacy blockchain provider (#13725) --- Cargo.lock | 1 - crates/storage/provider/Cargo.toml | 3 +- crates/storage/provider/src/providers/mod.rs | 892 +----------------- crates/storage/provider/src/traits/mod.rs | 3 - .../provider/src/traits/tree_viewer.rs | 22 - 5 files changed, 5 insertions(+), 916 deletions(-) delete mode 100644 crates/storage/provider/src/traits/tree_viewer.rs diff --git a/Cargo.lock b/Cargo.lock index c5dff17cf..22f123e02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8666,7 +8666,6 @@ dependencies = [ "parking_lot", "rand 0.8.5", "rayon", - "reth-blockchain-tree-api", "reth-chain-state", "reth-chainspec", "reth-codecs", diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index 84808ed7c..0955821b4 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -14,7 +14,6 @@ workspace = true [dependencies] # reth reth-chainspec.workspace = true -reth-blockchain-tree-api.workspace = true reth-execution-types.workspace = true reth-primitives = { workspace = true, features = ["reth-codec", "secp256k1"] } reth-primitives-traits = { workspace = true, features = ["reth-codec"] } @@ -43,7 +42,7 @@ alloy-consensus.workspace = true revm.workspace = true # optimism -reth-optimism-primitives = { workspace = true, optional = true } +reth-optimism-primitives = { workspace = true, features = ["reth-codec"], optional = true } # async tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread"] } diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index f1c799cd2..6ff53e4af 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -1,51 +1,9 @@ -use core::fmt; +//! Contains the main provider types and traits for interacting with the blockchain's storage. -use crate::{ - AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt, - BlockSource, BlockchainTreePendingStateProvider, CanonStateNotifications, - CanonStateSubscriptions, ChainSpecProvider, ChainStateBlockReader, ChangeSetReader, - DatabaseProviderFactory, FullExecutionDataProvider, HeaderProvider, NodePrimitivesProvider, - ProviderError, PruneCheckpointReader, ReceiptProvider, ReceiptProviderIdExt, - StageCheckpointReader, StateProviderBox, StateProviderFactory, StaticFileProviderFactory, - TransactionVariant, TransactionsProvider, TreeViewer, WithdrawalsProvider, -}; -use alloy_consensus::{transaction::TransactionMeta, Header}; -use alloy_eips::{ - eip4895::Withdrawals, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, -}; -use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256}; -use alloy_rpc_types_engine::ForkchoiceState; -use reth_blockchain_tree_api::{ - error::{CanonicalError, InsertBlockError}, - BlockValidationKind, BlockchainTreeEngine, BlockchainTreeViewer, CanonicalOutcome, - InsertPayloadOk, -}; -use reth_chain_state::{ChainInfoTracker, ForkChoiceNotifications, ForkChoiceSubscriptions}; -use reth_chainspec::{ChainInfo, EthereumHardforks}; +use reth_chainspec::EthereumHardforks; use reth_db::table::Value; -use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; -use reth_node_types::{ - BlockTy, FullNodePrimitives, HeaderTy, NodeTypes, NodeTypesWithDB, NodeTypesWithEngine, - ReceiptTy, TxTy, -}; -use reth_primitives::{ - Account, BlockWithSenders, EthPrimitives, Receipt, SealedBlock, SealedBlockFor, - SealedBlockWithSenders, SealedHeader, -}; -use reth_prune_types::{PruneCheckpoint, PruneSegment}; -use reth_stages_types::{StageCheckpoint, StageId}; -use reth_storage_api::{ - BlockBodyIndicesProvider, CanonChainTracker, OmmersProvider, StateCommitmentProvider, -}; -use reth_storage_errors::provider::ProviderResult; -use std::{ - collections::BTreeMap, - ops::{RangeBounds, RangeInclusive}, - sync::Arc, - time::Instant, -}; - -use tracing::trace; +use reth_node_types::{FullNodePrimitives, NodeTypes, NodeTypesWithDB, NodeTypesWithEngine}; +use reth_primitives::EthPrimitives; mod database; pub use database::*; @@ -123,845 +81,3 @@ impl EngineNodeTypes for T where T: ProviderNodeTypes + NodeTypesWithEngine { /// tree. pub trait TreeNodeTypes: ProviderNodeTypes + NodeTypesForTree {} impl TreeNodeTypes for T where T: ProviderNodeTypes + NodeTypesForTree {} - -/// The main type for interacting with the blockchain. -/// -/// This type serves as the main entry point for interacting with the blockchain and provides data -/// from database storage and from the blockchain tree (pending state etc.) It is a simple wrapper -/// type that holds an instance of the database and the blockchain tree. -pub struct BlockchainProvider { - /// Provider type used to access the database. - database: ProviderFactory, - /// The blockchain tree instance. - tree: Arc>, - /// Tracks the chain info wrt forkchoice updates - chain_info: ChainInfoTracker, -} - -impl Clone for BlockchainProvider { - fn clone(&self) -> Self { - Self { - database: self.database.clone(), - tree: self.tree.clone(), - chain_info: self.chain_info.clone(), - } - } -} - -impl BlockchainProvider { - /// Sets the treeviewer for the provider. - #[doc(hidden)] - pub fn with_tree(mut self, tree: Arc>) -> Self { - self.tree = tree; - self - } -} - -impl BlockchainProvider { - /// Create new provider instance that wraps the database and the blockchain tree, using the - /// provided latest header to initialize the chain info tracker, alongside the finalized header - /// if it exists. - pub fn with_blocks( - database: ProviderFactory, - tree: Arc>, - latest: SealedHeader, - finalized: Option, - safe: Option, - ) -> Self { - Self { database, tree, chain_info: ChainInfoTracker::new(latest, finalized, safe) } - } - - /// Create a new provider using only the database and the tree, fetching the latest header from - /// the database to initialize the provider. - pub fn new( - database: ProviderFactory, - tree: Arc>, - ) -> ProviderResult { - let provider = database.provider()?; - let best = provider.chain_info()?; - let latest_header = provider - .header_by_number(best.best_number)? - .ok_or_else(|| ProviderError::HeaderNotFound(best.best_number.into()))?; - - let finalized_header = provider - .last_finalized_block_number()? - .map(|num| provider.sealed_header(num)) - .transpose()? - .flatten(); - - let safe_header = provider - .last_safe_block_number()? - .map(|num| provider.sealed_header(num)) - .transpose()? - .flatten(); - - Ok(Self::with_blocks( - database, - tree, - SealedHeader::new(latest_header, best.best_hash), - finalized_header, - safe_header, - )) - } - - /// Ensures that the given block number is canonical (synced) - /// - /// This is a helper for guarding the [`HistoricalStateProvider`] against block numbers that are - /// out of range and would lead to invalid results, mainly during initial sync. - /// - /// Verifying the `block_number` would be expensive since we need to lookup sync table - /// Instead, we ensure that the `block_number` is within the range of the - /// [`Self::best_block_number`] which is updated when a block is synced. - #[inline] - fn ensure_canonical_block(&self, block_number: BlockNumber) -> ProviderResult<()> { - let latest = self.best_block_number()?; - if block_number > latest { - Err(ProviderError::HeaderNotFound(block_number.into())) - } else { - Ok(()) - } - } -} - -impl BlockchainProvider -where - Self: StateProviderFactory, - N: NodeTypesWithDB, -{ - /// Return a [`StateProviderBox`] that contains bundle state data provider. - /// Used to inspect or execute transaction on the pending state. - fn pending_with_provider( - &self, - bundle_state_data: Box, - ) -> ProviderResult { - let canonical_fork = bundle_state_data.canonical_fork(); - trace!(target: "providers::blockchain", ?canonical_fork, "Returning post state provider"); - - let state_provider = self.history_by_block_hash(canonical_fork.hash)?; - let bundle_state_provider = BundleStateProvider::new(state_provider, bundle_state_data); - Ok(Box::new(bundle_state_provider)) - } -} - -impl NodePrimitivesProvider for BlockchainProvider { - type Primitives = N::Primitives; -} - -impl DatabaseProviderFactory for BlockchainProvider { - type DB = N::DB; - type Provider = as DatabaseProviderFactory>::Provider; - type ProviderRW = as DatabaseProviderFactory>::ProviderRW; - - fn database_provider_ro(&self) -> ProviderResult { - self.database.database_provider_ro() - } - - fn database_provider_rw(&self) -> ProviderResult { - self.database.database_provider_rw() - } -} - -impl StateCommitmentProvider for BlockchainProvider { - type StateCommitment = N::StateCommitment; -} - -impl StaticFileProviderFactory for BlockchainProvider { - fn static_file_provider(&self) -> StaticFileProvider { - self.database.static_file_provider() - } -} - -impl HeaderProvider for BlockchainProvider { - type Header = Header; - - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { - self.database.header(block_hash) - } - - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { - self.database.header_by_number(num) - } - - fn header_td(&self, hash: &BlockHash) -> ProviderResult> { - self.database.header_td(hash) - } - - fn header_td_by_number(&self, number: BlockNumber) -> ProviderResult> { - self.database.header_td_by_number(number) - } - - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { - self.database.headers_range(range) - } - - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { - self.database.sealed_header(number) - } - - fn sealed_headers_range( - &self, - range: impl RangeBounds, - ) -> ProviderResult> { - self.database.sealed_headers_range(range) - } - - fn sealed_headers_while( - &self, - range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { - self.database.sealed_headers_while(range, predicate) - } -} - -impl BlockHashReader for BlockchainProvider { - fn block_hash(&self, number: u64) -> ProviderResult> { - self.database.block_hash(number) - } - - fn canonical_hashes_range( - &self, - start: BlockNumber, - end: BlockNumber, - ) -> ProviderResult> { - self.database.canonical_hashes_range(start, end) - } -} - -impl BlockNumReader for BlockchainProvider { - fn chain_info(&self) -> ProviderResult { - Ok(self.chain_info.chain_info()) - } - - fn best_block_number(&self) -> ProviderResult { - Ok(self.chain_info.get_canonical_block_number()) - } - - fn last_block_number(&self) -> ProviderResult { - self.database.last_block_number() - } - - fn block_number(&self, hash: B256) -> ProviderResult> { - self.database.block_number(hash) - } -} - -impl BlockIdReader for BlockchainProvider { - fn pending_block_num_hash(&self) -> ProviderResult> { - Ok(self.tree.pending_block_num_hash()) - } - - fn safe_block_num_hash(&self) -> ProviderResult> { - Ok(self.chain_info.get_safe_num_hash()) - } - - fn finalized_block_num_hash(&self) -> ProviderResult> { - Ok(self.chain_info.get_finalized_num_hash()) - } -} - -impl BlockReader for BlockchainProvider { - type Block = BlockTy; - - fn find_block_by_hash( - &self, - hash: B256, - source: BlockSource, - ) -> ProviderResult> { - let block = match source { - BlockSource::Any => { - // check database first - let mut block = self.database.block_by_hash(hash)?; - if block.is_none() { - // Note: it's fine to return the unsealed block because the caller already has - // the hash - block = self.tree.block_by_hash(hash).map(|block| block.unseal()); - } - block - } - BlockSource::Pending => self.tree.block_by_hash(hash).map(|block| block.unseal()), - BlockSource::Canonical => self.database.block_by_hash(hash)?, - }; - - Ok(block) - } - - fn block(&self, id: BlockHashOrNumber) -> ProviderResult> { - match id { - BlockHashOrNumber::Hash(hash) => self.find_block_by_hash(hash, BlockSource::Any), - BlockHashOrNumber::Number(num) => self.database.block_by_number(num), - } - } - - fn pending_block(&self) -> ProviderResult>> { - Ok(self.tree.pending_block()) - } - - fn pending_block_with_senders( - &self, - ) -> ProviderResult>> { - Ok(self.tree.pending_block_with_senders()) - } - - fn pending_block_and_receipts( - &self, - ) -> ProviderResult, Vec)>> { - Ok(self.tree.pending_block_and_receipts()) - } - - /// Returns the block with senders with matching number or hash from database. - /// - /// **NOTE: If [`TransactionVariant::NoHash`] is provided then the transactions have invalid - /// hashes, since they would need to be calculated on the spot, and we want fast querying.** - /// - /// Returns `None` if block is not found. - fn block_with_senders( - &self, - id: BlockHashOrNumber, - transaction_kind: TransactionVariant, - ) -> ProviderResult>> { - self.database.block_with_senders(id, transaction_kind) - } - - fn sealed_block_with_senders( - &self, - id: BlockHashOrNumber, - transaction_kind: TransactionVariant, - ) -> ProviderResult>> { - self.database.sealed_block_with_senders(id, transaction_kind) - } - - fn block_range(&self, range: RangeInclusive) -> ProviderResult> { - self.database.block_range(range) - } - - fn block_with_senders_range( - &self, - range: RangeInclusive, - ) -> ProviderResult>> { - self.database.block_with_senders_range(range) - } - - fn sealed_block_with_senders_range( - &self, - range: RangeInclusive, - ) -> ProviderResult>> { - self.database.sealed_block_with_senders_range(range) - } -} - -impl TransactionsProvider for BlockchainProvider { - type Transaction = TxTy; - - fn transaction_id(&self, tx_hash: TxHash) -> ProviderResult> { - self.database.transaction_id(tx_hash) - } - - fn transaction_by_id(&self, id: TxNumber) -> ProviderResult> { - self.database.transaction_by_id(id) - } - - fn transaction_by_id_unhashed( - &self, - id: TxNumber, - ) -> ProviderResult> { - self.database.transaction_by_id_unhashed(id) - } - - fn transaction_by_hash(&self, hash: TxHash) -> ProviderResult> { - self.database.transaction_by_hash(hash) - } - - fn transaction_by_hash_with_meta( - &self, - tx_hash: TxHash, - ) -> ProviderResult> { - self.database.transaction_by_hash_with_meta(tx_hash) - } - - fn transaction_block(&self, id: TxNumber) -> ProviderResult> { - self.database.transaction_block(id) - } - - fn transactions_by_block( - &self, - id: BlockHashOrNumber, - ) -> ProviderResult>> { - self.database.transactions_by_block(id) - } - - fn transactions_by_block_range( - &self, - range: impl RangeBounds, - ) -> ProviderResult>> { - self.database.transactions_by_block_range(range) - } - - fn transactions_by_tx_range( - &self, - range: impl RangeBounds, - ) -> ProviderResult> { - self.database.transactions_by_tx_range(range) - } - - fn senders_by_tx_range( - &self, - range: impl RangeBounds, - ) -> ProviderResult> { - self.database.senders_by_tx_range(range) - } - - fn transaction_sender(&self, id: TxNumber) -> ProviderResult> { - self.database.transaction_sender(id) - } -} - -impl ReceiptProvider for BlockchainProvider { - type Receipt = ReceiptTy; - - fn receipt(&self, id: TxNumber) -> ProviderResult> { - self.database.receipt(id) - } - - fn receipt_by_hash(&self, hash: TxHash) -> ProviderResult> { - self.database.receipt_by_hash(hash) - } - - fn receipts_by_block( - &self, - block: BlockHashOrNumber, - ) -> ProviderResult>> { - self.database.receipts_by_block(block) - } - - fn receipts_by_tx_range( - &self, - range: impl RangeBounds, - ) -> ProviderResult> { - self.database.receipts_by_tx_range(range) - } -} - -impl ReceiptProviderIdExt for BlockchainProvider { - fn receipts_by_block_id(&self, block: BlockId) -> ProviderResult>> { - match block { - BlockId::Hash(rpc_block_hash) => { - let mut receipts = self.receipts_by_block(rpc_block_hash.block_hash.into())?; - if receipts.is_none() && !rpc_block_hash.require_canonical.unwrap_or(false) { - receipts = self.tree.receipts_by_block_hash(rpc_block_hash.block_hash); - } - Ok(receipts) - } - BlockId::Number(num_tag) => match num_tag { - BlockNumberOrTag::Pending => Ok(self.tree.pending_receipts()), - _ => { - if let Some(num) = self.convert_block_number(num_tag)? { - self.receipts_by_block(num.into()) - } else { - Ok(None) - } - } - }, - } - } -} - -impl WithdrawalsProvider for BlockchainProvider { - fn withdrawals_by_block( - &self, - id: BlockHashOrNumber, - timestamp: u64, - ) -> ProviderResult> { - self.database.withdrawals_by_block(id, timestamp) - } -} - -impl OmmersProvider for BlockchainProvider { - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { - self.database.ommers(id) - } -} - -impl BlockBodyIndicesProvider for BlockchainProvider { - fn block_body_indices( - &self, - number: BlockNumber, - ) -> ProviderResult> { - self.database.block_body_indices(number) - } -} - -impl StageCheckpointReader for BlockchainProvider { - fn get_stage_checkpoint(&self, id: StageId) -> ProviderResult> { - self.database.provider()?.get_stage_checkpoint(id) - } - - fn get_stage_checkpoint_progress(&self, id: StageId) -> ProviderResult>> { - self.database.provider()?.get_stage_checkpoint_progress(id) - } - - fn get_all_checkpoints(&self) -> ProviderResult> { - self.database.provider()?.get_all_checkpoints() - } -} - -impl PruneCheckpointReader for BlockchainProvider { - fn get_prune_checkpoint( - &self, - segment: PruneSegment, - ) -> ProviderResult> { - self.database.provider()?.get_prune_checkpoint(segment) - } - - fn get_prune_checkpoints(&self) -> ProviderResult> { - self.database.provider()?.get_prune_checkpoints() - } -} - -impl ChainSpecProvider for BlockchainProvider { - type ChainSpec = N::ChainSpec; - - fn chain_spec(&self) -> Arc { - self.database.chain_spec() - } -} - -impl StateProviderFactory for BlockchainProvider { - /// Storage provider for latest block - fn latest(&self) -> ProviderResult { - trace!(target: "providers::blockchain", "Getting latest block state provider"); - self.database.latest() - } - - /// Returns a [`StateProviderBox`] indexed by the given block number or tag. - /// - /// Note: if a number is provided this will only look at historical(canonical) state. - fn state_by_block_number_or_tag( - &self, - number_or_tag: BlockNumberOrTag, - ) -> ProviderResult { - match number_or_tag { - BlockNumberOrTag::Latest => self.latest(), - BlockNumberOrTag::Finalized => { - // we can only get the finalized state by hash, not by num - let hash = - self.finalized_block_hash()?.ok_or(ProviderError::FinalizedBlockNotFound)?; - - // only look at historical state - self.history_by_block_hash(hash) - } - BlockNumberOrTag::Safe => { - // we can only get the safe state by hash, not by num - let hash = self.safe_block_hash()?.ok_or(ProviderError::SafeBlockNotFound)?; - - self.history_by_block_hash(hash) - } - BlockNumberOrTag::Earliest => self.history_by_block_number(0), - BlockNumberOrTag::Pending => self.pending(), - BlockNumberOrTag::Number(num) => { - // Note: The `BlockchainProvider` could also lookup the tree for the given block number, if for example the block number is `latest + 1`, however this should only support canonical state: - self.history_by_block_number(num) - } - } - } - - fn history_by_block_number( - &self, - block_number: BlockNumber, - ) -> ProviderResult { - trace!(target: "providers::blockchain", ?block_number, "Getting history by block number"); - self.ensure_canonical_block(block_number)?; - self.database.history_by_block_number(block_number) - } - - fn history_by_block_hash(&self, block_hash: BlockHash) -> ProviderResult { - trace!(target: "providers::blockchain", ?block_hash, "Getting history by block hash"); - self.database.history_by_block_hash(block_hash) - } - - fn state_by_block_hash(&self, block: BlockHash) -> ProviderResult { - trace!(target: "providers::blockchain", ?block, "Getting state by block hash"); - let mut state = self.history_by_block_hash(block); - - // we failed to get the state by hash, from disk, hash block be the pending block - if state.is_err() { - if let Ok(Some(pending)) = self.pending_state_by_hash(block) { - // we found pending block by hash - state = Ok(pending) - } - } - - state - } - - /// Returns the state provider for pending state. - /// - /// If there's no pending block available then the latest state provider is returned: - /// [`Self::latest`] - fn pending(&self) -> ProviderResult { - trace!(target: "providers::blockchain", "Getting provider for pending state"); - - if let Some(block) = self.tree.pending_block_num_hash() { - if let Ok(pending) = self.tree.pending_state_provider(block.hash) { - return self.pending_with_provider(pending) - } - } - - // fallback to latest state if the pending block is not available - self.latest() - } - - fn pending_state_by_hash(&self, block_hash: B256) -> ProviderResult> { - if let Some(state) = self.tree.find_pending_state_provider(block_hash) { - return Ok(Some(self.pending_with_provider(state)?)) - } - Ok(None) - } -} - -impl BlockchainTreeEngine for BlockchainProvider { - fn buffer_block(&self, block: SealedBlockWithSenders) -> Result<(), InsertBlockError> { - self.tree.buffer_block(block) - } - - fn insert_block( - &self, - block: SealedBlockWithSenders, - validation_kind: BlockValidationKind, - ) -> Result { - self.tree.insert_block(block, validation_kind) - } - - fn finalize_block(&self, finalized_block: BlockNumber) -> ProviderResult<()> { - self.tree.finalize_block(finalized_block) - } - - fn connect_buffered_blocks_to_canonical_hashes_and_finalize( - &self, - last_finalized_block: BlockNumber, - ) -> Result<(), CanonicalError> { - self.tree.connect_buffered_blocks_to_canonical_hashes_and_finalize(last_finalized_block) - } - - fn update_block_hashes_and_clear_buffered( - &self, - ) -> Result, CanonicalError> { - self.tree.update_block_hashes_and_clear_buffered() - } - - fn connect_buffered_blocks_to_canonical_hashes(&self) -> Result<(), CanonicalError> { - self.tree.connect_buffered_blocks_to_canonical_hashes() - } - - fn make_canonical(&self, block_hash: BlockHash) -> Result { - self.tree.make_canonical(block_hash) - } -} - -impl BlockchainTreeViewer for BlockchainProvider { - fn header_by_hash(&self, hash: BlockHash) -> Option { - self.tree.header_by_hash(hash) - } - - fn block_by_hash(&self, block_hash: BlockHash) -> Option { - self.tree.block_by_hash(block_hash) - } - - fn block_with_senders_by_hash(&self, block_hash: BlockHash) -> Option { - self.tree.block_with_senders_by_hash(block_hash) - } - - fn buffered_header_by_hash(&self, block_hash: BlockHash) -> Option { - self.tree.buffered_header_by_hash(block_hash) - } - - fn is_canonical(&self, hash: BlockHash) -> Result { - self.tree.is_canonical(hash) - } - - fn lowest_buffered_ancestor(&self, hash: BlockHash) -> Option { - self.tree.lowest_buffered_ancestor(hash) - } - - fn canonical_tip(&self) -> BlockNumHash { - self.tree.canonical_tip() - } - - fn pending_block_num_hash(&self) -> Option { - self.tree.pending_block_num_hash() - } - - fn pending_block_and_receipts(&self) -> Option<(SealedBlock, Vec)> { - self.tree.pending_block_and_receipts() - } - - fn receipts_by_block_hash(&self, block_hash: BlockHash) -> Option> { - self.tree.receipts_by_block_hash(block_hash) - } -} - -impl CanonChainTracker for BlockchainProvider { - type Header = HeaderTy; - - fn on_forkchoice_update_received(&self, _update: &ForkchoiceState) { - // update timestamp - self.chain_info.on_forkchoice_update_received(); - } - - fn last_received_update_timestamp(&self) -> Option { - self.chain_info.last_forkchoice_update_received_at() - } - - fn on_transition_configuration_exchanged(&self) { - self.chain_info.on_transition_configuration_exchanged(); - } - - fn last_exchanged_transition_configuration_timestamp(&self) -> Option { - self.chain_info.last_transition_configuration_exchanged_at() - } - - fn set_canonical_head(&self, header: SealedHeader) { - self.chain_info.set_canonical_head(header); - } - - fn set_safe(&self, header: SealedHeader) { - self.chain_info.set_safe(header); - } - - fn set_finalized(&self, header: SealedHeader) { - self.chain_info.set_finalized(header); - } -} - -impl BlockReaderIdExt for BlockchainProvider { - fn block_by_id(&self, id: BlockId) -> ProviderResult> { - match id { - BlockId::Number(num) => self.block_by_number_or_tag(num), - BlockId::Hash(hash) => { - // TODO: should we only apply this for the RPCs that are listed in EIP-1898? - // so not at the provider level? - // if we decide to do this at a higher level, then we can make this an automatic - // trait impl - if Some(true) == hash.require_canonical { - // check the database, canonical blocks are only stored in the database - self.find_block_by_hash(hash.block_hash, BlockSource::Canonical) - } else { - BlockReader::block_by_hash(self, hash.block_hash) - } - } - } - } - - fn header_by_number_or_tag( - &self, - id: BlockNumberOrTag, - ) -> ProviderResult> { - Ok(match id { - BlockNumberOrTag::Latest => Some(self.chain_info.get_canonical_head().unseal()), - BlockNumberOrTag::Finalized => { - self.chain_info.get_finalized_header().map(|h| h.unseal()) - } - BlockNumberOrTag::Safe => self.chain_info.get_safe_header().map(|h| h.unseal()), - BlockNumberOrTag::Earliest => self.header_by_number(0)?, - BlockNumberOrTag::Pending => self.tree.pending_header().map(|h| h.unseal()), - BlockNumberOrTag::Number(num) => self.header_by_number(num)?, - }) - } - - fn sealed_header_by_number_or_tag( - &self, - id: BlockNumberOrTag, - ) -> ProviderResult>> { - match id { - BlockNumberOrTag::Latest => Ok(Some(self.chain_info.get_canonical_head())), - BlockNumberOrTag::Finalized => Ok(self.chain_info.get_finalized_header()), - BlockNumberOrTag::Safe => Ok(self.chain_info.get_safe_header()), - BlockNumberOrTag::Earliest => self - .header_by_number(0)? - .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))), - BlockNumberOrTag::Pending => Ok(self.tree.pending_header()), - BlockNumberOrTag::Number(num) => self - .header_by_number(num)? - .map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h)))), - } - } - - fn sealed_header_by_id( - &self, - id: BlockId, - ) -> ProviderResult>> { - Ok(match id { - BlockId::Number(num) => self.sealed_header_by_number_or_tag(num)?, - BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(SealedHeader::seal), - }) - } - - fn header_by_id(&self, id: BlockId) -> ProviderResult> { - Ok(match id { - BlockId::Number(num) => self.header_by_number_or_tag(num)?, - BlockId::Hash(hash) => self.header(&hash.block_hash)?, - }) - } - - fn ommers_by_id(&self, id: BlockId) -> ProviderResult>> { - match id { - BlockId::Number(num) => self.ommers_by_number_or_tag(num), - BlockId::Hash(hash) => { - // TODO: EIP-1898 question, see above - // here it is not handled - self.ommers(BlockHashOrNumber::Hash(hash.block_hash)) - } - } - } -} - -impl BlockchainTreePendingStateProvider for BlockchainProvider { - fn find_pending_state_provider( - &self, - block_hash: BlockHash, - ) -> Option> { - self.tree.find_pending_state_provider(block_hash) - } -} - -impl CanonStateSubscriptions for BlockchainProvider { - fn subscribe_to_canonical_state(&self) -> CanonStateNotifications { - self.tree.subscribe_to_canonical_state() - } -} - -impl ForkChoiceSubscriptions for BlockchainProvider { - type Header = HeaderTy; - - fn subscribe_safe_block(&self) -> ForkChoiceNotifications { - let receiver = self.chain_info.subscribe_safe_block(); - ForkChoiceNotifications(receiver) - } - - fn subscribe_finalized_block(&self) -> ForkChoiceNotifications { - let receiver = self.chain_info.subscribe_finalized_block(); - ForkChoiceNotifications(receiver) - } -} - -impl ChangeSetReader for BlockchainProvider { - fn account_block_changeset( - &self, - block_number: BlockNumber, - ) -> ProviderResult> { - self.database.provider()?.account_block_changeset(block_number) - } -} - -impl AccountReader for BlockchainProvider { - /// Get basic account information. - fn basic_account(&self, address: &Address) -> ProviderResult> { - self.database.provider()?.basic_account(address) - } -} - -impl fmt::Debug for BlockchainProvider { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("BlockchainProvider").finish_non_exhaustive() - } -} diff --git a/crates/storage/provider/src/traits/mod.rs b/crates/storage/provider/src/traits/mod.rs index 4b3178fc6..09ba9f109 100644 --- a/crates/storage/provider/src/traits/mod.rs +++ b/crates/storage/provider/src/traits/mod.rs @@ -19,6 +19,3 @@ pub use static_file_provider::StaticFileProviderFactory; mod full; pub use full::{FullProvider, FullRpcProvider}; - -mod tree_viewer; -pub use tree_viewer::TreeViewer; diff --git a/crates/storage/provider/src/traits/tree_viewer.rs b/crates/storage/provider/src/traits/tree_viewer.rs deleted file mode 100644 index f75dbae24..000000000 --- a/crates/storage/provider/src/traits/tree_viewer.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::BlockchainTreePendingStateProvider; -use reth_blockchain_tree_api::{BlockchainTreeEngine, BlockchainTreeViewer}; -use reth_chain_state::CanonStateSubscriptions; - -/// Helper trait to combine all the traits we need for the `BlockchainProvider` -/// -/// This is a temporary solution -pub trait TreeViewer: - BlockchainTreeViewer - + BlockchainTreePendingStateProvider - + CanonStateSubscriptions - + BlockchainTreeEngine -{ -} - -impl TreeViewer for T where - T: BlockchainTreeViewer - + BlockchainTreePendingStateProvider - + CanonStateSubscriptions - + BlockchainTreeEngine -{ -}