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:
@ -24,6 +24,7 @@ reth-fs-util.workspace = true
|
||||
reth-node-types.workspace = true
|
||||
|
||||
# eth
|
||||
alloy-consensus.workspace = true
|
||||
alloy-genesis.workspace = true
|
||||
alloy-primitives.workspace = true
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
//! Reth genesis initialization utility functions.
|
||||
|
||||
use alloy_consensus::BlockHeader;
|
||||
use alloy_genesis::GenesisAccount;
|
||||
use alloy_primitives::{Address, B256, U256};
|
||||
use reth_chainspec::EthChainSpec;
|
||||
@ -8,7 +9,9 @@ use reth_config::config::EtlConfig;
|
||||
use reth_db::tables;
|
||||
use reth_db_api::{transaction::DbTxMut, DatabaseError};
|
||||
use reth_etl::Collector;
|
||||
use reth_primitives::{Account, Bytecode, GotExpected, Receipts, StaticFileSegment, StorageEntry};
|
||||
use reth_primitives::{
|
||||
Account, Bytecode, GotExpected, NodePrimitives, Receipts, StaticFileSegment, StorageEntry,
|
||||
};
|
||||
use reth_provider::{
|
||||
errors::provider::ProviderResult, providers::StaticFileWriter, writer::UnifiedStorageWriter,
|
||||
BlockHashReader, BlockNumReader, BundleStateInit, ChainSpecProvider, DBProvider,
|
||||
@ -69,7 +72,10 @@ impl From<DatabaseError> for InitDatabaseError {
|
||||
/// Write the genesis block if it has not already been written
|
||||
pub fn init_genesis<PF>(factory: &PF) -> Result<B256, InitDatabaseError>
|
||||
where
|
||||
PF: DatabaseProviderFactory + StaticFileProviderFactory + ChainSpecProvider + BlockHashReader,
|
||||
PF: DatabaseProviderFactory
|
||||
+ StaticFileProviderFactory<Primitives: NodePrimitives<BlockHeader: Compact>>
|
||||
+ ChainSpecProvider
|
||||
+ BlockHashReader,
|
||||
PF::ProviderRW: StaticFileProviderFactory<Primitives = PF::Primitives>
|
||||
+ StageCheckpointWriter
|
||||
+ HistoryWriter
|
||||
@ -78,7 +84,7 @@ where
|
||||
+ StateWriter
|
||||
+ StateWriter
|
||||
+ AsRef<PF::ProviderRW>,
|
||||
PF::ChainSpec: EthChainSpec<Header = reth_primitives::Header>,
|
||||
PF::ChainSpec: EthChainSpec<Header = <PF::Primitives as NodePrimitives>::BlockHeader>,
|
||||
{
|
||||
let chain = factory.chain_spec();
|
||||
|
||||
@ -307,15 +313,16 @@ pub fn insert_genesis_header<Provider, Spec>(
|
||||
chain: &Spec,
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
Provider: StaticFileProviderFactory + DBProvider<Tx: DbTxMut>,
|
||||
Spec: EthChainSpec<Header = reth_primitives::Header>,
|
||||
Provider: StaticFileProviderFactory<Primitives: NodePrimitives<BlockHeader: Compact>>
|
||||
+ DBProvider<Tx: DbTxMut>,
|
||||
Spec: EthChainSpec<Header = <Provider::Primitives as NodePrimitives>::BlockHeader>,
|
||||
{
|
||||
let (header, block_hash) = (chain.genesis_header(), chain.genesis_hash());
|
||||
let static_file_provider = provider.static_file_provider();
|
||||
|
||||
match static_file_provider.block_hash(0) {
|
||||
Ok(None) | Err(ProviderError::MissingStaticFileBlock(StaticFileSegment::Headers, 0)) => {
|
||||
let (difficulty, hash) = (header.difficulty, block_hash);
|
||||
let (difficulty, hash) = (header.difficulty(), block_hash);
|
||||
let mut writer = static_file_provider.latest_writer(StaticFileSegment::Headers)?;
|
||||
writer.append_header(header, difficulty, &hash)?;
|
||||
}
|
||||
@ -359,7 +366,7 @@ where
|
||||
let expected_state_root = provider_rw
|
||||
.header_by_number(block)?
|
||||
.ok_or_else(|| ProviderError::HeaderNotFound(block.into()))?
|
||||
.state_root;
|
||||
.state_root();
|
||||
|
||||
// first line can be state root
|
||||
let dump_state_root = parse_state_root(&mut reader)?;
|
||||
|
||||
@ -25,7 +25,7 @@ use reth_db::{models::BlockNumberAddress, transaction::DbTx, Database};
|
||||
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
||||
use reth_evm::ConfigureEvmEnv;
|
||||
use reth_execution_types::ExecutionOutcome;
|
||||
use reth_node_types::{BlockTy, NodeTypesWithDB, ReceiptTy, TxTy};
|
||||
use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy};
|
||||
use reth_primitives::{
|
||||
Account, Block, BlockWithSenders, EthPrimitives, NodePrimitives, Receipt, SealedBlock,
|
||||
SealedBlockFor, SealedBlockWithSenders, SealedHeader, StorageEntry, TransactionMeta,
|
||||
@ -89,7 +89,10 @@ impl<N: ProviderNodeTypes> BlockchainProvider2<N> {
|
||||
///
|
||||
/// This returns a `ProviderResult` since it tries the retrieve the last finalized header from
|
||||
/// `database`.
|
||||
pub fn with_latest(storage: ProviderFactory<N>, latest: SealedHeader) -> ProviderResult<Self> {
|
||||
pub fn with_latest(
|
||||
storage: ProviderFactory<N>,
|
||||
latest: SealedHeader<HeaderTy<N>>,
|
||||
) -> ProviderResult<Self> {
|
||||
let provider = storage.provider()?;
|
||||
let finalized_header = provider
|
||||
.last_finalized_block_number()?
|
||||
@ -175,11 +178,13 @@ impl<N: ProviderNodeTypes> StaticFileProviderFactory for BlockchainProvider2<N>
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> HeaderProvider for BlockchainProvider2<N> {
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Header>> {
|
||||
type Header = HeaderTy<N>;
|
||||
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Self::Header>> {
|
||||
self.consistent_provider()?.header(block_hash)
|
||||
}
|
||||
|
||||
fn header_by_number(&self, num: BlockNumber) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_number(&self, num: BlockNumber) -> ProviderResult<Option<Self::Header>> {
|
||||
self.consistent_provider()?.header_by_number(num)
|
||||
}
|
||||
|
||||
@ -191,26 +196,32 @@ impl<N: ProviderNodeTypes> HeaderProvider for BlockchainProvider2<N> {
|
||||
self.consistent_provider()?.header_td_by_number(number)
|
||||
}
|
||||
|
||||
fn headers_range(&self, range: impl RangeBounds<BlockNumber>) -> ProviderResult<Vec<Header>> {
|
||||
fn headers_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<Self::Header>> {
|
||||
self.consistent_provider()?.headers_range(range)
|
||||
}
|
||||
|
||||
fn sealed_header(&self, number: BlockNumber) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn sealed_header(
|
||||
&self,
|
||||
number: BlockNumber,
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.consistent_provider()?.sealed_header(number)
|
||||
}
|
||||
|
||||
fn sealed_headers_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<SealedHeader>> {
|
||||
) -> ProviderResult<Vec<SealedHeader<Self::Header>>> {
|
||||
self.consistent_provider()?.sealed_headers_range(range)
|
||||
}
|
||||
|
||||
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.consistent_provider()?.sealed_headers_while(range, predicate)
|
||||
}
|
||||
}
|
||||
@ -292,7 +303,7 @@ impl<N: ProviderNodeTypes> BlockReader for BlockchainProvider2<N> {
|
||||
Ok(self.canonical_in_memory_state.pending_block_and_receipts())
|
||||
}
|
||||
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Self::Header>>> {
|
||||
self.consistent_provider()?.ommers(id)
|
||||
}
|
||||
|
||||
@ -470,7 +481,7 @@ impl<N: ProviderNodeTypes> StageCheckpointReader for BlockchainProvider2<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> EvmEnvProvider for BlockchainProvider2<N> {
|
||||
impl<N: ProviderNodeTypes> EvmEnvProvider<HeaderTy<N>> for BlockchainProvider2<N> {
|
||||
fn fill_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
@ -479,7 +490,7 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for BlockchainProvider2<N> {
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv<Header = Header>,
|
||||
EvmConfig: ConfigureEvmEnv<Header = HeaderTy<N>>,
|
||||
{
|
||||
self.consistent_provider()?.fill_env_at(cfg, block_env, at, evm_config)
|
||||
}
|
||||
@ -488,11 +499,11 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for BlockchainProvider2<N> {
|
||||
&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>>,
|
||||
{
|
||||
self.consistent_provider()?.fill_env_with_header(cfg, block_env, header, evm_config)
|
||||
}
|
||||
@ -504,7 +515,7 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for BlockchainProvider2<N> {
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv<Header = Header>,
|
||||
EvmConfig: ConfigureEvmEnv<Header = HeaderTy<N>>,
|
||||
{
|
||||
self.consistent_provider()?.fill_cfg_env_at(cfg, at, evm_config)
|
||||
}
|
||||
@ -512,11 +523,11 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for BlockchainProvider2<N> {
|
||||
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>>,
|
||||
{
|
||||
self.consistent_provider()?.fill_cfg_env_with_header(cfg, header, evm_config)
|
||||
}
|
||||
@ -652,10 +663,9 @@ impl<N: ProviderNodeTypes> StateProviderFactory for BlockchainProvider2<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> CanonChainTracker for BlockchainProvider2<N>
|
||||
where
|
||||
Self: BlockReader,
|
||||
{
|
||||
impl<N: ProviderNodeTypes> CanonChainTracker for BlockchainProvider2<N> {
|
||||
type Header = HeaderTy<N>;
|
||||
|
||||
fn on_forkchoice_update_received(&self, _update: &ForkchoiceState) {
|
||||
// update timestamp
|
||||
self.canonical_in_memory_state.on_forkchoice_update_received();
|
||||
@ -673,15 +683,15 @@ where
|
||||
self.canonical_in_memory_state.last_exchanged_transition_configuration_timestamp()
|
||||
}
|
||||
|
||||
fn set_canonical_head(&self, header: SealedHeader) {
|
||||
fn set_canonical_head(&self, header: SealedHeader<Self::Header>) {
|
||||
self.canonical_in_memory_state.set_canonical_head(header);
|
||||
}
|
||||
|
||||
fn set_safe(&self, header: SealedHeader) {
|
||||
fn set_safe(&self, header: SealedHeader<Self::Header>) {
|
||||
self.canonical_in_memory_state.set_safe(header);
|
||||
}
|
||||
|
||||
fn set_finalized(&self, header: SealedHeader) {
|
||||
fn set_finalized(&self, header: SealedHeader<Self::Header>) {
|
||||
self.canonical_in_memory_state.set_finalized(header);
|
||||
}
|
||||
}
|
||||
@ -694,26 +704,32 @@ where
|
||||
self.consistent_provider()?.block_by_id(id)
|
||||
}
|
||||
|
||||
fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_number_or_tag(
|
||||
&self,
|
||||
id: BlockNumberOrTag,
|
||||
) -> ProviderResult<Option<Self::Header>> {
|
||||
self.consistent_provider()?.header_by_number_or_tag(id)
|
||||
}
|
||||
|
||||
fn sealed_header_by_number_or_tag(
|
||||
&self,
|
||||
id: BlockNumberOrTag,
|
||||
) -> ProviderResult<Option<SealedHeader>> {
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.consistent_provider()?.sealed_header_by_number_or_tag(id)
|
||||
}
|
||||
|
||||
fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn sealed_header_by_id(
|
||||
&self,
|
||||
id: BlockId,
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.consistent_provider()?.sealed_header_by_id(id)
|
||||
}
|
||||
|
||||
fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<Self::Header>> {
|
||||
self.consistent_provider()?.header_by_id(id)
|
||||
}
|
||||
|
||||
fn ommers_by_id(&self, id: BlockId) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers_by_id(&self, id: BlockId) -> ProviderResult<Option<Vec<Self::Header>>> {
|
||||
self.consistent_provider()?.ommers_by_id(id)
|
||||
}
|
||||
}
|
||||
@ -727,12 +743,14 @@ impl<N: NodeTypesWithDB<Primitives = EthPrimitives>> CanonStateSubscriptions
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> ForkChoiceSubscriptions for BlockchainProvider2<N> {
|
||||
fn subscribe_safe_block(&self) -> ForkChoiceNotifications {
|
||||
type Header = HeaderTy<N>;
|
||||
|
||||
fn subscribe_safe_block(&self) -> ForkChoiceNotifications<Self::Header> {
|
||||
let receiver = self.canonical_in_memory_state.subscribe_safe_block();
|
||||
ForkChoiceNotifications(receiver)
|
||||
}
|
||||
|
||||
fn subscribe_finalized_block(&self) -> ForkChoiceNotifications {
|
||||
fn subscribe_finalized_block(&self) -> ForkChoiceNotifications<Self::Header> {
|
||||
let receiver = self.canonical_in_memory_state.subscribe_finalized_block();
|
||||
ForkChoiceNotifications(receiver)
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ use crate::{
|
||||
StageCheckpointReader, StateReader, StaticFileProviderFactory, TransactionVariant,
|
||||
TransactionsProvider, WithdrawalsProvider,
|
||||
};
|
||||
use alloy_consensus::Header;
|
||||
use alloy_consensus::BlockHeader;
|
||||
use alloy_eips::{
|
||||
eip2718::Encodable2718,
|
||||
eip4895::{Withdrawal, Withdrawals},
|
||||
@ -19,7 +19,7 @@ use reth_db::models::BlockNumberAddress;
|
||||
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
||||
use reth_evm::ConfigureEvmEnv;
|
||||
use reth_execution_types::{BundleStateInit, ExecutionOutcome, RevertsInit};
|
||||
use reth_node_types::{BlockTy, ReceiptTy, TxTy};
|
||||
use reth_node_types::{BlockTy, HeaderTy, ReceiptTy, TxTy};
|
||||
use reth_primitives::{
|
||||
Account, BlockWithSenders, SealedBlockFor, SealedBlockWithSenders, SealedHeader, StorageEntry,
|
||||
TransactionMeta,
|
||||
@ -628,7 +628,9 @@ impl<N: ProviderNodeTypes> StaticFileProviderFactory for ConsistentProvider<N> {
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> HeaderProvider for ConsistentProvider<N> {
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Header>> {
|
||||
type Header = HeaderTy<N>;
|
||||
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Self::Header>> {
|
||||
self.get_in_memory_or_storage_by_block(
|
||||
(*block_hash).into(),
|
||||
|db_provider| db_provider.header(block_hash),
|
||||
@ -636,7 +638,7 @@ impl<N: ProviderNodeTypes> HeaderProvider for ConsistentProvider<N> {
|
||||
)
|
||||
}
|
||||
|
||||
fn header_by_number(&self, num: BlockNumber) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_number(&self, num: BlockNumber) -> ProviderResult<Option<Self::Header>> {
|
||||
self.get_in_memory_or_storage_by_block(
|
||||
num.into(),
|
||||
|db_provider| db_provider.header_by_number(num),
|
||||
@ -675,7 +677,10 @@ impl<N: ProviderNodeTypes> HeaderProvider for ConsistentProvider<N> {
|
||||
self.storage_provider.header_td_by_number(number)
|
||||
}
|
||||
|
||||
fn headers_range(&self, range: impl RangeBounds<BlockNumber>) -> ProviderResult<Vec<Header>> {
|
||||
fn headers_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<Self::Header>> {
|
||||
self.get_in_memory_or_storage_by_block_range_while(
|
||||
range,
|
||||
|db_provider, range, _| db_provider.headers_range(range),
|
||||
@ -684,7 +689,10 @@ impl<N: ProviderNodeTypes> HeaderProvider for ConsistentProvider<N> {
|
||||
)
|
||||
}
|
||||
|
||||
fn sealed_header(&self, number: BlockNumber) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn sealed_header(
|
||||
&self,
|
||||
number: BlockNumber,
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.get_in_memory_or_storage_by_block(
|
||||
number.into(),
|
||||
|db_provider| db_provider.sealed_header(number),
|
||||
@ -695,7 +703,7 @@ impl<N: ProviderNodeTypes> HeaderProvider for ConsistentProvider<N> {
|
||||
fn sealed_headers_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<SealedHeader>> {
|
||||
) -> ProviderResult<Vec<SealedHeader<Self::Header>>> {
|
||||
self.get_in_memory_or_storage_by_block_range_while(
|
||||
range,
|
||||
|db_provider, range, _| db_provider.sealed_headers_range(range),
|
||||
@ -707,8 +715,8 @@ impl<N: ProviderNodeTypes> HeaderProvider for ConsistentProvider<N> {
|
||||
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.get_in_memory_or_storage_by_block_range_while(
|
||||
range,
|
||||
|db_provider, range, predicate| db_provider.sealed_headers_while(range, predicate),
|
||||
@ -832,7 +840,7 @@ impl<N: ProviderNodeTypes> BlockReader for ConsistentProvider<N> {
|
||||
Ok(self.canonical_in_memory_state.pending_block_and_receipts())
|
||||
}
|
||||
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<HeaderTy<N>>>> {
|
||||
self.get_in_memory_or_storage_by_block(
|
||||
id,
|
||||
|db_provider| db_provider.ommers(id),
|
||||
@ -868,7 +876,7 @@ impl<N: ProviderNodeTypes> BlockReader for ConsistentProvider<N> {
|
||||
// Iterate from the lowest block in memory until our target block
|
||||
for state in block_state.chain().collect::<Vec<_>>().into_iter().rev() {
|
||||
let block_tx_count = state.block_ref().block.body.transactions().len() as u64;
|
||||
if state.block_ref().block().number == number {
|
||||
if state.block_ref().block().number() == number {
|
||||
stored_indices.tx_count = block_tx_count;
|
||||
} else {
|
||||
stored_indices.first_tx_num += block_tx_count;
|
||||
@ -1017,7 +1025,7 @@ impl<N: ProviderNodeTypes> TransactionsProvider for ConsistentProvider<N> {
|
||||
self.get_in_memory_or_storage_by_tx(
|
||||
id.into(),
|
||||
|provider| provider.transaction_block(id),
|
||||
|_, _, block_state| Ok(Some(block_state.block_ref().block().number)),
|
||||
|_, _, block_state| Ok(Some(block_state.block_ref().block().number())),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1222,7 +1230,7 @@ impl<N: ProviderNodeTypes> StageCheckpointReader for ConsistentProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> EvmEnvProvider for ConsistentProvider<N> {
|
||||
impl<N: ProviderNodeTypes> EvmEnvProvider<HeaderTy<N>> for ConsistentProvider<N> {
|
||||
fn fill_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
@ -1231,7 +1239,7 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for ConsistentProvider<N> {
|
||||
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))?;
|
||||
@ -1242,15 +1250,15 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for ConsistentProvider<N> {
|
||||
&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(())
|
||||
}
|
||||
@ -1262,7 +1270,7 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for ConsistentProvider<N> {
|
||||
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))?;
|
||||
@ -1272,15 +1280,15 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for ConsistentProvider<N> {
|
||||
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(())
|
||||
}
|
||||
@ -1326,7 +1334,7 @@ impl<N: ProviderNodeTypes> BlockReaderIdExt for ConsistentProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult<Option<HeaderTy<N>>> {
|
||||
Ok(match id {
|
||||
BlockNumberOrTag::Latest => {
|
||||
Some(self.canonical_in_memory_state.get_canonical_head().unseal())
|
||||
@ -1347,7 +1355,7 @@ impl<N: ProviderNodeTypes> BlockReaderIdExt for ConsistentProvider<N> {
|
||||
fn sealed_header_by_number_or_tag(
|
||||
&self,
|
||||
id: BlockNumberOrTag,
|
||||
) -> ProviderResult<Option<SealedHeader>> {
|
||||
) -> ProviderResult<Option<SealedHeader<HeaderTy<N>>>> {
|
||||
match id {
|
||||
BlockNumberOrTag::Latest => {
|
||||
Ok(Some(self.canonical_in_memory_state.get_canonical_head()))
|
||||
@ -1366,21 +1374,24 @@ impl<N: ProviderNodeTypes> BlockReaderIdExt for ConsistentProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn sealed_header_by_id(
|
||||
&self,
|
||||
id: BlockId,
|
||||
) -> ProviderResult<Option<SealedHeader<HeaderTy<N>>>> {
|
||||
Ok(match id {
|
||||
BlockId::Number(num) => self.sealed_header_by_number_or_tag(num)?,
|
||||
BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(SealedHeader::seal),
|
||||
})
|
||||
}
|
||||
|
||||
fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<HeaderTy<N>>> {
|
||||
Ok(match id {
|
||||
BlockId::Number(num) => self.header_by_number_or_tag(num)?,
|
||||
BlockId::Hash(hash) => self.header(&hash.block_hash)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn ommers_by_id(&self, id: BlockId) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers_by_id(&self, id: BlockId) -> ProviderResult<Option<Vec<HeaderTy<N>>>> {
|
||||
match id {
|
||||
BlockId::Number(num) => self.ommers_by_number_or_tag(num),
|
||||
BlockId::Hash(hash) => {
|
||||
|
||||
@ -7,7 +7,6 @@ use crate::{
|
||||
PruneCheckpointReader, StageCheckpointReader, StateProviderBox, StaticFileProviderFactory,
|
||||
TransactionVariant, TransactionsProvider, WithdrawalsProvider,
|
||||
};
|
||||
use alloy_consensus::Header;
|
||||
use alloy_eips::{
|
||||
eip4895::{Withdrawal, Withdrawals},
|
||||
BlockHashOrNumber,
|
||||
@ -19,7 +18,7 @@ use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv};
|
||||
use reth_db_api::{database::Database, models::StoredBlockBodyIndices};
|
||||
use reth_errors::{RethError, RethResult};
|
||||
use reth_evm::ConfigureEvmEnv;
|
||||
use reth_node_types::{BlockTy, NodeTypesWithDB, ReceiptTy, TxTy};
|
||||
use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy};
|
||||
use reth_primitives::{
|
||||
BlockWithSenders, SealedBlockFor, SealedBlockWithSenders, SealedHeader, StaticFileSegment,
|
||||
TransactionMeta,
|
||||
@ -228,21 +227,24 @@ impl<N: NodeTypesWithDB> StaticFileProviderFactory for ProviderFactory<N> {
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> HeaderSyncGapProvider for ProviderFactory<N> {
|
||||
type Header = HeaderTy<N>;
|
||||
fn sync_gap(
|
||||
&self,
|
||||
tip: watch::Receiver<B256>,
|
||||
highest_uninterrupted_block: BlockNumber,
|
||||
) -> ProviderResult<HeaderSyncGap> {
|
||||
) -> ProviderResult<HeaderSyncGap<Self::Header>> {
|
||||
self.provider()?.sync_gap(tip, highest_uninterrupted_block)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> HeaderProvider for ProviderFactory<N> {
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Header>> {
|
||||
type Header = HeaderTy<N>;
|
||||
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Self::Header>> {
|
||||
self.provider()?.header(block_hash)
|
||||
}
|
||||
|
||||
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,
|
||||
@ -270,7 +272,10 @@ impl<N: ProviderNodeTypes> HeaderProvider for ProviderFactory<N> {
|
||||
)
|
||||
}
|
||||
|
||||
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),
|
||||
@ -280,7 +285,10 @@ impl<N: ProviderNodeTypes> HeaderProvider for ProviderFactory<N> {
|
||||
)
|
||||
}
|
||||
|
||||
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,
|
||||
@ -292,15 +300,15 @@ impl<N: ProviderNodeTypes> HeaderProvider for ProviderFactory<N> {
|
||||
fn sealed_headers_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<SealedHeader>> {
|
||||
) -> ProviderResult<Vec<SealedHeader<Self::Header>>> {
|
||||
self.sealed_headers_while(range, |_| true)
|
||||
}
|
||||
|
||||
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),
|
||||
@ -385,7 +393,7 @@ impl<N: ProviderNodeTypes> BlockReader for ProviderFactory<N> {
|
||||
self.provider()?.pending_block_and_receipts()
|
||||
}
|
||||
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Self::Header>>> {
|
||||
self.provider()?.ommers(id)
|
||||
}
|
||||
|
||||
@ -570,7 +578,7 @@ impl<N: ProviderNodeTypes> StageCheckpointReader for ProviderFactory<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> EvmEnvProvider for ProviderFactory<N> {
|
||||
impl<N: ProviderNodeTypes> EvmEnvProvider<HeaderTy<N>> for ProviderFactory<N> {
|
||||
fn fill_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
@ -579,7 +587,7 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for ProviderFactory<N> {
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv<Header = Header>,
|
||||
EvmConfig: ConfigureEvmEnv<Header = HeaderTy<N>>,
|
||||
{
|
||||
self.provider()?.fill_env_at(cfg, block_env, at, evm_config)
|
||||
}
|
||||
@ -588,11 +596,11 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for ProviderFactory<N> {
|
||||
&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>>,
|
||||
{
|
||||
self.provider()?.fill_env_with_header(cfg, block_env, header, evm_config)
|
||||
}
|
||||
@ -604,7 +612,7 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for ProviderFactory<N> {
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv<Header = Header>,
|
||||
EvmConfig: ConfigureEvmEnv<Header = HeaderTy<N>>,
|
||||
{
|
||||
self.provider()?.fill_cfg_env_at(cfg, at, evm_config)
|
||||
}
|
||||
@ -612,11 +620,11 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for ProviderFactory<N> {
|
||||
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>>,
|
||||
{
|
||||
self.provider()?.fill_cfg_env_with_header(cfg, header, evm_config)
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
AccountReader, BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, BlockReaderIdExt,
|
||||
BlockSource, BlockchainTreePendingStateProvider, CanonChainTracker, CanonStateNotifications,
|
||||
BlockSource, BlockchainTreePendingStateProvider, CanonStateNotifications,
|
||||
CanonStateSubscriptions, ChainSpecProvider, ChainStateBlockReader, ChangeSetReader,
|
||||
DatabaseProviderFactory, EvmEnvProvider, FullExecutionDataProvider, HeaderProvider,
|
||||
NodePrimitivesProvider, ProviderError, PruneCheckpointReader, ReceiptProvider,
|
||||
@ -14,6 +14,7 @@ use alloy_eips::{
|
||||
BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag,
|
||||
};
|
||||
use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256};
|
||||
use alloy_rpc_types_engine::ForkchoiceState;
|
||||
use reth_blockchain_tree_api::{
|
||||
error::{CanonicalError, InsertBlockError},
|
||||
BlockValidationKind, BlockchainTreeEngine, BlockchainTreeViewer, CanonicalOutcome,
|
||||
@ -24,13 +25,16 @@ use reth_chainspec::{ChainInfo, EthereumHardforks};
|
||||
use reth_db::table::Value;
|
||||
use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices};
|
||||
use reth_evm::ConfigureEvmEnv;
|
||||
use reth_node_types::{BlockTy, FullNodePrimitives, NodeTypes, NodeTypesWithDB, ReceiptTy, TxTy};
|
||||
use reth_node_types::{
|
||||
BlockTy, FullNodePrimitives, HeaderTy, NodeTypes, NodeTypesWithDB, ReceiptTy, TxTy,
|
||||
};
|
||||
use reth_primitives::{
|
||||
Account, BlockWithSenders, EthPrimitives, Receipt, SealedBlock, SealedBlockFor,
|
||||
SealedBlockWithSenders, SealedHeader, TransactionMeta,
|
||||
};
|
||||
use reth_prune_types::{PruneCheckpoint, PruneSegment};
|
||||
use reth_stages_types::{StageCheckpoint, StageId};
|
||||
use reth_storage_api::CanonChainTracker;
|
||||
use reth_storage_errors::provider::ProviderResult;
|
||||
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
|
||||
use std::{
|
||||
@ -61,7 +65,6 @@ mod bundle_state_provider;
|
||||
pub use bundle_state_provider::BundleStateProvider;
|
||||
|
||||
mod consistent_view;
|
||||
use alloy_rpc_types_engine::ForkchoiceState;
|
||||
pub use consistent_view::{ConsistentDbView, ConsistentViewError};
|
||||
|
||||
mod blockchain_provider;
|
||||
@ -77,11 +80,7 @@ where
|
||||
Self: NodeTypes<
|
||||
ChainSpec: EthereumHardforks,
|
||||
Storage: ChainStorage<Self::Primitives>,
|
||||
Primitives: FullNodePrimitives<
|
||||
SignedTx: Value,
|
||||
Receipt: Value,
|
||||
BlockHeader = alloy_consensus::Header,
|
||||
>,
|
||||
Primitives: FullNodePrimitives<SignedTx: Value, Receipt: Value, BlockHeader: Value>,
|
||||
>,
|
||||
{
|
||||
}
|
||||
@ -90,11 +89,7 @@ impl<T> NodeTypesForProvider for T where
|
||||
T: NodeTypes<
|
||||
ChainSpec: EthereumHardforks,
|
||||
Storage: ChainStorage<T::Primitives>,
|
||||
Primitives: FullNodePrimitives<
|
||||
SignedTx: Value,
|
||||
Receipt: Value,
|
||||
BlockHeader = alloy_consensus::Header,
|
||||
>,
|
||||
Primitives: FullNodePrimitives<SignedTx: Value, Receipt: Value, BlockHeader: Value>,
|
||||
>
|
||||
{
|
||||
}
|
||||
@ -151,7 +146,7 @@ impl<N: NodeTypesWithDB> BlockchainProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> BlockchainProvider<N> {
|
||||
impl<N: TreeNodeTypes> BlockchainProvider<N> {
|
||||
/// Create new provider instance that wraps the database and the blockchain tree, using the
|
||||
/// provided latest header to initialize the chain info tracker, alongside the finalized header
|
||||
/// if it exists.
|
||||
@ -261,7 +256,9 @@ impl<N: ProviderNodeTypes> StaticFileProviderFactory for BlockchainProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> HeaderProvider for BlockchainProvider<N> {
|
||||
impl<N: TreeNodeTypes> HeaderProvider for BlockchainProvider<N> {
|
||||
type Header = Header;
|
||||
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Header>> {
|
||||
self.database.header(block_hash)
|
||||
}
|
||||
@ -593,7 +590,7 @@ impl<N: ProviderNodeTypes> StageCheckpointReader for BlockchainProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> EvmEnvProvider for BlockchainProvider<N> {
|
||||
impl<N: TreeNodeTypes> EvmEnvProvider for BlockchainProvider<N> {
|
||||
fn fill_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
@ -666,7 +663,7 @@ impl<N: ProviderNodeTypes> ChainSpecProvider for BlockchainProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> StateProviderFactory for BlockchainProvider<N> {
|
||||
impl<N: TreeNodeTypes> StateProviderFactory for BlockchainProvider<N> {
|
||||
/// Storage provider for latest block
|
||||
fn latest(&self) -> ProviderResult<StateProviderBox> {
|
||||
trace!(target: "providers::blockchain", "Getting latest block state provider");
|
||||
@ -840,10 +837,9 @@ impl<N: ProviderNodeTypes> BlockchainTreeViewer for BlockchainProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> CanonChainTracker for BlockchainProvider<N>
|
||||
where
|
||||
Self: BlockReader,
|
||||
{
|
||||
impl<N: TreeNodeTypes> CanonChainTracker for BlockchainProvider<N> {
|
||||
type Header = HeaderTy<N>;
|
||||
|
||||
fn on_forkchoice_update_received(&self, _update: &ForkchoiceState) {
|
||||
// update timestamp
|
||||
self.chain_info.on_forkchoice_update_received();
|
||||
@ -874,10 +870,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> BlockReaderIdExt for BlockchainProvider<N>
|
||||
where
|
||||
Self: BlockReader + ReceiptProviderIdExt,
|
||||
{
|
||||
impl<N: TreeNodeTypes> BlockReaderIdExt for BlockchainProvider<N> {
|
||||
fn block_by_id(&self, id: BlockId) -> ProviderResult<Option<Self::Block>> {
|
||||
match id {
|
||||
BlockId::Number(num) => self.block_by_number_or_tag(num),
|
||||
@ -896,7 +889,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_number_or_tag(
|
||||
&self,
|
||||
id: BlockNumberOrTag,
|
||||
) -> ProviderResult<Option<Self::Header>> {
|
||||
Ok(match id {
|
||||
BlockNumberOrTag::Latest => Some(self.chain_info.get_canonical_head().unseal()),
|
||||
BlockNumberOrTag::Finalized => {
|
||||
@ -912,7 +908,7 @@ where
|
||||
fn sealed_header_by_number_or_tag(
|
||||
&self,
|
||||
id: BlockNumberOrTag,
|
||||
) -> ProviderResult<Option<SealedHeader>> {
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
match id {
|
||||
BlockNumberOrTag::Latest => Ok(Some(self.chain_info.get_canonical_head())),
|
||||
BlockNumberOrTag::Finalized => Ok(self.chain_info.get_finalized_header()),
|
||||
@ -927,21 +923,24 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn sealed_header_by_id(
|
||||
&self,
|
||||
id: BlockId,
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
Ok(match id {
|
||||
BlockId::Number(num) => self.sealed_header_by_number_or_tag(num)?,
|
||||
BlockId::Hash(hash) => self.header(&hash.block_hash)?.map(SealedHeader::seal),
|
||||
})
|
||||
}
|
||||
|
||||
fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<Self::Header>> {
|
||||
Ok(match id {
|
||||
BlockId::Number(num) => self.header_by_number_or_tag(num)?,
|
||||
BlockId::Hash(hash) => self.header(&hash.block_hash)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn ommers_by_id(&self, id: BlockId) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers_by_id(&self, id: BlockId) -> ProviderResult<Option<Vec<Self::Header>>> {
|
||||
match id {
|
||||
BlockId::Number(num) => self.ommers_by_number_or_tag(num),
|
||||
BlockId::Hash(hash) => {
|
||||
@ -968,7 +967,9 @@ impl<N: ProviderNodeTypes> CanonStateSubscriptions for BlockchainProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ProviderNodeTypes> ForkChoiceSubscriptions for BlockchainProvider<N> {
|
||||
impl<N: TreeNodeTypes> ForkChoiceSubscriptions for BlockchainProvider<N> {
|
||||
type Header = HeaderTy<N>;
|
||||
|
||||
fn subscribe_safe_block(&self) -> ForkChoiceNotifications {
|
||||
let receiver = self.chain_info.subscribe_safe_block();
|
||||
ForkChoiceNotifications(receiver)
|
||||
|
||||
@ -6,7 +6,6 @@ use crate::{
|
||||
to_range, BlockHashReader, BlockNumReader, HeaderProvider, ReceiptProvider,
|
||||
TransactionsProvider,
|
||||
};
|
||||
use alloy_consensus::Header;
|
||||
use alloy_eips::{eip2718::Encodable2718, BlockHashOrNumber};
|
||||
use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256};
|
||||
use reth_chainspec::ChainInfo;
|
||||
@ -15,7 +14,7 @@ use reth_db::{
|
||||
BlockHashMask, HeaderMask, HeaderWithHashMask, ReceiptMask, StaticFileCursor,
|
||||
TDWithHashMask, TotalDifficultyMask, TransactionMask,
|
||||
},
|
||||
table::Decompress,
|
||||
table::{Decompress, Value},
|
||||
};
|
||||
use reth_node_types::NodePrimitives;
|
||||
use reth_primitives::{transaction::recover_signers, SealedHeader, TransactionMeta};
|
||||
@ -90,17 +89,19 @@ impl<'a, N: NodePrimitives> StaticFileJarProvider<'a, N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NodePrimitives> HeaderProvider for StaticFileJarProvider<'_, N> {
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Header>> {
|
||||
impl<N: NodePrimitives<BlockHeader: Value>> HeaderProvider for StaticFileJarProvider<'_, N> {
|
||||
type Header = N::BlockHeader;
|
||||
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Self::Header>> {
|
||||
Ok(self
|
||||
.cursor()?
|
||||
.get_two::<HeaderWithHashMask<Header>>(block_hash.into())?
|
||||
.get_two::<HeaderWithHashMask<Self::Header>>(block_hash.into())?
|
||||
.filter(|(_, hash)| hash == block_hash)
|
||||
.map(|(header, _)| header))
|
||||
}
|
||||
|
||||
fn header_by_number(&self, num: BlockNumber) -> ProviderResult<Option<Header>> {
|
||||
self.cursor()?.get_one::<HeaderMask<Header>>(num.into())
|
||||
fn header_by_number(&self, num: BlockNumber) -> ProviderResult<Option<Self::Header>> {
|
||||
self.cursor()?.get_one::<HeaderMask<Self::Header>>(num.into())
|
||||
}
|
||||
|
||||
fn header_td(&self, block_hash: &BlockHash) -> ProviderResult<Option<U256>> {
|
||||
@ -115,14 +116,17 @@ impl<N: NodePrimitives> HeaderProvider for StaticFileJarProvider<'_, N> {
|
||||
Ok(self.cursor()?.get_one::<TotalDifficultyMask>(num.into())?.map(Into::into))
|
||||
}
|
||||
|
||||
fn headers_range(&self, range: impl RangeBounds<BlockNumber>) -> ProviderResult<Vec<Header>> {
|
||||
fn headers_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<Self::Header>> {
|
||||
let range = to_range(range);
|
||||
|
||||
let mut cursor = self.cursor()?;
|
||||
let mut headers = Vec::with_capacity((range.end - range.start) as usize);
|
||||
|
||||
for num in range {
|
||||
if let Some(header) = cursor.get_one::<HeaderMask<Header>>(num.into())? {
|
||||
if let Some(header) = cursor.get_one::<HeaderMask<Self::Header>>(num.into())? {
|
||||
headers.push(header);
|
||||
}
|
||||
}
|
||||
@ -130,18 +134,21 @@ impl<N: NodePrimitives> HeaderProvider for StaticFileJarProvider<'_, N> {
|
||||
Ok(headers)
|
||||
}
|
||||
|
||||
fn sealed_header(&self, number: BlockNumber) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn sealed_header(
|
||||
&self,
|
||||
number: BlockNumber,
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
Ok(self
|
||||
.cursor()?
|
||||
.get_two::<HeaderWithHashMask<Header>>(number.into())?
|
||||
.get_two::<HeaderWithHashMask<Self::Header>>(number.into())?
|
||||
.map(|(header, hash)| SealedHeader::new(header, hash)))
|
||||
}
|
||||
|
||||
fn sealed_headers_while(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
mut predicate: impl FnMut(&SealedHeader) -> bool,
|
||||
) -> ProviderResult<Vec<SealedHeader>> {
|
||||
mut predicate: impl FnMut(&SealedHeader<Self::Header>) -> bool,
|
||||
) -> ProviderResult<Vec<SealedHeader<Self::Header>>> {
|
||||
let range = to_range(range);
|
||||
|
||||
let mut cursor = self.cursor()?;
|
||||
@ -149,7 +156,7 @@ impl<N: NodePrimitives> HeaderProvider for StaticFileJarProvider<'_, N> {
|
||||
|
||||
for number in range {
|
||||
if let Some((header, hash)) =
|
||||
cursor.get_two::<HeaderWithHashMask<Header>>(number.into())?
|
||||
cursor.get_two::<HeaderWithHashMask<Self::Header>>(number.into())?
|
||||
{
|
||||
let sealed = SealedHeader::new(header, hash);
|
||||
if !predicate(&sealed) {
|
||||
|
||||
@ -1235,12 +1235,14 @@ impl<N: NodePrimitives> StaticFileWriter for StaticFileProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NodePrimitives> HeaderProvider for StaticFileProvider<N> {
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Header>> {
|
||||
impl<N: NodePrimitives<BlockHeader: Value>> HeaderProvider for StaticFileProvider<N> {
|
||||
type Header = N::BlockHeader;
|
||||
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Self::Header>> {
|
||||
self.find_static_file(StaticFileSegment::Headers, |jar_provider| {
|
||||
Ok(jar_provider
|
||||
.cursor()?
|
||||
.get_two::<HeaderWithHashMask<Header>>(block_hash.into())?
|
||||
.get_two::<HeaderWithHashMask<Self::Header>>(block_hash.into())?
|
||||
.and_then(|(header, hash)| {
|
||||
if &hash == block_hash {
|
||||
return Some(header)
|
||||
@ -1250,7 +1252,7 @@ impl<N: NodePrimitives> HeaderProvider for StaticFileProvider<N> {
|
||||
})
|
||||
}
|
||||
|
||||
fn header_by_number(&self, num: BlockNumber) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_number(&self, num: BlockNumber) -> ProviderResult<Option<Self::Header>> {
|
||||
self.get_segment_provider_from_block(StaticFileSegment::Headers, num, None)
|
||||
.and_then(|provider| provider.header_by_number(num))
|
||||
.or_else(|err| {
|
||||
@ -1283,16 +1285,22 @@ impl<N: NodePrimitives> HeaderProvider for StaticFileProvider<N> {
|
||||
})
|
||||
}
|
||||
|
||||
fn headers_range(&self, range: impl RangeBounds<BlockNumber>) -> ProviderResult<Vec<Header>> {
|
||||
fn headers_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<Self::Header>> {
|
||||
self.fetch_range_with_predicate(
|
||||
StaticFileSegment::Headers,
|
||||
to_range(range),
|
||||
|cursor, number| cursor.get_one::<HeaderMask<Header>>(number.into()),
|
||||
|cursor, number| cursor.get_one::<HeaderMask<Self::Header>>(number.into()),
|
||||
|_| true,
|
||||
)
|
||||
}
|
||||
|
||||
fn sealed_header(&self, num: BlockNumber) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn sealed_header(
|
||||
&self,
|
||||
num: BlockNumber,
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.get_segment_provider_from_block(StaticFileSegment::Headers, num, None)
|
||||
.and_then(|provider| provider.sealed_header(num))
|
||||
.or_else(|err| {
|
||||
@ -1307,14 +1315,14 @@ impl<N: NodePrimitives> HeaderProvider for StaticFileProvider<N> {
|
||||
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.fetch_range_with_predicate(
|
||||
StaticFileSegment::Headers,
|
||||
to_range(range),
|
||||
|cursor, number| {
|
||||
Ok(cursor
|
||||
.get_two::<HeaderWithHashMask<Header>>(number.into())?
|
||||
.get_two::<HeaderWithHashMask<Self::Header>>(number.into())?
|
||||
.map(|(header, hash)| SealedHeader::new(header, hash)))
|
||||
},
|
||||
predicate,
|
||||
@ -1385,8 +1393,8 @@ impl<N: NodePrimitives<SignedTx: Value + SignedTransaction, Receipt: Value>> Rec
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: FullNodePrimitives<SignedTx: Value, Receipt: Value>> TransactionsProviderExt
|
||||
for StaticFileProvider<N>
|
||||
impl<N: FullNodePrimitives<SignedTx: Value, Receipt: Value, BlockHeader: Value>>
|
||||
TransactionsProviderExt for StaticFileProvider<N>
|
||||
{
|
||||
fn transaction_hashes_by_range(
|
||||
&self,
|
||||
@ -1582,7 +1590,9 @@ impl<N: NodePrimitives> BlockNumReader for StaticFileProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: FullNodePrimitives<SignedTx: Value, Receipt: Value>> BlockReader for StaticFileProvider<N> {
|
||||
impl<N: FullNodePrimitives<SignedTx: Value, Receipt: Value, BlockHeader: Value>> BlockReader
|
||||
for StaticFileProvider<N>
|
||||
{
|
||||
type Block = N::Block;
|
||||
|
||||
fn find_block_by_hash(
|
||||
@ -1618,7 +1628,7 @@ impl<N: FullNodePrimitives<SignedTx: Value, Receipt: Value>> BlockReader for Sta
|
||||
Err(ProviderError::UnsupportedProvider)
|
||||
}
|
||||
|
||||
fn ommers(&self, _id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers(&self, _id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Self::Header>>> {
|
||||
// Required data not present in static_files
|
||||
Err(ProviderError::UnsupportedProvider)
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ use super::{
|
||||
manager::StaticFileProviderInner, metrics::StaticFileProviderMetrics, StaticFileProvider,
|
||||
};
|
||||
use crate::providers::static_file::metrics::StaticFileProviderOperation;
|
||||
use alloy_consensus::Header;
|
||||
use alloy_consensus::BlockHeader;
|
||||
use alloy_primitives::{BlockHash, BlockNumber, TxNumber, U256};
|
||||
use parking_lot::{lock_api::RwLockWriteGuard, RawRwLock, RwLock};
|
||||
use reth_codecs::Compact;
|
||||
@ -526,16 +526,19 @@ impl<N: NodePrimitives> StaticFileProviderRW<N> {
|
||||
/// Returns the current [`BlockNumber`] as seen in the static file.
|
||||
pub fn append_header(
|
||||
&mut self,
|
||||
header: &Header,
|
||||
header: &N::BlockHeader,
|
||||
total_difficulty: U256,
|
||||
hash: &BlockHash,
|
||||
) -> ProviderResult<()> {
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
N::BlockHeader: Compact,
|
||||
{
|
||||
let start = Instant::now();
|
||||
self.ensure_no_queued_prune()?;
|
||||
|
||||
debug_assert!(self.writer.user_header().segment() == StaticFileSegment::Headers);
|
||||
|
||||
self.increment_block(header.number)?;
|
||||
self.increment_block(header.number())?;
|
||||
|
||||
self.append_column(header)?;
|
||||
self.append_column(CompactU256::from(total_difficulty))?;
|
||||
|
||||
@ -179,6 +179,8 @@ impl DatabaseProviderFactory for MockEthProvider {
|
||||
}
|
||||
|
||||
impl HeaderProvider for MockEthProvider {
|
||||
type Header = Header;
|
||||
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Header>> {
|
||||
let lock = self.headers.lock();
|
||||
Ok(lock.get(block_hash).cloned())
|
||||
|
||||
@ -284,6 +284,8 @@ impl ReceiptProvider for NoopProvider {
|
||||
impl ReceiptProviderIdExt for NoopProvider {}
|
||||
|
||||
impl HeaderProvider for NoopProvider {
|
||||
type Header = Header;
|
||||
|
||||
fn header(&self, _block_hash: &BlockHash) -> ProviderResult<Option<Header>> {
|
||||
Ok(None)
|
||||
}
|
||||
@ -586,6 +588,8 @@ impl CanonStateSubscriptions for NoopProvider {
|
||||
}
|
||||
|
||||
impl ForkChoiceSubscriptions for NoopProvider {
|
||||
type Header = Header;
|
||||
|
||||
fn subscribe_safe_block(&self) -> ForkChoiceNotifications {
|
||||
let (_, rx) = watch::channel(None);
|
||||
ForkChoiceNotifications(rx)
|
||||
|
||||
@ -7,7 +7,7 @@ use crate::{
|
||||
};
|
||||
use reth_chain_state::{CanonStateSubscriptions, ForkChoiceSubscriptions};
|
||||
use reth_chainspec::EthereumHardforks;
|
||||
use reth_node_types::{BlockTy, NodeTypesWithDB, ReceiptTy, TxTy};
|
||||
use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy};
|
||||
use reth_storage_api::NodePrimitivesProvider;
|
||||
|
||||
/// Helper trait to unify all provider traits for simplicity.
|
||||
@ -15,14 +15,18 @@ pub trait FullProvider<N: NodeTypesWithDB>:
|
||||
DatabaseProviderFactory<DB = N::DB>
|
||||
+ NodePrimitivesProvider<Primitives = N::Primitives>
|
||||
+ StaticFileProviderFactory
|
||||
+ BlockReaderIdExt<Transaction = TxTy<N>, Block = BlockTy<N>, Receipt = ReceiptTy<N>>
|
||||
+ AccountReader
|
||||
+ BlockReaderIdExt<
|
||||
Transaction = TxTy<N>,
|
||||
Block = BlockTy<N>,
|
||||
Receipt = ReceiptTy<N>,
|
||||
Header = HeaderTy<N>,
|
||||
> + AccountReader
|
||||
+ StateProviderFactory
|
||||
+ EvmEnvProvider
|
||||
+ ChainSpecProvider<ChainSpec = N::ChainSpec>
|
||||
+ ChangeSetReader
|
||||
+ CanonStateSubscriptions
|
||||
+ ForkChoiceSubscriptions
|
||||
+ ForkChoiceSubscriptions<Header = HeaderTy<N>>
|
||||
+ StageCheckpointReader
|
||||
+ Clone
|
||||
+ Unpin
|
||||
@ -34,14 +38,18 @@ impl<T, N: NodeTypesWithDB> FullProvider<N> for T where
|
||||
T: DatabaseProviderFactory<DB = N::DB>
|
||||
+ NodePrimitivesProvider<Primitives = N::Primitives>
|
||||
+ StaticFileProviderFactory
|
||||
+ BlockReaderIdExt<Transaction = TxTy<N>, Block = BlockTy<N>, Receipt = ReceiptTy<N>>
|
||||
+ AccountReader
|
||||
+ BlockReaderIdExt<
|
||||
Transaction = TxTy<N>,
|
||||
Block = BlockTy<N>,
|
||||
Receipt = ReceiptTy<N>,
|
||||
Header = HeaderTy<N>,
|
||||
> + AccountReader
|
||||
+ StateProviderFactory
|
||||
+ EvmEnvProvider
|
||||
+ ChainSpecProvider<ChainSpec = N::ChainSpec>
|
||||
+ ChangeSetReader
|
||||
+ CanonStateSubscriptions
|
||||
+ ForkChoiceSubscriptions
|
||||
+ ForkChoiceSubscriptions<Header = HeaderTy<N>>
|
||||
+ StageCheckpointReader
|
||||
+ Clone
|
||||
+ Unpin
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use alloy_consensus::{BlockHeader, Header};
|
||||
use alloy_eips::BlockHashOrNumber;
|
||||
use alloy_primitives::{BlockNumber, B256};
|
||||
use reth_network_p2p::headers::downloader::SyncTarget;
|
||||
@ -7,21 +8,21 @@ use tokio::sync::watch;
|
||||
|
||||
/// Represents a gap to sync: from `local_head` to `target`
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct HeaderSyncGap {
|
||||
pub struct HeaderSyncGap<H = Header> {
|
||||
/// The local head block. Represents lower bound of sync range.
|
||||
pub local_head: SealedHeader,
|
||||
pub local_head: SealedHeader<H>,
|
||||
|
||||
/// The sync target. Represents upper bound of sync range.
|
||||
pub target: SyncTarget,
|
||||
}
|
||||
|
||||
impl HeaderSyncGap {
|
||||
impl<H: BlockHeader> HeaderSyncGap<H> {
|
||||
/// Returns `true` if the gap from the head to the target was closed
|
||||
#[inline]
|
||||
pub fn is_closed(&self) -> bool {
|
||||
match self.target.tip() {
|
||||
BlockHashOrNumber::Hash(hash) => self.local_head.hash() == hash,
|
||||
BlockHashOrNumber::Number(num) => self.local_head.number == num,
|
||||
BlockHashOrNumber::Number(num) => self.local_head.number() == num,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,6 +30,9 @@ impl HeaderSyncGap {
|
||||
/// Client trait for determining the current headers sync gap.
|
||||
#[auto_impl::auto_impl(&, Arc)]
|
||||
pub trait HeaderSyncGapProvider: Send + Sync {
|
||||
/// The header type.
|
||||
type Header: Send + Sync;
|
||||
|
||||
/// Find a current sync gap for the headers depending on the last
|
||||
/// uninterrupted block number. Last uninterrupted block represents the block number before
|
||||
/// which there are no gaps. It's up to the caller to ensure that last uninterrupted block is
|
||||
@ -37,5 +41,5 @@ pub trait HeaderSyncGapProvider: Send + Sync {
|
||||
&self,
|
||||
tip: watch::Receiver<B256>,
|
||||
highest_uninterrupted_block: BlockNumber,
|
||||
) -> ProviderResult<HeaderSyncGap>;
|
||||
) -> ProviderResult<HeaderSyncGap<Self::Header>>;
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ use crate::{
|
||||
BlockNumReader, HeaderProvider, ReceiptProvider, ReceiptProviderIdExt, TransactionVariant,
|
||||
TransactionsProvider, WithdrawalsProvider,
|
||||
};
|
||||
use alloy_consensus::Header;
|
||||
use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag};
|
||||
use alloy_primitives::{BlockNumber, B256};
|
||||
use reth_db_models::StoredBlockBodyIndices;
|
||||
@ -57,6 +56,7 @@ pub trait BlockReader:
|
||||
/// The block type this provider reads.
|
||||
type Block: reth_primitives_traits::Block<
|
||||
Body: reth_primitives_traits::BlockBody<Transaction = Self::Transaction>,
|
||||
Header = Self::Header,
|
||||
>;
|
||||
|
||||
/// Tries to find in the given block source.
|
||||
@ -98,7 +98,7 @@ pub trait BlockReader:
|
||||
/// Returns the ommers/uncle headers of the given block from the database.
|
||||
///
|
||||
/// Returns `None` if block is not found.
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Header>>>;
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Self::Header>>>;
|
||||
|
||||
/// Returns the block with matching hash from the database.
|
||||
///
|
||||
@ -187,7 +187,7 @@ impl<T: BlockReader> BlockReader for std::sync::Arc<T> {
|
||||
) -> ProviderResult<Option<(SealedBlockFor<Self::Block>, Vec<Self::Receipt>)>> {
|
||||
T::pending_block_and_receipts(self)
|
||||
}
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Self::Header>>> {
|
||||
T::ommers(self, id)
|
||||
}
|
||||
fn block_by_hash(&self, hash: B256) -> ProviderResult<Option<Self::Block>> {
|
||||
@ -256,7 +256,7 @@ impl<T: BlockReader> BlockReader for &T {
|
||||
) -> ProviderResult<Option<(SealedBlockFor<Self::Block>, Vec<Self::Receipt>)>> {
|
||||
T::pending_block_and_receipts(self)
|
||||
}
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult<Option<Vec<Self::Header>>> {
|
||||
T::ommers(self, id)
|
||||
}
|
||||
fn block_by_hash(&self, hash: B256) -> ProviderResult<Option<Self::Block>> {
|
||||
@ -321,7 +321,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt {
|
||||
///
|
||||
/// Note: This returns a [`SealedHeader`] because it's expected that this is sealed by the
|
||||
/// provider and the caller does not know the hash.
|
||||
fn pending_header(&self) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn pending_header(&self) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.sealed_header_by_id(BlockNumberOrTag::Pending.into())
|
||||
}
|
||||
|
||||
@ -329,7 +329,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt {
|
||||
///
|
||||
/// Note: This returns a [`SealedHeader`] because it's expected that this is sealed by the
|
||||
/// provider and the caller does not know the hash.
|
||||
fn latest_header(&self) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn latest_header(&self) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.sealed_header_by_id(BlockNumberOrTag::Latest.into())
|
||||
}
|
||||
|
||||
@ -337,7 +337,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt {
|
||||
///
|
||||
/// Note: This returns a [`SealedHeader`] because it's expected that this is sealed by the
|
||||
/// provider and the caller does not know the hash.
|
||||
fn safe_header(&self) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn safe_header(&self) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.sealed_header_by_id(BlockNumberOrTag::Safe.into())
|
||||
}
|
||||
|
||||
@ -345,7 +345,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt {
|
||||
///
|
||||
/// Note: This returns a [`SealedHeader`] because it's expected that this is sealed by the
|
||||
/// provider and the caller does not know the hash.
|
||||
fn finalized_header(&self) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn finalized_header(&self) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.sealed_header_by_id(BlockNumberOrTag::Finalized.into())
|
||||
}
|
||||
|
||||
@ -378,7 +378,10 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt {
|
||||
/// Returns the header with matching tag from the database
|
||||
///
|
||||
/// Returns `None` if header is not found.
|
||||
fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult<Option<Header>> {
|
||||
fn header_by_number_or_tag(
|
||||
&self,
|
||||
id: BlockNumberOrTag,
|
||||
) -> ProviderResult<Option<Self::Header>> {
|
||||
self.convert_block_number(id)?
|
||||
.map_or_else(|| Ok(None), |num| self.header_by_hash_or_number(num.into()))
|
||||
}
|
||||
@ -389,7 +392,7 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt {
|
||||
fn sealed_header_by_number_or_tag(
|
||||
&self,
|
||||
id: BlockNumberOrTag,
|
||||
) -> ProviderResult<Option<SealedHeader>> {
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
self.convert_block_number(id)?
|
||||
.map_or_else(|| Ok(None), |num| self.header_by_hash_or_number(num.into()))?
|
||||
.map_or_else(|| Ok(None), |h| Ok(Some(SealedHeader::seal(h))))
|
||||
@ -398,22 +401,28 @@ pub trait BlockReaderIdExt: BlockReader + ReceiptProviderIdExt {
|
||||
/// Returns the sealed header with the matching `BlockId` from the database.
|
||||
///
|
||||
/// Returns `None` if header is not found.
|
||||
fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult<Option<SealedHeader>>;
|
||||
fn sealed_header_by_id(
|
||||
&self,
|
||||
id: BlockId,
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>>;
|
||||
|
||||
/// Returns the header with the matching `BlockId` from the database.
|
||||
///
|
||||
/// Returns `None` if header is not found.
|
||||
fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<Header>>;
|
||||
fn header_by_id(&self, id: BlockId) -> ProviderResult<Option<Self::Header>>;
|
||||
|
||||
/// Returns the ommers with the matching tag from the database.
|
||||
fn ommers_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult<Option<Vec<Header>>> {
|
||||
fn ommers_by_number_or_tag(
|
||||
&self,
|
||||
id: BlockNumberOrTag,
|
||||
) -> ProviderResult<Option<Vec<Self::Header>>> {
|
||||
self.convert_block_number(id)?.map_or_else(|| Ok(None), |num| self.ommers(num.into()))
|
||||
}
|
||||
|
||||
/// Returns the ommers with the matching `BlockId` from the database.
|
||||
///
|
||||
/// Returns `None` if block is not found.
|
||||
fn ommers_by_id(&self, id: BlockId) -> ProviderResult<Option<Vec<Header>>>;
|
||||
fn ommers_by_id(&self, id: BlockId) -> ProviderResult<Option<Vec<Self::Header>>>;
|
||||
}
|
||||
|
||||
/// Functionality to read the last known chain blocks from the database.
|
||||
|
||||
@ -4,6 +4,9 @@ use std::time::Instant;
|
||||
|
||||
/// A type that can track updates related to fork choice updates.
|
||||
pub trait CanonChainTracker: Send + Sync {
|
||||
/// The header type.
|
||||
type Header: Send + Sync;
|
||||
|
||||
/// Notify the tracker about a received fork choice update.
|
||||
fn on_forkchoice_update_received(&self, update: &ForkchoiceState);
|
||||
|
||||
@ -19,11 +22,11 @@ pub trait CanonChainTracker: Send + Sync {
|
||||
fn last_exchanged_transition_configuration_timestamp(&self) -> Option<Instant>;
|
||||
|
||||
/// Sets the canonical head of the chain.
|
||||
fn set_canonical_head(&self, header: SealedHeader);
|
||||
fn set_canonical_head(&self, header: SealedHeader<Self::Header>);
|
||||
|
||||
/// Sets the safe block of the chain.
|
||||
fn set_safe(&self, header: SealedHeader);
|
||||
fn set_safe(&self, header: SealedHeader<Self::Header>);
|
||||
|
||||
/// Sets the finalized block of the chain.
|
||||
fn set_finalized(&self, header: SealedHeader);
|
||||
fn set_finalized(&self, header: SealedHeader<Self::Header>);
|
||||
}
|
||||
|
||||
@ -1,34 +1,40 @@
|
||||
use alloy_consensus::Header;
|
||||
use alloy_eips::BlockHashOrNumber;
|
||||
use alloy_primitives::{BlockHash, BlockNumber, U256};
|
||||
use reth_primitives::SealedHeader;
|
||||
use reth_primitives_traits::BlockHeader;
|
||||
use reth_storage_errors::provider::ProviderResult;
|
||||
use std::ops::RangeBounds;
|
||||
|
||||
/// Client trait for fetching `Header` related data.
|
||||
#[auto_impl::auto_impl(&, Arc)]
|
||||
pub trait HeaderProvider: Send + Sync {
|
||||
/// The header type this provider supports.
|
||||
type Header: BlockHeader;
|
||||
|
||||
/// Check if block is known
|
||||
fn is_known(&self, block_hash: &BlockHash) -> ProviderResult<bool> {
|
||||
self.header(block_hash).map(|header| header.is_some())
|
||||
}
|
||||
|
||||
/// Get header by block hash
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Header>>;
|
||||
fn header(&self, block_hash: &BlockHash) -> ProviderResult<Option<Self::Header>>;
|
||||
|
||||
/// Retrieves the header sealed by the given block hash.
|
||||
fn sealed_header_by_hash(&self, block_hash: BlockHash) -> ProviderResult<Option<SealedHeader>> {
|
||||
fn sealed_header_by_hash(
|
||||
&self,
|
||||
block_hash: BlockHash,
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>> {
|
||||
Ok(self.header(&block_hash)?.map(|header| SealedHeader::new(header, block_hash)))
|
||||
}
|
||||
|
||||
/// Get header by block number
|
||||
fn header_by_number(&self, num: u64) -> ProviderResult<Option<Header>>;
|
||||
fn header_by_number(&self, num: u64) -> ProviderResult<Option<Self::Header>>;
|
||||
|
||||
/// Get header by block number or hash
|
||||
fn header_by_hash_or_number(
|
||||
&self,
|
||||
hash_or_num: BlockHashOrNumber,
|
||||
) -> ProviderResult<Option<Header>> {
|
||||
) -> ProviderResult<Option<Self::Header>> {
|
||||
match hash_or_num {
|
||||
BlockHashOrNumber::Hash(hash) => self.header(&hash),
|
||||
BlockHashOrNumber::Number(num) => self.header_by_number(num),
|
||||
@ -42,16 +48,22 @@ pub trait HeaderProvider: Send + Sync {
|
||||
fn header_td_by_number(&self, number: BlockNumber) -> ProviderResult<Option<U256>>;
|
||||
|
||||
/// Get headers in range of block numbers
|
||||
fn headers_range(&self, range: impl RangeBounds<BlockNumber>) -> ProviderResult<Vec<Header>>;
|
||||
fn headers_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<Self::Header>>;
|
||||
|
||||
/// Get a single sealed header by block number.
|
||||
fn sealed_header(&self, number: BlockNumber) -> ProviderResult<Option<SealedHeader>>;
|
||||
fn sealed_header(
|
||||
&self,
|
||||
number: BlockNumber,
|
||||
) -> ProviderResult<Option<SealedHeader<Self::Header>>>;
|
||||
|
||||
/// Get headers in range of block numbers.
|
||||
fn sealed_headers_range(
|
||||
&self,
|
||||
range: impl RangeBounds<BlockNumber>,
|
||||
) -> ProviderResult<Vec<SealedHeader>> {
|
||||
) -> ProviderResult<Vec<SealedHeader<Self::Header>>> {
|
||||
self.sealed_headers_while(range, |_| true)
|
||||
}
|
||||
|
||||
@ -59,6 +71,6 @@ pub trait HeaderProvider: Send + Sync {
|
||||
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>>>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user