mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat(tree): introduce executed_block_by_hash (#10553)
Co-authored-by: Roman Krasiuk <rokrassyuk@gmail.com>
This commit is contained in:
@ -28,7 +28,7 @@ use reth_primitives::{
|
|||||||
};
|
};
|
||||||
use reth_provider::{
|
use reth_provider::{
|
||||||
BlockReader, ExecutionOutcome, ProviderError, StateProviderBox, StateProviderFactory,
|
BlockReader, ExecutionOutcome, ProviderError, StateProviderBox, StateProviderFactory,
|
||||||
StateRootProvider,
|
StateReader, StateRootProvider, TransactionVariant,
|
||||||
};
|
};
|
||||||
use reth_revm::database::StateProviderDatabase;
|
use reth_revm::database::StateProviderDatabase;
|
||||||
use reth_rpc_types::{
|
use reth_rpc_types::{
|
||||||
@ -109,6 +109,11 @@ impl TreeState {
|
|||||||
self.blocks_by_hash.len()
|
self.blocks_by_hash.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the [`ExecutedBlock`] by hash.
|
||||||
|
fn executed_block_by_hash(&self, hash: B256) -> Option<&ExecutedBlock> {
|
||||||
|
self.blocks_by_hash.get(&hash)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the block by hash.
|
/// Returns the block by hash.
|
||||||
fn block_by_hash(&self, hash: B256) -> Option<Arc<SealedBlock>> {
|
fn block_by_hash(&self, hash: B256) -> Option<Arc<SealedBlock>> {
|
||||||
self.blocks_by_hash.get(&hash).map(|b| b.block.clone())
|
self.blocks_by_hash.get(&hash).map(|b| b.block.clone())
|
||||||
@ -547,7 +552,7 @@ impl<P: Debug, E: Debug, T: EngineTypes + Debug> std::fmt::Debug for EngineApiTr
|
|||||||
|
|
||||||
impl<P, E, T> EngineApiTreeHandler<P, E, T>
|
impl<P, E, T> EngineApiTreeHandler<P, E, T>
|
||||||
where
|
where
|
||||||
P: BlockReader + StateProviderFactory + Clone + 'static,
|
P: BlockReader + StateProviderFactory + StateReader + Clone + 'static,
|
||||||
E: BlockExecutorProvider,
|
E: BlockExecutorProvider,
|
||||||
T: EngineTypes,
|
T: EngineTypes,
|
||||||
{
|
{
|
||||||
@ -1337,6 +1342,45 @@ where
|
|||||||
.remove_persisted_blocks(self.persistence_state.last_persisted_block_number);
|
.remove_persisted_blocks(self.persistence_state.last_persisted_block_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return an [`ExecutedBlock`] from database or in-memory state by hash.
|
||||||
|
///
|
||||||
|
/// NOTE: This cannot fetch [`ExecutedBlock`]s for _finalized_ blocks, instead it can only
|
||||||
|
/// fetch [`ExecutedBlock`]s for _canonical_ blocks, or blocks from sidechains that the node
|
||||||
|
/// has in memory.
|
||||||
|
///
|
||||||
|
/// For finalized blocks, this will return `None`.
|
||||||
|
#[allow(unused)]
|
||||||
|
fn executed_block_by_hash(&self, hash: B256) -> ProviderResult<Option<ExecutedBlock>> {
|
||||||
|
// check memory first
|
||||||
|
let block = self.state.tree_state.executed_block_by_hash(hash).cloned();
|
||||||
|
|
||||||
|
if block.is_some() {
|
||||||
|
return Ok(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some((_, updates)) = self.state.tree_state.persisted_trie_updates.get(&hash) else {
|
||||||
|
return Ok(None)
|
||||||
|
};
|
||||||
|
|
||||||
|
let SealedBlockWithSenders { block, senders } = self
|
||||||
|
.provider
|
||||||
|
.sealed_block_with_senders(hash.into(), TransactionVariant::WithHash)?
|
||||||
|
.ok_or_else(|| ProviderError::HeaderNotFound(hash.into()))?;
|
||||||
|
let execution_output = self
|
||||||
|
.provider
|
||||||
|
.get_state(block.number)?
|
||||||
|
.ok_or_else(|| ProviderError::StateForNumberNotFound(block.number))?;
|
||||||
|
let hashed_state = execution_output.hash_state_slow();
|
||||||
|
|
||||||
|
Ok(Some(ExecutedBlock {
|
||||||
|
block: Arc::new(block),
|
||||||
|
senders: Arc::new(senders),
|
||||||
|
trie: updates.clone(),
|
||||||
|
execution_output: Arc::new(execution_output),
|
||||||
|
hashed_state: Arc::new(hashed_state),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
/// Return sealed block from database or in-memory state by hash.
|
/// Return sealed block from database or in-memory state by hash.
|
||||||
fn sealed_header_by_hash(&self, hash: B256) -> ProviderResult<Option<SealedHeader>> {
|
fn sealed_header_by_hash(&self, hash: B256) -> ProviderResult<Option<SealedHeader>> {
|
||||||
// check memory first
|
// check memory first
|
||||||
@ -1705,7 +1749,7 @@ where
|
|||||||
///
|
///
|
||||||
/// This is invoked on a valid forkchoice update, or if we can make the target block canonical.
|
/// This is invoked on a valid forkchoice update, or if we can make the target block canonical.
|
||||||
fn on_canonical_chain_update(&mut self, chain_update: NewCanonicalChain) {
|
fn on_canonical_chain_update(&mut self, chain_update: NewCanonicalChain) {
|
||||||
trace!(target: "engine", new_blocks = %chain_update.new_block_count(), reorged_blocks = %chain_update.reorged_block_count() ,"applying new chain update");
|
trace!(target: "engine", new_blocks = %chain_update.new_block_count(), reorged_blocks = %chain_update.reorged_block_count(), "applying new chain update");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
// update the tracked canonical head
|
// update the tracked canonical head
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
traits::{BlockSource, ReceiptProvider},
|
traits::{BlockSource, ReceiptProvider},
|
||||||
AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt,
|
AccountReader, BlockExecutionReader, BlockHashReader, BlockIdReader, BlockNumReader,
|
||||||
ChainSpecProvider, ChangeSetReader, EvmEnvProvider, HeaderProvider, ReceiptProviderIdExt,
|
BlockReader, BlockReaderIdExt, ChainSpecProvider, ChangeSetReader, EvmEnvProvider,
|
||||||
RequestsProvider, StateProvider, StateProviderBox, StateProviderFactory, StateRootProvider,
|
HeaderProvider, ReceiptProviderIdExt, RequestsProvider, StateProvider, StateProviderBox,
|
||||||
TransactionVariant, TransactionsProvider, WithdrawalsProvider,
|
StateProviderFactory, StateReader, StateRootProvider, TransactionVariant, TransactionsProvider,
|
||||||
|
WithdrawalsProvider,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use reth_chainspec::{ChainInfo, ChainSpec};
|
use reth_chainspec::{ChainInfo, ChainSpec};
|
||||||
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
||||||
use reth_evm::ConfigureEvmEnv;
|
use reth_evm::ConfigureEvmEnv;
|
||||||
|
use reth_execution_types::{Chain, ExecutionOutcome};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
keccak256, Account, Address, Block, BlockHash, BlockHashOrNumber, BlockId, BlockNumber,
|
keccak256, Account, Address, Block, BlockHash, BlockHashOrNumber, BlockId, BlockNumber,
|
||||||
BlockNumberOrTag, BlockWithSenders, Bytecode, Bytes, Header, Receipt, SealedBlock,
|
BlockNumberOrTag, BlockWithSenders, Bytecode, Bytes, Header, Receipt, SealedBlock,
|
||||||
@ -787,3 +789,18 @@ impl ChangeSetReader for MockEthProvider {
|
|||||||
Ok(Vec::default())
|
Ok(Vec::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BlockExecutionReader for MockEthProvider {
|
||||||
|
fn get_block_and_execution_range(
|
||||||
|
&self,
|
||||||
|
_range: RangeInclusive<BlockNumber>,
|
||||||
|
) -> ProviderResult<Chain> {
|
||||||
|
Ok(Chain::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StateReader for MockEthProvider {
|
||||||
|
fn get_state(&self, _block: BlockNumber) -> ProviderResult<Option<ExecutionOutcome>> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user