From 332cce1f9b193e9fe52d4903a3f6858d7fc96130 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Dec 2024 14:24:48 +0100 Subject: [PATCH] feat: add header AT to provider (#13030) Co-authored-by: Arsenii Kulikov --- Cargo.lock | 2 + .../commands/debug_cmd/in_memory_merkle.rs | 1 + bin/reth/src/commands/debug_cmd/merkle.rs | 1 + .../src/commands/debug_cmd/replay_engine.rs | 1 + crates/blockchain-tree/src/blockchain_tree.rs | 7 +- crates/chain-state/src/notifications.rs | 11 +- crates/cli/commands/Cargo.toml | 4 +- .../commands/src/init_state/without_evm.rs | 25 ++-- .../cli/commands/src/stage/dump/execution.rs | 3 + crates/cli/commands/src/stage/dump/merkle.rs | 32 ++--- .../beacon/src/engine/hooks/static_file.rs | 4 +- crates/consensus/beacon/src/engine/mod.rs | 17 ++- crates/consensus/common/src/validation.rs | 2 + crates/engine/local/Cargo.toml | 1 + crates/engine/local/src/miner.rs | 3 +- crates/engine/tree/src/tree/mod.rs | 12 +- crates/evm/src/provider.rs | 19 ++- crates/exex/exex/src/manager.rs | 6 +- crates/net/downloaders/src/bodies/bodies.rs | 13 +- crates/net/downloaders/src/bodies/task.rs | 4 +- crates/net/network/src/config.rs | 7 +- crates/net/network/src/eth_requests.rs | 14 +-- crates/net/network/src/test_utils/testnet.rs | 21 +++- crates/node/builder/src/builder/mod.rs | 14 ++- crates/node/builder/src/launch/common.rs | 2 + crates/node/builder/src/setup.rs | 4 +- crates/node/core/src/node_config.rs | 6 +- crates/node/events/src/cl.rs | 9 +- crates/optimism/rpc/src/eth/pending_block.rs | 1 + crates/optimism/rpc/src/witness.rs | 4 +- crates/payload/basic/src/lib.rs | 6 +- crates/primitives-traits/src/block/header.rs | 26 ++-- crates/rpc/rpc-builder/src/eth.rs | 7 +- crates/rpc/rpc-builder/src/lib.rs | 27 +++- crates/rpc/rpc-eth-api/src/helpers/fee.rs | 18 ++- .../rpc-eth-api/src/helpers/pending_block.rs | 5 +- crates/rpc/rpc-eth-types/src/cache/mod.rs | 21 +++- crates/rpc/rpc-eth-types/src/gas_oracle.rs | 6 +- crates/rpc/rpc/src/eth/core.rs | 10 +- crates/rpc/rpc/src/eth/filter.rs | 19 +-- .../rpc/rpc/src/eth/helpers/pending_block.rs | 1 + crates/rpc/rpc/src/validation.rs | 4 +- crates/stages/stages/src/stages/bodies.rs | 6 +- crates/stages/stages/src/stages/execution.rs | 11 +- .../stages/src/stages/hashing_account.rs | 6 +- crates/stages/stages/src/stages/headers.rs | 40 +++--- crates/stages/stages/src/stages/merkle.rs | 5 +- .../stages/src/stages/sender_recovery.rs | 5 +- crates/stages/stages/src/stages/utils.rs | 2 +- .../static-file/src/segments/headers.rs | 15 ++- .../static-file/src/static_file_producer.rs | 2 +- crates/storage/db-common/Cargo.toml | 1 + crates/storage/db-common/src/init.rs | 21 ++-- .../src/providers/blockchain_provider.rs | 80 +++++++----- .../provider/src/providers/consistent.rs | 67 +++++----- .../provider/src/providers/database/mod.rs | 44 ++++--- .../src/providers/database/provider.rs | 118 ++++++++++-------- crates/storage/provider/src/providers/mod.rs | 63 +++++----- .../provider/src/providers/static_file/jar.rs | 35 +++--- .../src/providers/static_file/manager.rs | 38 +++--- .../src/providers/static_file/writer.rs | 11 +- .../storage/provider/src/test_utils/mock.rs | 2 + .../storage/provider/src/test_utils/noop.rs | 4 + crates/storage/provider/src/traits/full.rs | 22 ++-- .../provider/src/traits/header_sync_gap.rs | 14 ++- crates/storage/storage-api/src/block.rs | 37 +++--- crates/storage/storage-api/src/chain_info.rs | 9 +- crates/storage/storage-api/src/header.rs | 32 +++-- crates/transaction-pool/src/maintain.rs | 9 +- examples/db-access/Cargo.toml | 1 + examples/db-access/src/main.rs | 3 +- 71 files changed, 669 insertions(+), 434 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf011d0f6..2a9d52220 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2987,6 +2987,7 @@ dependencies = [ name = "example-db-access" version = "0.0.0" dependencies = [ + "alloy-consensus", "alloy-primitives", "alloy-rpc-types-eth", "eyre", @@ -7202,6 +7203,7 @@ dependencies = [ name = "reth-engine-local" version = "1.1.2" dependencies = [ + "alloy-consensus", "alloy-primitives", "alloy-rpc-types-engine", "eyre", diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index 870dc1ddf..6fbfa33b8 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -63,6 +63,7 @@ impl> Command { Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, >( diff --git a/bin/reth/src/commands/debug_cmd/merkle.rs b/bin/reth/src/commands/debug_cmd/merkle.rs index 78e32df52..16a1f1112 100644 --- a/bin/reth/src/commands/debug_cmd/merkle.rs +++ b/bin/reth/src/commands/debug_cmd/merkle.rs @@ -62,6 +62,7 @@ impl> Command { Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, >( diff --git a/bin/reth/src/commands/debug_cmd/replay_engine.rs b/bin/reth/src/commands/debug_cmd/replay_engine.rs index f0016a129..4b98fc85d 100644 --- a/bin/reth/src/commands/debug_cmd/replay_engine.rs +++ b/bin/reth/src/commands/debug_cmd/replay_engine.rs @@ -61,6 +61,7 @@ impl> Command { Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, >( diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index ec9beb20a..757729d54 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -1424,7 +1424,12 @@ mod tests { } fn setup_genesis< - N: ProviderNodeTypes>, + N: ProviderNodeTypes< + Primitives: FullNodePrimitives< + BlockBody = reth_primitives::BlockBody, + BlockHeader = reth_primitives::Header, + >, + >, >( factory: &ProviderFactory, mut genesis: SealedBlock, diff --git a/crates/chain-state/src/notifications.rs b/crates/chain-state/src/notifications.rs index c4e041543..498528813 100644 --- a/crates/chain-state/src/notifications.rs +++ b/crates/chain-state/src/notifications.rs @@ -162,19 +162,22 @@ pub struct ForkChoiceNotifications( /// A trait that allows to register to fork choice related events /// and get notified when a new fork choice is available. pub trait ForkChoiceSubscriptions: Send + Sync { + /// Block Header type. + type Header: Clone + Send + Sync + 'static; + /// Get notified when a new safe block of the chain is selected. - fn subscribe_safe_block(&self) -> ForkChoiceNotifications; + fn subscribe_safe_block(&self) -> ForkChoiceNotifications; /// Get notified when a new finalized block of the chain is selected. - fn subscribe_finalized_block(&self) -> ForkChoiceNotifications; + fn subscribe_finalized_block(&self) -> ForkChoiceNotifications; /// Convenience method to get a stream of the new safe blocks of the chain. - fn safe_block_stream(&self) -> ForkChoiceStream { + fn safe_block_stream(&self) -> ForkChoiceStream> { ForkChoiceStream::new(self.subscribe_safe_block().0) } /// Convenience method to get a stream of the new finalized blocks of the chain. - fn finalized_block_stream(&self) -> ForkChoiceStream { + fn finalized_block_stream(&self) -> ForkChoiceStream> { ForkChoiceStream::new(self.subscribe_finalized_block().0) } } diff --git a/crates/cli/commands/Cargo.toml b/crates/cli/commands/Cargo.toml index 90acb82d7..2220efda5 100644 --- a/crates/cli/commands/Cargo.toml +++ b/crates/cli/commands/Cargo.toml @@ -17,7 +17,7 @@ reth-cli.workspace = true reth-ethereum-cli.workspace = true reth-cli-runner.workspace = true reth-cli-util.workspace = true -reth-codecs = { workspace = true, optional = true } +reth-codecs.workspace = true reth-config.workspace = true reth-consensus.workspace = true reth-db = { workspace = true, features = ["mdbx"] } @@ -110,7 +110,7 @@ arbitrary = [ "reth-prune-types/test-utils", "reth-stages-types/test-utils", "reth-trie-common/test-utils", - "reth-codecs?/arbitrary", + "reth-codecs/arbitrary", "reth-prune-types?/arbitrary", "reth-stages-types?/arbitrary", "reth-trie-common?/arbitrary", diff --git a/crates/cli/commands/src/init_state/without_evm.rs b/crates/cli/commands/src/init_state/without_evm.rs index 22236d14c..f8f72709a 100644 --- a/crates/cli/commands/src/init_state/without_evm.rs +++ b/crates/cli/commands/src/init_state/without_evm.rs @@ -1,7 +1,8 @@ use alloy_primitives::{BlockNumber, B256, U256}; use alloy_rlp::Decodable; -use alloy_consensus::Header; +use alloy_consensus::{BlockHeader, Header}; +use reth_codecs::Compact; use reth_node_builder::NodePrimitives; use reth_primitives::{SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment}; use reth_provider::{ @@ -27,26 +28,26 @@ pub(crate) fn read_header_from_file(path: PathBuf) -> Result( provider_rw: &Provider, - header: SealedHeader, + header: SealedHeader<::BlockHeader>, total_difficulty: U256, ) -> Result<(), eyre::Error> where - Provider: StaticFileProviderFactory + Provider: StaticFileProviderFactory> + StageCheckpointWriter - + BlockWriter>, + + BlockWriter::Block>, { info!(target: "reth::cli", "Setting up dummy EVM chain before importing state."); let static_file_provider = provider_rw.static_file_provider(); // Write EVM dummy data up to `header - 1` block - append_dummy_chain(&static_file_provider, header.number - 1)?; + append_dummy_chain(&static_file_provider, header.number() - 1)?; info!(target: "reth::cli", "Appending first valid block."); append_first_block(provider_rw, &header, total_difficulty)?; for stage in StageId::ALL { - provider_rw.save_stage_checkpoint(stage, StageCheckpoint::new(header.number))?; + provider_rw.save_stage_checkpoint(stage, StageCheckpoint::new(header.number()))?; } info!(target: "reth::cli", "Set up finished."); @@ -60,12 +61,12 @@ where /// height. fn append_first_block( provider_rw: &Provider, - header: &SealedHeader, + header: &SealedHeader<::BlockHeader>, total_difficulty: U256, ) -> Result<(), eyre::Error> where - Provider: BlockWriter> - + StaticFileProviderFactory, + Provider: BlockWriter::Block> + + StaticFileProviderFactory>, { provider_rw.insert_block( SealedBlockWithSenders::new(SealedBlock::new(header.clone(), Default::default()), vec![]) @@ -81,9 +82,9 @@ where &header.hash(), )?; - sf_provider.latest_writer(StaticFileSegment::Receipts)?.increment_block(header.number)?; + sf_provider.latest_writer(StaticFileSegment::Receipts)?.increment_block(header.number())?; - sf_provider.latest_writer(StaticFileSegment::Transactions)?.increment_block(header.number)?; + sf_provider.latest_writer(StaticFileSegment::Transactions)?.increment_block(header.number())?; Ok(()) } @@ -93,7 +94,7 @@ where /// * Headers: It will push an empty block. /// * Transactions: It will not push any tx, only increments the end block range. /// * Receipts: It will not push any receipt, only increments the end block range. -fn append_dummy_chain( +fn append_dummy_chain>( sf_provider: &StaticFileProvider, target_height: BlockNumber, ) -> Result<(), eyre::Error> { diff --git a/crates/cli/commands/src/stage/dump/execution.rs b/crates/cli/commands/src/stage/dump/execution.rs index 70fd23f98..73d2e8a9f 100644 --- a/crates/cli/commands/src/stage/dump/execution.rs +++ b/crates/cli/commands/src/stage/dump/execution.rs @@ -31,6 +31,7 @@ where Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, E: BlockExecutorProvider, @@ -143,6 +144,7 @@ fn unwind_and_copy< Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, >( @@ -186,6 +188,7 @@ where Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, E: BlockExecutorProvider, diff --git a/crates/cli/commands/src/stage/dump/merkle.rs b/crates/cli/commands/src/stage/dump/merkle.rs index ce1874372..59a25c492 100644 --- a/crates/cli/commands/src/stage/dump/merkle.rs +++ b/crates/cli/commands/src/stage/dump/merkle.rs @@ -25,21 +25,23 @@ use reth_stages::{ }; use tracing::info; -pub(crate) async fn dump_merkle_stage< - N: ProviderNodeTypes< - DB = Arc, - Primitives: NodePrimitives< - Block = reth_primitives::Block, - Receipt = reth_primitives::Receipt, - >, - >, ->( +pub(crate) async fn dump_merkle_stage( db_tool: &DbTool, from: BlockNumber, to: BlockNumber, output_datadir: ChainPath, should_run: bool, -) -> Result<()> { +) -> Result<()> +where + N: ProviderNodeTypes< + DB = Arc, + Primitives: NodePrimitives< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, + >, + >, +{ let (output_db, tip_block_number) = setup(from, to, &output_datadir.db(), db_tool)?; output_db.update(|tx| { @@ -81,6 +83,7 @@ fn unwind_and_copy< Primitives: NodePrimitives< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, >, >( @@ -161,11 +164,10 @@ fn unwind_and_copy< } /// Try to re-execute the stage straight away -fn dry_run( - output_provider_factory: ProviderFactory, - to: u64, - from: u64, -) -> eyre::Result<()> { +fn dry_run(output_provider_factory: ProviderFactory, to: u64, from: u64) -> eyre::Result<()> +where + N: ProviderNodeTypes>, +{ info!(target: "reth::cli", "Executing stage."); let provider = output_provider_factory.database_provider_rw()?; diff --git a/crates/consensus/beacon/src/engine/hooks/static_file.rs b/crates/consensus/beacon/src/engine/hooks/static_file.rs index 7cd286f65..b4b38239a 100644 --- a/crates/consensus/beacon/src/engine/hooks/static_file.rs +++ b/crates/consensus/beacon/src/engine/hooks/static_file.rs @@ -36,7 +36,7 @@ where Provider: StaticFileProviderFactory + DatabaseProviderFactory< Provider: StaticFileProviderFactory< - Primitives: NodePrimitives, + Primitives: NodePrimitives, > + StageCheckpointReader + BlockReader + ChainStateBlockReader, @@ -152,7 +152,7 @@ where Provider: StaticFileProviderFactory + DatabaseProviderFactory< Provider: StaticFileProviderFactory< - Primitives: NodePrimitives, + Primitives: NodePrimitives, > + StageCheckpointReader + BlockReader + ChainStateBlockReader, diff --git a/crates/consensus/beacon/src/engine/mod.rs b/crates/consensus/beacon/src/engine/mod.rs index 7a894f08e..f188e495b 100644 --- a/crates/consensus/beacon/src/engine/mod.rs +++ b/crates/consensus/beacon/src/engine/mod.rs @@ -21,7 +21,7 @@ use reth_network_p2p::{ sync::{NetworkSyncUpdater, SyncState}, EthBlockClient, }; -use reth_node_types::{Block, BlockTy, NodeTypesWithEngine}; +use reth_node_types::{Block, BlockTy, HeaderTy, NodeTypesWithEngine}; use reth_payload_builder::PayloadBuilderHandle; use reth_payload_builder_primitives::PayloadBuilder; use reth_payload_primitives::{PayloadAttributes, PayloadBuilderAttributes}; @@ -234,9 +234,9 @@ impl BeaconConsensusEngine where N: EngineNodeTypes, BT: BlockchainTreeEngine - + BlockReader> + + BlockReader, Header = HeaderTy> + BlockIdReader - + CanonChainTracker + + CanonChainTracker
> + StageCheckpointReader + ChainSpecProvider + 'static, @@ -1804,9 +1804,9 @@ where N: EngineNodeTypes, Client: EthBlockClient + 'static, BT: BlockchainTreeEngine - + BlockReader> + + BlockReader, Header = HeaderTy> + BlockIdReader - + CanonChainTracker + + CanonChainTracker
> + StageCheckpointReader + ChainSpecProvider + Unpin @@ -2179,7 +2179,12 @@ mod tests { fn insert_blocks< 'a, - N: ProviderNodeTypes>, + N: ProviderNodeTypes< + Primitives: FullNodePrimitives< + BlockBody = reth_primitives::BlockBody, + BlockHeader = reth_primitives::Header, + >, + >, >( provider_factory: ProviderFactory, mut blocks: impl Iterator, diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index dce7d2579..2d681be44 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -391,6 +391,8 @@ mod tests { } impl HeaderProvider for Provider { + type Header = Header; + fn is_known(&self, _block_hash: &BlockHash) -> ProviderResult { Ok(self.is_known) } diff --git a/crates/engine/local/Cargo.toml b/crates/engine/local/Cargo.toml index d8a66e65e..b3ad169e3 100644 --- a/crates/engine/local/Cargo.toml +++ b/crates/engine/local/Cargo.toml @@ -29,6 +29,7 @@ reth-transaction-pool.workspace = true reth-stages-api.workspace = true # alloy +alloy-consensus.workspace = true alloy-primitives.workspace = true alloy-rpc-types-engine.workspace = true diff --git a/crates/engine/local/src/miner.rs b/crates/engine/local/src/miner.rs index a5c7cf4d4..29418c0b7 100644 --- a/crates/engine/local/src/miner.rs +++ b/crates/engine/local/src/miner.rs @@ -1,5 +1,6 @@ //! Contains the implementation of the mining mode for the local engine. +use alloy_consensus::BlockHeader; use alloy_primitives::{TxHash, B256}; use alloy_rpc_types_engine::{CancunPayloadFields, ExecutionPayloadSidecar, ForkchoiceState}; use eyre::OptionExt; @@ -114,7 +115,7 @@ where to_engine, mode, payload_builder, - last_timestamp: latest_header.timestamp, + last_timestamp: latest_header.timestamp(), last_block_hashes: vec![latest_header.hash()], }; diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index cdd066cdc..16e07e518 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -540,9 +540,13 @@ impl std::fmt::Debug impl EngineApiTreeHandler where - N: NodePrimitives, + N: NodePrimitives< + Block = reth_primitives::Block, + BlockHeader = reth_primitives::Header, + Receipt = reth_primitives::Receipt, + >, P: DatabaseProviderFactory - + BlockReader + + BlockReader + StateProviderFactory + StateReader + Clone @@ -1357,7 +1361,7 @@ where // update the tracked chain height, after backfill sync both the canonical height and // persisted height are the same self.state.tree_state.set_canonical_head(new_head.num_hash()); - self.persistence_state.finish(new_head.hash(), new_head.number); + self.persistence_state.finish(new_head.hash(), new_head.number()); // update the tracked canonical head self.canonical_in_memory_state.set_canonical_head(new_head); @@ -1622,7 +1626,7 @@ where // the hash could belong to an unknown block or a persisted block if let Some(header) = self.provider.header(&hash)? { - debug!(target: "engine::tree", %hash, number = %header.number, "found canonical state for block in database"); + debug!(target: "engine::tree", %hash, number = %header.number(), "found canonical state for block in database"); // the block is known and persisted let historical = self.provider.state_by_block_hash(hash)?; return Ok(Some(historical)) diff --git a/crates/evm/src/provider.rs b/crates/evm/src/provider.rs index 5f86eb74d..ec2f1803d 100644 --- a/crates/evm/src/provider.rs +++ b/crates/evm/src/provider.rs @@ -3,7 +3,6 @@ use crate::ConfigureEvmEnv; use alloy_consensus::Header; use alloy_eips::BlockHashOrNumber; -use reth_primitives::NodePrimitives; use reth_storage_errors::provider::ProviderResult; use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}; @@ -13,7 +12,7 @@ use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}; /// This type is mainly used to provide required data to configure the EVM environment that is /// usually stored on disk. #[auto_impl::auto_impl(&, Arc)] -pub trait EvmEnvProvider: Send + Sync { +pub trait EvmEnvProvider: Send + Sync { /// Fills the [`CfgEnvWithHandlerCfg`] and [BlockEnv] fields with values specific to the given /// [BlockHashOrNumber]. fn fill_env_at( @@ -24,17 +23,17 @@ pub trait EvmEnvProvider: Se evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
; + EvmConfig: ConfigureEvmEnv
; /// Fills the default [`CfgEnvWithHandlerCfg`] and [BlockEnv] fields with values specific to the /// given block header. fn env_with_header( &self, - header: &N::BlockHeader, + header: &H, evm_config: EvmConfig, ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
, { let mut cfg = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), SpecId::LATEST); let mut block_env = BlockEnv::default(); @@ -48,11 +47,11 @@ pub trait EvmEnvProvider: Se &self, cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, - header: &N::BlockHeader, + header: &H, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
; + EvmConfig: ConfigureEvmEnv
; /// Fills the [`CfgEnvWithHandlerCfg`] fields with values specific to the given /// [BlockHashOrNumber]. @@ -63,15 +62,15 @@ pub trait EvmEnvProvider: Se evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
; + EvmConfig: ConfigureEvmEnv
; /// Fills the [`CfgEnvWithHandlerCfg`] fields with values specific to the given block header. fn fill_cfg_env_with_header( &self, cfg: &mut CfgEnvWithHandlerCfg, - header: &N::BlockHeader, + header: &H, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
; + EvmConfig: ConfigureEvmEnv
; } diff --git a/crates/exex/exex/src/manager.rs b/crates/exex/exex/src/manager.rs index a3b92e9f1..16a930526 100644 --- a/crates/exex/exex/src/manager.rs +++ b/crates/exex/exex/src/manager.rs @@ -246,7 +246,7 @@ pub struct ExExManager { /// Write-Ahead Log for the [`ExExNotification`]s. wal: Wal, /// A stream of finalized headers. - finalized_header_stream: ForkChoiceStream, + finalized_header_stream: ForkChoiceStream>, /// A handle to the `ExEx` manager. handle: ExExManagerHandle, @@ -270,7 +270,7 @@ where handles: Vec>, max_capacity: usize, wal: Wal, - finalized_header_stream: ForkChoiceStream, + finalized_header_stream: ForkChoiceStream>, ) -> Self { let num_exexs = handles.len(); @@ -355,7 +355,7 @@ where /// /// This function checks if all ExExes are on the canonical chain and finalizes the WAL if /// necessary. - fn finalize_wal(&self, finalized_header: SealedHeader) -> eyre::Result<()> { + fn finalize_wal(&self, finalized_header: SealedHeader) -> eyre::Result<()> { debug!(target: "exex::manager", header = ?finalized_header.num_hash(), "Received finalized header"); // Check if all ExExes are on the canonical chain diff --git a/crates/net/downloaders/src/bodies/bodies.rs b/crates/net/downloaders/src/bodies/bodies.rs index 82f45dd23..682995e7e 100644 --- a/crates/net/downloaders/src/bodies/bodies.rs +++ b/crates/net/downloaders/src/bodies/bodies.rs @@ -1,5 +1,6 @@ use super::queue::BodiesRequestQueue; use crate::{bodies::task::TaskDownloader, metrics::BodyDownloaderMetrics}; +use alloy_consensus::BlockHeader; use alloy_primitives::BlockNumber; use futures::Stream; use futures_util::StreamExt; @@ -14,7 +15,7 @@ use reth_network_p2p::{ error::{DownloadError, DownloadResult}, }; use reth_primitives::SealedHeader; -use reth_primitives_traits::size::InMemorySize; +use reth_primitives_traits::{size::InMemorySize, BlockHeader as _}; use reth_storage_api::HeaderProvider; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use std::{ @@ -71,7 +72,7 @@ where Provider: HeaderProvider + Unpin + 'static, { /// Returns the next contiguous request. - fn next_headers_request(&self) -> DownloadResult>> { + fn next_headers_request(&self) -> DownloadResult>>> { let start_at = match self.in_progress_queue.last_requested_block_number { Some(num) => num + 1, None => *self.download_range.start(), @@ -96,7 +97,7 @@ where &self, range: RangeInclusive, max_non_empty: u64, - ) -> DownloadResult>> { + ) -> DownloadResult>>> { if range.is_empty() || max_non_empty == 0 { return Ok(None) } @@ -109,7 +110,7 @@ where let mut collected = 0; let mut non_empty_headers = 0; let headers = self.provider.sealed_headers_while(range.clone(), |header| { - let should_take = range.contains(&header.number) && + let should_take = range.contains(&header.number()) && non_empty_headers < max_non_empty && collected < self.stream_batch_size; @@ -300,7 +301,7 @@ where impl BodyDownloader for BodiesDownloader where B: BodiesClient + 'static, - Provider: HeaderProvider + Unpin + 'static, + Provider: HeaderProvider
+ Unpin + 'static, { type Body = B::Body; @@ -350,7 +351,7 @@ where impl Stream for BodiesDownloader where B: BodiesClient + 'static, - Provider: HeaderProvider + Unpin + 'static, + Provider: HeaderProvider
+ Unpin + 'static, { type Item = BodyDownloaderResult; diff --git a/crates/net/downloaders/src/bodies/task.rs b/crates/net/downloaders/src/bodies/task.rs index a2b63c8ed..89af9813e 100644 --- a/crates/net/downloaders/src/bodies/task.rs +++ b/crates/net/downloaders/src/bodies/task.rs @@ -52,10 +52,10 @@ impl TaskDownloader { /// /// fn t< /// B: BodiesClient + 'static, - /// Provider: HeaderProvider + Unpin + 'static, + /// Provider: HeaderProvider
+ Unpin + 'static, /// >( /// client: Arc, - /// consensus: Arc>, + /// consensus: Arc>, /// provider: Provider, /// ) { /// let downloader = BodiesDownloaderBuilder::default().build(client, consensus, provider); diff --git a/crates/net/network/src/config.rs b/crates/net/network/src/config.rs index a7d8a98fa..bde2cf78d 100644 --- a/crates/net/network/src/config.rs +++ b/crates/net/network/src/config.rs @@ -147,8 +147,11 @@ where impl NetworkConfig where - C: BlockReader - + HeaderProvider + C: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + HeaderProvider + Clone + Unpin + 'static, diff --git a/crates/net/network/src/eth_requests.rs b/crates/net/network/src/eth_requests.rs index bb45507bd..ee8640daa 100644 --- a/crates/net/network/src/eth_requests.rs +++ b/crates/net/network/src/eth_requests.rs @@ -4,7 +4,7 @@ use crate::{ budget::DEFAULT_BUDGET_TRY_DRAIN_DOWNLOADERS, metered_poll_nested_stream_with_budget, metrics::EthRequestHandlerMetrics, }; -use alloy_consensus::Header; +use alloy_consensus::BlockHeader; use alloy_eips::BlockHashOrNumber; use alloy_rlp::Encodable; use futures::StreamExt; @@ -83,7 +83,7 @@ where C: BlockReader + HeaderProvider + ReceiptProvider, { /// Returns the list of requested headers - fn get_headers_response(&self, request: GetBlockHeaders) -> Vec
{ + fn get_headers_response(&self, request: GetBlockHeaders) -> Vec { let GetBlockHeaders { start_block, limit, skip, direction } = request; let mut headers = Vec::new(); @@ -105,7 +105,7 @@ where if let Some(header) = self.client.header_by_hash_or_number(block).unwrap_or_default() { match direction { HeadersDirection::Rising => { - if let Some(next) = (header.number + 1).checked_add(skip) { + if let Some(next) = (header.number() + 1).checked_add(skip) { block = next.into() } else { break @@ -116,14 +116,14 @@ where // prevent under flows for block.number == 0 and `block.number - skip < // 0` if let Some(next) = - header.number.checked_sub(1).and_then(|num| num.checked_sub(skip)) + header.number().checked_sub(1).and_then(|num| num.checked_sub(skip)) { block = next.into() } else { break } } else { - block = header.parent_hash.into() + block = header.parent_hash().into() } } } @@ -146,7 +146,7 @@ where &self, _peer_id: PeerId, request: GetBlockHeaders, - response: oneshot::Sender>>, + response: oneshot::Sender>>, ) { self.metrics.eth_headers_requests_received_total.increment(1); let headers = self.get_headers_response(request); @@ -225,7 +225,7 @@ where impl Future for EthRequestHandler where C: BlockReader - + HeaderProvider + + HeaderProvider
+ Unpin, { type Output = (); diff --git a/crates/net/network/src/test_utils/testnet.rs b/crates/net/network/src/test_utils/testnet.rs index 9801ecf92..bdd021183 100644 --- a/crates/net/network/src/test_utils/testnet.rs +++ b/crates/net/network/src/test_utils/testnet.rs @@ -194,8 +194,11 @@ where impl Testnet where - C: BlockReader - + HeaderProvider + C: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + HeaderProvider + Clone + Unpin + 'static, @@ -257,8 +260,11 @@ impl fmt::Debug for Testnet { impl Future for Testnet where - C: BlockReader - + HeaderProvider + C: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + HeaderProvider + Unpin + 'static, Pool: TransactionPool + Unpin + 'static, @@ -455,8 +461,11 @@ where impl Future for Peer where - C: BlockReader - + HeaderProvider + C: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + HeaderProvider + Unpin + 'static, Pool: TransactionPool + Unpin + 'static, diff --git a/crates/node/builder/src/builder/mod.rs b/crates/node/builder/src/builder/mod.rs index 06d5294d8..b311cc4e2 100644 --- a/crates/node/builder/src/builder/mod.rs +++ b/crates/node/builder/src/builder/mod.rs @@ -651,8 +651,11 @@ impl BuilderContext { pub fn start_network(&self, builder: NetworkBuilder<(), ()>, pool: Pool) -> NetworkHandle where Pool: TransactionPool + Unpin + 'static, - Node::Provider: - BlockReader, + Node::Provider: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + >, { self.start_network_with(builder, pool, Default::default()) } @@ -671,8 +674,11 @@ impl BuilderContext { ) -> NetworkHandle where Pool: TransactionPool + Unpin + 'static, - Node::Provider: - BlockReader, + Node::Provider: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + >, { let (handle, network, txpool, eth) = builder .transactions(pool, tx_config) diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index 2d126266a..25c81a8d5 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -385,6 +385,7 @@ where Block = reth_primitives::Block, BlockBody = reth_primitives::BlockBody, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, { let factory = ProviderFactory::new( @@ -456,6 +457,7 @@ where Block = reth_primitives::Block, BlockBody = reth_primitives::BlockBody, Receipt = reth_primitives::Receipt, + BlockHeader = reth_primitives::Header, >, { let factory = self.create_provider_factory().await?; diff --git a/crates/node/builder/src/setup.rs b/crates/node/builder/src/setup.rs index ec4ee4956..0a0e4f10d 100644 --- a/crates/node/builder/src/setup.rs +++ b/crates/node/builder/src/setup.rs @@ -14,7 +14,7 @@ use reth_exex::ExExManagerHandle; use reth_network_p2p::{ bodies::downloader::BodyDownloader, headers::downloader::HeaderDownloader, BlockClient, }; -use reth_node_api::{BodyTy, HeaderTy}; +use reth_node_api::{BodyTy, HeaderTy, NodePrimitives}; use reth_provider::{providers::ProviderNodeTypes, ProviderFactory}; use reth_stages::{prelude::DefaultStages, stages::ExecutionStage, Pipeline, StageSet}; use reth_static_file::StaticFileProducer; @@ -41,6 +41,7 @@ where N: ProviderNodeTypes, Client: BlockClient
, Body = BodyTy> + 'static, Executor: BlockExecutorProvider, + N::Primitives: NodePrimitives, { // building network downloaders using the fetch client let header_downloader = ReverseHeadersDownloaderBuilder::new(config.headers) @@ -88,6 +89,7 @@ where H: HeaderDownloader
> + 'static, B: BodyDownloader> + 'static, Executor: BlockExecutorProvider, + N::Primitives: NodePrimitives, { let mut builder = Pipeline::::builder(); diff --git a/crates/node/core/src/node_config.rs b/crates/node/core/src/node_config.rs index 2fd39bde8..861e47fc3 100644 --- a/crates/node/core/src/node_config.rs +++ b/crates/node/core/src/node_config.rs @@ -319,9 +319,9 @@ impl NodeConfig { Ok(Head { number: head, hash, - difficulty: header.difficulty, + difficulty: header.difficulty(), total_difficulty, - timestamp: header.timestamp, + timestamp: header.timestamp(), }) } @@ -344,7 +344,7 @@ impl NodeConfig { // try to look up the header in the database if let Some(header) = header { info!(target: "reth::cli", ?tip, "Successfully looked up tip block in the database"); - return Ok(header.number) + return Ok(header.number()) } Ok(self.fetch_tip_from_network(client, tip.into()).await.number()) diff --git a/crates/node/events/src/cl.rs b/crates/node/events/src/cl.rs index bf0d4a59b..dac13fe07 100644 --- a/crates/node/events/src/cl.rs +++ b/crates/node/events/src/cl.rs @@ -1,5 +1,6 @@ //! Events related to Consensus Layer health. +use alloy_consensus::Header; use futures::Stream; use reth_storage_api::CanonChainTracker; use std::{ @@ -20,9 +21,9 @@ const NO_TRANSITION_CONFIG_EXCHANGED_PERIOD: Duration = Duration::from_secs(120) const NO_FORKCHOICE_UPDATE_RECEIVED_PERIOD: Duration = Duration::from_secs(120); /// A Stream of [`ConsensusLayerHealthEvent`]. -pub struct ConsensusLayerHealthEvents { +pub struct ConsensusLayerHealthEvents { interval: Interval, - canon_chain: Box, + canon_chain: Box>, } impl fmt::Debug for ConsensusLayerHealthEvents { @@ -31,9 +32,9 @@ impl fmt::Debug for ConsensusLayerHealthEvents { } } -impl ConsensusLayerHealthEvents { +impl ConsensusLayerHealthEvents { /// Creates a new [`ConsensusLayerHealthEvents`] with the given canonical chain tracker. - pub fn new(canon_chain: Box) -> Self { + pub fn new(canon_chain: Box>) -> Self { // Skip the first tick to prevent the false `ConsensusLayerHealthEvent::NeverSeen` event. let interval = tokio::time::interval_at(Instant::now() + CHECK_INTERVAL, CHECK_INTERVAL); Self { interval, canon_chain } diff --git a/crates/optimism/rpc/src/eth/pending_block.rs b/crates/optimism/rpc/src/eth/pending_block.rs index 98ea65778..852c4454f 100644 --- a/crates/optimism/rpc/src/eth/pending_block.rs +++ b/crates/optimism/rpc/src/eth/pending_block.rs @@ -27,6 +27,7 @@ where Provider: BlockReaderIdExt< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, > + EvmEnvProvider + ChainSpecProvider + StateProviderFactory, diff --git a/crates/optimism/rpc/src/witness.rs b/crates/optimism/rpc/src/witness.rs index ed9d77e73..278c785cb 100644 --- a/crates/optimism/rpc/src/witness.rs +++ b/crates/optimism/rpc/src/witness.rs @@ -31,7 +31,7 @@ impl OpDebugWitnessApi { impl OpDebugWitnessApi where - Provider: BlockReaderIdExt, + Provider: BlockReaderIdExt
, { /// Fetches the parent header by hash. fn parent_header(&self, parent_block_hash: B256) -> ProviderResult { @@ -45,7 +45,7 @@ where impl DebugExecutionWitnessApiServer for OpDebugWitnessApi where - Provider: BlockReaderIdExt + Provider: BlockReaderIdExt
+ StateProviderFactory + ChainSpecProvider + 'static, diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 0ab411d3e..8e9c06865 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -132,7 +132,11 @@ impl BasicPayloadJobGenerator PayloadJobGenerator for BasicPayloadJobGenerator where - Client: StateProviderFactory + BlockReaderIdExt + Clone + Unpin + 'static, + Client: StateProviderFactory + + BlockReaderIdExt
+ + Clone + + Unpin + + 'static, Pool: TransactionPool + Unpin + 'static, Tasks: TaskSpawner + Clone + Unpin + 'static, Builder: PayloadBuilder + Unpin + 'static, diff --git a/crates/primitives-traits/src/block/header.rs b/crates/primitives-traits/src/block/header.rs index 6ac85d82c..47d50a45b 100644 --- a/crates/primitives-traits/src/block/header.rs +++ b/crates/primitives-traits/src/block/header.rs @@ -30,27 +30,15 @@ pub trait BlockHeader: + MaybeSerde + MaybeArbitrary + MaybeSerdeBincodeCompat + + AsRef + 'static { + /// Returns whether this header corresponds to an empty block. + fn is_empty(&self) -> bool; } -impl BlockHeader for T where - T: Send - + Sync - + Unpin - + Clone - + Default - + fmt::Debug - + PartialEq - + Eq - + alloy_rlp::Encodable - + alloy_rlp::Decodable - + alloy_consensus::BlockHeader - + Sealable - + InMemorySize - + MaybeSerde - + MaybeArbitrary - + MaybeSerdeBincodeCompat - + 'static -{ +impl BlockHeader for alloy_consensus::Header { + fn is_empty(&self) -> bool { + self.is_empty() + } } diff --git a/crates/rpc/rpc-builder/src/eth.rs b/crates/rpc/rpc-builder/src/eth.rs index 2a781fc08..283fba6e9 100644 --- a/crates/rpc/rpc-builder/src/eth.rs +++ b/crates/rpc/rpc-builder/src/eth.rs @@ -29,8 +29,11 @@ pub struct EthHandlers { impl EthHandlers where Provider: StateProviderFactory - + BlockReader - + EvmEnvProvider + + BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + EvmEnvProvider + Clone + Unpin + 'static, diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 3817c4d3b..e2141dcf1 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -41,6 +41,7 @@ //! Transaction = TransactionSigned, //! Block = reth_primitives::Block, //! Receipt = reth_primitives::Receipt, +//! Header = reth_primitives::Header, //! > + AccountReader //! + ChangeSetReader, //! Pool: TransactionPool + Unpin + 'static, @@ -121,6 +122,7 @@ //! Transaction = TransactionSigned, //! Block = reth_primitives::Block, //! Receipt = reth_primitives::Receipt, +//! Header = reth_primitives::Header, //! > + AccountReader //! + ChangeSetReader, //! Pool: TransactionPool + Unpin + 'static, @@ -201,7 +203,7 @@ use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers}; use reth_primitives::{EthPrimitives, NodePrimitives}; use reth_provider::{ AccountReader, BlockReader, CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader, - EvmEnvProvider, FullRpcProvider, ReceiptProvider, StateProviderFactory, + EvmEnvProvider, FullRpcProvider, HeaderProvider, ReceiptProvider, StateProviderFactory, }; use reth_rpc::{ AdminApi, DebugApi, EngineEthApi, EthBundle, NetApi, OtterscanApi, RPCApi, RethApi, TraceApi, @@ -269,8 +271,11 @@ pub async fn launch, ) -> Result where - Provider: FullRpcProvider - + AccountReader + Provider: FullRpcProvider< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + AccountReader + ChangeSetReader, Pool: TransactionPool + 'static, Network: NetworkInfo + Peers + Clone + 'static, @@ -667,6 +672,7 @@ where Provider: BlockReader< Block = ::Block, Receipt = ::Receipt, + Header = ::Header, >, { let Self { @@ -743,7 +749,11 @@ where ) -> RpcRegistryInner where EthApi: EthApiTypes + 'static, - Provider: BlockReader, + Provider: BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + >, { let Self { provider, @@ -781,6 +791,7 @@ where Provider: BlockReader< Block = ::Block, Receipt = ::Receipt, + Header = ::Header, >, { let mut modules = TransportRpcModules::default(); @@ -940,8 +951,11 @@ impl RpcRegistryInner where Provider: StateProviderFactory - + BlockReader - + EvmEnvProvider + + BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + EvmEnvProvider + Clone + Unpin + 'static, @@ -1311,6 +1325,7 @@ where Provider: FullRpcProvider< Block = ::Block, Receipt = ::Receipt, + Header = ::Header, > + AccountReader + ChangeSetReader, Pool: TransactionPool + 'static, diff --git a/crates/rpc/rpc-eth-api/src/helpers/fee.rs b/crates/rpc/rpc-eth-api/src/helpers/fee.rs index 0099e0f6b..5843e945b 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/fee.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/fee.rs @@ -163,11 +163,11 @@ pub trait EthFees: LoadFee { for header in &headers { - base_fee_per_gas.push(header.base_fee_per_gas.unwrap_or_default() as u128); - gas_used_ratio.push(header.gas_used as f64 / header.gas_limit as f64); + base_fee_per_gas.push(header.base_fee_per_gas().unwrap_or_default() as u128); + gas_used_ratio.push(header.gas_used() as f64 / header.gas_limit() as f64); base_fee_per_blob_gas.push(header.blob_fee().unwrap_or_default()); blob_gas_used_ratio.push( - header.blob_gas_used.unwrap_or_default() as f64 + header.blob_gas_used().unwrap_or_default() as f64 / alloy_eips::eip4844::MAX_DATA_GAS_PER_BLOCK as f64, ); @@ -181,8 +181,8 @@ pub trait EthFees: LoadFee { rewards.push( calculate_reward_percentiles_for_block( percentiles, - header.gas_used, - header.base_fee_per_gas.unwrap_or_default(), + header.gas_used(), + header.base_fee_per_gas().unwrap_or_default(), &block.body.transactions, &receipts, ) @@ -198,14 +198,10 @@ pub trait EthFees: LoadFee { // The unwrap is safe since we checked earlier that we got at least 1 header. let last_header = headers.last().expect("is present"); base_fee_per_gas.push( + last_header.next_block_base_fee( self.provider() .chain_spec() - .base_fee_params_at_timestamp(last_header.timestamp) - .next_block_base_fee( - last_header.gas_used , - last_header.gas_limit, - last_header.base_fee_per_gas.unwrap_or_default() , - ) as u128, + .base_fee_params_at_timestamp(last_header.timestamp())).unwrap_or_default() as u128 ); // Same goes for the `base_fee_per_blob_gas`: diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index e3ef6621b..4394feb28 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -3,7 +3,7 @@ use super::SpawnBlocking; use crate::{EthApiTypes, FromEthApiError, FromEvmError, RpcNodeCore}; -use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; +use alloy_consensus::{BlockHeader, Header, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::{ eip4844::MAX_DATA_GAS_PER_BLOCK, eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE, }; @@ -50,6 +50,7 @@ pub trait LoadPendingBlock: Provider: BlockReaderIdExt< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, > + EvmEnvProvider + ChainSpecProvider + StateProviderFactory, @@ -88,7 +89,7 @@ pub trait LoadPendingBlock: let chain_spec = self.provider().chain_spec(); latest_header.base_fee_per_gas = latest_header.next_block_base_fee( - chain_spec.base_fee_params_at_timestamp(latest_header.timestamp), + chain_spec.base_fee_params_at_timestamp(latest_header.timestamp()), ); // update excess blob gas consumed above target diff --git a/crates/rpc/rpc-eth-types/src/cache/mod.rs b/crates/rpc/rpc-eth-types/src/cache/mod.rs index 2dcabc0d1..7a0d9dfa0 100644 --- a/crates/rpc/rpc-eth-types/src/cache/mod.rs +++ b/crates/rpc/rpc-eth-types/src/cache/mod.rs @@ -96,8 +96,11 @@ impl EthStateCache { pub fn spawn(provider: Provider, config: EthStateCacheConfig) -> Self where Provider: StateProviderFactory - + BlockReader - + Clone + + BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + Clone + Unpin + 'static, { @@ -115,8 +118,11 @@ impl EthStateCache { ) -> Self where Provider: StateProviderFactory - + BlockReader - + Clone + + BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + Clone + Unpin + 'static, Tasks: TaskSpawner + Clone + 'static, @@ -331,8 +337,11 @@ where impl Future for EthStateCacheService where Provider: StateProviderFactory - + BlockReader - + Clone + + BlockReader< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + Clone + Unpin + 'static, Tasks: TaskSpawner + Clone + 'static, diff --git a/crates/rpc/rpc-eth-types/src/gas_oracle.rs b/crates/rpc/rpc-eth-types/src/gas_oracle.rs index 3f8186ae1..73cab209f 100644 --- a/crates/rpc/rpc-eth-types/src/gas_oracle.rs +++ b/crates/rpc/rpc-eth-types/src/gas_oracle.rs @@ -1,7 +1,7 @@ //! An implementation of the eth gas price oracle, used for providing gas price estimates based on //! previous blocks. -use alloy_consensus::constants::GWEI_TO_WEI; +use alloy_consensus::{constants::GWEI_TO_WEI, BlockHeader}; use alloy_eips::BlockNumberOrTag; use alloy_primitives::{B256, U256}; use alloy_rpc_types_eth::BlockId; @@ -142,8 +142,8 @@ where let mut populated_blocks = 0; // we only check a maximum of 2 * max_block_history, or the number of blocks in the chain - let max_blocks = if self.oracle_config.max_block_history * 2 > header.number { - header.number + let max_blocks = if self.oracle_config.max_block_history * 2 > header.number() { + header.number() } else { self.oracle_config.max_block_history * 2 }; diff --git a/crates/rpc/rpc/src/eth/core.rs b/crates/rpc/rpc/src/eth/core.rs index 86e0f9f38..092d94851 100644 --- a/crates/rpc/rpc/src/eth/core.rs +++ b/crates/rpc/rpc/src/eth/core.rs @@ -3,6 +3,7 @@ use std::sync::Arc; +use alloy_consensus::BlockHeader; use alloy_eips::BlockNumberOrTag; use alloy_network::Ethereum; use alloy_primitives::U256; @@ -286,7 +287,7 @@ where .header_by_number_or_tag(BlockNumberOrTag::Latest) .ok() .flatten() - .map(|header| header.number) + .map(|header| header.number()) .unwrap_or_default(), ); @@ -438,8 +439,11 @@ mod tests { use crate::EthApi; fn build_test_eth_api< - P: BlockReaderIdExt - + BlockReader + P: BlockReaderIdExt< + Block = reth_primitives::Block, + Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, + > + BlockReader + ChainSpecProvider + EvmEnvProvider + StateProviderFactory diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 200afadaa..b16b370b2 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -1,5 +1,6 @@ //! `eth_` `Filter` RPC handler implementation +use alloy_consensus::BlockHeader; use alloy_primitives::TxHash; use alloy_rpc_types_eth::{ BlockNumHash, Filter, FilterBlockOption, FilterChanges, FilterId, FilteredParams, Log, @@ -380,7 +381,7 @@ where .header_by_hash_or_number(block_hash.into())? .ok_or_else(|| ProviderError::HeaderNotFound(block_hash.into()))?; - let block_num_hash = BlockNumHash::new(header.number, block_hash); + let block_num_hash = BlockNumHash::new(header.number(), block_hash); // we also need to ensure that the receipts are available and return an error if // not, in case the block hash been reorged @@ -402,7 +403,7 @@ where block_num_hash, &receipts, false, - header.timestamp, + header.timestamp(), )?; Ok(all_logs) @@ -483,20 +484,20 @@ where for (idx, header) in headers.iter().enumerate() { // only if filter matches - if FilteredParams::matches_address(header.logs_bloom, &address_filter) && - FilteredParams::matches_topics(header.logs_bloom, &topics_filter) + if FilteredParams::matches_address(header.logs_bloom(), &address_filter) && + FilteredParams::matches_topics(header.logs_bloom(), &topics_filter) { // these are consecutive headers, so we can use the parent hash of the next // block to get the current header's hash let block_hash = match headers.get(idx + 1) { - Some(parent) => parent.parent_hash, + Some(parent) => parent.parent_hash(), None => self .provider - .block_hash(header.number)? - .ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?, + .block_hash(header.number())? + .ok_or_else(|| ProviderError::HeaderNotFound(header.number().into()))?, }; - let num_hash = BlockNumHash::new(header.number, block_hash); + let num_hash = BlockNumHash::new(header.number(), block_hash); if let Some((receipts, maybe_block)) = self.receipts_and_maybe_block(&num_hash, chain_info.best_number).await? { @@ -509,7 +510,7 @@ where num_hash, &receipts, false, - header.timestamp, + header.timestamp(), )?; // size check but only if range is multiple blocks, so we always return all diff --git a/crates/rpc/rpc/src/eth/helpers/pending_block.rs b/crates/rpc/rpc/src/eth/helpers/pending_block.rs index a67522ce0..794b9dde8 100644 --- a/crates/rpc/rpc/src/eth/helpers/pending_block.rs +++ b/crates/rpc/rpc/src/eth/helpers/pending_block.rs @@ -21,6 +21,7 @@ where Provider: BlockReaderIdExt< Block = reth_primitives::Block, Receipt = reth_primitives::Receipt, + Header = reth_primitives::Header, > + EvmEnvProvider + ChainSpecProvider + StateProviderFactory, diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index 91a3dae2c..d862bc5f3 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -89,7 +89,7 @@ where impl ValidationApi where - Provider: BlockReaderIdExt + Provider: BlockReaderIdExt
+ ChainSpecProvider + StateProviderFactory + HeaderProvider @@ -410,7 +410,7 @@ where #[async_trait] impl BlockSubmissionValidationApiServer for ValidationApi where - Provider: BlockReaderIdExt + Provider: BlockReaderIdExt
+ ChainSpecProvider + StateProviderFactory + HeaderProvider diff --git a/crates/stages/stages/src/stages/bodies.rs b/crates/stages/stages/src/stages/bodies.rs index c1fde11c2..0f90ff69e 100644 --- a/crates/stages/stages/src/stages/bodies.rs +++ b/crates/stages/stages/src/stages/bodies.rs @@ -75,7 +75,9 @@ impl BodyStage { unwind_block: Option, ) -> Result<(), StageError> where - Provider: DBProvider + BlockReader + StaticFileProviderFactory, + Provider: DBProvider + + BlockReader
+ + StaticFileProviderFactory, { // Get id for the next tx_num of zero if there are no transactions. let next_tx_num = provider @@ -152,7 +154,7 @@ where Provider: DBProvider + StaticFileProviderFactory + StatsReader - + BlockReader + + BlockReader
+ BlockWriter>, D: BodyDownloader>, { diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index f7832dd78..c8cc89080 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -193,7 +193,10 @@ where unwind_to: Option, ) -> Result<(), StageError> where - Provider: StaticFileProviderFactory + DBProvider + BlockReader + HeaderProvider, + Provider: StaticFileProviderFactory + + DBProvider + + BlockReader + + HeaderProvider
, { // If thre's any receipts pruning configured, receipts are written directly to database and // inconsistencies are expected. @@ -265,8 +268,10 @@ impl Stage for ExecutionStage where E: BlockExecutorProvider>, Provider: DBProvider - + BlockReader::Block> - + StaticFileProviderFactory + + BlockReader< + Block = ::Block, + Header = ::BlockHeader, + > + StaticFileProviderFactory + StatsReader + BlockHashReader + StateWriter::Receipt> diff --git a/crates/stages/stages/src/stages/hashing_account.rs b/crates/stages/stages/src/stages/hashing_account.rs index e6b1e5484..551c10d77 100644 --- a/crates/stages/stages/src/stages/hashing_account.rs +++ b/crates/stages/stages/src/stages/hashing_account.rs @@ -63,8 +63,10 @@ impl AccountHashingStage { opts: SeedOpts, ) -> Result, StageError> where - N::Primitives: - reth_primitives_traits::FullNodePrimitives, + N::Primitives: reth_primitives_traits::FullNodePrimitives< + BlockBody = reth_primitives::BlockBody, + BlockHeader = reth_primitives::Header, + >, { use alloy_primitives::U256; use reth_db_api::models::AccountBeforeTx; diff --git a/crates/stages/stages/src/stages/headers.rs b/crates/stages/stages/src/stages/headers.rs index 100fe4e97..7b9b394b5 100644 --- a/crates/stages/stages/src/stages/headers.rs +++ b/crates/stages/stages/src/stages/headers.rs @@ -1,3 +1,4 @@ +use alloy_consensus::BlockHeader; use alloy_primitives::{BlockHash, BlockNumber, Bytes, B256}; use futures_util::StreamExt; use reth_config::config::EtlConfig; @@ -10,7 +11,7 @@ use reth_db_api::{ }; use reth_etl::Collector; use reth_network_p2p::headers::{downloader::HeaderDownloader, error::HeadersDownloaderError}; -use reth_primitives::{SealedHeader, StaticFileSegment}; +use reth_primitives::{NodePrimitives, SealedHeader, StaticFileSegment}; use reth_primitives_traits::serde_bincode_compat; use reth_provider::{ providers::StaticFileWriter, BlockHashReader, DBProvider, HeaderProvider, HeaderSyncGap, @@ -50,7 +51,7 @@ pub struct HeaderStage { /// Consensus client implementation consensus: Arc>, /// Current sync gap. - sync_gap: Option, + sync_gap: Option>, /// ETL collector with `HeaderHash` -> `BlockNumber` hash_collector: Collector, /// ETL collector with `BlockNumber` -> `BincodeSealedHeader` @@ -63,7 +64,7 @@ pub struct HeaderStage { impl HeaderStage where - Downloader: HeaderDownloader
, + Downloader: HeaderDownloader, { /// Create a new header stage pub fn new( @@ -89,10 +90,14 @@ where /// /// Writes to static files ( `Header | HeaderTD | HeaderHash` ) and [`tables::HeaderNumbers`] /// database table. - fn write_headers + StaticFileProviderFactory>( - &mut self, - provider: &P, - ) -> Result { + fn write_headers

(&mut self, provider: &P) -> Result + where + P: DBProvider + + StaticFileProviderFactory< + Primitives: NodePrimitives, + >, + Downloader: HeaderDownloader

::BlockHeader>, + { let total_headers = self.header_collector.len(); info!(target: "sync::stages::headers", total = total_headers, "Writing headers"); @@ -121,19 +126,19 @@ where info!(target: "sync::stages::headers", progress = %format!("{:.2}%", (index as f64 / total_headers as f64) * 100.0), "Writing headers"); } - let sealed_header: SealedHeader = - bincode::deserialize::>(&header_buf) + let sealed_header: SealedHeader = + bincode::deserialize::>(&header_buf) .map_err(|err| StageError::Fatal(Box::new(err)))? .into(); let (header, header_hash) = sealed_header.split(); - if header.number == 0 { + if header.number() == 0 { continue } - last_header_number = header.number; + last_header_number = header.number(); // Increase total difficulty - td += header.difficulty; + td += header.difficulty(); // Header validation self.consensus.validate_header_with_total_difficulty(&header, td).map_err(|error| { @@ -193,9 +198,10 @@ where impl Stage for HeaderStage where - P: HeaderSyncGapProvider, - D: HeaderDownloader
, Provider: DBProvider + StaticFileProviderFactory, + Provider::Primitives: NodePrimitives, + P: HeaderSyncGapProvider
::BlockHeader>, + D: HeaderDownloader
::BlockHeader>, { /// Return the id of the stage fn id(&self) -> StageId { @@ -232,7 +238,7 @@ where } debug!(target: "sync::stages::headers", ?tip, head = ?gap.local_head.hash(), "Commencing sync"); - let local_head_number = gap.local_head.number; + let local_head_number = gap.local_head.number(); // let the downloader know what to sync self.downloader.update_sync_gap(gap.local_head, gap.target); @@ -241,9 +247,9 @@ where loop { match ready!(self.downloader.poll_next_unpin(cx)) { Some(Ok(headers)) => { - info!(target: "sync::stages::headers", total = headers.len(), from_block = headers.first().map(|h| h.number), to_block = headers.last().map(|h| h.number), "Received headers"); + info!(target: "sync::stages::headers", total = headers.len(), from_block = headers.first().map(|h| h.number()), to_block = headers.last().map(|h| h.number()), "Received headers"); for header in headers { - let header_number = header.number; + let header_number = header.number(); self.hash_collector.insert(header.hash(), header_number)?; self.header_collector.insert( diff --git a/crates/stages/stages/src/stages/merkle.rs b/crates/stages/stages/src/stages/merkle.rs index 2d2503b53..8095dfed9 100644 --- a/crates/stages/stages/src/stages/merkle.rs +++ b/crates/stages/stages/src/stages/merkle.rs @@ -1,3 +1,4 @@ +use alloy_consensus::BlockHeader; use alloy_primitives::{BlockNumber, B256}; use reth_codecs::Compact; use reth_consensus::ConsensusError; @@ -135,7 +136,7 @@ where Provider: DBProvider + TrieWriter + StatsReader - + HeaderProvider + + HeaderProvider
+ StageCheckpointReader + StageCheckpointWriter, { @@ -168,7 +169,7 @@ where let target_block = provider .header_by_number(to_block)? .ok_or_else(|| ProviderError::HeaderNotFound(to_block.into()))?; - let target_block_root = target_block.state_root; + let target_block_root = target_block.state_root(); let mut checkpoint = self.get_execution_checkpoint(provider)?; let (trie_root, entities_checkpoint) = if range.is_empty() { diff --git a/crates/stages/stages/src/stages/sender_recovery.rs b/crates/stages/stages/src/stages/sender_recovery.rs index 674d03502..d34a4b079 100644 --- a/crates/stages/stages/src/stages/sender_recovery.rs +++ b/crates/stages/stages/src/stages/sender_recovery.rs @@ -59,7 +59,7 @@ impl Default for SenderRecoveryStage { impl Stage for SenderRecoveryStage where Provider: DBProvider - + BlockReader + + BlockReader
+ StaticFileProviderFactory> + StatsReader + PruneCheckpointReader, @@ -146,7 +146,8 @@ fn recover_range( senders_cursor: &mut CURSOR, ) -> Result<(), StageError> where - Provider: DBProvider + HeaderProvider + StaticFileProviderFactory, + Provider: + DBProvider + HeaderProvider
+ StaticFileProviderFactory, CURSOR: DbCursorRW, { debug!(target: "sync::stages::sender_recovery", ?tx_range, "Sending batch for processing"); diff --git a/crates/stages/stages/src/stages/utils.rs b/crates/stages/stages/src/stages/utils.rs index 5aa1f3f88..34aaeee44 100644 --- a/crates/stages/stages/src/stages/utils.rs +++ b/crates/stages/stages/src/stages/utils.rs @@ -258,7 +258,7 @@ pub(crate) fn missing_static_data_error( segment: StaticFileSegment, ) -> Result where - Provider: BlockReader + StaticFileProviderFactory, + Provider: BlockReader
+ StaticFileProviderFactory, { let mut last_block = static_file_provider.get_highest_static_file_block(segment).unwrap_or_default(); diff --git a/crates/static-file/static-file/src/segments/headers.rs b/crates/static-file/static-file/src/segments/headers.rs index e06e1f09a..dff80a23f 100644 --- a/crates/static-file/static-file/src/segments/headers.rs +++ b/crates/static-file/static-file/src/segments/headers.rs @@ -1,7 +1,9 @@ use crate::segments::Segment; use alloy_primitives::BlockNumber; -use reth_db::tables; +use reth_codecs::Compact; +use reth_db::{table::Value, tables}; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; +use reth_primitives_traits::NodePrimitives; use reth_provider::{providers::StaticFileWriter, DBProvider, StaticFileProviderFactory}; use reth_static_file_types::StaticFileSegment; use reth_storage_errors::provider::ProviderResult; @@ -11,7 +13,11 @@ use std::ops::RangeInclusive; #[derive(Debug, Default)] pub struct Headers; -impl Segment for Headers { +impl Segment for Headers +where + Provider: StaticFileProviderFactory> + + DBProvider, +{ fn segment(&self) -> StaticFileSegment { StaticFileSegment::Headers } @@ -25,7 +31,10 @@ impl Segment for Hea let mut static_file_writer = static_file_provider.get_writer(*block_range.start(), StaticFileSegment::Headers)?; - let mut headers_cursor = provider.tx_ref().cursor_read::()?; + let mut headers_cursor = provider + .tx_ref() + .cursor_read::::BlockHeader>>( + )?; let headers_walker = headers_cursor.walk_range(block_range.clone())?; let mut header_td_cursor = diff --git a/crates/static-file/static-file/src/static_file_producer.rs b/crates/static-file/static-file/src/static_file_producer.rs index 371a344d8..30a72561b 100644 --- a/crates/static-file/static-file/src/static_file_producer.rs +++ b/crates/static-file/static-file/src/static_file_producer.rs @@ -90,7 +90,7 @@ where Provider: StaticFileProviderFactory + DatabaseProviderFactory< Provider: StaticFileProviderFactory< - Primitives: NodePrimitives, + Primitives: NodePrimitives, > + StageCheckpointReader + BlockReader, >, diff --git a/crates/storage/db-common/Cargo.toml b/crates/storage/db-common/Cargo.toml index 9e4954357..28dbc33e9 100644 --- a/crates/storage/db-common/Cargo.toml +++ b/crates/storage/db-common/Cargo.toml @@ -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 diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index 9d4fb4ff0..d738aaec4 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -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 for InitDatabaseError { /// Write the genesis block if it has not already been written pub fn init_genesis(factory: &PF) -> Result where - PF: DatabaseProviderFactory + StaticFileProviderFactory + ChainSpecProvider + BlockHashReader, + PF: DatabaseProviderFactory + + StaticFileProviderFactory> + + ChainSpecProvider + + BlockHashReader, PF::ProviderRW: StaticFileProviderFactory + StageCheckpointWriter + HistoryWriter @@ -78,7 +84,7 @@ where + StateWriter + StateWriter + AsRef, - PF::ChainSpec: EthChainSpec
, + PF::ChainSpec: EthChainSpec
::BlockHeader>, { let chain = factory.chain_spec(); @@ -307,15 +313,16 @@ pub fn insert_genesis_header( chain: &Spec, ) -> ProviderResult<()> where - Provider: StaticFileProviderFactory + DBProvider, - Spec: EthChainSpec
, + Provider: StaticFileProviderFactory> + + DBProvider, + Spec: EthChainSpec
::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)?; diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 08f5e4680..1bb65a6e4 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -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 BlockchainProvider2 { /// /// This returns a `ProviderResult` since it tries the retrieve the last finalized header from /// `database`. - pub fn with_latest(storage: ProviderFactory, latest: SealedHeader) -> ProviderResult { + pub fn with_latest( + storage: ProviderFactory, + latest: SealedHeader>, + ) -> ProviderResult { let provider = storage.provider()?; let finalized_header = provider .last_finalized_block_number()? @@ -175,11 +178,13 @@ impl StaticFileProviderFactory for BlockchainProvider2 } impl HeaderProvider for BlockchainProvider2 { - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { + type Header = HeaderTy; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.consistent_provider()?.header(block_hash) } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { self.consistent_provider()?.header_by_number(num) } @@ -191,26 +196,32 @@ impl HeaderProvider for BlockchainProvider2 { self.consistent_provider()?.header_td_by_number(number) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { self.consistent_provider()?.headers_range(range) } - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>> { self.consistent_provider()?.sealed_header(number) } fn sealed_headers_range( &self, range: impl RangeBounds, - ) -> ProviderResult> { + ) -> ProviderResult>> { self.consistent_provider()?.sealed_headers_range(range) } fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { self.consistent_provider()?.sealed_headers_while(range, predicate) } } @@ -292,7 +303,7 @@ impl BlockReader for BlockchainProvider2 { Ok(self.canonical_in_memory_state.pending_block_and_receipts()) } - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { self.consistent_provider()?.ommers(id) } @@ -470,7 +481,7 @@ impl StageCheckpointReader for BlockchainProvider2 { } } -impl EvmEnvProvider for BlockchainProvider2 { +impl EvmEnvProvider> for BlockchainProvider2 { fn fill_env_at( &self, cfg: &mut CfgEnvWithHandlerCfg, @@ -479,7 +490,7 @@ impl EvmEnvProvider for BlockchainProvider2 { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.consistent_provider()?.fill_env_at(cfg, block_env, at, evm_config) } @@ -488,11 +499,11 @@ impl EvmEnvProvider for BlockchainProvider2 { &self, cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.consistent_provider()?.fill_env_with_header(cfg, block_env, header, evm_config) } @@ -504,7 +515,7 @@ impl EvmEnvProvider for BlockchainProvider2 { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.consistent_provider()?.fill_cfg_env_at(cfg, at, evm_config) } @@ -512,11 +523,11 @@ impl EvmEnvProvider for BlockchainProvider2 { fn fill_cfg_env_with_header( &self, cfg: &mut CfgEnvWithHandlerCfg, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.consistent_provider()?.fill_cfg_env_with_header(cfg, header, evm_config) } @@ -652,10 +663,9 @@ impl StateProviderFactory for BlockchainProvider2 { } } -impl CanonChainTracker for BlockchainProvider2 -where - Self: BlockReader, -{ +impl CanonChainTracker for BlockchainProvider2 { + type Header = HeaderTy; + 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.canonical_in_memory_state.set_canonical_head(header); } - fn set_safe(&self, header: SealedHeader) { + fn set_safe(&self, header: SealedHeader) { self.canonical_in_memory_state.set_safe(header); } - fn set_finalized(&self, header: SealedHeader) { + fn set_finalized(&self, header: SealedHeader) { 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> { + fn header_by_number_or_tag( + &self, + id: BlockNumberOrTag, + ) -> ProviderResult> { self.consistent_provider()?.header_by_number_or_tag(id) } fn sealed_header_by_number_or_tag( &self, id: BlockNumberOrTag, - ) -> ProviderResult> { + ) -> ProviderResult>> { self.consistent_provider()?.sealed_header_by_number_or_tag(id) } - fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult> { + fn sealed_header_by_id( + &self, + id: BlockId, + ) -> ProviderResult>> { self.consistent_provider()?.sealed_header_by_id(id) } - fn header_by_id(&self, id: BlockId) -> ProviderResult> { + fn header_by_id(&self, id: BlockId) -> ProviderResult> { self.consistent_provider()?.header_by_id(id) } - fn ommers_by_id(&self, id: BlockId) -> ProviderResult>> { + fn ommers_by_id(&self, id: BlockId) -> ProviderResult>> { self.consistent_provider()?.ommers_by_id(id) } } @@ -727,12 +743,14 @@ impl> CanonStateSubscriptions } impl ForkChoiceSubscriptions for BlockchainProvider2 { - fn subscribe_safe_block(&self) -> ForkChoiceNotifications { + type Header = HeaderTy; + + fn subscribe_safe_block(&self) -> ForkChoiceNotifications { let receiver = self.canonical_in_memory_state.subscribe_safe_block(); ForkChoiceNotifications(receiver) } - fn subscribe_finalized_block(&self) -> ForkChoiceNotifications { + fn subscribe_finalized_block(&self) -> ForkChoiceNotifications { let receiver = self.canonical_in_memory_state.subscribe_finalized_block(); ForkChoiceNotifications(receiver) } diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index e70f4b4e5..5aea5be27 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -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 StaticFileProviderFactory for ConsistentProvider { } impl HeaderProvider for ConsistentProvider { - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { + type Header = HeaderTy; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.get_in_memory_or_storage_by_block( (*block_hash).into(), |db_provider| db_provider.header(block_hash), @@ -636,7 +638,7 @@ impl HeaderProvider for ConsistentProvider { ) } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { self.get_in_memory_or_storage_by_block( num.into(), |db_provider| db_provider.header_by_number(num), @@ -675,7 +677,10 @@ impl HeaderProvider for ConsistentProvider { self.storage_provider.header_td_by_number(number) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { self.get_in_memory_or_storage_by_block_range_while( range, |db_provider, range, _| db_provider.headers_range(range), @@ -684,7 +689,10 @@ impl HeaderProvider for ConsistentProvider { ) } - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>> { self.get_in_memory_or_storage_by_block( number.into(), |db_provider| db_provider.sealed_header(number), @@ -695,7 +703,7 @@ impl HeaderProvider for ConsistentProvider { fn sealed_headers_range( &self, range: impl RangeBounds, - ) -> ProviderResult> { + ) -> ProviderResult>> { 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 HeaderProvider for ConsistentProvider { fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { 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 BlockReader for ConsistentProvider { Ok(self.canonical_in_memory_state.pending_block_and_receipts()) } - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>>> { self.get_in_memory_or_storage_by_block( id, |db_provider| db_provider.ommers(id), @@ -868,7 +876,7 @@ impl BlockReader for ConsistentProvider { // Iterate from the lowest block in memory until our target block for state in block_state.chain().collect::>().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 TransactionsProvider for ConsistentProvider { 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 StageCheckpointReader for ConsistentProvider { } } -impl EvmEnvProvider for ConsistentProvider { +impl EvmEnvProvider> for ConsistentProvider { fn fill_env_at( &self, cfg: &mut CfgEnvWithHandlerCfg, @@ -1231,7 +1239,7 @@ impl EvmEnvProvider for ConsistentProvider { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { 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 EvmEnvProvider for ConsistentProvider { &self, cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { 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 EvmEnvProvider for ConsistentProvider { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { 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 EvmEnvProvider for ConsistentProvider { fn fill_cfg_env_with_header( &self, cfg: &mut CfgEnvWithHandlerCfg, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { 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 BlockReaderIdExt for ConsistentProvider { } } - fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult> { + fn header_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult>> { Ok(match id { BlockNumberOrTag::Latest => { Some(self.canonical_in_memory_state.get_canonical_head().unseal()) @@ -1347,7 +1355,7 @@ impl BlockReaderIdExt for ConsistentProvider { fn sealed_header_by_number_or_tag( &self, id: BlockNumberOrTag, - ) -> ProviderResult> { + ) -> ProviderResult>>> { match id { BlockNumberOrTag::Latest => { Ok(Some(self.canonical_in_memory_state.get_canonical_head())) @@ -1366,21 +1374,24 @@ impl BlockReaderIdExt for ConsistentProvider { } } - fn sealed_header_by_id(&self, id: BlockId) -> ProviderResult> { + fn sealed_header_by_id( + &self, + id: BlockId, + ) -> ProviderResult>>> { 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> { + fn header_by_id(&self, id: BlockId) -> ProviderResult>> { 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>> { + fn ommers_by_id(&self, id: BlockId) -> ProviderResult>>> { match id { BlockId::Number(num) => self.ommers_by_number_or_tag(num), BlockId::Hash(hash) => { diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 3c22a1a73..d34d67d9d 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -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 StaticFileProviderFactory for ProviderFactory { } impl HeaderSyncGapProvider for ProviderFactory { + type Header = HeaderTy; fn sync_gap( &self, tip: watch::Receiver, highest_uninterrupted_block: BlockNumber, - ) -> ProviderResult { + ) -> ProviderResult> { self.provider()?.sync_gap(tip, highest_uninterrupted_block) } } impl HeaderProvider for ProviderFactory { - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { + type Header = HeaderTy; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.provider()?.header(block_hash) } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { self.static_file_provider.get_with_static_file_or_database( StaticFileSegment::Headers, num, @@ -270,7 +272,10 @@ impl HeaderProvider for ProviderFactory { ) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { self.static_file_provider.get_range_with_static_file_or_database( StaticFileSegment::Headers, to_range(range), @@ -280,7 +285,10 @@ impl HeaderProvider for ProviderFactory { ) } - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>> { self.static_file_provider.get_with_static_file_or_database( StaticFileSegment::Headers, number, @@ -292,15 +300,15 @@ impl HeaderProvider for ProviderFactory { fn sealed_headers_range( &self, range: impl RangeBounds, - ) -> ProviderResult> { + ) -> ProviderResult>> { self.sealed_headers_while(range, |_| true) } fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { self.static_file_provider.get_range_with_static_file_or_database( StaticFileSegment::Headers, to_range(range), @@ -385,7 +393,7 @@ impl BlockReader for ProviderFactory { self.provider()?.pending_block_and_receipts() } - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { self.provider()?.ommers(id) } @@ -570,7 +578,7 @@ impl StageCheckpointReader for ProviderFactory { } } -impl EvmEnvProvider for ProviderFactory { +impl EvmEnvProvider> for ProviderFactory { fn fill_env_at( &self, cfg: &mut CfgEnvWithHandlerCfg, @@ -579,7 +587,7 @@ impl EvmEnvProvider for ProviderFactory { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.provider()?.fill_env_at(cfg, block_env, at, evm_config) } @@ -588,11 +596,11 @@ impl EvmEnvProvider for ProviderFactory { &self, cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.provider()?.fill_env_with_header(cfg, block_env, header, evm_config) } @@ -604,7 +612,7 @@ impl EvmEnvProvider for ProviderFactory { evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.provider()?.fill_cfg_env_at(cfg, at, evm_config) } @@ -612,11 +620,11 @@ impl EvmEnvProvider for ProviderFactory { fn fill_cfg_env_with_header( &self, cfg: &mut CfgEnvWithHandlerCfg, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { self.provider()?.fill_cfg_env_with_header(cfg, header, evm_config) } diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index cfbe20cf4..9dddbb9c0 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -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 DatabaseProvider StateCommitmentProvider for DatabaseProvi type StateCommitment = N::StateCommitment; } -impl DatabaseProvider { +impl< + Tx: DbTx + DbTxMut + 'static, + N: NodeTypesForProvider>, + > DatabaseProvider +{ // 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 DatabaseProvider { construct_block: BF, ) -> ProviderResult> where - N::ChainSpec: EthereumHardforks, - H: AsRef
, + H: AsRef>, HF: FnOnce(BlockNumber) -> ProviderResult>, BF: FnOnce(H, BodyTy, Vec
) -> ProviderResult>, { @@ -610,8 +614,7 @@ impl DatabaseProvider { mut assemble_block: F, ) -> ProviderResult> where - N::ChainSpec: EthereumHardforks, - H: AsRef
, + H: AsRef>, HF: FnOnce(RangeInclusive) -> ProviderResult>, F: FnMut(H, BodyTy, Range) -> ProviderResult, { @@ -634,7 +637,7 @@ impl DatabaseProvider { // 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 DatabaseProvider { assemble_block: BF, ) -> ProviderResult> where - N::ChainSpec: EthereumHardforks, - H: AsRef
, + H: AsRef>, HF: Fn(RangeInclusive) -> ProviderResult>, BF: Fn(H, BodyTy, Vec
) -> ProviderResult, { @@ -943,12 +945,16 @@ impl ChangeSetReader for DatabaseProvider { } } -impl HeaderSyncGapProvider for DatabaseProvider { +impl HeaderSyncGapProvider + for DatabaseProvider +{ + type Header = HeaderTy; + fn sync_gap( &self, tip: watch::Receiver, highest_uninterrupted_block: BlockNumber, - ) -> ProviderResult { + ) -> ProviderResult> { 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 HeaderSyncGapProvider for DatabaseProvide } } -impl> HeaderProvider - for DatabaseProvider -{ - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { +impl HeaderProvider for DatabaseProvider { + type Header = HeaderTy; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { if let Some(num) = self.block_number(*block_hash)? { Ok(self.header_by_number(num)?) } else { @@ -998,12 +1004,12 @@ impl> HeaderProvi } } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { 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::(num)?), + || Ok(self.tx.get::>(num)?), ) } @@ -1030,17 +1036,25 @@ impl> HeaderProvi ) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { 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::(range).map_err(Into::into), + |range, _| { + self.cursor_read_collect::>(range).map_err(Into::into) + }, |_| true, ) } - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>> { self.static_file_provider.get_with_static_file_or_database( StaticFileSegment::Headers, number, @@ -1061,15 +1075,17 @@ impl> HeaderProvi fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { 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::()?.walk_range(range)? { + for entry in + self.tx.cursor_read::>()?.walk_range(range)? + { let (number, header) = entry?; let hash = self .block_hash(number)? @@ -1210,7 +1226,7 @@ impl 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>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { 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 BlockReader for DatabaseProvid return Ok(Some(Vec::new())) } - let ommers = self.tx.get::(number)?.map(|o| o.ommers); + let ommers = + self.tx.get::>(number)?.map(|o| o.ommers); return Ok(ommers) } @@ -1450,9 +1467,9 @@ impl 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> Withdrawals } } -impl> EvmEnvProvider +impl EvmEnvProvider> for DatabaseProvider { fn fill_env_at( @@ -1629,7 +1646,7 @@ impl> EvmEnvProvi evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { 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> EvmEnvProvi &self, cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { 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> EvmEnvProvi evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { 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> EvmEnvProvi fn fill_cfg_env_with_header( &self, cfg: &mut CfgEnvWithHandlerCfg, - header: &Header, + header: &HeaderTy, evm_config: EvmConfig, ) -> ProviderResult<()> where - EvmConfig: ConfigureEvmEnv
, + EvmConfig: ConfigureEvmEnv
>, { 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 BlockWrite block: SealedBlockWithSenders, write_to: StorageLocation, ) -> ProviderResult { - 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 BlockWrite durations_recorder.record_relative(metrics::Action::InsertCanonicalHeaders); // Put header with canonical hashes. - self.tx.put::(block_number, block.header.as_ref().clone())?; + self.tx + .put::>>(block_number, block.header.as_ref().clone())?; durations_recorder.record_relative(metrics::Action::InsertHeaders); self.tx.put::(block_number, ttd.into())?; @@ -2979,7 +2997,7 @@ impl BlockWrite self.tx.delete::(hash, None)?; rev_headers.delete_current()?; } - self.remove::(block + 1..)?; + self.remove::>>(block + 1..)?; self.remove::(block + 1..)?; // First transaction to be removed @@ -3063,10 +3081,10 @@ impl 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(); diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index 6631b5b1b..44cd5554b 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -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, - Primitives: FullNodePrimitives< - SignedTx: Value, - Receipt: Value, - BlockHeader = alloy_consensus::Header, - >, + Primitives: FullNodePrimitives, >, { } @@ -90,11 +89,7 @@ impl NodeTypesForProvider for T where T: NodeTypes< ChainSpec: EthereumHardforks, Storage: ChainStorage, - Primitives: FullNodePrimitives< - SignedTx: Value, - Receipt: Value, - BlockHeader = alloy_consensus::Header, - >, + Primitives: FullNodePrimitives, > { } @@ -151,7 +146,7 @@ impl BlockchainProvider { } } -impl BlockchainProvider { +impl BlockchainProvider { /// 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 StaticFileProviderFactory for BlockchainProvider { } } -impl HeaderProvider for BlockchainProvider { +impl HeaderProvider for BlockchainProvider { + type Header = Header; + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.database.header(block_hash) } @@ -593,7 +590,7 @@ impl StageCheckpointReader for BlockchainProvider { } } -impl EvmEnvProvider for BlockchainProvider { +impl EvmEnvProvider for BlockchainProvider { fn fill_env_at( &self, cfg: &mut CfgEnvWithHandlerCfg, @@ -666,7 +663,7 @@ impl ChainSpecProvider for BlockchainProvider { } } -impl StateProviderFactory for BlockchainProvider { +impl StateProviderFactory for BlockchainProvider { /// Storage provider for latest block fn latest(&self) -> ProviderResult { trace!(target: "providers::blockchain", "Getting latest block state provider"); @@ -840,10 +837,9 @@ impl BlockchainTreeViewer for BlockchainProvider { } } -impl CanonChainTracker for BlockchainProvider -where - Self: BlockReader, -{ +impl CanonChainTracker for BlockchainProvider { + type Header = HeaderTy; + fn on_forkchoice_update_received(&self, _update: &ForkchoiceState) { // update timestamp self.chain_info.on_forkchoice_update_received(); @@ -874,10 +870,7 @@ where } } -impl BlockReaderIdExt for BlockchainProvider -where - Self: BlockReader + ReceiptProviderIdExt, -{ +impl BlockReaderIdExt for BlockchainProvider { fn block_by_id(&self, id: BlockId) -> ProviderResult> { 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> { + fn header_by_number_or_tag( + &self, + id: BlockNumberOrTag, + ) -> ProviderResult> { 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> { + ) -> ProviderResult>> { 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> { + fn sealed_header_by_id( + &self, + id: BlockId, + ) -> ProviderResult>> { 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> { + fn header_by_id(&self, id: BlockId) -> ProviderResult> { 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>> { + fn ommers_by_id(&self, id: BlockId) -> ProviderResult>> { match id { BlockId::Number(num) => self.ommers_by_number_or_tag(num), BlockId::Hash(hash) => { @@ -968,7 +967,9 @@ impl CanonStateSubscriptions for BlockchainProvider { } } -impl ForkChoiceSubscriptions for BlockchainProvider { +impl ForkChoiceSubscriptions for BlockchainProvider { + type Header = HeaderTy; + fn subscribe_safe_block(&self) -> ForkChoiceNotifications { let receiver = self.chain_info.subscribe_safe_block(); ForkChoiceNotifications(receiver) diff --git a/crates/storage/provider/src/providers/static_file/jar.rs b/crates/storage/provider/src/providers/static_file/jar.rs index 659b093d9..8f2d002ab 100644 --- a/crates/storage/provider/src/providers/static_file/jar.rs +++ b/crates/storage/provider/src/providers/static_file/jar.rs @@ -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 HeaderProvider for StaticFileJarProvider<'_, N> { - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { +impl> HeaderProvider for StaticFileJarProvider<'_, N> { + type Header = N::BlockHeader; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { Ok(self .cursor()? - .get_two::>(block_hash.into())? + .get_two::>(block_hash.into())? .filter(|(_, hash)| hash == block_hash) .map(|(header, _)| header)) } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { - self.cursor()?.get_one::>(num.into()) + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + self.cursor()?.get_one::>(num.into()) } fn header_td(&self, block_hash: &BlockHash) -> ProviderResult> { @@ -115,14 +116,17 @@ impl HeaderProvider for StaticFileJarProvider<'_, N> { Ok(self.cursor()?.get_one::(num.into())?.map(Into::into)) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { 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::>(num.into())? { + if let Some(header) = cursor.get_one::>(num.into())? { headers.push(header); } } @@ -130,18 +134,21 @@ impl HeaderProvider for StaticFileJarProvider<'_, N> { Ok(headers) } - fn sealed_header(&self, number: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>> { Ok(self .cursor()? - .get_two::>(number.into())? + .get_two::>(number.into())? .map(|(header, hash)| SealedHeader::new(header, hash))) } fn sealed_headers_while( &self, range: impl RangeBounds, - mut predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + mut predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { let range = to_range(range); let mut cursor = self.cursor()?; @@ -149,7 +156,7 @@ impl HeaderProvider for StaticFileJarProvider<'_, N> { for number in range { if let Some((header, hash)) = - cursor.get_two::>(number.into())? + cursor.get_two::>(number.into())? { let sealed = SealedHeader::new(header, hash); if !predicate(&sealed) { diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 3b49f8d40..eca382af7 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -1235,12 +1235,14 @@ impl StaticFileWriter for StaticFileProvider { } } -impl HeaderProvider for StaticFileProvider { - fn header(&self, block_hash: &BlockHash) -> ProviderResult> { +impl> HeaderProvider for StaticFileProvider { + type Header = N::BlockHeader; + + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { self.find_static_file(StaticFileSegment::Headers, |jar_provider| { Ok(jar_provider .cursor()? - .get_two::>(block_hash.into())? + .get_two::>(block_hash.into())? .and_then(|(header, hash)| { if &hash == block_hash { return Some(header) @@ -1250,7 +1252,7 @@ impl HeaderProvider for StaticFileProvider { }) } - fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { + fn header_by_number(&self, num: BlockNumber) -> ProviderResult> { 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 HeaderProvider for StaticFileProvider { }) } - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult> { + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult> { self.fetch_range_with_predicate( StaticFileSegment::Headers, to_range(range), - |cursor, number| cursor.get_one::>(number.into()), + |cursor, number| cursor.get_one::>(number.into()), |_| true, ) } - fn sealed_header(&self, num: BlockNumber) -> ProviderResult> { + fn sealed_header( + &self, + num: BlockNumber, + ) -> ProviderResult>> { 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 HeaderProvider for StaticFileProvider { fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult> { + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>> { self.fetch_range_with_predicate( StaticFileSegment::Headers, to_range(range), |cursor, number| { Ok(cursor - .get_two::>(number.into())? + .get_two::>(number.into())? .map(|(header, hash)| SealedHeader::new(header, hash))) }, predicate, @@ -1385,8 +1393,8 @@ impl> Rec } } -impl> TransactionsProviderExt - for StaticFileProvider +impl> + TransactionsProviderExt for StaticFileProvider { fn transaction_hashes_by_range( &self, @@ -1582,7 +1590,9 @@ impl BlockNumReader for StaticFileProvider { } } -impl> BlockReader for StaticFileProvider { +impl> BlockReader + for StaticFileProvider +{ type Block = N::Block; fn find_block_by_hash( @@ -1618,7 +1628,7 @@ impl> BlockReader for Sta Err(ProviderError::UnsupportedProvider) } - fn ommers(&self, _id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, _id: BlockHashOrNumber) -> ProviderResult>> { // Required data not present in static_files Err(ProviderError::UnsupportedProvider) } diff --git a/crates/storage/provider/src/providers/static_file/writer.rs b/crates/storage/provider/src/providers/static_file/writer.rs index 6f5335ec6..b7f60c164 100644 --- a/crates/storage/provider/src/providers/static_file/writer.rs +++ b/crates/storage/provider/src/providers/static_file/writer.rs @@ -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 StaticFileProviderRW { /// 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))?; diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 12c0330ac..385e5e820 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -179,6 +179,8 @@ impl DatabaseProviderFactory for MockEthProvider { } impl HeaderProvider for MockEthProvider { + type Header = Header; + fn header(&self, block_hash: &BlockHash) -> ProviderResult> { let lock = self.headers.lock(); Ok(lock.get(block_hash).cloned()) diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index ff6b3fccb..5120afffa 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -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> { 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) diff --git a/crates/storage/provider/src/traits/full.rs b/crates/storage/provider/src/traits/full.rs index 0d28f8373..be485839f 100644 --- a/crates/storage/provider/src/traits/full.rs +++ b/crates/storage/provider/src/traits/full.rs @@ -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: DatabaseProviderFactory + NodePrimitivesProvider + StaticFileProviderFactory - + BlockReaderIdExt, Block = BlockTy, Receipt = ReceiptTy> - + AccountReader + + BlockReaderIdExt< + Transaction = TxTy, + Block = BlockTy, + Receipt = ReceiptTy, + Header = HeaderTy, + > + AccountReader + StateProviderFactory + EvmEnvProvider + ChainSpecProvider + ChangeSetReader + CanonStateSubscriptions - + ForkChoiceSubscriptions + + ForkChoiceSubscriptions
> + StageCheckpointReader + Clone + Unpin @@ -34,14 +38,18 @@ impl FullProvider for T where T: DatabaseProviderFactory + NodePrimitivesProvider + StaticFileProviderFactory - + BlockReaderIdExt, Block = BlockTy, Receipt = ReceiptTy> - + AccountReader + + BlockReaderIdExt< + Transaction = TxTy, + Block = BlockTy, + Receipt = ReceiptTy, + Header = HeaderTy, + > + AccountReader + StateProviderFactory + EvmEnvProvider + ChainSpecProvider + ChangeSetReader + CanonStateSubscriptions - + ForkChoiceSubscriptions + + ForkChoiceSubscriptions
> + StageCheckpointReader + Clone + Unpin diff --git a/crates/storage/provider/src/traits/header_sync_gap.rs b/crates/storage/provider/src/traits/header_sync_gap.rs index 5ce7e1197..b572750d4 100644 --- a/crates/storage/provider/src/traits/header_sync_gap.rs +++ b/crates/storage/provider/src/traits/header_sync_gap.rs @@ -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 { /// The local head block. Represents lower bound of sync range. - pub local_head: SealedHeader, + pub local_head: SealedHeader, /// The sync target. Represents upper bound of sync range. pub target: SyncTarget, } -impl HeaderSyncGap { +impl HeaderSyncGap { /// 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, highest_uninterrupted_block: BlockNumber, - ) -> ProviderResult; + ) -> ProviderResult>; } diff --git a/crates/storage/storage-api/src/block.rs b/crates/storage/storage-api/src/block.rs index 204e9027d..917796038 100644 --- a/crates/storage/storage-api/src/block.rs +++ b/crates/storage/storage-api/src/block.rs @@ -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, + 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>>; + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>>; /// Returns the block with matching hash from the database. /// @@ -187,7 +187,7 @@ impl BlockReader for std::sync::Arc { ) -> ProviderResult, Vec)>> { T::pending_block_and_receipts(self) } - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { T::ommers(self, id) } fn block_by_hash(&self, hash: B256) -> ProviderResult> { @@ -256,7 +256,7 @@ impl BlockReader for &T { ) -> ProviderResult, Vec)>> { T::pending_block_and_receipts(self) } - fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { + fn ommers(&self, id: BlockHashOrNumber) -> ProviderResult>> { T::ommers(self, id) } fn block_by_hash(&self, hash: B256) -> ProviderResult> { @@ -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> { + fn pending_header(&self) -> ProviderResult>> { 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> { + fn latest_header(&self) -> ProviderResult>> { 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> { + fn safe_header(&self) -> ProviderResult>> { 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> { + fn finalized_header(&self) -> ProviderResult>> { 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> { + fn header_by_number_or_tag( + &self, + id: BlockNumberOrTag, + ) -> ProviderResult> { 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> { + ) -> ProviderResult>> { 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>; + fn sealed_header_by_id( + &self, + id: BlockId, + ) -> ProviderResult>>; /// 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>; + fn header_by_id(&self, id: BlockId) -> ProviderResult>; /// Returns the ommers with the matching tag from the database. - fn ommers_by_number_or_tag(&self, id: BlockNumberOrTag) -> ProviderResult>> { + fn ommers_by_number_or_tag( + &self, + id: BlockNumberOrTag, + ) -> ProviderResult>> { 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>>; + fn ommers_by_id(&self, id: BlockId) -> ProviderResult>>; } /// Functionality to read the last known chain blocks from the database. diff --git a/crates/storage/storage-api/src/chain_info.rs b/crates/storage/storage-api/src/chain_info.rs index 39f8639dd..b6f58b7e7 100644 --- a/crates/storage/storage-api/src/chain_info.rs +++ b/crates/storage/storage-api/src/chain_info.rs @@ -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; /// Sets the canonical head of the chain. - fn set_canonical_head(&self, header: SealedHeader); + fn set_canonical_head(&self, header: SealedHeader); /// Sets the safe block of the chain. - fn set_safe(&self, header: SealedHeader); + fn set_safe(&self, header: SealedHeader); /// Sets the finalized block of the chain. - fn set_finalized(&self, header: SealedHeader); + fn set_finalized(&self, header: SealedHeader); } diff --git a/crates/storage/storage-api/src/header.rs b/crates/storage/storage-api/src/header.rs index c068f7c1d..2f1c9750e 100644 --- a/crates/storage/storage-api/src/header.rs +++ b/crates/storage/storage-api/src/header.rs @@ -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 { self.header(block_hash).map(|header| header.is_some()) } /// Get header by block hash - fn header(&self, block_hash: &BlockHash) -> ProviderResult>; + fn header(&self, block_hash: &BlockHash) -> ProviderResult>; /// Retrieves the header sealed by the given block hash. - fn sealed_header_by_hash(&self, block_hash: BlockHash) -> ProviderResult> { + fn sealed_header_by_hash( + &self, + block_hash: BlockHash, + ) -> ProviderResult>> { 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>; + fn header_by_number(&self, num: u64) -> ProviderResult>; /// Get header by block number or hash fn header_by_hash_or_number( &self, hash_or_num: BlockHashOrNumber, - ) -> ProviderResult> { + ) -> ProviderResult> { 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>; /// Get headers in range of block numbers - fn headers_range(&self, range: impl RangeBounds) -> ProviderResult>; + fn headers_range( + &self, + range: impl RangeBounds, + ) -> ProviderResult>; /// Get a single sealed header by block number. - fn sealed_header(&self, number: BlockNumber) -> ProviderResult>; + fn sealed_header( + &self, + number: BlockNumber, + ) -> ProviderResult>>; /// Get headers in range of block numbers. fn sealed_headers_range( &self, range: impl RangeBounds, - ) -> ProviderResult> { + ) -> ProviderResult>> { self.sealed_headers_while(range, |_| true) } @@ -59,6 +71,6 @@ pub trait HeaderProvider: Send + Sync { fn sealed_headers_while( &self, range: impl RangeBounds, - predicate: impl FnMut(&SealedHeader) -> bool, - ) -> ProviderResult>; + predicate: impl FnMut(&SealedHeader) -> bool, + ) -> ProviderResult>>; } diff --git a/crates/transaction-pool/src/maintain.rs b/crates/transaction-pool/src/maintain.rs index cb75af7db..1a5fd8399 100644 --- a/crates/transaction-pool/src/maintain.rs +++ b/crates/transaction-pool/src/maintain.rs @@ -7,6 +7,7 @@ use crate::{ traits::{CanonicalStateUpdate, TransactionPool, TransactionPoolExt}, BlockInfo, PoolTransaction, PoolUpdateKind, }; +use alloy_consensus::BlockHeader; use alloy_eips::BlockNumberOrTag; use alloy_primitives::{Address, BlockHash, BlockNumber}; use futures_util::{ @@ -110,11 +111,13 @@ pub async fn maintain_transaction_pool( let latest = SealedHeader::seal(latest); let chain_spec = client.chain_spec(); let info = BlockInfo { - block_gas_limit: latest.gas_limit, + block_gas_limit: latest.gas_limit(), last_seen_block_hash: latest.hash(), - last_seen_block_number: latest.number, + last_seen_block_number: latest.number(), pending_basefee: latest - .next_block_base_fee(chain_spec.base_fee_params_at_timestamp(latest.timestamp + 12)) + .next_block_base_fee( + chain_spec.base_fee_params_at_timestamp(latest.timestamp() + 12), + ) .unwrap_or_default(), pending_blob_fee: latest.next_block_blob_fee(), }; diff --git a/examples/db-access/Cargo.toml b/examples/db-access/Cargo.toml index 3310d1cbd..ec278ac1c 100644 --- a/examples/db-access/Cargo.toml +++ b/examples/db-access/Cargo.toml @@ -14,6 +14,7 @@ reth-provider.workspace = true reth-node-ethereum.workspace = true reth-node-types.workspace = true +alloy-consensus.workspace = true alloy-rpc-types-eth.workspace = true alloy-primitives.workspace = true diff --git a/examples/db-access/src/main.rs b/examples/db-access/src/main.rs index 9f95fb51d..727bd1bff 100644 --- a/examples/db-access/src/main.rs +++ b/examples/db-access/src/main.rs @@ -1,3 +1,4 @@ +use alloy_consensus::BlockHeader; use alloy_primitives::{Address, B256}; use alloy_rpc_types_eth::{Filter, FilteredParams}; use reth_chainspec::ChainSpecBuilder; @@ -193,7 +194,7 @@ fn receipts_provider_example< // receipts and do something with the data // 1. get the bloom from the header let header = provider.header_by_number(header_num)?.unwrap(); - let bloom = header.logs_bloom; + let bloom = header.logs_bloom(); // 2. Construct the address/topics filters // For a hypothetical address, we'll want to filter down for a specific indexed topic (e.g.