mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-30 01:28:21 -05:00
feat: add safe and finalized tags to StateProviderFactory (#2654)
This commit is contained in:
@@ -95,9 +95,4 @@ pub enum ProviderError {
|
||||
/// Unable to compute state root on top of historical block
|
||||
#[error("Unable to compute state root on top of historical block")]
|
||||
StateRootNotAvailableForHistoricalBlock,
|
||||
|
||||
#[error("Safe tag currently unsupported")]
|
||||
SafeTagUnsupported,
|
||||
#[error("Finalized tag currently unsupported")]
|
||||
FinalizedTagUnsupported,
|
||||
}
|
||||
|
||||
@@ -137,12 +137,12 @@ where
|
||||
DB: Database,
|
||||
Tree: BlockchainTreeViewer + Send + Sync,
|
||||
{
|
||||
fn safe_block_num(&self) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
Ok(self.chain_info.get_safe_num_hash().map(|num_hash| num_hash.number))
|
||||
fn safe_block_num_hash(&self) -> Result<Option<reth_primitives::BlockNumHash>> {
|
||||
Ok(self.chain_info.get_safe_num_hash())
|
||||
}
|
||||
|
||||
fn finalized_block_num(&self) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
Ok(self.chain_info.get_finalized_num_hash().map(|num_hash| num_hash.number))
|
||||
fn finalized_block_num_hash(&self) -> Result<Option<reth_primitives::BlockNumHash>> {
|
||||
Ok(self.chain_info.get_finalized_num_hash())
|
||||
}
|
||||
|
||||
fn pending_block_num_hash(&self) -> Result<Option<reth_primitives::BlockNumHash>> {
|
||||
|
||||
@@ -263,7 +263,7 @@ impl BlockNumProvider for MockEthProvider {
|
||||
}
|
||||
|
||||
impl BlockIdProvider for MockEthProvider {
|
||||
fn safe_block_num(&self) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
fn safe_block_num_hash(&self) -> Result<Option<reth_primitives::BlockNumHash>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ impl BlockIdProvider for MockEthProvider {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn finalized_block_num(&self) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
fn finalized_block_num_hash(&self) -> Result<Option<reth_primitives::BlockNumHash>> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,11 +76,11 @@ impl BlockIdProvider for NoopProvider {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn safe_block_num(&self) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
fn safe_block_num_hash(&self) -> Result<Option<reth_primitives::BlockNumHash>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn finalized_block_num(&self) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
fn finalized_block_num_hash(&self) -> Result<Option<reth_primitives::BlockNumHash>> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +104,29 @@ pub trait BlockIdProvider: BlockNumProvider + Send + Sync {
|
||||
/// Get the current pending block number and hash.
|
||||
fn pending_block_num_hash(&self) -> Result<Option<reth_primitives::BlockNumHash>>;
|
||||
|
||||
/// Get the current safe block number and hash.
|
||||
fn safe_block_num_hash(&self) -> Result<Option<reth_primitives::BlockNumHash>>;
|
||||
|
||||
/// Get the current finalized block number and hash.
|
||||
fn finalized_block_num_hash(&self) -> Result<Option<reth_primitives::BlockNumHash>>;
|
||||
|
||||
/// Get the safe block number.
|
||||
fn safe_block_num(&self) -> Result<Option<reth_primitives::BlockNumber>>;
|
||||
fn safe_block_num(&self) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
self.safe_block_num_hash().map(|res_opt| res_opt.map(|num_hash| num_hash.number))
|
||||
}
|
||||
|
||||
/// Get the finalized block number.
|
||||
fn finalized_block_num(&self) -> Result<Option<reth_primitives::BlockNumber>>;
|
||||
fn finalized_block_num(&self) -> Result<Option<reth_primitives::BlockNumber>> {
|
||||
self.finalized_block_num_hash().map(|res_opt| res_opt.map(|num_hash| num_hash.number))
|
||||
}
|
||||
|
||||
/// Get the safe block hash.
|
||||
fn safe_block_hash(&self) -> Result<Option<H256>> {
|
||||
self.safe_block_num_hash().map(|res_opt| res_opt.map(|num_hash| num_hash.hash))
|
||||
}
|
||||
|
||||
/// Get the finalized block hash.
|
||||
fn finalized_block_hash(&self) -> Result<Option<H256>> {
|
||||
self.finalized_block_num_hash().map(|res_opt| res_opt.map(|num_hash| num_hash.hash))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::AccountProvider;
|
||||
use crate::{post_state::PostState, BlockHashProvider};
|
||||
use crate::{post_state::PostState, BlockHashProvider, BlockIdProvider};
|
||||
use auto_impl::auto_impl;
|
||||
use reth_interfaces::{provider::ProviderError, Result};
|
||||
use reth_primitives::{
|
||||
@@ -96,7 +96,7 @@ pub trait StateProvider:
|
||||
/// 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.
|
||||
pub trait StateProviderFactory: Send + Sync {
|
||||
pub trait StateProviderFactory: BlockIdProvider + Send + Sync {
|
||||
/// Storage provider for latest block.
|
||||
fn latest(&self) -> Result<StateProviderBox<'_>>;
|
||||
|
||||
@@ -108,15 +108,31 @@ pub trait StateProviderFactory: Send + Sync {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a [StateProvider] indexed by the given block number or tag
|
||||
/// Returns a [StateProvider] indexed by the given block number or tag.
|
||||
fn history_by_block_number_or_tag(
|
||||
&self,
|
||||
number_or_tag: BlockNumberOrTag,
|
||||
) -> Result<StateProviderBox<'_>> {
|
||||
match number_or_tag {
|
||||
BlockNumberOrTag::Latest => self.latest(),
|
||||
BlockNumberOrTag::Finalized => Err(ProviderError::FinalizedTagUnsupported.into()),
|
||||
BlockNumberOrTag::Safe => Err(ProviderError::SafeTagUnsupported.into()),
|
||||
BlockNumberOrTag::Finalized => {
|
||||
// we can only get the finalized state by hash, not by num
|
||||
let hash = match self.finalized_block_hash()? {
|
||||
Some(hash) => hash,
|
||||
None => return Err(ProviderError::HeaderNotFound.into()),
|
||||
};
|
||||
|
||||
self.state_by_block_hash(hash)
|
||||
}
|
||||
BlockNumberOrTag::Safe => {
|
||||
// we can only get the safe state by hash, not by num
|
||||
let hash = match self.safe_block_hash()? {
|
||||
Some(hash) => hash,
|
||||
None => return Err(ProviderError::HeaderNotFound.into()),
|
||||
};
|
||||
|
||||
self.state_by_block_hash(hash)
|
||||
}
|
||||
BlockNumberOrTag::Earliest => self.history_by_block_number(0),
|
||||
BlockNumberOrTag::Pending => self.pending(),
|
||||
BlockNumberOrTag::Number(num) => self.history_by_block_number(num),
|
||||
|
||||
Reference in New Issue
Block a user