mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: get rid of lifetime GATs (#5478)
This commit is contained in:
@ -50,7 +50,7 @@ impl<DB: Database> ProviderFactory<DB> {
|
||||
/// Returns a provider with a created `DbTx` inside, which allows fetching data from the
|
||||
/// database using different types of providers. Example: [`HeaderProvider`]
|
||||
/// [`BlockHashReader`]. This may fail if the inner read database transaction fails to open.
|
||||
pub fn provider(&self) -> ProviderResult<DatabaseProviderRO<'_, DB>> {
|
||||
pub fn provider(&self) -> ProviderResult<DatabaseProviderRO<DB>> {
|
||||
let mut provider = DatabaseProvider::new(self.db.tx()?, self.chain_spec.clone());
|
||||
|
||||
if let Some(snapshot_provider) = &self.snapshot_provider {
|
||||
@ -64,7 +64,7 @@ impl<DB: Database> ProviderFactory<DB> {
|
||||
/// data from the database using different types of providers. Example: [`HeaderProvider`]
|
||||
/// [`BlockHashReader`]. This may fail if the inner read/write database transaction fails to
|
||||
/// open.
|
||||
pub fn provider_rw(&self) -> ProviderResult<DatabaseProviderRW<'_, DB>> {
|
||||
pub fn provider_rw(&self) -> ProviderResult<DatabaseProviderRW<DB>> {
|
||||
let mut provider = DatabaseProvider::new_rw(self.db.tx_mut()?, self.chain_spec.clone());
|
||||
|
||||
if let Some(snapshot_provider) = &self.snapshot_provider {
|
||||
@ -123,7 +123,7 @@ impl<DB: Clone> Clone for ProviderFactory<DB> {
|
||||
|
||||
impl<DB: Database> ProviderFactory<DB> {
|
||||
/// Storage provider for latest block
|
||||
pub fn latest(&self) -> ProviderResult<StateProviderBox<'_>> {
|
||||
pub fn latest(&self) -> ProviderResult<StateProviderBox> {
|
||||
trace!(target: "providers::db", "Returning latest state provider");
|
||||
Ok(Box::new(LatestStateProvider::new(self.db.tx()?)))
|
||||
}
|
||||
@ -132,7 +132,7 @@ impl<DB: Database> ProviderFactory<DB> {
|
||||
fn state_provider_by_block_number(
|
||||
&self,
|
||||
mut block_number: BlockNumber,
|
||||
) -> ProviderResult<StateProviderBox<'_>> {
|
||||
) -> ProviderResult<StateProviderBox> {
|
||||
let provider = self.provider()?;
|
||||
|
||||
if block_number == provider.best_block_number().unwrap_or_default() &&
|
||||
@ -175,17 +175,14 @@ impl<DB: Database> ProviderFactory<DB> {
|
||||
pub fn history_by_block_number(
|
||||
&self,
|
||||
block_number: BlockNumber,
|
||||
) -> ProviderResult<StateProviderBox<'_>> {
|
||||
) -> ProviderResult<StateProviderBox> {
|
||||
let state_provider = self.state_provider_by_block_number(block_number)?;
|
||||
trace!(target: "providers::db", ?block_number, "Returning historical state provider for block number");
|
||||
Ok(state_provider)
|
||||
}
|
||||
|
||||
/// Storage provider for state at that given block hash
|
||||
pub fn history_by_block_hash(
|
||||
&self,
|
||||
block_hash: BlockHash,
|
||||
) -> ProviderResult<StateProviderBox<'_>> {
|
||||
pub fn history_by_block_hash(&self, block_hash: BlockHash) -> ProviderResult<StateProviderBox> {
|
||||
let block_number = self
|
||||
.provider()?
|
||||
.block_number(block_hash)?
|
||||
|
||||
@ -14,7 +14,7 @@ use itertools::{izip, Itertools};
|
||||
use reth_db::{
|
||||
common::KeyValue,
|
||||
cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO},
|
||||
database::{Database, DatabaseGAT},
|
||||
database::Database,
|
||||
models::{
|
||||
sharded_key, storage_sharded_key::StorageShardedKey, AccountBeforeTx, BlockNumberAddress,
|
||||
ShardedKey, StoredBlockBodyIndices, StoredBlockOmmers, StoredBlockWithdrawals,
|
||||
@ -55,39 +55,37 @@ use std::{
|
||||
use tracing::{debug, warn};
|
||||
|
||||
/// A [`DatabaseProvider`] that holds a read-only database transaction.
|
||||
pub type DatabaseProviderRO<'this, DB> = DatabaseProvider<<DB as DatabaseGAT<'this>>::TX>;
|
||||
pub type DatabaseProviderRO<DB> = DatabaseProvider<<DB as Database>::TX>;
|
||||
|
||||
/// A [`DatabaseProvider`] that holds a read-write database transaction.
|
||||
///
|
||||
/// Ideally this would be an alias type. However, there's some weird compiler error (<https://github.com/rust-lang/rust/issues/102211>), that forces us to wrap this in a struct instead.
|
||||
/// Once that issue is solved, we can probably revert back to being an alias type.
|
||||
#[derive(Debug)]
|
||||
pub struct DatabaseProviderRW<'this, DB: Database>(
|
||||
pub DatabaseProvider<<DB as DatabaseGAT<'this>>::TXMut>,
|
||||
);
|
||||
pub struct DatabaseProviderRW<DB: Database>(pub DatabaseProvider<<DB as Database>::TXMut>);
|
||||
|
||||
impl<'this, DB: Database> Deref for DatabaseProviderRW<'this, DB> {
|
||||
type Target = DatabaseProvider<<DB as DatabaseGAT<'this>>::TXMut>;
|
||||
impl<DB: Database> Deref for DatabaseProviderRW<DB> {
|
||||
type Target = DatabaseProvider<<DB as Database>::TXMut>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB: Database> DerefMut for DatabaseProviderRW<'_, DB> {
|
||||
impl<DB: Database> DerefMut for DatabaseProviderRW<DB> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'this, DB: Database> DatabaseProviderRW<'this, DB> {
|
||||
impl<DB: Database> DatabaseProviderRW<DB> {
|
||||
/// Commit database transaction
|
||||
pub fn commit(self) -> ProviderResult<bool> {
|
||||
self.0.commit()
|
||||
}
|
||||
|
||||
/// Consume `DbTx` or `DbTxMut`.
|
||||
pub fn into_tx(self) -> <DB as DatabaseGAT<'this>>::TXMut {
|
||||
pub fn into_tx(self) -> <DB as Database>::TXMut {
|
||||
self.0.into_tx()
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,7 +508,7 @@ where
|
||||
Tree: BlockchainTreePendingStateProvider + BlockchainTreeViewer,
|
||||
{
|
||||
/// Storage provider for latest block
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox> {
|
||||
trace!(target: "providers::blockchain", "Getting latest block state provider");
|
||||
self.database.latest()
|
||||
}
|
||||
@ -516,18 +516,18 @@ where
|
||||
fn history_by_block_number(
|
||||
&self,
|
||||
block_number: BlockNumber,
|
||||
) -> ProviderResult<StateProviderBox<'_>> {
|
||||
) -> ProviderResult<StateProviderBox> {
|
||||
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<StateProviderBox<'_>> {
|
||||
fn history_by_block_hash(&self, block_hash: BlockHash) -> ProviderResult<StateProviderBox> {
|
||||
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<StateProviderBox<'_>> {
|
||||
fn state_by_block_hash(&self, block: BlockHash) -> ProviderResult<StateProviderBox> {
|
||||
trace!(target: "providers::blockchain", ?block, "Getting state by block hash");
|
||||
let mut state = self.history_by_block_hash(block);
|
||||
|
||||
@ -546,7 +546,7 @@ where
|
||||
///
|
||||
/// If there's no pending block available then the latest state provider is returned:
|
||||
/// [Self::latest]
|
||||
fn pending(&self) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn pending(&self) -> ProviderResult<StateProviderBox> {
|
||||
trace!(target: "providers::blockchain", "Getting provider for pending state");
|
||||
|
||||
if let Some(block) = self.tree.pending_block_num_hash() {
|
||||
@ -559,10 +559,7 @@ where
|
||||
self.latest()
|
||||
}
|
||||
|
||||
fn pending_state_by_hash(
|
||||
&self,
|
||||
block_hash: B256,
|
||||
) -> ProviderResult<Option<StateProviderBox<'_>>> {
|
||||
fn pending_state_by_hash(&self, block_hash: B256) -> ProviderResult<Option<StateProviderBox>> {
|
||||
if let Some(state) = self.tree.find_pending_state_provider(block_hash) {
|
||||
return Ok(Some(self.pending_with_provider(state)?))
|
||||
}
|
||||
@ -572,7 +569,7 @@ where
|
||||
fn pending_with_provider(
|
||||
&self,
|
||||
bundle_state_data: Box<dyn BundleStateDataProvider>,
|
||||
) -> ProviderResult<StateProviderBox<'_>> {
|
||||
) -> ProviderResult<StateProviderBox> {
|
||||
let canonical_fork = bundle_state_data.canonical_fork();
|
||||
trace!(target: "providers::blockchain", ?canonical_fork, "Returning post state provider");
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ use reth_primitives::{
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Assert genesis block
|
||||
pub fn assert_genesis_block<DB: Database>(provider: &DatabaseProviderRW<'_, DB>, g: SealedBlock) {
|
||||
pub fn assert_genesis_block<DB: Database>(provider: &DatabaseProviderRW<DB>, g: SealedBlock) {
|
||||
let n = g.number;
|
||||
let h = B256::ZERO;
|
||||
let tx = provider;
|
||||
|
||||
@ -581,73 +581,67 @@ impl EvmEnvProvider for MockEthProvider {
|
||||
}
|
||||
|
||||
impl StateProviderFactory for MockEthProvider {
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn history_by_block_number(&self, _block: BlockNumber) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn history_by_block_number(&self, _block: BlockNumber) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn history_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn history_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn state_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn state_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn pending(&self) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn pending(&self) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn pending_state_by_hash(
|
||||
&self,
|
||||
_block_hash: B256,
|
||||
) -> ProviderResult<Option<StateProviderBox<'_>>> {
|
||||
fn pending_state_by_hash(&self, _block_hash: B256) -> ProviderResult<Option<StateProviderBox>> {
|
||||
Ok(Some(Box::new(self.clone())))
|
||||
}
|
||||
|
||||
fn pending_with_provider<'a>(
|
||||
&'a self,
|
||||
_bundle_state_data: Box<dyn BundleStateDataProvider + 'a>,
|
||||
) -> ProviderResult<StateProviderBox<'a>> {
|
||||
) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
impl StateProviderFactory for Arc<MockEthProvider> {
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn history_by_block_number(&self, _block: BlockNumber) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn history_by_block_number(&self, _block: BlockNumber) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn history_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn history_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn state_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn state_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn pending(&self) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn pending(&self) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
|
||||
fn pending_state_by_hash(
|
||||
&self,
|
||||
_block_hash: B256,
|
||||
) -> ProviderResult<Option<StateProviderBox<'_>>> {
|
||||
fn pending_state_by_hash(&self, _block_hash: B256) -> ProviderResult<Option<StateProviderBox>> {
|
||||
Ok(Some(Box::new(self.clone())))
|
||||
}
|
||||
|
||||
fn pending_with_provider<'a>(
|
||||
&'a self,
|
||||
_bundle_state_data: Box<dyn BundleStateDataProvider + 'a>,
|
||||
) -> ProviderResult<StateProviderBox<'a>> {
|
||||
) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,37 +347,34 @@ impl EvmEnvProvider for NoopProvider {
|
||||
}
|
||||
|
||||
impl StateProviderFactory for NoopProvider {
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(*self))
|
||||
}
|
||||
|
||||
fn history_by_block_number(&self, _block: BlockNumber) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn history_by_block_number(&self, _block: BlockNumber) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(*self))
|
||||
}
|
||||
|
||||
fn history_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn history_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(*self))
|
||||
}
|
||||
|
||||
fn state_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn state_by_block_hash(&self, _block: BlockHash) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(*self))
|
||||
}
|
||||
|
||||
fn pending(&self) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn pending(&self) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(*self))
|
||||
}
|
||||
|
||||
fn pending_state_by_hash(
|
||||
&self,
|
||||
_block_hash: B256,
|
||||
) -> ProviderResult<Option<StateProviderBox<'_>>> {
|
||||
fn pending_state_by_hash(&self, _block_hash: B256) -> ProviderResult<Option<StateProviderBox>> {
|
||||
Ok(Some(Box::new(*self)))
|
||||
}
|
||||
|
||||
fn pending_with_provider<'a>(
|
||||
&'a self,
|
||||
_bundle_state_data: Box<dyn crate::BundleStateDataProvider + 'a>,
|
||||
) -> ProviderResult<StateProviderBox<'a>> {
|
||||
) -> ProviderResult<StateProviderBox> {
|
||||
Ok(Box::new(*self))
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ use reth_primitives::{
|
||||
use reth_trie::updates::TrieUpdates;
|
||||
|
||||
/// Type alias of boxed [StateProvider].
|
||||
pub type StateProviderBox<'a> = Box<dyn StateProvider + 'a>;
|
||||
pub type StateProviderBox = Box<dyn StateProvider>;
|
||||
|
||||
/// An abstraction for a type that provides state data.
|
||||
#[auto_impl(&, Arc, Box)]
|
||||
@ -100,13 +100,13 @@ pub trait StateProvider: BlockHashReader + AccountReader + StateRootProvider + S
|
||||
/// to be used, since block `n` was executed on its parent block's state.
|
||||
pub trait StateProviderFactory: BlockIdReader + Send + Sync {
|
||||
/// Storage provider for latest block.
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox<'_>>;
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox>;
|
||||
|
||||
/// Returns a [StateProvider] indexed by the given [BlockId].
|
||||
///
|
||||
/// Note: if a number or hash is provided this will __only__ look at historical(canonical)
|
||||
/// state.
|
||||
fn state_by_block_id(&self, block_id: BlockId) -> ProviderResult<StateProviderBox<'_>> {
|
||||
fn state_by_block_id(&self, block_id: BlockId) -> ProviderResult<StateProviderBox> {
|
||||
match block_id {
|
||||
BlockId::Number(block_number) => self.state_by_block_number_or_tag(block_number),
|
||||
BlockId::Hash(block_hash) => self.history_by_block_hash(block_hash.into()),
|
||||
@ -119,7 +119,7 @@ pub trait StateProviderFactory: BlockIdReader + Send + Sync {
|
||||
fn state_by_block_number_or_tag(
|
||||
&self,
|
||||
number_or_tag: BlockNumberOrTag,
|
||||
) -> ProviderResult<StateProviderBox<'_>> {
|
||||
) -> ProviderResult<StateProviderBox> {
|
||||
match number_or_tag {
|
||||
BlockNumberOrTag::Latest => self.latest(),
|
||||
BlockNumberOrTag::Finalized => {
|
||||
@ -153,40 +153,37 @@ pub trait StateProviderFactory: BlockIdReader + Send + Sync {
|
||||
///
|
||||
///
|
||||
/// Note: this only looks at historical blocks, not pending blocks.
|
||||
fn history_by_block_number(&self, block: BlockNumber) -> ProviderResult<StateProviderBox<'_>>;
|
||||
fn history_by_block_number(&self, block: BlockNumber) -> ProviderResult<StateProviderBox>;
|
||||
|
||||
/// 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) -> ProviderResult<StateProviderBox<'_>>;
|
||||
fn history_by_block_hash(&self, block: BlockHash) -> ProviderResult<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) -> ProviderResult<StateProviderBox<'_>>;
|
||||
fn state_by_block_hash(&self, block: BlockHash) -> ProviderResult<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) -> ProviderResult<StateProviderBox<'_>>;
|
||||
fn pending(&self) -> ProviderResult<StateProviderBox>;
|
||||
|
||||
/// Storage provider for pending state for the given block hash.
|
||||
///
|
||||
/// Represents the state at the block that extends the canonical chain.
|
||||
///
|
||||
/// If the block couldn't be found, returns `None`.
|
||||
fn pending_state_by_hash(
|
||||
&self,
|
||||
block_hash: B256,
|
||||
) -> ProviderResult<Option<StateProviderBox<'_>>>;
|
||||
fn pending_state_by_hash(&self, block_hash: B256) -> ProviderResult<Option<StateProviderBox>>;
|
||||
|
||||
/// Return a [StateProvider] 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<dyn BundleStateDataProvider>,
|
||||
) -> ProviderResult<StateProviderBox<'_>>;
|
||||
) -> ProviderResult<StateProviderBox>;
|
||||
}
|
||||
|
||||
/// Blockchain trait provider that gives access to the blockchain state that is not yet committed
|
||||
|
||||
Reference in New Issue
Block a user