diff --git a/crates/interfaces/src/provider.rs b/crates/interfaces/src/provider.rs
index d690f7b4d4..3caf0840be 100644
--- a/crates/interfaces/src/provider.rs
+++ b/crates/interfaces/src/provider.rs
@@ -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,
}
diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs
index 239fb46a3f..924d4b0674 100644
--- a/crates/storage/provider/src/providers/mod.rs
+++ b/crates/storage/provider/src/providers/mod.rs
@@ -137,12 +137,12 @@ where
DB: Database,
Tree: BlockchainTreeViewer + Send + Sync,
{
- fn safe_block_num(&self) -> Result> {
- Ok(self.chain_info.get_safe_num_hash().map(|num_hash| num_hash.number))
+ fn safe_block_num_hash(&self) -> Result > {
+ Ok(self.chain_info.get_safe_num_hash())
}
- fn finalized_block_num(&self) -> Result > {
- Ok(self.chain_info.get_finalized_num_hash().map(|num_hash| num_hash.number))
+ fn finalized_block_num_hash(&self) -> Result > {
+ Ok(self.chain_info.get_finalized_num_hash())
}
fn pending_block_num_hash(&self) -> Result > {
diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs
index e98556e60d..3b2172e011 100644
--- a/crates/storage/provider/src/test_utils/mock.rs
+++ b/crates/storage/provider/src/test_utils/mock.rs
@@ -263,7 +263,7 @@ impl BlockNumProvider for MockEthProvider {
}
impl BlockIdProvider for MockEthProvider {
- fn safe_block_num(&self) -> Result > {
+ fn safe_block_num_hash(&self) -> Result > {
Ok(None)
}
@@ -271,7 +271,7 @@ impl BlockIdProvider for MockEthProvider {
Ok(None)
}
- fn finalized_block_num(&self) -> Result > {
+ fn finalized_block_num_hash(&self) -> Result > {
Ok(None)
}
}
diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs
index 9d614ba2ae..d3bf077cac 100644
--- a/crates/storage/provider/src/test_utils/noop.rs
+++ b/crates/storage/provider/src/test_utils/noop.rs
@@ -76,11 +76,11 @@ impl BlockIdProvider for NoopProvider {
Ok(None)
}
- fn safe_block_num(&self) -> Result > {
+ fn safe_block_num_hash(&self) -> Result > {
Ok(None)
}
- fn finalized_block_num(&self) -> Result > {
+ fn finalized_block_num_hash(&self) -> Result > {
Ok(None)
}
}
diff --git a/crates/storage/provider/src/traits/block_id.rs b/crates/storage/provider/src/traits/block_id.rs
index 9376ddc688..5ef0e38487 100644
--- a/crates/storage/provider/src/traits/block_id.rs
+++ b/crates/storage/provider/src/traits/block_id.rs
@@ -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 >;
+ /// Get the current safe block number and hash.
+ fn safe_block_num_hash(&self) -> Result >;
+
+ /// Get the current finalized block number and hash.
+ fn finalized_block_num_hash(&self) -> Result >;
+
/// Get the safe block number.
- fn safe_block_num(&self) -> Result >;
+ fn safe_block_num(&self) -> Result > {
+ 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 >;
+ fn finalized_block_num(&self) -> Result > {
+ 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 > {
+ 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 > {
+ self.finalized_block_num_hash().map(|res_opt| res_opt.map(|num_hash| num_hash.hash))
+ }
}
diff --git a/crates/storage/provider/src/traits/state.rs b/crates/storage/provider/src/traits/state.rs
index 00ffa2029b..e5ed7e5fcc 100644
--- a/crates/storage/provider/src/traits/state.rs
+++ b/crates/storage/provider/src/traits/state.rs
@@ -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>;
@@ -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> {
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),