mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: impl StateReader for BlockchainProvider2 (#10618)
This commit is contained in:
@ -4,7 +4,7 @@ use crate::{
|
|||||||
CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader, DatabaseProviderFactory,
|
CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader, DatabaseProviderFactory,
|
||||||
DatabaseProviderRO, EvmEnvProvider, FinalizedBlockReader, HeaderProvider, ProviderError,
|
DatabaseProviderRO, EvmEnvProvider, FinalizedBlockReader, HeaderProvider, ProviderError,
|
||||||
ProviderFactory, PruneCheckpointReader, ReceiptProvider, ReceiptProviderIdExt,
|
ProviderFactory, PruneCheckpointReader, ReceiptProvider, ReceiptProviderIdExt,
|
||||||
RequestsProvider, StageCheckpointReader, StateProviderBox, StateProviderFactory,
|
RequestsProvider, StageCheckpointReader, StateProviderBox, StateProviderFactory, StateReader,
|
||||||
StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider,
|
StaticFileProviderFactory, TransactionVariant, TransactionsProvider, WithdrawalsProvider,
|
||||||
};
|
};
|
||||||
use alloy_rpc_types_engine::ForkchoiceState;
|
use alloy_rpc_types_engine::ForkchoiceState;
|
||||||
@ -18,6 +18,7 @@ use reth_db_api::{
|
|||||||
models::{AccountBeforeTx, StoredBlockBodyIndices},
|
models::{AccountBeforeTx, StoredBlockBodyIndices},
|
||||||
};
|
};
|
||||||
use reth_evm::ConfigureEvmEnv;
|
use reth_evm::ConfigureEvmEnv;
|
||||||
|
use reth_execution_types::ExecutionOutcome;
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
Account, Address, Block, BlockHash, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumber,
|
Account, Address, Block, BlockHash, BlockHashOrNumber, BlockId, BlockNumHash, BlockNumber,
|
||||||
BlockNumberOrTag, BlockWithSenders, EthereumHardforks, Header, Receipt, SealedBlock,
|
BlockNumberOrTag, BlockWithSenders, EthereumHardforks, Header, Receipt, SealedBlock,
|
||||||
@ -1433,6 +1434,20 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<DB> StateReader for BlockchainProvider2<DB>
|
||||||
|
where
|
||||||
|
DB: Database + Sync + Send,
|
||||||
|
{
|
||||||
|
fn get_state(&self, block: BlockNumber) -> ProviderResult<Option<ExecutionOutcome>> {
|
||||||
|
if let Some(state) = self.canonical_in_memory_state.state_by_number(block) {
|
||||||
|
let state = state.block().execution_outcome().clone();
|
||||||
|
Ok(Some(state))
|
||||||
|
} else {
|
||||||
|
self.database.provider()?.get_state(block..=block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::{
|
use std::{
|
||||||
|
|||||||
@ -603,6 +603,7 @@ impl<DB, Spec> Clone for ProviderFactory<DB, Spec> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@ -11,8 +11,8 @@ use crate::{
|
|||||||
FinalizedBlockWriter, HashingWriter, HeaderProvider, HeaderSyncGap, HeaderSyncGapProvider,
|
FinalizedBlockWriter, HashingWriter, HeaderProvider, HeaderSyncGap, HeaderSyncGapProvider,
|
||||||
HistoricalStateProvider, HistoryWriter, LatestStateProvider, OriginalValuesKnown,
|
HistoricalStateProvider, HistoryWriter, LatestStateProvider, OriginalValuesKnown,
|
||||||
ProviderError, PruneCheckpointReader, PruneCheckpointWriter, RequestsProvider, RevertsInit,
|
ProviderError, PruneCheckpointReader, PruneCheckpointWriter, RequestsProvider, RevertsInit,
|
||||||
StageCheckpointReader, StateChangeWriter, StateProviderBox, StateWriter, StatsReader,
|
StageCheckpointReader, StateChangeWriter, StateProviderBox, StateReader, StateWriter,
|
||||||
StorageReader, StorageTrieWriter, TransactionVariant, TransactionsProvider,
|
StatsReader, StorageReader, StorageTrieWriter, TransactionVariant, TransactionsProvider,
|
||||||
TransactionsProviderExt, TrieWriter, WithdrawalsProvider,
|
TransactionsProviderExt, TrieWriter, WithdrawalsProvider,
|
||||||
};
|
};
|
||||||
use itertools::{izip, Itertools};
|
use itertools::{izip, Itertools};
|
||||||
@ -777,12 +777,14 @@ impl<TX: DbTx> DatabaseProvider<TX> {
|
|||||||
/// 1. Take the old value from the changeset
|
/// 1. Take the old value from the changeset
|
||||||
/// 2. Take the new value from the local state
|
/// 2. Take the new value from the local state
|
||||||
/// 3. Set the local state to the value in the changeset
|
/// 3. Set the local state to the value in the changeset
|
||||||
|
///
|
||||||
|
/// If the range is empty, or there are no blocks for the given range, then this returns `None`.
|
||||||
pub fn get_state(
|
pub fn get_state(
|
||||||
&self,
|
&self,
|
||||||
range: RangeInclusive<BlockNumber>,
|
range: RangeInclusive<BlockNumber>,
|
||||||
) -> ProviderResult<ExecutionOutcome> {
|
) -> ProviderResult<Option<ExecutionOutcome>> {
|
||||||
if range.is_empty() {
|
if range.is_empty() {
|
||||||
return Ok(ExecutionOutcome::default())
|
return Ok(None)
|
||||||
}
|
}
|
||||||
let start_block_number = *range.start();
|
let start_block_number = *range.start();
|
||||||
|
|
||||||
@ -790,10 +792,14 @@ impl<TX: DbTx> DatabaseProvider<TX> {
|
|||||||
let block_bodies = self.get::<tables::BlockBodyIndices>(range.clone())?;
|
let block_bodies = self.get::<tables::BlockBodyIndices>(range.clone())?;
|
||||||
|
|
||||||
// get transaction receipts
|
// get transaction receipts
|
||||||
let from_transaction_num =
|
let Some(from_transaction_num) = block_bodies.first().map(|bodies| bodies.1.first_tx_num())
|
||||||
block_bodies.first().expect("already checked if there are blocks").1.first_tx_num();
|
else {
|
||||||
let to_transaction_num =
|
return Ok(None)
|
||||||
block_bodies.last().expect("already checked if there are blocks").1.last_tx_num();
|
};
|
||||||
|
let Some(to_transaction_num) = block_bodies.last().map(|bodies| bodies.1.last_tx_num())
|
||||||
|
else {
|
||||||
|
return Ok(None)
|
||||||
|
};
|
||||||
|
|
||||||
let storage_range = BlockNumberAddress::range(range.clone());
|
let storage_range = BlockNumberAddress::range(range.clone());
|
||||||
|
|
||||||
@ -830,14 +836,14 @@ impl<TX: DbTx> DatabaseProvider<TX> {
|
|||||||
receipts.push(block_receipts);
|
receipts.push(block_receipts);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ExecutionOutcome::new_init(
|
Ok(Some(ExecutionOutcome::new_init(
|
||||||
state,
|
state,
|
||||||
reverts,
|
reverts,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
receipts.into(),
|
receipts.into(),
|
||||||
start_block_number,
|
start_block_number,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Populate a [`BundleStateInit`] and [`RevertsInit`] using cursors over the
|
/// Populate a [`BundleStateInit`] and [`RevertsInit`] using cursors over the
|
||||||
@ -3223,12 +3229,18 @@ impl<TX: DbTx> BlockExecutionReader for DatabaseProvider<TX> {
|
|||||||
let blocks = self.get_block_range(range.clone())?;
|
let blocks = self.get_block_range(range.clone())?;
|
||||||
|
|
||||||
// get execution res
|
// get execution res
|
||||||
let execution_state = self.get_state(range)?;
|
let execution_state = self.get_state(range)?.unwrap_or_default();
|
||||||
|
|
||||||
Ok(Chain::new(blocks, execution_state, None))
|
Ok(Chain::new(blocks, execution_state, None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<TX: DbTx> StateReader for DatabaseProvider<TX> {
|
||||||
|
fn get_state(&self, block: BlockNumber) -> ProviderResult<Option<ExecutionOutcome>> {
|
||||||
|
self.get_state(block..=block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<TX: DbTxMut + DbTx> BlockExecutionWriter for DatabaseProvider<TX> {
|
impl<TX: DbTxMut + DbTx> BlockExecutionWriter for DatabaseProvider<TX> {
|
||||||
fn take_block_and_execution_range(
|
fn take_block_and_execution_range(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@ -22,7 +22,7 @@ pub trait BlockExecutionWriter: BlockWriter + Send + Sync {
|
|||||||
) -> ProviderResult<()>;
|
) -> ProviderResult<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// BlockExecution Writer
|
/// BlockExecution Reader
|
||||||
#[auto_impl::auto_impl(&, Arc, Box)]
|
#[auto_impl::auto_impl(&, Arc, Box)]
|
||||||
pub trait BlockExecutionReader: BlockReader + Send + Sync {
|
pub trait BlockExecutionReader: BlockReader + Send + Sync {
|
||||||
/// Get range of blocks and its execution result
|
/// Get range of blocks and its execution result
|
||||||
@ -32,6 +32,13 @@ pub trait BlockExecutionReader: BlockReader + Send + Sync {
|
|||||||
) -> ProviderResult<Chain>;
|
) -> ProviderResult<Chain>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This just receives state, or [`ExecutionOutcome`], from the provider
|
||||||
|
#[auto_impl::auto_impl(&, Arc, Box)]
|
||||||
|
pub trait StateReader: Send + Sync {
|
||||||
|
/// Get the [`ExecutionOutcome`] for the given block
|
||||||
|
fn get_state(&self, block: BlockNumber) -> ProviderResult<Option<ExecutionOutcome>>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Block Writer
|
/// Block Writer
|
||||||
#[auto_impl::auto_impl(&, Arc, Box)]
|
#[auto_impl::auto_impl(&, Arc, Box)]
|
||||||
pub trait BlockWriter: Send + Sync {
|
pub trait BlockWriter: Send + Sync {
|
||||||
|
|||||||
Reference in New Issue
Block a user