mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
chore: add find_block_by_hash and more docs (#2405)
This commit is contained in:
@ -11,7 +11,7 @@
|
||||
/// Various provider traits.
|
||||
mod traits;
|
||||
pub use traits::{
|
||||
AccountProvider, BlockExecutor, BlockHashProvider, BlockIdProvider, BlockProvider,
|
||||
AccountProvider, BlockExecutor, BlockHashProvider, BlockIdProvider, BlockProvider, BlockSource,
|
||||
BlockchainTreePendingStateProvider, CanonStateNotification, CanonStateNotificationSender,
|
||||
CanonStateNotifications, CanonStateSubscriptions, EvmEnvProvider, ExecutorFactory,
|
||||
HeaderProvider, PostStateDataProvider, ReceiptProvider, StateProvider, StateProviderBox,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
providers::state::{historical::HistoricalStateProvider, latest::LatestStateProvider},
|
||||
traits::ReceiptProvider,
|
||||
traits::{BlockSource, ReceiptProvider},
|
||||
BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider, HeaderProvider,
|
||||
ProviderError, StateProviderBox, TransactionsProvider, WithdrawalsProvider,
|
||||
};
|
||||
@ -158,6 +158,14 @@ impl<DB: Database> BlockIdProvider for ShareableDatabase<DB> {
|
||||
}
|
||||
|
||||
impl<DB: Database> BlockProvider for ShareableDatabase<DB> {
|
||||
fn find_block_by_hash(&self, hash: H256, source: BlockSource) -> Result<Option<Block>> {
|
||||
if source.is_database() {
|
||||
self.block(hash.into())
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn block(&self, id: BlockId) -> Result<Option<Block>> {
|
||||
if let Some(number) = self.block_number_for_id(id)? {
|
||||
if let Some(header) = self.header_by_number(number)? {
|
||||
|
||||
@ -27,6 +27,7 @@ use std::{
|
||||
mod database;
|
||||
mod post_state_provider;
|
||||
mod state;
|
||||
use crate::traits::BlockSource;
|
||||
pub use database::*;
|
||||
pub use post_state_provider::PostStateProvider;
|
||||
|
||||
@ -140,6 +141,25 @@ where
|
||||
DB: Database,
|
||||
Tree: BlockchainTreeViewer + Send + Sync,
|
||||
{
|
||||
fn find_block_by_hash(&self, hash: H256, source: BlockSource) -> Result<Option<Block>> {
|
||||
let block = match source {
|
||||
BlockSource::Any => {
|
||||
// check pending source first
|
||||
// Note: it's fine to return the unsealed block because the caller already has the
|
||||
// hash
|
||||
let mut block = self.tree.block_by_hash(hash).map(|block| block.unseal());
|
||||
if block.is_none() {
|
||||
block = self.database.block_by_hash(hash)?;
|
||||
}
|
||||
block
|
||||
}
|
||||
BlockSource::Pending => self.tree.block_by_hash(hash).map(|block| block.unseal()),
|
||||
BlockSource::Database => self.database.block_by_hash(hash)?,
|
||||
};
|
||||
|
||||
Ok(block)
|
||||
}
|
||||
|
||||
fn block(&self, id: BlockId) -> Result<Option<Block>> {
|
||||
self.database.block(id)
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
use crate::{
|
||||
traits::ReceiptProvider, AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider,
|
||||
EvmEnvProvider, HeaderProvider, PostState, PostStateDataProvider, StateProvider,
|
||||
StateProviderBox, StateProviderFactory, StateRootProvider, TransactionsProvider,
|
||||
traits::{BlockSource, ReceiptProvider},
|
||||
AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider,
|
||||
HeaderProvider, PostState, PostStateDataProvider, StateProvider, StateProviderBox,
|
||||
StateProviderFactory, StateRootProvider, TransactionsProvider,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use reth_interfaces::Result;
|
||||
@ -254,6 +255,10 @@ impl BlockIdProvider for MockEthProvider {
|
||||
}
|
||||
|
||||
impl BlockProvider for MockEthProvider {
|
||||
fn find_block_by_hash(&self, hash: H256, _source: BlockSource) -> Result<Option<Block>> {
|
||||
self.block(hash.into())
|
||||
}
|
||||
|
||||
fn block(&self, id: BlockId) -> Result<Option<Block>> {
|
||||
let lock = self.blocks.lock();
|
||||
match id {
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
use crate::{
|
||||
traits::ReceiptProvider, AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider,
|
||||
EvmEnvProvider, HeaderProvider, PostState, StateProvider, StateProviderBox,
|
||||
StateProviderFactory, StateRootProvider, TransactionsProvider,
|
||||
traits::{BlockSource, ReceiptProvider},
|
||||
AccountProvider, BlockHashProvider, BlockIdProvider, BlockProvider, EvmEnvProvider,
|
||||
HeaderProvider, PostState, StateProvider, StateProviderBox, StateProviderFactory,
|
||||
StateRootProvider, TransactionsProvider,
|
||||
};
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{
|
||||
@ -43,6 +44,10 @@ impl BlockIdProvider for NoopProvider {
|
||||
}
|
||||
|
||||
impl BlockProvider for NoopProvider {
|
||||
fn find_block_by_hash(&self, hash: H256, _source: BlockSource) -> Result<Option<Block>> {
|
||||
self.block(hash.into())
|
||||
}
|
||||
|
||||
fn block(&self, _id: BlockId) -> Result<Option<Block>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@ -2,32 +2,79 @@ use crate::{BlockIdProvider, HeaderProvider, ReceiptProvider, TransactionsProvid
|
||||
use reth_interfaces::Result;
|
||||
use reth_primitives::{Block, BlockId, BlockNumberOrTag, Header, H256};
|
||||
|
||||
/// A helper enum that represents the origin of the requested block.
|
||||
///
|
||||
/// This helper type's sole purpose is to give the caller more control over from where blocks can be
|
||||
/// fetched.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
|
||||
pub enum BlockSource {
|
||||
/// Check all available sources.
|
||||
///
|
||||
/// Note: it's expected that looking up pending blocks is faster than looking up blocks in the
|
||||
/// database so this prioritizes Pending > Database.
|
||||
#[default]
|
||||
Any,
|
||||
/// The block was fetched from the pending block source, the blockchain tree that buffers
|
||||
/// blocks that are not yet finalized.
|
||||
Pending,
|
||||
/// The block was fetched from the database.
|
||||
Database,
|
||||
}
|
||||
|
||||
impl BlockSource {
|
||||
/// Returns `true` if the block source is `Pending` or `Any`.
|
||||
pub fn is_pending(&self) -> bool {
|
||||
matches!(self, BlockSource::Pending | BlockSource::Any)
|
||||
}
|
||||
|
||||
/// Returns `true` if the block source is `Database` or `Any`.
|
||||
pub fn is_database(&self) -> bool {
|
||||
matches!(self, BlockSource::Database | BlockSource::Any)
|
||||
}
|
||||
}
|
||||
|
||||
/// Api trait for fetching `Block` related data.
|
||||
///
|
||||
/// If not requested otherwise, implementers of this trait should prioritize fetching blocks from
|
||||
/// the database.
|
||||
#[auto_impl::auto_impl(&, Arc)]
|
||||
pub trait BlockProvider:
|
||||
BlockIdProvider + HeaderProvider + TransactionsProvider + ReceiptProvider + Send + Sync
|
||||
{
|
||||
/// Returns the block.
|
||||
/// Tries to find in the given block source.
|
||||
///
|
||||
/// Note: this only operates on the hash because the number might be ambiguous.
|
||||
///
|
||||
/// Returns `None` if block is not found.
|
||||
fn find_block_by_hash(&self, hash: H256, source: BlockSource) -> Result<Option<Block>>;
|
||||
|
||||
/// Returns the block with given id from the database.
|
||||
///
|
||||
/// Returns `None` if block is not found.
|
||||
fn block(&self, id: BlockId) -> Result<Option<Block>>;
|
||||
|
||||
/// Returns the ommers/uncle headers of the given block.
|
||||
/// Returns the ommers/uncle headers of the given block from the database.
|
||||
///
|
||||
/// Returns `None` if block is not found.
|
||||
fn ommers(&self, id: BlockId) -> Result<Option<Vec<Header>>>;
|
||||
|
||||
/// Returns the block. Returns `None` if block is not found.
|
||||
/// Returns the block with matching hash from the database.
|
||||
///
|
||||
/// Returns `None` if block is not found.
|
||||
fn block_by_hash(&self, hash: H256) -> Result<Option<Block>> {
|
||||
self.block(hash.into())
|
||||
}
|
||||
|
||||
/// Returns the block. Returns `None` if block is not found.
|
||||
/// Returns the block with matching tag from the database
|
||||
///
|
||||
/// Returns `None` if block is not found.
|
||||
fn block_by_number_or_tag(&self, num: BlockNumberOrTag) -> Result<Option<Block>> {
|
||||
self.block(num.into())
|
||||
}
|
||||
|
||||
/// Returns the block. Returns `None` if block is not found.
|
||||
/// Returns the block with matching number from database.
|
||||
///
|
||||
/// Returns `None` if block is not found.
|
||||
fn block_by_number(&self, num: u64) -> Result<Option<Block>> {
|
||||
self.block(num.into())
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ mod account;
|
||||
pub use account::AccountProvider;
|
||||
|
||||
mod block;
|
||||
pub use block::BlockProvider;
|
||||
pub use block::{BlockProvider, BlockSource};
|
||||
|
||||
mod block_hash;
|
||||
pub use block_hash::BlockHashProvider;
|
||||
|
||||
Reference in New Issue
Block a user