feat: consensus trait generic over NodePrimitives (#13026)

This commit is contained in:
Arsenii Kulikov
2024-11-30 02:26:36 +04:00
committed by GitHub
parent 55ddaab1e4
commit 5d71150355
26 changed files with 166 additions and 113 deletions

1
Cargo.lock generated
View File

@ -8283,6 +8283,7 @@ dependencies = [
"reth-consensus-common", "reth-consensus-common",
"reth-optimism-chainspec", "reth-optimism-chainspec",
"reth-optimism-forks", "reth-optimism-forks",
"reth-optimism-primitives",
"reth-primitives", "reth-primitives",
"reth-trie-common", "reth-trie-common",
"tracing", "tracing",

View File

@ -17,7 +17,7 @@ use reth_chainspec::ChainSpec;
use reth_cli::chainspec::ChainSpecParser; use reth_cli::chainspec::ChainSpecParser;
use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs};
use reth_cli_runner::CliContext; use reth_cli_runner::CliContext;
use reth_consensus::Consensus; use reth_consensus::{Consensus, FullConsensus};
use reth_errors::RethResult; use reth_errors::RethResult;
use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_evm::execute::{BlockExecutorProvider, Executor};
use reth_execution_types::ExecutionOutcome; use reth_execution_types::ExecutionOutcome;
@ -128,7 +128,7 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
) -> eyre::Result<()> { ) -> eyre::Result<()> {
let Environment { provider_factory, .. } = self.env.init::<N>(AccessRights::RW)?; let Environment { provider_factory, .. } = self.env.init::<N>(AccessRights::RW)?;
let consensus: Arc<dyn Consensus> = let consensus: Arc<dyn FullConsensus> =
Arc::new(EthBeaconConsensus::new(provider_factory.chain_spec())); Arc::new(EthBeaconConsensus::new(provider_factory.chain_spec()));
let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec());

View File

@ -12,7 +12,7 @@ use reth_cli_commands::common::{AccessRights, CliNodeTypes, Environment, Environ
use reth_cli_runner::CliContext; use reth_cli_runner::CliContext;
use reth_cli_util::get_secret_key; use reth_cli_util::get_secret_key;
use reth_config::Config; use reth_config::Config;
use reth_consensus::Consensus; use reth_consensus::FullConsensus;
use reth_db::DatabaseEnv; use reth_db::DatabaseEnv;
use reth_engine_util::engine_store::{EngineMessageStore, StoredEngineApiMessage}; use reth_engine_util::engine_store::{EngineMessageStore, StoredEngineApiMessage};
use reth_fs_util as fs; use reth_fs_util as fs;
@ -92,7 +92,7 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
let Environment { provider_factory, config, data_dir } = let Environment { provider_factory, config, data_dir } =
self.env.init::<N>(AccessRights::RW)?; self.env.init::<N>(AccessRights::RW)?;
let consensus: Arc<dyn Consensus> = let consensus: Arc<dyn FullConsensus> =
Arc::new(EthBeaconConsensus::new(provider_factory.chain_spec())); Arc::new(EthBeaconConsensus::new(provider_factory.chain_spec()));
let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec()); let executor = EthExecutorProvider::ethereum(provider_factory.chain_spec());

View File

@ -11,7 +11,7 @@ use reth_blockchain_tree_api::{
error::{BlockchainTreeError, InsertBlockErrorKind}, error::{BlockchainTreeError, InsertBlockErrorKind},
BlockAttachment, BlockValidationKind, BlockAttachment, BlockValidationKind,
}; };
use reth_consensus::{Consensus, ConsensusError, PostExecutionInput}; use reth_consensus::{ConsensusError, PostExecutionInput};
use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_evm::execute::{BlockExecutorProvider, Executor};
use reth_execution_errors::BlockExecutionError; use reth_execution_errors::BlockExecutionError;
use reth_execution_types::{Chain, ExecutionOutcome}; use reth_execution_types::{Chain, ExecutionOutcome};

View File

