diff --git a/Cargo.lock b/Cargo.lock index c0ad6f5b230b..e7859a6cc30a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8283,6 +8283,7 @@ dependencies = [ "reth-consensus-common", "reth-optimism-chainspec", "reth-optimism-forks", + "reth-optimism-primitives", "reth-primitives", "reth-trie-common", "tracing", diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index dc00e07d8830..e08c32b93a4f 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -17,7 +17,7 @@ use reth_chainspec::ChainSpec; use reth_cli::chainspec::ChainSpecParser; use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use reth_cli_runner::CliContext; -use reth_consensus::Consensus; +use reth_consensus::{Consensus, FullConsensus}; use reth_errors::RethResult; use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_execution_types::ExecutionOutcome; @@ -128,7 +128,7 @@ impl> Command { ) -> eyre::Result<()> { let Environment { provider_factory, .. } = self.env.init::(AccessRights::RW)?; - let consensus: Arc = + let consensus: Arc = Arc::new(EthBeaconConsensus::new(provider_factory.chain_spec())); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()); diff --git a/bin/reth/src/commands/debug_cmd/replay_engine.rs b/bin/reth/src/commands/debug_cmd/replay_engine.rs index 04d3b5763aef..f0016a129bde 100644 --- a/bin/reth/src/commands/debug_cmd/replay_engine.rs +++ b/bin/reth/src/commands/debug_cmd/replay_engine.rs @@ -12,7 +12,7 @@ use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, Environ use reth_cli_runner::CliContext; use reth_cli_util::get_secret_key; use reth_config::Config; -use reth_consensus::Consensus; +use reth_consensus::FullConsensus; use reth_db::DatabaseEnv; use reth_engine_util::engine_store::{EngineMessageStore, StoredEngineApiMessage}; use reth_fs_util as fs; @@ -92,7 +92,7 @@ impl> Command { let Environment { provider_factory, config, data_dir } = self.env.init::(AccessRights::RW)?; - let consensus: Arc = + let consensus: Arc = Arc::new(EthBeaconConsensus::new(provider_factory.chain_spec())); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()); diff --git a/crates/blockchain-tree/src/chain.rs b/crates/blockchain-tree/src/chain.rs index ba4f91d9c798..a3cbd432de88 100644 --- a/crates/blockchain-tree/src/chain.rs +++ b/crates/blockchain-tree/src/chain.rs @@ -11,7 +11,7 @@ use reth_blockchain_tree_api::{ error::{BlockchainTreeError, InsertBlockErrorKind}, BlockAttachment, BlockValidationKind, }; -use reth_consensus::{Consensus, ConsensusError, PostExecutionInput}; +use reth_consensus::{ConsensusError, PostExecutionInput}; use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_execution_errors::BlockExecutionError; use reth_execution_types::{Chain, ExecutionOutcome}; diff --git a/crates/blockchain-tree/src/externals.rs b/crates/blockchain-tree/src/externals.rs index 2a825921f893..9e72008e838f 100644 --- a/crates/blockchain-tree/src/externals.rs +++ b/crates/blockchain-tree/src/externals.rs @@ -1,7 +1,7 @@ //! Blockchain tree externals. use alloy_primitives::{BlockHash, BlockNumber}; -use reth_consensus::Consensus; +use reth_consensus::FullConsensus; use reth_db::{static_file::BlockHashMask, tables}; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; use reth_node_types::NodeTypesWithDB; @@ -28,7 +28,7 @@ pub struct TreeExternals { /// The provider factory, used to commit the canonical chain, or unwind it. pub(crate) provider_factory: ProviderFactory, /// The consensus engine. - pub(crate) consensus: Arc, + pub(crate) consensus: Arc, /// The executor factory to execute blocks with. pub(crate) executor_factory: E, } @@ -37,7 +37,7 @@ impl TreeExternals { /// Create new tree externals. pub fn new( provider_factory: ProviderFactory, - consensus: Arc, + consensus: Arc, executor_factory: E, ) -> Self { Self { provider_factory, consensus, executor_factory } diff --git a/crates/consensus/beacon/src/engine/test_utils.rs b/crates/consensus/beacon/src/engine/test_utils.rs index 0ebef1efe6e6..ae627cae6961 100644 --- a/crates/consensus/beacon/src/engine/test_utils.rs +++ b/crates/consensus/beacon/src/engine/test_utils.rs @@ -13,7 +13,7 @@ use reth_blockchain_tree::{ }; use reth_chainspec::ChainSpec; use reth_config::config::StageConfig; -use reth_consensus::{test_utils::TestConsensus, Consensus}; +use reth_consensus::{test_utils::TestConsensus, FullConsensus}; use reth_db::{test_utils::TempDatabase, DatabaseEnv as DE}; use reth_downloaders::{ bodies::bodies::BodiesDownloaderBuilder, @@ -332,7 +332,7 @@ where let provider_factory = create_test_provider_factory_with_chain_spec(self.base_config.chain_spec.clone()); - let consensus: Arc = match self.base_config.consensus { + let consensus: Arc = match self.base_config.consensus { TestConsensusConfig::Real => { Arc::new(EthBeaconConsensus::new(Arc::clone(&self.base_config.chain_spec))) } @@ -374,13 +374,17 @@ where .into_task(); let body_downloader = BodiesDownloaderBuilder::default() - .build(client.clone(), consensus.clone(), provider_factory.clone()) + .build( + client.clone(), + consensus.clone().as_consensus(), + provider_factory.clone(), + ) .into_task(); Pipeline::::builder().add_stages(DefaultStages::new( provider_factory.clone(), tip_rx.clone(), - Arc::clone(&consensus), + consensus.clone().as_consensus(), header_downloader, body_downloader, executor_factory.clone(), diff --git a/crates/consensus/consensus/src/lib.rs b/crates/consensus/consensus/src/lib.rs index 3ad53456cbdf..ba1b1321e776 100644 --- a/crates/consensus/consensus/src/lib.rs +++ b/crates/consensus/consensus/src/lib.rs @@ -16,8 +16,8 @@ use alloy_consensus::Header; use alloy_eips::eip7685::Requests; use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256}; use reth_primitives::{ - BlockBody, BlockWithSenders, GotExpected, GotExpectedBoxed, InvalidTransactionError, Receipt, - SealedBlock, SealedHeader, + BlockBody, BlockWithSenders, EthPrimitives, GotExpected, GotExpectedBoxed, + InvalidTransactionError, NodePrimitives, Receipt, SealedBlock, SealedHeader, }; use reth_primitives_traits::constants::MINIMUM_GAS_LIMIT; @@ -28,7 +28,7 @@ pub mod noop; /// test helpers for mocking consensus pub mod test_utils; -/// Post execution input passed to [`Consensus::validate_block_post_execution`]. +/// Post execution input passed to [`FullConsensus::validate_block_post_execution`]. #[derive(Debug)] pub struct PostExecutionInput<'a, R = Receipt> { /// Receipts of the block. @@ -44,11 +44,28 @@ impl<'a, R> PostExecutionInput<'a, R> { } } -/// Consensus is a protocol that chooses canonical chain. +/// [`Consensus`] implementation which knows full node primitives and is able to validation block's +/// execution outcome. #[auto_impl::auto_impl(&, Arc)] -pub trait Consensus: - AsHeaderValidator + HeaderValidator + Debug + Send + Sync +pub trait FullConsensus: + AsConsensus { + /// Validate a block considering world state, i.e. things that can not be checked before + /// execution. + /// + /// See the Yellow Paper sections 4.3.2 "Holistic Validity". + /// + /// Note: validating blocks does not include other validations of the Consensus + fn validate_block_post_execution( + &self, + block: &BlockWithSenders, + input: PostExecutionInput<'_, N::Receipt>, + ) -> Result<(), ConsensusError>; +} + +/// Consensus is a protocol that chooses canonical chain. +#[auto_impl::auto_impl(&, Arc)] +pub trait Consensus: AsHeaderValidator { /// Ensures that body field values match the header. fn validate_body_against_header( &self, @@ -67,18 +84,6 @@ pub trait Consensus: /// Note: validating blocks does not include other validations of the Consensus fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError>; - - /// Validate a block considering world state, i.e. things that can not be checked before - /// execution. - /// - /// See the Yellow Paper sections 4.3.2 "Holistic Validity". - /// - /// Note: validating blocks does not include other validations of the Consensus - fn validate_block_post_execution( - &self, - block: &BlockWithSenders, - input: PostExecutionInput<'_>, - ) -> Result<(), ConsensusError>; } /// HeaderValidator is a protocol that validates headers and their relationships. @@ -162,6 +167,23 @@ impl, H> AsHeaderValidator for T { } } +/// Helper trait to cast `Arc` to `Arc` +pub trait AsConsensus: Consensus { + /// Converts the [`Arc`] of self to [`Arc`] of [`HeaderValidator`] + fn as_consensus<'a>(self: Arc) -> Arc + 'a> + where + Self: 'a; +} + +impl, H, B> AsConsensus for T { + fn as_consensus<'a>(self: Arc) -> Arc + 'a> + where + Self: 'a, + { + self + } +} + /// Consensus Errors #[derive(Debug, PartialEq, Eq, Clone, derive_more::Display, derive_more::Error)] pub enum ConsensusError { diff --git a/crates/consensus/consensus/src/noop.rs b/crates/consensus/consensus/src/noop.rs index 6d12af08d519..c56e9867a256 100644 --- a/crates/consensus/consensus/src/noop.rs +++ b/crates/consensus/consensus/src/noop.rs @@ -1,6 +1,6 @@ -use crate::{Consensus, ConsensusError, HeaderValidator, PostExecutionInput}; +use crate::{Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput}; use alloy_primitives::U256; -use reth_primitives::{BlockWithSenders, SealedBlock, SealedHeader}; +use reth_primitives::{BlockWithSenders, NodePrimitives, SealedBlock, SealedHeader}; /// A Consensus implementation that does nothing. #[derive(Debug, Copy, Clone, Default)] @@ -44,11 +44,13 @@ impl Consensus for NoopConsensus { ) -> Result<(), ConsensusError> { Ok(()) } +} +impl FullConsensus for NoopConsensus { fn validate_block_post_execution( &self, - _block: &BlockWithSenders, - _input: PostExecutionInput<'_>, + _block: &BlockWithSenders, + _input: PostExecutionInput<'_, N::Receipt>, ) -> Result<(), ConsensusError> { Ok(()) } diff --git a/crates/consensus/consensus/src/test_utils.rs b/crates/consensus/consensus/src/test_utils.rs index ba683dd255f8..082c8ca8bb5a 100644 --- a/crates/consensus/consensus/src/test_utils.rs +++ b/crates/consensus/consensus/src/test_utils.rs @@ -1,7 +1,7 @@ -use crate::{Consensus, ConsensusError, HeaderValidator, PostExecutionInput}; +use crate::{Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput}; use alloy_primitives::U256; use core::sync::atomic::{AtomicBool, Ordering}; -use reth_primitives::{BlockWithSenders, SealedBlock, SealedHeader}; +use reth_primitives::{BlockWithSenders, NodePrimitives, SealedBlock, SealedHeader}; /// Consensus engine implementation for testing #[derive(Debug)] @@ -46,34 +46,36 @@ impl TestConsensus { } } -impl Consensus for TestConsensus { - fn validate_body_against_header( +impl FullConsensus for TestConsensus { + fn validate_block_post_execution( &self, - _body: &B, - _header: &SealedHeader, + _block: &BlockWithSenders, + _input: PostExecutionInput<'_, N::Receipt>, ) -> Result<(), ConsensusError> { - if self.fail_body_against_header() { + if self.fail_validation() { Err(ConsensusError::BaseFeeMissing) } else { Ok(()) } } +} - fn validate_block_pre_execution( +impl Consensus for TestConsensus { + fn validate_body_against_header( &self, - _block: &SealedBlock, + _body: &B, + _header: &SealedHeader, ) -> Result<(), ConsensusError> { - if self.fail_validation() { + if self.fail_body_against_header() { Err(ConsensusError::BaseFeeMissing) } else { Ok(()) } } - fn validate_block_post_execution( + fn validate_block_pre_execution( &self, - _block: &BlockWithSenders, - _input: PostExecutionInput<'_>, + _block: &SealedBlock, ) -> Result<(), ConsensusError> { if self.fail_validation() { Err(ConsensusError::BaseFeeMissing) diff --git a/crates/engine/local/src/service.rs b/crates/engine/local/src/service.rs index 79d9d844d734..b06750d66df0 100644 --- a/crates/engine/local/src/service.rs +++ b/crates/engine/local/src/service.rs @@ -18,7 +18,7 @@ use crate::miner::{LocalMiner, MiningMode}; use futures_util::{Stream, StreamExt}; use reth_beacon_consensus::{BeaconConsensusEngineEvent, EngineNodeTypes}; use reth_chainspec::EthChainSpec; -use reth_consensus::Consensus; +use reth_consensus::FullConsensus; use reth_engine_primitives::{BeaconEngineMessage, EngineValidator}; use reth_engine_service::service::EngineMessageStream; use reth_engine_tree::{ @@ -64,7 +64,7 @@ where /// Constructor for [`LocalEngineService`]. #[allow(clippy::too_many_arguments)] pub fn new( - consensus: Arc, + consensus: Arc, executor_factory: impl BlockExecutorProvider, provider: ProviderFactory, blockchain_db: BlockchainProvider2, diff --git a/crates/engine/service/src/service.rs b/crates/engine/service/src/service.rs index 8bb26d69140c..d3c07c638711 100644 --- a/crates/engine/service/src/service.rs +++ b/crates/engine/service/src/service.rs @@ -2,7 +2,7 @@ use futures::{Stream, StreamExt}; use pin_project::pin_project; use reth_beacon_consensus::{BeaconConsensusEngineEvent, EngineNodeTypes}; use reth_chainspec::EthChainSpec; -use reth_consensus::Consensus; +use reth_consensus::FullConsensus; use reth_engine_primitives::{BeaconEngineMessage, EngineValidator}; use reth_engine_tree::{ backfill::PipelineSync, @@ -65,7 +65,7 @@ where /// Constructor for `EngineService`. #[allow(clippy::too_many_arguments)] pub fn new( - consensus: Arc, + consensus: Arc, executor_factory: E, chain_spec: Arc, client: Client, @@ -87,7 +87,7 @@ where let engine_kind = if chain_spec.is_optimism() { EngineApiKind::OpStack } else { EngineApiKind::Ethereum }; - let downloader = BasicBlockDownloader::new(client, consensus.clone()); + let downloader = BasicBlockDownloader::new(client, consensus.clone().as_consensus()); let persistence_handle = PersistenceHandle::spawn_service(provider, pruner, sync_metrics_tx); diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 7b8ec8838922..96c032082669 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -25,7 +25,7 @@ use reth_blockchain_tree::{ use reth_chain_state::{ CanonicalInMemoryState, ExecutedBlock, MemoryOverlayStateProvider, NewCanonicalChain, }; -use reth_consensus::{Consensus, PostExecutionInput}; +use reth_consensus::{Consensus, FullConsensus, PostExecutionInput}; use reth_engine_primitives::{ BeaconEngineMessage, BeaconOnNewPayloadError, EngineApiMessageVersion, EngineTypes, EngineValidator, ForkchoiceStateTracker, OnForkChoiceUpdated, @@ -473,7 +473,7 @@ where { provider: P, executor_provider: E, - consensus: Arc, + consensus: Arc, payload_validator: V, /// Keeps track of internals such as executed and buffered blocks. state: EngineApiTreeState, @@ -557,7 +557,7 @@ where pub fn new( provider: P, executor_provider: E, - consensus: Arc, + consensus: Arc, payload_validator: V, outgoing: UnboundedSender, state: EngineApiTreeState, @@ -606,7 +606,7 @@ where pub fn spawn_new( provider: P, executor_provider: E, - consensus: Arc, + consensus: Arc, payload_validator: V, persistence: PersistenceHandle, payload_builder: PayloadBuilderHandle, diff --git a/crates/ethereum/consensus/src/lib.rs b/crates/ethereum/consensus/src/lib.rs index 96dfbae3f166..ba737e56728c 100644 --- a/crates/ethereum/consensus/src/lib.rs +++ b/crates/ethereum/consensus/src/lib.rs @@ -11,14 +11,18 @@ use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_primitives::U256; use reth_chainspec::{EthChainSpec, EthereumHardfork, EthereumHardforks}; -use reth_consensus::{Consensus, ConsensusError, HeaderValidator, PostExecutionInput}; +use reth_consensus::{ + Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput, +}; use reth_consensus_common::validation::{ validate_4844_header_standalone, validate_against_parent_4844, validate_against_parent_eip1559_base_fee, validate_against_parent_hash_number, validate_against_parent_timestamp, validate_block_pre_execution, validate_body_against_header, validate_header_base_fee, validate_header_extradata, validate_header_gas, }; -use reth_primitives::{BlockBody, BlockWithSenders, SealedBlock, SealedHeader}; +use reth_primitives::{ + Block, BlockBody, BlockWithSenders, NodePrimitives, Receipt, SealedBlock, SealedHeader, +}; use reth_primitives_traits::constants::MINIMUM_GAS_LIMIT; use std::{fmt::Debug, sync::Arc, time::SystemTime}; @@ -90,6 +94,25 @@ impl EthBeaconConsensus } } +impl FullConsensus for EthBeaconConsensus +where + ChainSpec: Send + Sync + EthChainSpec + EthereumHardforks + Debug, + N: NodePrimitives< + BlockHeader = Header, + BlockBody = BlockBody, + Block = Block, + Receipt = Receipt, + >, +{ + fn validate_block_post_execution( + &self, + block: &BlockWithSenders, + input: PostExecutionInput<'_>, + ) -> Result<(), ConsensusError> { + validate_block_post_execution(block, &self.chain_spec, input.receipts, input.requests) + } +} + impl Consensus for EthBeaconConsensus { @@ -104,14 +127,6 @@ impl Consensu fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> { validate_block_pre_execution(block, &self.chain_spec) } - - fn validate_block_post_execution( - &self, - block: &BlockWithSenders, - input: PostExecutionInput<'_>, - ) -> Result<(), ConsensusError> { - validate_block_post_execution(block, &self.chain_spec, input.receipts, input.requests) - } } impl HeaderValidator diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index 9db0c44c6c69..ad673588bf95 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -327,9 +327,9 @@ pub struct EthereumConsensusBuilder { impl ConsensusBuilder for EthereumConsensusBuilder where - Node: FullNodeTypes>, + Node: FullNodeTypes>, { - type Consensus = Arc; + type Consensus = Arc; async fn build_consensus(self, ctx: &BuilderContext) -> eyre::Result { Ok(Arc::new(EthBeaconConsensus::new(ctx.chain_spec()))) diff --git a/crates/node/api/src/node.rs b/crates/node/api/src/node.rs index d640c0dbb0ea..7778fea7b5e1 100644 --- a/crates/node/api/src/node.rs +++ b/crates/node/api/src/node.rs @@ -4,7 +4,7 @@ use crate::ConfigureEvm; use alloy_consensus::Header; use alloy_rpc_types_engine::JwtSecret; use reth_beacon_consensus::BeaconConsensusEngineHandle; -use reth_consensus::Consensus; +use reth_consensus::FullConsensus; use reth_evm::execute::BlockExecutorProvider; use reth_network_api::FullNetwork; use reth_node_core::node_config::NodeConfig; @@ -56,7 +56,7 @@ pub trait FullNodeComponents: FullNodeTypes + Clone + 'static { type Executor: BlockExecutorProvider::Primitives>; /// The consensus type of the node. - type Consensus: Consensus + Clone + Unpin + 'static; + type Consensus: FullConsensus<::Primitives> + Clone + Unpin + 'static; /// Network API. type Network: FullNetwork; diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs index 46b6824dba73..b265dc927e75 100644 --- a/crates/node/builder/src/components/builder.rs +++ b/crates/node/builder/src/components/builder.rs @@ -8,7 +8,7 @@ use crate::{ BuilderContext, ConfigureEvm, FullNodeTypes, }; use alloy_consensus::Header; -use reth_consensus::Consensus; +use reth_consensus::FullConsensus; use reth_evm::execute::BlockExecutorProvider; use reth_node_api::{NodeTypes, NodeTypesWithEngine}; use reth_payload_builder::PayloadBuilderHandle; @@ -378,7 +378,7 @@ where Pool: TransactionPool + Unpin + 'static, EVM: ConfigureEvm
, Executor: BlockExecutorProvider::Primitives>, - Cons: Consensus + Clone + Unpin + 'static, + Cons: FullConsensus<::Primitives> + Clone + Unpin + 'static, { type Components = Components; diff --git a/crates/node/builder/src/components/consensus.rs b/crates/node/builder/src/components/consensus.rs index 6c90bda54752..074080d337b1 100644 --- a/crates/node/builder/src/components/consensus.rs +++ b/crates/node/builder/src/components/consensus.rs @@ -1,11 +1,16 @@ //! Consensus component for the node builder. +use reth_node_api::NodeTypes; + use crate::{BuilderContext, FullNodeTypes}; use std::future::Future; /// A type that knows how to build the consensus implementation. pub trait ConsensusBuilder: Send { /// The consensus implementation to build. - type Consensus: reth_consensus::Consensus + Clone + Unpin + 'static; + type Consensus: reth_consensus::FullConsensus<::Primitives> + + Clone + + Unpin + + 'static; /// Creates the consensus implementation. fn build_consensus( @@ -17,7 +22,10 @@ pub trait ConsensusBuilder: Send { impl ConsensusBuilder for F where Node: FullNodeTypes, - Consensus: reth_consensus::Consensus + Clone + Unpin + 'static, + Consensus: reth_consensus::FullConsensus<::Primitives> + + Clone + + Unpin + + 'static, F: FnOnce(&BuilderContext) -> Fut + Send, Fut: Future> + Send, { diff --git a/crates/node/builder/src/components/mod.rs b/crates/node/builder/src/components/mod.rs index a3f3017463db..a7d15dd29df1 100644 --- a/crates/node/builder/src/components/mod.rs +++ b/crates/node/builder/src/components/mod.rs @@ -23,7 +23,7 @@ pub use pool::*; use crate::{ConfigureEvm, FullNodeTypes}; use alloy_consensus::Header; -use reth_consensus::Consensus; +use reth_consensus::FullConsensus; use reth_evm::execute::BlockExecutorProvider; use reth_network::NetworkHandle; use reth_network_api::FullNetwork; @@ -47,7 +47,7 @@ pub trait NodeComponents: Clone + Unpin + Send + Sync + 'stati type Executor: BlockExecutorProvider::Primitives>; /// The consensus type of the node. - type Consensus: Consensus + Clone + Unpin + 'static; + type Consensus: FullConsensus<::Primitives> + Clone + Unpin + 'static; /// Network API. type Network: FullNetwork; @@ -100,7 +100,7 @@ where Pool: TransactionPool + Unpin + 'static, EVM: ConfigureEvm
, Executor: BlockExecutorProvider::Primitives>, - Cons: Consensus + Clone + Unpin + 'static, + Cons: FullConsensus<::Primitives> + Clone + Unpin + 'static, { type Pool = Pool; type Evm = EVM; @@ -140,7 +140,7 @@ where Pool: TransactionPool, EVM: ConfigureEvm
, Executor: BlockExecutorProvider, - Cons: Consensus + Clone, + Cons: Clone, { fn clone(&self) -> Self { Self { diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index 830909c8cc4c..2d126266a25c 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -13,7 +13,6 @@ use rayon::ThreadPoolBuilder; use reth_beacon_consensus::EthBeaconConsensus; use reth_chainspec::{Chain, EthChainSpec, EthereumHardforks}; use reth_config::{config::EtlConfig, PruneConfig}; -use reth_consensus::Consensus; use reth_db_api::{database::Database, database_metrics::DatabaseMetrics}; use reth_db_common::init::{init_genesis, InitDatabaseError}; use reth_downloaders::{bodies::noop::NoopBodiesDownloader, headers::noop::NoopHeaderDownloader}; @@ -681,7 +680,6 @@ where let components = components_builder.build_components(&builder_ctx).await?; let blockchain_db = self.blockchain_db().clone(); - let consensus = Arc::new(components.consensus().clone()); let node_adapter = NodeAdapter { components, @@ -699,7 +697,6 @@ where }, node_adapter, head, - consensus, }; let ctx = LaunchContextWith { @@ -855,11 +852,6 @@ where Ok(None) } - /// Returns the configured `Consensus`. - pub fn consensus(&self) -> Arc { - self.right().consensus.clone() - } - /// Returns the metrics sender. pub fn sync_metrics_tx(&self) -> UnboundedSender { self.right().db_provider_container.metrics_sender.clone() @@ -1029,7 +1021,6 @@ where db_provider_container: WithMeteredProvider, node_adapter: NodeAdapter, head: Head, - consensus: Arc, } #[cfg(test)] diff --git a/crates/node/builder/src/launch/engine.rs b/crates/node/builder/src/launch/engine.rs index b1141314d106..264de07048a0 100644 --- a/crates/node/builder/src/launch/engine.rs +++ b/crates/node/builder/src/launch/engine.rs @@ -175,13 +175,15 @@ where )); info!(target: "reth::cli", "StaticFileProducer initialized"); + let consensus = Arc::new(ctx.components().consensus().clone()); + // Configure the pipeline let pipeline_exex_handle = exex_manager_handle.clone().unwrap_or_else(ExExManagerHandle::empty); let pipeline = build_networked_pipeline( &ctx.toml_config().stages, network_client.clone(), - ctx.consensus(), + consensus.clone(), ctx.provider_factory().clone(), ctx.task_executor(), ctx.sync_metrics_tx(), @@ -223,7 +225,7 @@ where let mut engine_service = if ctx.is_dev() { let eth_service = LocalEngineService::new( - ctx.consensus(), + consensus.clone(), ctx.components().block_executor().clone(), ctx.provider_factory().clone(), ctx.blockchain_db().clone(), @@ -242,7 +244,7 @@ where Either::Left(eth_service) } else { let eth_service = EngineService::new( - ctx.consensus(), + consensus.clone(), ctx.components().block_executor().clone(), ctx.chain_spec(), network_client.clone(), diff --git a/crates/node/builder/src/launch/mod.rs b/crates/node/builder/src/launch/mod.rs index 9f2c027f76b5..e23ce38da75b 100644 --- a/crates/node/builder/src/launch/mod.rs +++ b/crates/node/builder/src/launch/mod.rs @@ -236,7 +236,7 @@ where let pipeline = crate::setup::build_networked_pipeline( &ctx.toml_config().stages, network_client.clone(), - ctx.consensus(), + consensus.clone(), ctx.provider_factory().clone(), ctx.task_executor(), ctx.sync_metrics_tx(), diff --git a/crates/optimism/consensus/Cargo.toml b/crates/optimism/consensus/Cargo.toml index 0dffceaddca9..30f16e4eb228 100644 --- a/crates/optimism/consensus/Cargo.toml +++ b/crates/optimism/consensus/Cargo.toml @@ -22,6 +22,7 @@ reth-trie-common.workspace = true # op-reth reth-optimism-forks.workspace = true reth-optimism-chainspec.workspace = true +reth-optimism-primitives.workspace = true # ethereum alloy-primitives.workspace = true diff --git a/crates/optimism/consensus/src/lib.rs b/crates/optimism/consensus/src/lib.rs index cb357db924ad..b50efd5f6f26 100644 --- a/crates/optimism/consensus/src/lib.rs +++ b/crates/optimism/consensus/src/lib.rs @@ -12,7 +12,9 @@ use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_primitives::{B64, U256}; use reth_chainspec::EthereumHardforks; -use reth_consensus::{Consensus, ConsensusError, HeaderValidator, PostExecutionInput}; +use reth_consensus::{ + Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput, +}; use reth_consensus_common::validation::{ validate_against_parent_4844, validate_against_parent_eip1559_base_fee, validate_against_parent_hash_number, validate_against_parent_timestamp, @@ -21,6 +23,7 @@ use reth_consensus_common::validation::{ }; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_forks::OpHardforks; +use reth_optimism_primitives::OpPrimitives; use reth_primitives::{BlockBody, BlockWithSenders, GotExpected, SealedBlock, SealedHeader}; use std::{sync::Arc, time::SystemTime}; @@ -46,6 +49,16 @@ impl OpBeaconConsensus { } } +impl FullConsensus for OpBeaconConsensus { + fn validate_block_post_execution( + &self, + block: &BlockWithSenders, + input: PostExecutionInput<'_>, + ) -> Result<(), ConsensusError> { + validate_block_post_execution(block, &self.chain_spec, input.receipts) + } +} + impl Consensus for OpBeaconConsensus { fn validate_body_against_header( &self, @@ -80,14 +93,6 @@ impl Consensus for OpBeaconConsensus { Ok(()) } - - fn validate_block_post_execution( - &self, - block: &BlockWithSenders, - input: PostExecutionInput<'_>, - ) -> Result<(), ConsensusError> { - validate_block_post_execution(block, &self.chain_spec, input.receipts) - } } impl HeaderValidator for OpBeaconConsensus { diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 429cb9ae229b..bdf8c3f58eed 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -569,9 +569,9 @@ pub struct OpConsensusBuilder; impl ConsensusBuilder for OpConsensusBuilder where - Node: FullNodeTypes>, + Node: FullNodeTypes>, { - type Consensus = Arc; + type Consensus = Arc; async fn build_consensus(self, ctx: &BuilderContext) -> eyre::Result { Ok(Arc::new(OpBeaconConsensus::new(ctx.chain_spec()))) diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 46b3888f05b1..3817c4d3b378 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -49,7 +49,7 @@ //! CanonStateSubscriptions + Clone + 'static, //! EvmConfig: ConfigureEvm
, //! BlockExecutor: BlockExecutorProvider, -//! Consensus: reth_consensus::Consensus + Clone + 'static, +//! Consensus: reth_consensus::FullConsensus + Clone + 'static, //! { //! // configure the rpc module per transport //! let transports = TransportRpcModuleConfig::default().with_http(vec![ @@ -131,7 +131,7 @@ //! EngineT: EngineTypes, //! EvmConfig: ConfigureEvm
, //! BlockExecutor: BlockExecutorProvider, -//! Consensus: reth_consensus::Consensus + Clone + 'static, +//! Consensus: reth_consensus::FullConsensus + Clone + 'static, //! { //! // configure the rpc module per transport //! let transports = TransportRpcModuleConfig::default().with_http(vec![ @@ -194,7 +194,7 @@ use jsonrpsee::{ Methods, RpcModule, }; use reth_chainspec::EthereumHardforks; -use reth_consensus::Consensus; +use reth_consensus::FullConsensus; use reth_engine_primitives::EngineTypes; use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers}; @@ -266,7 +266,7 @@ pub async fn launch, block_executor: BlockExecutor, - consensus: Arc, + consensus: Arc, ) -> Result where Provider: FullRpcProvider @@ -641,7 +641,7 @@ where Receipt = reth_primitives::Receipt, >, >, - Consensus: reth_consensus::Consensus + Clone + 'static, + Consensus: reth_consensus::FullConsensus + Clone + 'static, { /// Configures all [`RpcModule`]s specific to the given [`TransportRpcModuleConfig`] which can /// be used to start the transport server(s). @@ -1293,7 +1293,7 @@ where /// Instantiates `ValidationApi` pub fn validation_api(&self) -> ValidationApi where - Consensus: reth_consensus::Consensus + Clone + 'static, + Consensus: reth_consensus::FullConsensus + Clone + 'static, { ValidationApi::new( self.provider.clone(), @@ -1324,7 +1324,7 @@ where Receipt = reth_primitives::Receipt, >, >, - Consensus: reth_consensus::Consensus + Clone + 'static, + Consensus: reth_consensus::FullConsensus + Clone + 'static, { /// Configures the auth module that includes the /// * `engine_` namespace diff --git a/crates/rpc/rpc/src/validation.rs b/crates/rpc/rpc/src/validation.rs index 1885c8ad2e0c..1aa502c1f104 100644 --- a/crates/rpc/rpc/src/validation.rs +++ b/crates/rpc/rpc/src/validation.rs @@ -10,7 +10,7 @@ use alloy_rpc_types_engine::{ use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_chainspec::{ChainSpecProvider, EthereumHardforks}; -use reth_consensus::{Consensus, PostExecutionInput}; +use reth_consensus::{Consensus, FullConsensus, PostExecutionInput}; use reth_errors::{BlockExecutionError, ConsensusError, ProviderError}; use reth_ethereum_consensus::GAS_LIMIT_BOUND_DIVISOR; use reth_evm::execute::{BlockExecutorProvider, Executor}; @@ -44,7 +44,7 @@ where /// Create a new instance of the [`ValidationApi`] pub fn new( provider: Provider, - consensus: Arc, + consensus: Arc, executor_provider: E, config: ValidationApiConfig, task_spawner: Box, @@ -475,7 +475,7 @@ pub struct ValidationApiInner { /// The provider that can interact with the chain. provider: Provider, /// Consensus implementation. - consensus: Arc, + consensus: Arc, /// Execution payload validator. payload_validator: ExecutionPayloadValidator, /// Block executor factory.