mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add StateProviderFactor::state_by_block_hash (#2390)
This commit is contained in:
@ -5,7 +5,6 @@ use reth_db::database::Database;
|
||||
use reth_interfaces::{
|
||||
blockchain_tree::{BlockStatus, BlockchainTreeEngine, BlockchainTreeViewer},
|
||||
consensus::Consensus,
|
||||
provider::ProviderError,
|
||||
Error,
|
||||
};
|
||||
use reth_primitives::{BlockHash, BlockNumHash, BlockNumber, SealedBlock, SealedBlockWithSenders};
|
||||
@ -101,17 +100,12 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTreeViewer
|
||||
impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTreePendingStateProvider
|
||||
for ShareableBlockchainTree<DB, C, EF>
|
||||
{
|
||||
fn pending_state_provider(
|
||||
fn find_pending_state_provider(
|
||||
&self,
|
||||
block_hash: BlockHash,
|
||||
) -> Result<Box<dyn PostStateDataProvider>, Error> {
|
||||
let post_state = self
|
||||
.tree
|
||||
.read()
|
||||
.post_state_data(block_hash)
|
||||
.ok_or(ProviderError::UnknownBlockHash(block_hash))
|
||||
.map(Box::new)?;
|
||||
Ok(Box::new(post_state))
|
||||
) -> Option<Box<dyn PostStateDataProvider>> {
|
||||
let provider = self.tree.read().post_state_data(block_hash)?;
|
||||
Some(Box::new(provider))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -270,6 +270,16 @@ where
|
||||
self.database.history_by_block_hash(block_hash)
|
||||
}
|
||||
|
||||
fn state_by_block_hash(&self, block: BlockHash) -> Result<StateProviderBox<'_>> {
|
||||
// check tree first
|
||||
if let Some(pending) = self.tree.find_pending_state_provider(block) {
|
||||
return self.pending_with_provider(pending)
|
||||
}
|
||||
|
||||
// not found in tree, check database
|
||||
self.history_by_block_hash(block)
|
||||
}
|
||||
|
||||
/// Storage provider for pending state.
|
||||
fn pending(&self) -> Result<StateProviderBox<'_>> {
|
||||
if let Some(block) = self.tree.pending_block() {
|
||||
@ -351,11 +361,11 @@ where
|
||||
DB: Send + Sync,
|
||||
Tree: BlockchainTreePendingStateProvider,
|
||||
{
|
||||
fn pending_state_provider(
|
||||
fn find_pending_state_provider(
|
||||
&self,
|
||||
block_hash: BlockHash,
|
||||
) -> Result<Box<dyn PostStateDataProvider>> {
|
||||
self.tree.pending_state_provider(block_hash)
|
||||
) -> Option<Box<dyn PostStateDataProvider>> {
|
||||
self.tree.find_pending_state_provider(block_hash)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -353,6 +353,10 @@ impl StateProviderFactory for MockEthProvider {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn state_by_block_hash(&self, _block: BlockHash) -> Result<StateProviderBox<'_>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn pending(&self) -> Result<StateProviderBox<'_>> {
|
||||
todo!()
|
||||
}
|
||||
@ -378,6 +382,10 @@ impl StateProviderFactory for Arc<MockEthProvider> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn state_by_block_hash(&self, _block: BlockHash) -> Result<StateProviderBox<'_>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn pending(&self) -> Result<StateProviderBox<'_>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@ -203,6 +203,10 @@ impl StateProviderFactory for NoopProvider {
|
||||
Ok(Box::new(*self))
|
||||
}
|
||||
|
||||
fn state_by_block_hash(&self, _block: BlockHash) -> Result<StateProviderBox<'_>> {
|
||||
Ok(Box::new(*self))
|
||||
}
|
||||
|
||||
fn pending(&self) -> Result<StateProviderBox<'_>> {
|
||||
Ok(Box::new(*self))
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use super::AccountProvider;
|
||||
use crate::{post_state::PostState, BlockHashProvider};
|
||||
use auto_impl::auto_impl;
|
||||
use reth_interfaces::Result;
|
||||
use reth_interfaces::{provider::ProviderError, Result};
|
||||
use reth_primitives::{
|
||||
Address, BlockHash, BlockId, BlockNumHash, BlockNumber, BlockNumberOrTag, Bytecode, Bytes,
|
||||
StorageKey, StorageValue, H256, KECCAK_EMPTY, U256,
|
||||
@ -74,7 +74,18 @@ pub trait StateProvider:
|
||||
}
|
||||
|
||||
/// Light wrapper that returns `StateProvider` implementations that correspond to the given
|
||||
/// `BlockNumber` or the latest state.
|
||||
/// `BlockNumber`, the latest state, or the pending state.
|
||||
///
|
||||
/// This type differentiates states into `historical`, `latest` and `pending`, where the `latest`
|
||||
/// block determines what is historical or pending: `[historical..latest..pending]`.
|
||||
///
|
||||
/// The `latest` state represents the state after the most recent block has been committed to the
|
||||
/// database, `historical` states are states that have been committed to the database before the
|
||||
/// `latest` state, and `pending` states are states that have not yet been committed to the
|
||||
/// database which may or may not become the `latest` state, depending on consensus.
|
||||
///
|
||||
/// Note: the `pending` block is considered the block that extends the canonical chain but one and
|
||||
/// has the `latest` block as its parent.
|
||||
pub trait StateProviderFactory: Send + Sync {
|
||||
/// Storage provider for latest block.
|
||||
fn latest(&self) -> Result<StateProviderBox<'_>>;
|
||||
@ -106,13 +117,26 @@ pub trait StateProviderFactory: Send + Sync {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a [StateProvider] indexed by the given block number.
|
||||
/// Returns a historical [StateProvider] indexed by the given historic block number.
|
||||
///
|
||||
///
|
||||
/// Note: this only looks at historical blocks, not pending blocks.
|
||||
fn history_by_block_number(&self, block: BlockNumber) -> Result<StateProviderBox<'_>>;
|
||||
|
||||
/// Returns a [StateProvider] indexed by the given block hash.
|
||||
/// Returns a historical [StateProvider] indexed by the given block hash.
|
||||
///
|
||||
/// Note: this only looks at historical blocks, not pending blocks.
|
||||
fn history_by_block_hash(&self, block: BlockHash) -> Result<StateProviderBox<'_>>;
|
||||
|
||||
/// Returns _any_[StateProvider] with matching block hash.
|
||||
///
|
||||
/// This will return a [StateProvider] for either a historical or pending block.
|
||||
fn state_by_block_hash(&self, block: BlockHash) -> Result<StateProviderBox<'_>>;
|
||||
|
||||
/// Storage provider for pending state.
|
||||
///
|
||||
/// Represents the state at the block that extends the canonical chain by one.
|
||||
/// If there's no `pending` block, then this is equal to [StateProviderFactory::latest]
|
||||
fn pending(&self) -> Result<StateProviderBox<'_>>;
|
||||
|
||||
/// Return a [StateProvider] that contains post state data provider.
|
||||
@ -133,7 +157,17 @@ pub trait BlockchainTreePendingStateProvider: Send + Sync {
|
||||
fn pending_state_provider(
|
||||
&self,
|
||||
block_hash: BlockHash,
|
||||
) -> Result<Box<dyn PostStateDataProvider>>;
|
||||
) -> Result<Box<dyn PostStateDataProvider>> {
|
||||
Ok(self
|
||||
.find_pending_state_provider(block_hash)
|
||||
.ok_or(ProviderError::UnknownBlockHash(block_hash))?)
|
||||
}
|
||||
|
||||
/// Returns state provider if a matching block exists.
|
||||
fn find_pending_state_provider(
|
||||
&self,
|
||||
block_hash: BlockHash,
|
||||
) -> Option<Box<dyn PostStateDataProvider>>;
|
||||
}
|
||||
|
||||
/// Post state data needs for execution on it.
|
||||
|
||||
Reference in New Issue
Block a user