@ -1,7 +1,7 @@
//! Blockchain tree externals. //! Blockchain tree externals.
use alloy_primitives::{BlockHash, BlockNumber}; use alloy_primitives::{BlockHash, BlockNumber};
use reth_consensus::Consensus; use reth_consensus::FullConsensus;
use reth_db::{static_file::BlockHashMask, tables}; use reth_db::{static_file::BlockHashMask, tables};
use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx};
use reth_node_types::NodeTypesWithDB; use reth_node_types::NodeTypesWithDB;
@ -28,7 +28,7 @@ pub struct TreeExternals<N: NodeTypesWithDB, E> {
/// The provider factory, used to commit the canonical chain, or unwind it. /// The provider factory, used to commit the canonical chain, or unwind it.
pub(crate) provider_factory: ProviderFactory<N>, pub(crate) provider_factory: ProviderFactory<N>,
/// The consensus engine. /// The consensus engine.
pub(crate) consensus: Arc<dyn Consensus>, pub(crate) consensus: Arc<dyn FullConsensus>,
/// The executor factory to execute blocks with. /// The executor factory to execute blocks with.
pub(crate) executor_factory: E, pub(crate) executor_factory: E,
} }
@ -37,7 +37,7 @@ impl<N: ProviderNodeTypes, E> TreeExternals<N, E> {
/// Create new tree externals. /// Create new tree externals.
pub fn new( pub fn new(
provider_factory: ProviderFactory<N>, provider_factory: ProviderFactory<N>,
consensus: Arc<dyn Consensus>, consensus: Arc<dyn FullConsensus>,
executor_factory: E, executor_factory: E,
) -> Self { ) -> Self {
Self { provider_factory, consensus, executor_factory } Self { provider_factory, consensus, executor_factory }

View File

@ -13,7 +13,7 @@ use reth_blockchain_tree::{
}; };
use reth_chainspec::ChainSpec; use reth_chainspec::ChainSpec;
use reth_config::config::StageConfig; 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_db::{test_utils::TempDatabase, DatabaseEnv as DE};
use reth_downloaders::{ use reth_downloaders::{
bodies::bodies::BodiesDownloaderBuilder, bodies::bodies::BodiesDownloaderBuilder,
@ -332,7 +332,7 @@ where
let provider_factory = let provider_factory =
create_test_provider_factory_with_chain_spec(self.base_config.chain_spec.clone()); create_test_provider_factory_with_chain_spec(self.base_config.chain_spec.clone());
let consensus: Arc<dyn Consensus> = match self.base_config.consensus { let consensus: Arc<dyn FullConsensus> = match self.base_config.consensus {
TestConsensusConfig::Real => { TestConsensusConfig::Real => {
Arc::new(EthBeaconConsensus::new(Arc::clone(&self.base_config.chain_spec))) Arc::new(EthBeaconConsensus::new(Arc::clone(&self.base_config.chain_spec)))
} }
@ -374,13 +374,17 @@ where
.into_task(); .into_task();
let body_downloader = BodiesDownloaderBuilder::default() 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(); .into_task();
Pipeline::<MockNodeTypesWithDB>::builder().add_stages(DefaultStages::new( Pipeline::<MockNodeTypesWithDB>::builder().add_stages(DefaultStages::new(
provider_factory.clone(), provider_factory.clone(),
tip_rx.clone(), tip_rx.clone(),
Arc::clone(&consensus), consensus.clone().as_consensus(),
header_downloader, header_downloader,
body_downloader, body_downloader,
executor_factory.clone(), executor_factory.clone(),

View File

@ -16,8 +16,8 @@ use alloy_consensus::Header;
use alloy_eips::eip7685::Requests; use alloy_eips::eip7685::Requests;
use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256}; use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256};
use reth_primitives::{ use reth_primitives::{
BlockBody, BlockWithSenders, GotExpected, GotExpectedBoxed, InvalidTransactionError, Receipt, BlockBody, BlockWithSenders, EthPrimitives, GotExpected, GotExpectedBoxed,
SealedBlock, SealedHeader, InvalidTransactionError, NodePrimitives, Receipt, SealedBlock, SealedHeader,
}; };
use reth_primitives_traits::constants::MINIMUM_GAS_LIMIT; use reth_primitives_traits::constants::MINIMUM_GAS_LIMIT;
@ -28,7 +28,7 @@ pub mod noop;
/// test helpers for mocking consensus /// test helpers for mocking consensus
pub mod test_utils; 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)] #[derive(Debug)]
pub struct PostExecutionInput<'a, R = Receipt> { pub struct PostExecutionInput<'a, R = Receipt> {
/// Receipts of the block. /// Receipts of the block.
@ -44,11 +44,28 @@ impl<'a, R> PostExecutionInput<'a, R> {
} }
} }
/// [`Consensus`] implementation which knows full node primitives and is able to validation block's
/// execution outcome.
#[auto_impl::auto_impl(&, Arc)]
pub trait FullConsensus<N: NodePrimitives = EthPrimitives>:
AsConsensus<N::BlockHeader, N::BlockBody>
{
/// 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<N::Block>,
input: PostExecutionInput<'_, N::Receipt>,
) -> Result<(), ConsensusError>;
}
/// Consensus is a protocol that chooses canonical chain. /// Consensus is a protocol that chooses canonical chain.
#[auto_impl::auto_impl(&, Arc)] #[auto_impl::auto_impl(&, Arc)]
pub trait Consensus<H = Header, B = BlockBody>: pub trait Consensus<H = Header, B = BlockBody>: AsHeaderValidator<H> {
AsHeaderValidator<H> + HeaderValidator<H> + Debug + Send + Sync
{
/// Ensures that body field values match the header. /// Ensures that body field values match the header.
fn validate_body_against_header( fn validate_body_against_header(
&self, &self,
@ -67,18 +84,6 @@ pub trait Consensus<H = Header, B = BlockBody>:
/// Note: validating blocks does not include other validations of the Consensus /// Note: validating blocks does not include other validations of the Consensus
fn validate_block_pre_execution(&self, block: &SealedBlock<H, B>) fn validate_block_pre_execution(&self, block: &SealedBlock<H, B>)
-> Result<(), ConsensusError>; -> 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. /// HeaderValidator is a protocol that validates headers and their relationships.
@ -162,6 +167,23 @@ impl<T: HeaderValidator<H>, H> AsHeaderValidator<H> for T {
} }
} }
/// Helper trait to cast `Arc<dyn FullConsensus>` to `Arc<dyn Consensus>`
pub trait AsConsensus<H, B>: Consensus<H, B> {
/// Converts the [`Arc`] of self to [`Arc`] of [`HeaderValidator`]
fn as_consensus<'a>(self: Arc<Self>) -> Arc<dyn Consensus<H, B> + 'a>
where
Self: 'a;
}
impl<T: Consensus<H, B>, H, B> AsConsensus<H, B> for T {
fn as_consensus<'a>(self: Arc<Self>) -> Arc<dyn Consensus<H, B> + 'a>
where
Self: 'a,
{
self
}
}
/// Consensus Errors /// Consensus Errors
#[derive(Debug, PartialEq, Eq, Clone, derive_more::Display, derive_more::Error)] #[derive(Debug, PartialEq, Eq, Clone, derive_more::Display, derive_more::Error)]
pub enum ConsensusError { pub enum ConsensusError {

View File

@ -1,6 +1,6 @@
use crate::{Consensus, ConsensusError, HeaderValidator, PostExecutionInput}; use crate::{Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput};
use alloy_primitives::U256; use alloy_primitives::U256;
use reth_primitives::{BlockWithSenders, SealedBlock, SealedHeader}; use reth_primitives::{BlockWithSenders, NodePrimitives, SealedBlock, SealedHeader};
/// A Consensus implementation that does nothing. /// A Consensus implementation that does nothing.
#[derive(Debug, Copy, Clone, Default)] #[derive(Debug, Copy, Clone, Default)]
@ -44,11 +44,13 @@ impl<H, B> Consensus<H, B> for NoopConsensus {
) -> Result<(), ConsensusError> { ) -> Result<(), ConsensusError> {
Ok(()) Ok(())
} }
}
impl<N: NodePrimitives> FullConsensus<N> for NoopConsensus {
fn validate_block_post_execution( fn validate_block_post_execution(
&self, &self,
_block: &BlockWithSenders, _block: &BlockWithSenders<N::Block>,
_input: PostExecutionInput<'_>, _input: PostExecutionInput<'_, N::Receipt>,
) -> Result<(), ConsensusError> { ) -> Result<(), ConsensusError> {
Ok(()) Ok(())
} }

View File

@ -1,7 +1,7 @@
use crate::{Consensus, ConsensusError, HeaderValidator, PostExecutionInput}; use crate::{Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput};
use alloy_primitives::U256; use alloy_primitives::U256;
use core::sync::atomic::{AtomicBool, Ordering}; use core::sync::atomic::{AtomicBool, Ordering};
use reth_primitives::{BlockWithSenders, SealedBlock, SealedHeader}; use reth_primitives::{BlockWithSenders, NodePrimitives, SealedBlock, SealedHeader};
/// Consensus engine implementation for testing /// Consensus engine implementation for testing
#[derive(Debug)] #[derive(Debug)]
@ -46,6 +46,20 @@ impl TestConsensus {
} }
} }
impl<N: NodePrimitives> FullConsensus<N> for TestConsensus {
fn validate_block_post_execution(
&self,
_block: &BlockWithSenders<N::Block>,
_input: PostExecutionInput<'_, N::Receipt>,
) -> Result<(), ConsensusError> {
if self.fail_validation() {
Err(ConsensusError::BaseFeeMissing)
} else {
Ok(())
}
}
}
impl<H, B> Consensus<H, B> for TestConsensus { impl<H, B> Consensus<H, B> for TestConsensus {
fn validate_body_against_header( fn validate_body_against_header(
&self, &self,
@ -69,18 +83,6 @@ impl<H, B> Consensus<H, B> for TestConsensus {
Ok(()) Ok(())
} }
} }
fn validate_block_post_execution(
&self,
_block: &BlockWithSenders,
_input: PostExecutionInput<'_>,
) -> Result<(), ConsensusError> {
if self.fail_validation() {
Err(ConsensusError::BaseFeeMissing)
} else {
Ok(())
}
}
} }
impl<H> HeaderValidator<H> for TestConsensus { impl<H> HeaderValidator<H> for TestConsensus {

View File

@ -18,7 +18,7 @@ use crate::miner::{LocalMiner, MiningMode};
use futures_util::{Stream, StreamExt}; use futures_util::{Stream, StreamExt};
use reth_beacon_consensus::{BeaconConsensusEngineEvent, EngineNodeTypes}; use reth_beacon_consensus::{BeaconConsensusEngineEvent, EngineNodeTypes};
use reth_chainspec::EthChainSpec; use reth_chainspec::EthChainSpec;
use reth_consensus::Consensus; use reth_consensus::FullConsensus;
use reth_engine_primitives::{BeaconEngineMessage, EngineValidator}; use reth_engine_primitives::{BeaconEngineMessage, EngineValidator};
use reth_engine_service::service::EngineMessageStream; use reth_engine_service::service::EngineMessageStream;
use reth_engine_tree::{ use reth_engine_tree::{
@ -64,7 +64,7 @@ where
/// Constructor for [`LocalEngineService`]. /// Constructor for [`LocalEngineService`].
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new<B, V>( pub fn new<B, V>(
consensus: Arc<dyn Consensus>, consensus: Arc<dyn FullConsensus>,
executor_factory: impl BlockExecutorProvider<Primitives = N::Primitives>, executor_factory: impl BlockExecutorProvider<Primitives = N::Primitives>,
provider: ProviderFactory<N>, provider: ProviderFactory<N>,
blockchain_db: BlockchainProvider2<N>, blockchain_db: BlockchainProvider2<N>,

View File

@ -2,7 +2,7 @@ use futures::{Stream, StreamExt};
use pin_project::pin_project; use pin_project::pin_project;
use reth_beacon_consensus::{BeaconConsensusEngineEvent, EngineNodeTypes}; use reth_beacon_consensus::{BeaconConsensusEngineEvent, EngineNodeTypes};
use reth_chainspec::EthChainSpec; use reth_chainspec::EthChainSpec;
use reth_consensus::Consensus; use reth_consensus::FullConsensus;
use reth_engine_primitives::{BeaconEngineMessage, EngineValidator}; use reth_engine_primitives::{BeaconEngineMessage, EngineValidator};
use reth_engine_tree::{ use reth_engine_tree::{
backfill::PipelineSync, backfill::PipelineSync,
@ -65,7 +65,7 @@ where
/// Constructor for `EngineService`. /// Constructor for `EngineService`.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new<V>( pub fn new<V>(
consensus: Arc<dyn Consensus>, consensus: Arc<dyn FullConsensus>,
executor_factory: E, executor_factory: E,
chain_spec: Arc<N::ChainSpec>, chain_spec: Arc<N::ChainSpec>,
client: Client, client: Client,
@ -87,7 +87,7 @@ where
let engine_kind = let engine_kind =
if chain_spec.is_optimism() { EngineApiKind::OpStack } else { EngineApiKind::Ethereum }; 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 = let persistence_handle =
PersistenceHandle::spawn_service(provider, pruner, sync_metrics_tx); PersistenceHandle::spawn_service(provider, pruner, sync_metrics_tx);

View File

@ -25,7 +25,7 @@ use reth_blockchain_tree::{
use reth_chain_state::{ use reth_chain_state::{
CanonicalInMemoryState, ExecutedBlock, MemoryOverlayStateProvider, NewCanonicalChain, CanonicalInMemoryState, ExecutedBlock, MemoryOverlayStateProvider, NewCanonicalChain,
}; };
use reth_consensus::{Consensus, PostExecutionInput}; use reth_consensus::{Consensus, FullConsensus, PostExecutionInput};
use reth_engine_primitives::{ use reth_engine_primitives::{
BeaconEngineMessage, BeaconOnNewPayloadError, EngineApiMessageVersion, EngineTypes, BeaconEngineMessage, BeaconOnNewPayloadError, EngineApiMessageVersion, EngineTypes,
EngineValidator, ForkchoiceStateTracker, OnForkChoiceUpdated, EngineValidator, ForkchoiceStateTracker, OnForkChoiceUpdated,
@ -473,7 +473,7 @@ where
{ {
provider: P, provider: P,
executor_provider: E, executor_provider: E,
consensus: Arc<dyn Consensus>, consensus: Arc<dyn FullConsensus>,
payload_validator: V, payload_validator: V,
/// Keeps track of internals such as executed and buffered blocks. /// Keeps track of internals such as executed and buffered blocks.
state: EngineApiTreeState, state: EngineApiTreeState,
@ -557,7 +557,7 @@ where
pub fn new( pub fn new(
provider: P, provider: P,
executor_provider: E, executor_provider: E,
consensus: Arc<dyn Consensus>, consensus: Arc<dyn FullConsensus>,
payload_validator: V, payload_validator: V,
outgoing: UnboundedSender<EngineApiEvent>, outgoing: UnboundedSender<EngineApiEvent>,
state: EngineApiTreeState, state: EngineApiTreeState,
@ -606,7 +606,7 @@ where
pub fn spawn_new( pub fn spawn_new(
provider: P, provider: P,
executor_provider: E, executor_provider: E,
consensus: Arc<dyn Consensus>, consensus: Arc<dyn FullConsensus>,
payload_validator: V, payload_validator: V,
persistence: PersistenceHandle, persistence: PersistenceHandle,
payload_builder: PayloadBuilderHandle<T>, payload_builder: PayloadBuilderHandle<T>,

View File

@ -11,14 +11,18 @@
use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH};
use alloy_primitives::U256; use alloy_primitives::U256;
use reth_chainspec::{EthChainSpec, EthereumHardfork, EthereumHardforks}; 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::{ use reth_consensus_common::validation::{
validate_4844_header_standalone, validate_against_parent_4844, validate_4844_header_standalone, validate_against_parent_4844,
validate_against_parent_eip1559_base_fee, validate_against_parent_hash_number, validate_against_parent_eip1559_base_fee, validate_against_parent_hash_number,
validate_against_parent_timestamp, validate_block_pre_execution, validate_body_against_header, validate_against_parent_timestamp, validate_block_pre_execution, validate_body_against_header,
validate_header_base_fee, validate_header_extradata, validate_header_gas, 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 reth_primitives_traits::constants::MINIMUM_GAS_LIMIT;
use std::{fmt::Debug, sync::Arc, time::SystemTime}; use std::{fmt::Debug, sync::Arc, time::SystemTime};
@ -90,6 +94,25 @@ impl<ChainSpec: EthChainSpec + EthereumHardforks> EthBeaconConsensus<ChainSpec>
} }
} }
impl<ChainSpec, N> FullConsensus<N> for EthBeaconConsensus<ChainSpec>
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<ChainSpec: Send + Sync + EthChainSpec + EthereumHardforks + Debug> Consensus impl<ChainSpec: Send + Sync + EthChainSpec + EthereumHardforks + Debug> Consensus
for EthBeaconConsensus<ChainSpec> for EthBeaconConsensus<ChainSpec>
{ {
@ -104,14 +127,6 @@ impl<ChainSpec: Send + Sync + EthChainSpec + EthereumHardforks + Debug> Consensu
fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> { fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> {
validate_block_pre_execution(block, &self.chain_spec) 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<ChainSpec: Send + Sync + EthChainSpec + EthereumHardforks + Debug> HeaderValidator impl<ChainSpec: Send + Sync + EthChainSpec + EthereumHardforks + Debug> HeaderValidator

View File

@ -327,9 +327,9 @@ pub struct EthereumConsensusBuilder {
impl<Node> ConsensusBuilder<Node> for EthereumConsensusBuilder impl<Node> ConsensusBuilder<Node> for EthereumConsensusBuilder
where where
Node: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec>>, Node: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec, Primitives = EthPrimitives>>,
{ {
type Consensus = Arc<dyn reth_consensus::Consensus>; type Consensus = Arc<dyn reth_consensus::FullConsensus>;
async fn build_consensus(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Consensus> { async fn build_consensus(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Consensus> {
Ok(Arc::new(EthBeaconConsensus::new(ctx.chain_spec()))) Ok(Arc::new(EthBeaconConsensus::new(ctx.chain_spec())))

View File

@ -4,7 +4,7 @@ use crate::ConfigureEvm;
use alloy_consensus::Header; use alloy_consensus::Header;
use alloy_rpc_types_engine::JwtSecret; use alloy_rpc_types_engine::JwtSecret;
use reth_beacon_consensus::BeaconConsensusEngineHandle; use reth_beacon_consensus::BeaconConsensusEngineHandle;
use reth_consensus::Consensus; use reth_consensus::FullConsensus;
use reth_evm::execute::BlockExecutorProvider; use reth_evm::execute::BlockExecutorProvider;
use reth_network_api::FullNetwork; use reth_network_api::FullNetwork;
use reth_node_core::node_config::NodeConfig; use reth_node_core::node_config::NodeConfig;
@ -56,7 +56,7 @@ pub trait FullNodeComponents: FullNodeTypes + Clone + 'static {
type Executor: BlockExecutorProvider<Primitives = <Self::Types as NodeTypes>::Primitives>; type Executor: BlockExecutorProvider<Primitives = <Self::Types as NodeTypes>::Primitives>;
/// The consensus type of the node. /// The consensus type of the node.
type Consensus: Consensus + Clone + Unpin + 'static; type Consensus: FullConsensus<<Self::Types as NodeTypes>::Primitives> + Clone + Unpin + 'static;
/// Network API. /// Network API.
type Network: FullNetwork; type Network: FullNetwork;

View File

@ -8,7 +8,7 @@ use crate::{
BuilderContext, ConfigureEvm, FullNodeTypes, BuilderContext, ConfigureEvm, FullNodeTypes,
}; };
use alloy_consensus::Header; use alloy_consensus::Header;
use reth_consensus::Consensus; use reth_consensus::FullConsensus;
use reth_evm::execute::BlockExecutorProvider; use reth_evm::execute::BlockExecutorProvider;
use reth_node_api::{NodeTypes, NodeTypesWithEngine}; use reth_node_api::{NodeTypes, NodeTypesWithEngine};
use reth_payload_builder::PayloadBuilderHandle; use reth_payload_builder::PayloadBuilderHandle;
@ -378,7 +378,7 @@ where
Pool: TransactionPool + Unpin + 'static, Pool: TransactionPool + Unpin + 'static,
EVM: ConfigureEvm<Header = Header>, EVM: ConfigureEvm<Header = Header>,
Executor: BlockExecutorProvider<Primitives = <Node::Types as NodeTypes>::Primitives>, Executor: BlockExecutorProvider<Primitives = <Node::Types as NodeTypes>::Primitives>,
Cons: Consensus + Clone + Unpin + 'static, Cons: FullConsensus<<Node::Types as NodeTypes>::Primitives> + Clone + Unpin + 'static,
{ {
type Components = Components<Node, Pool, EVM, Executor, Cons>; type Components = Components<Node, Pool, EVM, Executor, Cons>;

View File

@ -1,11 +1,16 @@
//! Consensus component for the node builder. //! Consensus component for the node builder.
use reth_node_api::NodeTypes;
use crate::{BuilderContext, FullNodeTypes}; use crate::{BuilderContext, FullNodeTypes};
use std::future::Future; use std::future::Future;
/// A type that knows how to build the consensus implementation. /// A type that knows how to build the consensus implementation.
pub trait ConsensusBuilder<Node: FullNodeTypes>: Send { pub trait ConsensusBuilder<Node: FullNodeTypes>: Send {
/// The consensus implementation to build. /// The consensus implementation to build.
type Consensus: reth_consensus::Consensus + Clone + Unpin + 'static; type Consensus: reth_consensus::FullConsensus<<Node::Types as NodeTypes>::Primitives>
+ Clone
+ Unpin
+ 'static;
/// Creates the consensus implementation. /// Creates the consensus implementation.
fn build_consensus( fn build_consensus(
@ -17,7 +22,10 @@ pub trait ConsensusBuilder<Node: FullNodeTypes>: Send {
impl<Node, F, Fut, Consensus> ConsensusBuilder<Node> for F impl<Node, F, Fut, Consensus> ConsensusBuilder<Node> for F
where where
Node: FullNodeTypes, Node: FullNodeTypes,
Consensus: reth_consensus::Consensus + Clone + Unpin + 'static, Consensus: reth_consensus::FullConsensus<<Node::Types as NodeTypes>::Primitives>
+ Clone
+ Unpin
+ 'static,
F: FnOnce(&BuilderContext<Node>) -> Fut + Send, F: FnOnce(&BuilderContext<Node>) -> Fut + Send,
Fut: Future<Output = eyre::Result<Consensus>> + Send, Fut: Future<Output = eyre::Result<Consensus>> + Send,
{ {

View File

@ -23,7 +23,7 @@ pub use pool::*;
use crate::{ConfigureEvm, FullNodeTypes}; use crate::{ConfigureEvm, FullNodeTypes};
use alloy_consensus::Header; use alloy_consensus::Header;
use reth_consensus::Consensus; use reth_consensus::FullConsensus;
use reth_evm::execute::BlockExecutorProvider; use reth_evm::execute::BlockExecutorProvider;
use reth_network::NetworkHandle; use reth_network::NetworkHandle;
use reth_network_api::FullNetwork; use reth_network_api::FullNetwork;
@ -47,7 +47,7 @@ pub trait NodeComponents<T: FullNodeTypes>: Clone + Unpin + Send + Sync + 'stati
type Executor: BlockExecutorProvider<Primitives = <T::Types as NodeTypes>::Primitives>; type Executor: BlockExecutorProvider<Primitives = <T::Types as NodeTypes>::Primitives>;
/// The consensus type of the node. /// The consensus type of the node.
type Consensus: Consensus + Clone + Unpin + 'static; type Consensus: FullConsensus<<T::Types as NodeTypes>::Primitives> + Clone + Unpin + 'static;
/// Network API. /// Network API.
type Network: FullNetwork; type Network: FullNetwork;
@ -100,7 +100,7 @@ where
Pool: TransactionPool + Unpin + 'static, Pool: TransactionPool + Unpin + 'static,
EVM: ConfigureEvm<Header = Header>, EVM: ConfigureEvm<Header = Header>,
Executor: BlockExecutorProvider<Primitives = <Node::Types as NodeTypes>::Primitives>, Executor: BlockExecutorProvider<Primitives = <Node::Types as NodeTypes>::Primitives>,
Cons: Consensus + Clone + Unpin + 'static, Cons: FullConsensus<<Node::Types as NodeTypes>::Primitives> + Clone + Unpin + 'static,
{ {
type Pool = Pool; type Pool = Pool;
type Evm = EVM; type Evm = EVM;
@ -140,7 +140,7 @@ where
Pool: TransactionPool, Pool: TransactionPool,
EVM: ConfigureEvm<Header = Header>, EVM: ConfigureEvm<Header = Header>,
Executor: BlockExecutorProvider, Executor: BlockExecutorProvider,
Cons: Consensus + Clone, Cons: Clone,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {

View File

@ -13,7 +13,6 @@ use rayon::ThreadPoolBuilder;
use reth_beacon_consensus::EthBeaconConsensus; use reth_beacon_consensus::EthBeaconConsensus;
use reth_chainspec::{Chain, EthChainSpec, EthereumHardforks}; use reth_chainspec::{Chain, EthChainSpec, EthereumHardforks};
use reth_config::{config::EtlConfig, PruneConfig}; use reth_config::{config::EtlConfig, PruneConfig};
use reth_consensus::Consensus;
use reth_db_api::{database::Database, database_metrics::DatabaseMetrics}; use reth_db_api::{database::Database, database_metrics::DatabaseMetrics};
use reth_db_common::init::{init_genesis, InitDatabaseError}; use reth_db_common::init::{init_genesis, InitDatabaseError};
use reth_downloaders::{bodies::noop::NoopBodiesDownloader, headers::noop::NoopHeaderDownloader}; use reth_downloaders::{bodies::noop::NoopBodiesDownloader, headers::noop::NoopHeaderDownloader};
@ -681,7 +680,6 @@ where
let components = components_builder.build_components(&builder_ctx).await?; let components = components_builder.build_components(&builder_ctx).await?;
let blockchain_db = self.blockchain_db().clone(); let blockchain_db = self.blockchain_db().clone();
let consensus = Arc::new(components.consensus().clone());
let node_adapter = NodeAdapter { let node_adapter = NodeAdapter {
components, components,
@ -699,7 +697,6 @@ where
}, },
node_adapter, node_adapter,
head, head,
consensus,
}; };
let ctx = LaunchContextWith { let ctx = LaunchContextWith {
@ -855,11 +852,6 @@ where
Ok(None) Ok(None)
} }
/// Returns the configured `Consensus`.
pub fn consensus(&self) -> Arc<dyn Consensus> {
self.right().consensus.clone()
}
/// Returns the metrics sender. /// Returns the metrics sender.
pub fn sync_metrics_tx(&self) -> UnboundedSender<MetricEvent> { pub fn sync_metrics_tx(&self) -> UnboundedSender<MetricEvent> {
self.right().db_provider_container.metrics_sender.clone() self.right().db_provider_container.metrics_sender.clone()
@ -1029,7 +1021,6 @@ where
db_provider_container: WithMeteredProvider<T::Types>, db_provider_container: WithMeteredProvider<T::Types>,
node_adapter: NodeAdapter<T, CB::Components>, node_adapter: NodeAdapter<T, CB::Components>,
head: Head, head: Head,
consensus: Arc<dyn Consensus>,
} }
#[cfg(test)] #[cfg(test)]

View File

@ -175,13 +175,15 @@ where
)); ));
info!(target: "reth::cli", "StaticFileProducer initialized"); info!(target: "reth::cli", "StaticFileProducer initialized");
let consensus = Arc::new(ctx.components().consensus().clone());
// Configure the pipeline // Configure the pipeline
let pipeline_exex_handle = let pipeline_exex_handle =
exex_manager_handle.clone().unwrap_or_else(ExExManagerHandle::empty); exex_manager_handle.clone().unwrap_or_else(ExExManagerHandle::empty);
let pipeline = build_networked_pipeline( let pipeline = build_networked_pipeline(
&ctx.toml_config().stages, &ctx.toml_config().stages,
network_client.clone(), network_client.clone(),
ctx.consensus(), consensus.clone(),
ctx.provider_factory().clone(), ctx.provider_factory().clone(),
ctx.task_executor(), ctx.task_executor(),
ctx.sync_metrics_tx(), ctx.sync_metrics_tx(),
@ -223,7 +225,7 @@ where
let mut engine_service = if ctx.is_dev() { let mut engine_service = if ctx.is_dev() {
let eth_service = LocalEngineService::new( let eth_service = LocalEngineService::new(
ctx.consensus(), consensus.clone(),
ctx.components().block_executor().clone(), ctx.components().block_executor().clone(),
ctx.provider_factory().clone(), ctx.provider_factory().clone(),
ctx.blockchain_db().clone(), ctx.blockchain_db().clone(),
@ -242,7 +244,7 @@ where
Either::Left(eth_service) Either::Left(eth_service)
} else { } else {
let eth_service = EngineService::new( let eth_service = EngineService::new(
ctx.consensus(), consensus.clone(),
ctx.components().block_executor().clone(), ctx.components().block_executor().clone(),
ctx.chain_spec(), ctx.chain_spec(),
network_client.clone(), network_client.clone(),

View File

@ -236,7 +236,7 @@ where
let pipeline = crate::setup::build_networked_pipeline( let pipeline = crate::setup::build_networked_pipeline(
&ctx.toml_config().stages, &ctx.toml_config().stages,
network_client.clone(), network_client.clone(),
ctx.consensus(), consensus.clone(),
ctx.provider_factory().clone(), ctx.provider_factory().clone(),
ctx.task_executor(), ctx.task_executor(),
ctx.sync_metrics_tx(), ctx.sync_metrics_tx(),

View File

@ -22,6 +22,7 @@ reth-trie-common.workspace = true
# op-reth # op-reth
reth-optimism-forks.workspace = true reth-optimism-forks.workspace = true
reth-optimism-chainspec.workspace = true reth-optimism-chainspec.workspace = true
reth-optimism-primitives.workspace = true
# ethereum # ethereum
alloy-primitives.workspace = true alloy-primitives.workspace = true

View File

@ -12,7 +12,9 @@
use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH}; use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH};
use alloy_primitives::{B64, U256}; use alloy_primitives::{B64, U256};
use reth_chainspec::EthereumHardforks; use reth_chainspec::EthereumHardforks;
use reth_consensus::{Consensus, ConsensusError, HeaderValidator, PostExecutionInput}; use reth_consensus::{
Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput,
};
use reth_consensus_common::validation::{ use reth_consensus_common::validation::{
validate_against_parent_4844, validate_against_parent_eip1559_base_fee, validate_against_parent_4844, validate_against_parent_eip1559_base_fee,
validate_against_parent_hash_number, validate_against_parent_timestamp, 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_chainspec::OpChainSpec;
use reth_optimism_forks::OpHardforks; use reth_optimism_forks::OpHardforks;
use reth_optimism_primitives::OpPrimitives;
use reth_primitives::{BlockBody, BlockWithSenders, GotExpected, SealedBlock, SealedHeader}; use reth_primitives::{BlockBody, BlockWithSenders, GotExpected, SealedBlock, SealedHeader};
use std::{sync::Arc, time::SystemTime}; use std::{sync::Arc, time::SystemTime};
@ -46,6 +49,16 @@ impl OpBeaconConsensus {
} }
} }
impl FullConsensus<OpPrimitives> 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 { impl Consensus for OpBeaconConsensus {
fn validate_body_against_header( fn validate_body_against_header(
&self, &self,
@ -80,14 +93,6 @@ impl Consensus for OpBeaconConsensus {
Ok(()) 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 { impl HeaderValidator for OpBeaconConsensus {

View File

@ -569,9 +569,9 @@ pub struct OpConsensusBuilder;
impl<Node> ConsensusBuilder<Node> for OpConsensusBuilder impl<Node> ConsensusBuilder<Node> for OpConsensusBuilder
where where
Node: FullNodeTypes<Types: NodeTypes<ChainSpec = OpChainSpec>>, Node: FullNodeTypes<Types: NodeTypes<ChainSpec = OpChainSpec, Primitives = OpPrimitives>>,
{ {
type Consensus = Arc<dyn reth_consensus::Consensus>; type Consensus = Arc<OpBeaconConsensus>;
async fn build_consensus(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Consensus> { async fn build_consensus(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Consensus> {
Ok(Arc::new(OpBeaconConsensus::new(ctx.chain_spec()))) Ok(Arc::new(OpBeaconConsensus::new(ctx.chain_spec())))

View File

@ -49,7 +49,7 @@
//! CanonStateSubscriptions<Primitives = reth_primitives::EthPrimitives> + Clone + 'static, //! CanonStateSubscriptions<Primitives = reth_primitives::EthPrimitives> + Clone + 'static,
//! EvmConfig: ConfigureEvm<Header = Header>, //! EvmConfig: ConfigureEvm<Header = Header>,
//! BlockExecutor: BlockExecutorProvider<Primitives = Events::Primitives>, //! BlockExecutor: BlockExecutorProvider<Primitives = Events::Primitives>,
//! Consensus: reth_consensus::Consensus + Clone + 'static, //! Consensus: reth_consensus::FullConsensus + Clone + 'static,
//! { //! {
//! // configure the rpc module per transport //! // configure the rpc module per transport
//! let transports = TransportRpcModuleConfig::default().with_http(vec![ //! let transports = TransportRpcModuleConfig::default().with_http(vec![
@ -131,7 +131,7 @@
//! EngineT: EngineTypes, //! EngineT: EngineTypes,
//! EvmConfig: ConfigureEvm<Header = Header>, //! EvmConfig: ConfigureEvm<Header = Header>,
//! BlockExecutor: BlockExecutorProvider<Primitives = Events::Primitives>, //! BlockExecutor: BlockExecutorProvider<Primitives = Events::Primitives>,
//! Consensus: reth_consensus::Consensus + Clone + 'static, //! Consensus: reth_consensus::FullConsensus + Clone + 'static,
//! { //! {
//! // configure the rpc module per transport //! // configure the rpc module per transport
//! let transports = TransportRpcModuleConfig::default().with_http(vec![ //! let transports = TransportRpcModuleConfig::default().with_http(vec![
@ -194,7 +194,7 @@ use jsonrpsee::{
Methods, RpcModule, Methods, RpcModule,
}; };
use reth_chainspec::EthereumHardforks; use reth_chainspec::EthereumHardforks;
use reth_consensus::Consensus; use reth_consensus::FullConsensus;
use reth_engine_primitives::EngineTypes; use reth_engine_primitives::EngineTypes;
use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm};
use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers}; use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers};
@ -266,7 +266,7 @@ pub async fn launch<Provider, Pool, Network, Tasks, Events, EvmConfig, EthApi, B
evm_config: EvmConfig, evm_config: EvmConfig,
eth: DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, EthApi>, eth: DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, EthApi>,
block_executor: BlockExecutor, block_executor: BlockExecutor,
consensus: Arc<dyn Consensus>, consensus: Arc<dyn FullConsensus>,
) -> Result<RpcServerHandle, RpcError> ) -> Result<RpcServerHandle, RpcError>
where where
Provider: FullRpcProvider<Block = reth_primitives::Block, Receipt = reth_primitives::Receipt> Provider: FullRpcProvider<Block = reth_primitives::Block, Receipt = reth_primitives::Receipt>
@ -641,7 +641,7 @@ where
Receipt = reth_primitives::Receipt, 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 /// Configures all [`RpcModule`]s specific to the given [`TransportRpcModuleConfig`] which can
/// be used to start the transport server(s). /// be used to start the transport server(s).
@ -1293,7 +1293,7 @@ where
/// Instantiates `ValidationApi` /// Instantiates `ValidationApi`
pub fn validation_api(&self) -> ValidationApi<Provider, BlockExecutor> pub fn validation_api(&self) -> ValidationApi<Provider, BlockExecutor>
where where
Consensus: reth_consensus::Consensus + Clone + 'static, Consensus: reth_consensus::FullConsensus + Clone + 'static,
{ {
ValidationApi::new( ValidationApi::new(
self.provider.clone(), self.provider.clone(),
@ -1324,7 +1324,7 @@ where
Receipt = reth_primitives::Receipt, Receipt = reth_primitives::Receipt,
>, >,
>, >,
Consensus: reth_consensus::Consensus + Clone + 'static, Consensus: reth_consensus::FullConsensus + Clone + 'static,
{ {
/// Configures the auth module that includes the /// Configures the auth module that includes the
/// * `engine_` namespace /// * `engine_` namespace

View File

@ -10,7 +10,7 @@ use alloy_rpc_types_engine::{
use async_trait::async_trait; use async_trait::async_trait;
use jsonrpsee::core::RpcResult; use jsonrpsee::core::RpcResult;
use reth_chainspec::{ChainSpecProvider, EthereumHardforks}; use reth_chainspec::{ChainSpecProvider, EthereumHardforks};
use reth_consensus::{Consensus, PostExecutionInput}; use reth_consensus::{Consensus, FullConsensus, PostExecutionInput};
use reth_errors::{BlockExecutionError, ConsensusError, ProviderError}; use reth_errors::{BlockExecutionError, ConsensusError, ProviderError};
use reth_ethereum_consensus::GAS_LIMIT_BOUND_DIVISOR; use reth_ethereum_consensus::GAS_LIMIT_BOUND_DIVISOR;
use reth_evm::execute::{BlockExecutorProvider, Executor}; use reth_evm::execute::{BlockExecutorProvider, Executor};
@ -44,7 +44,7 @@ where
/// Create a new instance of the [`ValidationApi`] /// Create a new instance of the [`ValidationApi`]
pub fn new( pub fn new(
provider: Provider, provider: Provider,
consensus: Arc<dyn Consensus>, consensus: Arc<dyn FullConsensus>,
executor_provider: E, executor_provider: E,
config: ValidationApiConfig, config: ValidationApiConfig,
task_spawner: Box<dyn TaskSpawner>, task_spawner: Box<dyn TaskSpawner>,
@ -475,7 +475,7 @@ pub struct ValidationApiInner<Provider: ChainSpecProvider, E> {
/// The provider that can interact with the chain. /// The provider that can interact with the chain.
provider: Provider, provider: Provider,
/// Consensus implementation. /// Consensus implementation.
consensus: Arc<dyn Consensus>, consensus: Arc<dyn FullConsensus>,
/// Execution payload validator. /// Execution payload validator.
payload_validator: ExecutionPayloadValidator<Provider::ChainSpec>, payload_validator: ExecutionPayloadValidator<Provider::ChainSpec>,
/// Block executor factory. /// Block executor factory.