mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add header AT to provider (#13030)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
This commit is contained in:
@ -19,7 +19,7 @@ use crate::{
|
||||
StorageLocation, StorageReader, StorageTrieWriter, TransactionVariant, TransactionsProvider,
|
||||
TransactionsProviderExt, TrieWriter, WithdrawalsProvider,
|
||||
};
|
||||
use alloy_consensus::Header;
|
||||
use alloy_consensus::{BlockHeader, Header};
|
||||
use alloy_eips::{
|
||||
eip2718::Encodable2718,
|
||||
eip4895::{Withdrawal, Withdrawals},
|
||||
@ -50,10 +50,11 @@ use reth_db_api::{
|
||||
use reth_evm::ConfigureEvmEnv;
|
||||
use reth_execution_types::{Chain, ExecutionOutcome};
|
||||
use reth_network_p2p::headers::downloader::SyncTarget;
|
||||
use reth_node_types::{BlockTy, BodyTy, NodeTypes, ReceiptTy, TxTy};
|
||||
use reth_node_types::{BlockTy, BodyTy, HeaderTy, NodeTypes, ReceiptTy, TxTy};
|
||||
use reth_primitives::{
|
||||
Account, BlockExt, BlockWithSenders, Bytecode, GotExpected, SealedBlock, SealedBlockFor,
|
||||
SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry, TransactionMeta,
|
||||
Account, BlockExt, BlockWithSenders, Bytecode, GotExpected, NodePrimitives, SealedBlock,
|
||||
SealedBlockFor, SealedBlockWithSenders, SealedHeader, StaticFileSegment, StorageEntry,
|
||||
TransactionMeta,
|
||||
};
|
||||
use reth_primitives_traits::{Block as _, BlockBody as _, SignedTransaction};
|
||||
use reth_prune_types::{PruneCheckpoint, PruneModes, PruneSegment};
|
||||
@ -326,7 +327,7 @@ impl<TX: DbTx + DbTxMut + 'static, N: NodeTypesForProvider> DatabaseProvider<TX,
|
||||
let parent_state_root = self
|
||||
.header_by_number(parent_number)?
|
||||
.ok_or_else(|| ProviderError::HeaderNotFound(parent_number.into()))?
|
||||
.state_root;
|
||||
.state_root();
|
||||
|
||||
// state root should be always correct as we are reverting state.
|
||||
// but for sake of double verification we will check it again.
|
||||
@ -420,7 +421,11 @@ impl<TX: DbTx + 'static, N: NodeTypes> StateCommitmentProvider for DatabaseProvi
|
||||
type StateCommitment = N::StateCommitment;
|
||||
}
|
||||
|
||||
impl<Tx: DbTx + DbTxMut + 'static, N: NodeTypesForProvider + 'static> DatabaseProvider<Tx, N> {
|
||||
impl<
|
||||
Tx: DbTx + DbTxMut + 'static,
|
||||
N: NodeTypesForProvider<Primitives: NodePrimitives<BlockHeader = Header>>,
|
||||
> DatabaseProvider<Tx, N>
|
||||
{
|
||||
// TODO: uncomment below, once `reth debug_cmd` has been feature gated with dev.
|
||||
// #[cfg(any(test, feature = "test-utils"))]
|
||||
/// Inserts an historical block. **Used for setting up test environments**
|
||||
@ -560,8 +565,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> DatabaseProvider<TX, N> {
|
||||
construct_block: BF,
|
||||
) -> ProviderResult<Option<B>>
|
||||
where
|
||||
N::ChainSpec: EthereumHardforks,
|
||||
H: AsRef<Header>,
|
||||
H: AsRef<HeaderTy<N>>,
|
||||
HF: FnOnce(BlockNumber) -> ProviderResult<Option<H>>,
|
||||
BF: FnOnce(H, BodyTy<N>, Vec<Address>) -> ProviderResult<Option<B>>,
|
||||
{
|
||||
@ -610,8 +614,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> DatabaseProvider<TX, N> {
|
||||
mut assemble_block: F,
|
||||
) -> ProviderResult<Vec<R>>
|
||||
where
|
||||
N::ChainSpec: EthereumHardforks,
|
||||
H: AsRef<Header>,
|
||||
H: AsRef<HeaderTy<N>>,
|
||||
HF: FnOnce(RangeInclusive<BlockNumber>) -> ProviderResult<Vec<H>>,
|
||||
F: FnMut(H, BodyTy<N>, Range<TxNumber>) -> ProviderResult<R>,
|
||||
{
|
||||
@ -634,7 +637,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> DatabaseProvider<TX, N> {
|
||||
// have enough information to return the block anyways, so
|
||||
// we skip the block.
|
||||
if let Some((_, block_body_indices)) =
|
||||
block_body_cursor.seek_exact(header.as_ref().number)?
|
||||
block_body_cursor.seek_exact(header.as_ref().number())?
|
||||
{
|
||||
let tx_range = block_body_indices.tx_num_range();
|
||||
present_headers.push((header, tx_range));
|
||||
@ -678,8 +681,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> DatabaseProvider<TX, N> {
|
||||
assemble_block: BF,
|
||||
) -> ProviderResult<Vec<B>>
|
||||
where
|
||||
N::ChainSpec: EthereumHardforks,
|
||||
H: AsRef<Header>,
|
||||
H: AsRef<HeaderTy<N>>,
|
||||
HF: Fn(RangeInclusive<BlockNumber>) -> ProviderResult<Vec<H>>,
|
||||
BF: Fn(H, BodyTy<N>, Vec<Address>) -> ProviderResult<B>,
|
||||
{
|
||||
@ -943,12 +945,16 @@ impl<TX: DbTx, N: NodeTypes> ChangeSetReader for DatabaseProvider<TX, N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<TX: DbTx + 'static, N: NodeTypes> HeaderSyncGapProvider for DatabaseProvider<TX, N> {
|
||||
impl<TX: DbTx + 'static, N: NodeTypesForProvider> HeaderSyncGapProvider
|
||||
for DatabaseProvider<TX, N>
|
||||
{
|
||||
type Header = HeaderTy<N>;
|
||||
|
||||
fn sync_gap(
|
||||
&self,
|
||||
tip: watch::Receiver<B256>,
|
||||
highest_uninterrupted_block: BlockNumber,
|
||||
) -> ProviderResult<HeaderSyncGap> {
|
||||
) -> ProviderResult<HeaderSyncGap<Self::Header>> {
|
||||
let static_file_provider = self.static_file_provider();
|
||||
|
||||
// Make sure Headers static file is at the same height. If it's further, this
|
||||
@ -987,10 +993,10 @@ impl<TX: DbTx + 'static, N: NodeTypes> HeaderSyncGapProvider for DatabaseProvide
|
||||
}
|
||||
}
|
||||
|
||||
impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> HeaderProvider
|
||||
for DatabaseProvider<TX, N>
|
||||
{
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Header>> {
|
||||
impl<TX: DbTx + 'static, N: NodeTypesForProvider> HeaderProvider for DatabaseProvider<TX, N> {
|
||||
type Header = HeaderTy<N>;
|
||||
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Self::Header>> {
|
||||
if let Some(num) = self.block_number(*block_hash)? {
|
||||
Ok(self.header_by_number(num)?)
|
||||
} else {
|
||||
@ -998,12 +1004,12 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> HeaderProvi
|
||||
}
|
||||
}
|
||||
|
||||
fn header_by_number(&self, num: BlockNumber) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_number(&self, num: BlockNumber) -> ProviderResult<Option<Self::Header>> {
|
||||
self.static_file_provider.get_with_static_file_or_database(
|
||||
StaticFileSegment::Headers,
|
||||
num,
|
||||
|static_file| static_file.header_by_number(num),
|
||||
|| Ok(self.tx.get::<tables::Headers>(num)?),
|
||||
|| Ok(self.tx.get::<tables::Headers<Self::Header>>(num)?),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1030,17 +1036,25 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> HeaderProvi
|
||||
)
|
||||
}
|
||||
|
||||
fn headers_range(&self, range: impl RangeBounds<BlockNumber>) -> ProviderResult<Vec<Header>> {
|
||||
fn headers_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<Self::Header>> {
|
||||
self.static_file_provider.get_range_with_static_file_or_database(
|
||||
StaticFileSegment::Headers,
|
||||
to_range(range),
|
||||
|static_file, range, _| static_file.headers_range(range),
|
||||
|range, _| self.cursor_read_collect::<tables::Headers>(range).map_err(Into::into),
|
||||
|range, _| {
|
||||
self.cursor_read_collect::<tables::Headers<Self::Header>>(range).map_err(Into::into)
|
||||
},
|
||||
|_| true,
|
||||
)
|
||||
}
|
||||
|
||||
fn sealed_header(&self, number: BlockNumber) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn sealed_header(
|
||||
&self,
|
||||
number: BlockNumber,
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.static_file_provider.get_with_static_file_or_database(
|
||||
StaticFileSegment::Headers,
|
||||
number,
|
||||
@ -1061,15 +1075,17 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> HeaderProvi
|
||||
fn sealed_headers_while(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
predicate: impl FnMut(&SealedHeader) -> bool,
|
||||
) -> ProviderResult<Vec<SealedHeader>> {
|
||||
predicate: impl FnMut(&SealedHeader<Self::Header>) -> bool,
|
||||
) -> ProviderResult<Vec<SealedHeader<Self::Header>>> {
|
||||
self.static_file_provider.get_range_with_static_file_or_database(
|
||||
StaticFileSegment::Headers,
|
||||
to_range(range),
|
||||
|static_file, range, predicate| static_file.sealed_headers_while(range, predicate),
|
||||
|range, mut predicate| {
|
||||
let mut headers = vec![];
|
||||
for entry in self.tx.cursor_read::<tables::Headers>()?.walk_range(range)? {
|
||||
for entry in
|
||||
self.tx.cursor_read::<tables::Headers<Self::Header>>()?.walk_range(range)?
|
||||
{
|
||||
let (number, header) = entry?;
|
||||
let hash = self
|
||||
.block_hash(number)?
|
||||
@ -1210,7 +1226,7 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> BlockReader for DatabaseProvid
|
||||
///
|
||||
/// If the block is not found, this returns `None`.
|
||||
/// If the block exists, but doesn't contain ommers, this returns `None`.
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Self::Header>>> {
|
||||
if let Some(number) = self.convert_hash_or_number(id)? {
|
||||
// If the Paris (Merge) hardfork block is known and block is after it, return empty
|
||||
// ommers.
|
||||
@ -1218,7 +1234,8 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> BlockReader for DatabaseProvid
|
||||
return Ok(Some(Vec::new()))
|
||||
}
|
||||
|
||||
let ommers = self.tx.get::<tables::BlockOmmers>(number)?.map(|o| o.ommers);
|
||||
let ommers =
|
||||
self.tx.get::<tables::BlockOmmers<Self::Header>>(number)?.map(|o| o.ommers);
|
||||
return Ok(ommers)
|
||||
}
|
||||
|
||||
@ -1450,9 +1467,9 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> TransactionsProvider for Datab
|
||||
index,
|
||||
block_hash,
|
||||
block_number,
|
||||
base_fee: header.base_fee_per_gas,
|
||||
excess_blob_gas: header.excess_blob_gas,
|
||||
timestamp: header.timestamp,
|
||||
base_fee: header.base_fee_per_gas(),
|
||||
excess_blob_gas: header.excess_blob_gas(),
|
||||
timestamp: header.timestamp(),
|
||||
};
|
||||
|
||||
return Ok(Some((transaction, meta)))
|
||||
@ -1618,7 +1635,7 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> Withdrawals
|
||||
}
|
||||
}
|
||||
|
||||
impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> EvmEnvProvider
|
||||
impl<TX: DbTx + 'static, N: NodeTypesForProvider> EvmEnvProvider<HeaderTy<N>>
|
||||
for DatabaseProvider<TX, N>
|
||||
{
|
||||
fn fill_env_at<EvmConfig>(
|
||||
@ -1629,7 +1646,7 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> EvmEnvProvi
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv<Header = Header>,
|
||||
EvmConfig: ConfigureEvmEnv<Header = HeaderTy<N>>,
|
||||
{
|
||||
let hash = self.convert_number(at)?.ok_or(ProviderError::HeaderNotFound(at))?;
|
||||
let header = self.header(&hash)?.ok_or(ProviderError::HeaderNotFound(at))?;
|
||||
@ -1640,15 +1657,15 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> EvmEnvProvi
|
||||
&self,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
block_env: &mut BlockEnv,
|
||||
header: &Header,
|
||||
header: &HeaderTy<N>,
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv<Header = Header>,
|
||||
EvmConfig: ConfigureEvmEnv<Header = HeaderTy<N>>,
|
||||
{
|
||||
let total_difficulty = self
|
||||
.header_td_by_number(header.number)?
|
||||
.ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?;
|
||||
.header_td_by_number(header.number())?
|
||||
.ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?;
|
||||
evm_config.fill_cfg_and_block_env(cfg, block_env, header, total_difficulty);
|
||||
Ok(())
|
||||
}
|
||||
@ -1660,7 +1677,7 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> EvmEnvProvi
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv<Header = Header>,
|
||||
EvmConfig: ConfigureEvmEnv<Header = HeaderTy<N>>,
|
||||
{
|
||||
let hash = self.convert_number(at)?.ok_or(ProviderError::HeaderNotFound(at))?;
|
||||
let header = self.header(&hash)?.ok_or(ProviderError::HeaderNotFound(at))?;
|
||||
@ -1670,15 +1687,15 @@ impl<TX: DbTx + 'static, N: NodeTypes<ChainSpec: EthereumHardforks>> EvmEnvProvi
|
||||
fn fill_cfg_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
header: &Header,
|
||||
header: &HeaderTy<N>,
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv<Header = Header>,
|
||||
EvmConfig: ConfigureEvmEnv<Header = HeaderTy<N>>,
|
||||
{
|
||||
let total_difficulty = self
|
||||
.header_td_by_number(header.number)?
|
||||
.ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?;
|
||||
.header_td_by_number(header.number())?
|
||||
.ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?;
|
||||
evm_config.fill_cfg_env(cfg, header, total_difficulty);
|
||||
Ok(())
|
||||
}
|
||||
@ -2813,18 +2830,18 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockWrite
|
||||
block: SealedBlockWithSenders<Self::Block>,
|
||||
write_to: StorageLocation,
|
||||
) -> ProviderResult<StoredBlockBodyIndices> {
|
||||
let block_number = block.number;
|
||||
let block_number = block.number();
|
||||
|
||||
let mut durations_recorder = metrics::DurationsRecorder::default();
|
||||
|
||||
// total difficulty
|
||||
let ttd = if block_number == 0 {
|
||||
block.difficulty
|
||||
block.difficulty()
|
||||
} else {
|
||||
let parent_block_number = block_number - 1;
|
||||
let parent_ttd = self.header_td_by_number(parent_block_number)?.unwrap_or_default();
|
||||
durations_recorder.record_relative(metrics::Action::GetParentTD);
|
||||
parent_ttd + block.difficulty
|
||||
parent_ttd + block.difficulty()
|
||||
};
|
||||
|
||||
if write_to.database() {
|
||||
@ -2832,7 +2849,8 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockWrite
|
||||
durations_recorder.record_relative(metrics::Action::InsertCanonicalHeaders);
|
||||
|
||||
// Put header with canonical hashes.
|
||||
self.tx.put::<tables::Headers>(block_number, block.header.as_ref().clone())?;
|
||||
self.tx
|
||||
.put::<tables::Headers<HeaderTy<N>>>(block_number, block.header.as_ref().clone())?;
|
||||
durations_recorder.record_relative(metrics::Action::InsertHeaders);
|
||||
|
||||
self.tx.put::<tables::HeaderTerminalDifficulties>(block_number, ttd.into())?;
|
||||
@ -2979,7 +2997,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockWrite
|
||||
self.tx.delete::<tables::HeaderNumbers>(hash, None)?;
|
||||
rev_headers.delete_current()?;
|
||||
}
|
||||
self.remove::<tables::Headers>(block + 1..)?;
|
||||
self.remove::<tables::Headers<HeaderTy<N>>>(block + 1..)?;
|
||||
self.remove::<tables::HeaderTerminalDifficulties>(block + 1..)?;
|
||||
|
||||
// First transaction to be removed
|
||||
@ -3063,10 +3081,10 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockWrite
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
let first_number = blocks.first().unwrap().number;
|
||||
let first_number = blocks.first().unwrap().number();
|
||||
|
||||
let last = blocks.last().unwrap();
|
||||
let last_block_number = last.number;
|
||||
let last_block_number = last.number();
|
||||
|
||||
let mut durations_recorder = metrics::DurationsRecorder::default();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user