From 1a6c25003c4b8d42cabed935f8283b212b4e4313 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Wed, 29 May 2024 11:16:25 -0700 Subject: [PATCH 1/5] fix: Node uses optimism beacon consensus for op chains --- Cargo.lock | 1 + bin/reth/Cargo.toml | 1 + crates/node/builder/Cargo.toml | 18 ++++++++++++++++-- crates/node/builder/src/launch/mod.rs | 6 ++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f9600585a2c8..40e4b0802be3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7332,6 +7332,7 @@ dependencies = [ "reth-node-api", "reth-node-core", "reth-node-events", + "reth-optimism-consensus", "reth-payload-builder", "reth-primitives", "reth-provider", diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index 38410737ecfb..1c3c959597f3 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -146,6 +146,7 @@ optimism = [ "reth-beacon-consensus/optimism", "reth-blockchain-tree/optimism", "dep:reth-node-optimism", + "reth-node-builder/optimism", "reth-node-core/optimism", ] diff --git a/crates/node/builder/Cargo.toml b/crates/node/builder/Cargo.toml index d2e7c8052796..4a782001dd96 100644 --- a/crates/node/builder/Cargo.toml +++ b/crates/node/builder/Cargo.toml @@ -54,16 +54,19 @@ tokio = { workspace = true, features = [ ] } tokio-stream.workspace = true -# ethereum +## ethereum discv5.workspace = true -# crypto +## crypto secp256k1 = { workspace = true, features = [ "global-context", "rand-std", "recovery", ] } +## optimism +reth-optimism-consensus = { workspace = true, features = ["optimism"] } + ## misc aquamarine.workspace = true eyre.workspace = true @@ -74,3 +77,14 @@ backon.workspace = true [dev-dependencies] tempfile.workspace = true + +[features] +optimism = [ + "reth-primitives/optimism", + "reth-rpc/optimism", + "reth-provider/optimism", + "reth-beacon-consensus/optimism", + "reth-blockchain-tree/optimism", + "reth-node-core/optimism", + "reth-optimism-consensus/optimism", +] diff --git a/crates/node/builder/src/launch/mod.rs b/crates/node/builder/src/launch/mod.rs index cd9971ad7806..67ba492d294e 100644 --- a/crates/node/builder/src/launch/mod.rs +++ b/crates/node/builder/src/launch/mod.rs @@ -29,6 +29,10 @@ use reth_node_core::{ version::{CARGO_PKG_VERSION, CLIENT_CODE, NAME_CLIENT, VERGEN_GIT_SHA}, }; use reth_node_events::{cl::ConsensusLayerHealthEvents, node}; + +#[cfg(feature = "optimism")] +use reth_optimism_consensus::OptimismBeaconConsensus; + use reth_primitives::format_ether; use reth_provider::providers::BlockchainProvider; use reth_rpc_engine_api::EngineApi; @@ -133,6 +137,8 @@ where // setup the consensus instance let consensus: Arc = if ctx.is_dev() { Arc::new(AutoSealConsensus::new(ctx.chain_spec())) + } else if cfg!(feature = "optimism") && ctx.chain_spec().is_optimism() { + Arc::new(OptimismBeaconConsensus::new(ctx.chain_spec())) } else { Arc::new(EthBeaconConsensus::new(ctx.chain_spec())) }; From 7eacdea412136830a82bc5a07a04078670ac3635 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Wed, 29 May 2024 12:34:57 -0700 Subject: [PATCH 2/5] Fix usage of optimism feature --- crates/node/builder/Cargo.toml | 8 +++++--- crates/node/builder/src/launch/mod.rs | 9 +++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/crates/node/builder/Cargo.toml b/crates/node/builder/Cargo.toml index 4a782001dd96..8273549ad8ea 100644 --- a/crates/node/builder/Cargo.toml +++ b/crates/node/builder/Cargo.toml @@ -64,8 +64,10 @@ secp256k1 = { workspace = true, features = [ "recovery", ] } -## optimism -reth-optimism-consensus = { workspace = true, features = ["optimism"] } +## Optimism +reth-optimism-consensus = { workspace = true, optional = true, features = [ + "optimism", +] } ## misc aquamarine.workspace = true @@ -86,5 +88,5 @@ optimism = [ "reth-beacon-consensus/optimism", "reth-blockchain-tree/optimism", "reth-node-core/optimism", - "reth-optimism-consensus/optimism", + "dep:reth-optimism-consensus", ] diff --git a/crates/node/builder/src/launch/mod.rs b/crates/node/builder/src/launch/mod.rs index 67ba492d294e..b4381eadc09e 100644 --- a/crates/node/builder/src/launch/mod.rs +++ b/crates/node/builder/src/launch/mod.rs @@ -137,9 +137,14 @@ where // setup the consensus instance let consensus: Arc = if ctx.is_dev() { Arc::new(AutoSealConsensus::new(ctx.chain_spec())) - } else if cfg!(feature = "optimism") && ctx.chain_spec().is_optimism() { - Arc::new(OptimismBeaconConsensus::new(ctx.chain_spec())) } else { + #[cfg(feature = "optimism")] + if ctx.chain_spec().is_optimism() { + Arc::new(OptimismBeaconConsensus::new(ctx.chain_spec())) + } else { + Arc::new(EthBeaconConsensus::new(ctx.chain_spec())) + } + #[cfg(not(feature = "optimism"))] Arc::new(EthBeaconConsensus::new(ctx.chain_spec())) }; From a2b2422ed15df84417f306b5f7689ed8a13a5c0c Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Mon, 10 Jun 2024 16:37:22 -0700 Subject: [PATCH 3/5] Add consensus as a node component --- Cargo.lock | 6 +- crates/ethereum/node/Cargo.toml | 4 +- crates/ethereum/node/src/node.rs | 30 ++++- crates/exex/test-utils/Cargo.toml | 1 + crates/exex/test-utils/src/lib.rs | 32 ++++- crates/node/builder/Cargo.toml | 6 - crates/node/builder/src/builder/mod.rs | 5 + crates/node/builder/src/components/builder.rs | 124 ++++++++++++++---- .../node/builder/src/components/consensus.rs | 32 +++++ crates/node/builder/src/components/mod.rs | 26 +++- crates/node/builder/src/launch/mod.rs | 26 +--- crates/optimism/node/Cargo.toml | 1 + crates/optimism/node/src/node.rs | 23 +++- examples/custom-engine-types/src/main.rs | 4 +- 14 files changed, 259 insertions(+), 61 deletions(-) create mode 100644 crates/node/builder/src/components/consensus.rs diff --git a/Cargo.lock b/Cargo.lock index 40e4b0802be3..dab0f5ae5f0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7033,6 +7033,7 @@ dependencies = [ "rand 0.8.5", "reth-blockchain-tree", "reth-config", + "reth-consensus", "reth-db", "reth-db-common", "reth-evm", @@ -7332,7 +7333,6 @@ dependencies = [ "reth-node-api", "reth-node-core", "reth-node-events", - "reth-optimism-consensus", "reth-payload-builder", "reth-primitives", "reth-provider", @@ -7421,7 +7421,10 @@ dependencies = [ "futures", "futures-util", "reth", + "reth-auto-seal-consensus", "reth-basic-payload-builder", + "reth-beacon-consensus", + "reth-consensus", "reth-db", "reth-e2e-test-utils", "reth-ethereum-engine-primitives", @@ -7484,6 +7487,7 @@ dependencies = [ "reth-network", "reth-node-api", "reth-node-builder", + "reth-optimism-consensus", "reth-optimism-payload-builder", "reth-payload-builder", "reth-primitives", diff --git a/crates/ethereum/node/Cargo.toml b/crates/ethereum/node/Cargo.toml index 072f91b28fd6..ee1df5565db5 100644 --- a/crates/ethereum/node/Cargo.toml +++ b/crates/ethereum/node/Cargo.toml @@ -22,6 +22,9 @@ reth-provider.workspace = true reth-transaction-pool.workspace = true reth-network.workspace = true reth-evm-ethereum.workspace = true +reth-consensus.workspace = true +reth-auto-seal-consensus.workspace = true +reth-beacon-consensus.workspace = true # misc eyre.workspace = true @@ -38,4 +41,3 @@ futures.workspace = true tokio.workspace = true futures-util.workspace = true serde_json.workspace = true - diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index 96698ccfccd4..55592762304a 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -1,12 +1,15 @@ //! Ethereum Node types config. use crate::{EthEngineTypes, EthEvmConfig}; +use reth_auto_seal_consensus::AutoSealConsensus; use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig}; +use reth_beacon_consensus::EthBeaconConsensus; use reth_evm_ethereum::execute::EthExecutorProvider; use reth_network::NetworkHandle; use reth_node_builder::{ components::{ - ComponentsBuilder, ExecutorBuilder, NetworkBuilder, PayloadServiceBuilder, PoolBuilder, + ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, + PayloadServiceBuilder, PoolBuilder, }, node::{FullNodeTypes, NodeTypes}, BuilderContext, Node, PayloadBuilderConfig, @@ -18,6 +21,7 @@ use reth_transaction_pool::{ blobstore::DiskFileBlobStore, EthTransactionPool, TransactionPool, TransactionValidationTaskExecutor, }; +use std::sync::Arc; /// Type configuration for a regular Ethereum node. #[derive(Debug, Default, Clone, Copy)] @@ -32,6 +36,7 @@ impl EthereumNode { EthereumPayloadBuilder, EthereumNetworkBuilder, EthereumExecutorBuilder, + EthereumConsensusBuilder, > where Node: FullNodeTypes, @@ -42,6 +47,7 @@ impl EthereumNode { .payload(EthereumPayloadBuilder::default()) .network(EthereumNetworkBuilder::default()) .executor(EthereumExecutorBuilder::default()) + .consensus(EthereumConsensusBuilder::default()) } } @@ -60,6 +66,7 @@ where EthereumPayloadBuilder, EthereumNetworkBuilder, EthereumExecutorBuilder, + EthereumConsensusBuilder, >; fn components_builder(self) -> Self::ComponentsBuilder { @@ -227,3 +234,24 @@ where Ok(handle) } } + +/// A basic ethereum consensus builder. +#[derive(Debug, Default, Clone, Copy)] +pub struct EthereumConsensusBuilder { + // TODO add closure to modify consensus +} + +impl ConsensusBuilder for EthereumConsensusBuilder +where + Node: FullNodeTypes, +{ + type Consensus = Arc; + + async fn build_consensus(self, ctx: &BuilderContext) -> eyre::Result { + if ctx.is_dev() { + Ok(Arc::new(AutoSealConsensus::new(ctx.chain_spec()))) + } else { + Ok(Arc::new(EthBeaconConsensus::new(ctx.chain_spec()))) + } + } +} diff --git a/crates/exex/test-utils/Cargo.toml b/crates/exex/test-utils/Cargo.toml index 42412db8d9b9..ab14c21fc70b 100644 --- a/crates/exex/test-utils/Cargo.toml +++ b/crates/exex/test-utils/Cargo.toml @@ -14,6 +14,7 @@ workspace = true ## reth reth-blockchain-tree.workspace = true reth-config.workspace = true +reth-consensus.workspace = true reth-db = { workspace = true, features = ["test-utils"] } reth-db-common.workspace = true reth-evm = { workspace = true, features = ["test-utils"] } diff --git a/crates/exex/test-utils/src/lib.rs b/crates/exex/test-utils/src/lib.rs index 2c7b57172825..76e153067088 100644 --- a/crates/exex/test-utils/src/lib.rs +++ b/crates/exex/test-utils/src/lib.rs @@ -10,6 +10,7 @@ use futures_util::FutureExt; use reth_blockchain_tree::noop::NoopBlockchainTree; +use reth_consensus::test_utils::TestConsensus; use reth_db::{test_utils::TempDatabase, DatabaseEnv}; use reth_db_common::init::init_genesis; use reth_evm::test_utils::MockExecutorProvider; @@ -18,7 +19,8 @@ use reth_network::{config::SecretKey, NetworkConfigBuilder, NetworkManager}; use reth_node_api::{FullNodeTypes, FullNodeTypesAdapter, NodeTypes}; use reth_node_builder::{ components::{ - Components, ComponentsBuilder, ExecutorBuilder, NodeComponentsBuilder, PoolBuilder, + Components, ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NodeComponentsBuilder, + PoolBuilder, }, BuilderContext, Node, NodeAdapter, RethFullAdapter, }; @@ -83,6 +85,22 @@ where } } +/// A test [`ConsensusBuilder`] that builds a [`TestConsensus`]. +#[derive(Debug, Default, Clone, Copy)] +#[non_exhaustive] +pub struct TestConsensusBuilder; + +impl ConsensusBuilder for TestConsensusBuilder +where + Node: FullNodeTypes, +{ + type Consensus = Arc; + + async fn build_consensus(self, _ctx: &BuilderContext) -> eyre::Result { + Ok(Arc::new(TestConsensus::default())) + } +} + /// A test [`Node`]. #[derive(Debug, Default, Clone, Copy)] #[non_exhaustive] @@ -103,6 +121,7 @@ where EthereumPayloadBuilder, EthereumNetworkBuilder, TestExecutorBuilder, + TestConsensusBuilder, >; fn components_builder(self) -> Self::ComponentsBuilder { @@ -112,6 +131,7 @@ where .payload(EthereumPayloadBuilder::default()) .network(EthereumNetworkBuilder::default()) .executor(TestExecutorBuilder::default()) + .consensus(TestConsensusBuilder::default()) } } @@ -198,6 +218,7 @@ pub async fn test_exex_context_with_chain_spec( let transaction_pool = testing_pool(); let evm_config = EthEvmConfig::default(); let executor = MockExecutorProvider::default(); + let consensus = Arc::new(TestConsensus::default()); let provider_factory = create_test_provider_factory_with_chain_spec(chain_spec); let genesis_hash = init_genesis(provider_factory.clone())?; @@ -217,7 +238,14 @@ pub async fn test_exex_context_with_chain_spec( let task_executor = tasks.executor(); let components = NodeAdapter::, _> { - components: Components { transaction_pool, evm_config, executor, network, payload_builder }, + components: Components { + transaction_pool, + evm_config, + executor, + consensus, + network, + payload_builder, + }, task_executor, provider, }; diff --git a/crates/node/builder/Cargo.toml b/crates/node/builder/Cargo.toml index 8273549ad8ea..22566f8edef3 100644 --- a/crates/node/builder/Cargo.toml +++ b/crates/node/builder/Cargo.toml @@ -64,11 +64,6 @@ secp256k1 = { workspace = true, features = [ "recovery", ] } -## Optimism -reth-optimism-consensus = { workspace = true, optional = true, features = [ - "optimism", -] } - ## misc aquamarine.workspace = true eyre.workspace = true @@ -88,5 +83,4 @@ optimism = [ "reth-beacon-consensus/optimism", "reth-blockchain-tree/optimism", "reth-node-core/optimism", - "dep:reth-optimism-consensus", ] diff --git a/crates/node/builder/src/builder/mod.rs b/crates/node/builder/src/builder/mod.rs index 52467f476b39..0bef193e3bc9 100644 --- a/crates/node/builder/src/builder/mod.rs +++ b/crates/node/builder/src/builder/mod.rs @@ -457,6 +457,11 @@ impl BuilderContext { self.provider().chain_spec() } + /// Returns true if the node is configured as --dev + pub const fn is_dev(&self) -> bool { + self.config().dev.dev + } + /// Returns the transaction pool config of the node. pub fn pool_config(&self) -> PoolConfig { self.config().txpool.pool_config() diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs index 33ecd00bb46f..72d2e6933da5 100644 --- a/crates/node/builder/src/components/builder.rs +++ b/crates/node/builder/src/components/builder.rs @@ -2,11 +2,12 @@ use crate::{ components::{ - Components, ExecutorBuilder, NetworkBuilder, NodeComponents, PayloadServiceBuilder, - PoolBuilder, + Components, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, NodeComponents, + PayloadServiceBuilder, PoolBuilder, }, BuilderContext, ConfigureEvm, FullNodeTypes, }; +use reth_consensus::Consensus; use reth_evm::execute::BlockExecutorProvider; use reth_transaction_pool::TransactionPool; use std::{future::Future, marker::PhantomData}; @@ -31,19 +32,22 @@ use std::{future::Future, marker::PhantomData}; /// All component builders are captured in the builder state and will be consumed once the node is /// launched. #[derive(Debug)] -pub struct ComponentsBuilder { +pub struct ComponentsBuilder { pool_builder: PoolB, payload_builder: PayloadB, network_builder: NetworkB, executor_builder: ExecB, + consensus_builder: ConsB, _marker: PhantomData, } -impl - ComponentsBuilder +impl + ComponentsBuilder { /// Configures the node types. - pub fn node_types(self) -> ComponentsBuilder + pub fn node_types( + self, + ) -> ComponentsBuilder where Types: FullNodeTypes, { @@ -52,6 +56,7 @@ impl payload_builder, network_builder, executor_builder: evm_builder, + consensus_builder, _marker, } = self; ComponentsBuilder { @@ -59,6 +64,7 @@ impl pool_builder, payload_builder, network_builder, + consensus_builder, _marker: Default::default(), } } @@ -70,6 +76,7 @@ impl payload_builder: self.payload_builder, network_builder: self.network_builder, executor_builder: self.executor_builder, + consensus_builder: self.consensus_builder, _marker: self._marker, } } @@ -81,6 +88,7 @@ impl payload_builder: f(self.payload_builder), network_builder: self.network_builder, executor_builder: self.executor_builder, + consensus_builder: self.consensus_builder, _marker: self._marker, } } @@ -92,6 +100,7 @@ impl payload_builder: self.payload_builder, network_builder: f(self.network_builder), executor_builder: self.executor_builder, + consensus_builder: self.consensus_builder, _marker: self._marker, } } @@ -103,13 +112,26 @@ impl payload_builder: self.payload_builder, network_builder: self.network_builder, executor_builder: f(self.executor_builder), + consensus_builder: self.consensus_builder, + _marker: self._marker, + } + } + + /// Apply a function to the consensus builder. + pub fn map_consensus(self, f: impl FnOnce(ConsB) -> ConsB) -> Self { + Self { + pool_builder: self.pool_builder, + payload_builder: self.payload_builder, + network_builder: self.network_builder, + executor_builder: self.executor_builder, + consensus_builder: f(self.consensus_builder), _marker: self._marker, } } } -impl - ComponentsBuilder +impl + ComponentsBuilder where Node: FullNodeTypes, { @@ -120,7 +142,7 @@ where pub fn pool( self, pool_builder: PB, - ) -> ComponentsBuilder + ) -> ComponentsBuilder where PB: PoolBuilder, { @@ -129,6 +151,7 @@ where payload_builder, network_builder, executor_builder: evm_builder, + consensus_builder, _marker, } = self; ComponentsBuilder { @@ -136,13 +159,14 @@ where payload_builder, network_builder, executor_builder: evm_builder, + consensus_builder, _marker, } } } -impl - ComponentsBuilder +impl + ComponentsBuilder where Node: FullNodeTypes, PoolB: PoolBuilder, @@ -154,7 +178,7 @@ where pub fn network( self, network_builder: NB, - ) -> ComponentsBuilder + ) -> ComponentsBuilder where NB: NetworkBuilder, { @@ -163,6 +187,7 @@ where payload_builder, network_builder: _, executor_builder: evm_builder, + consensus_builder, _marker, } = self; ComponentsBuilder { @@ -170,6 +195,7 @@ where payload_builder, network_builder, executor_builder: evm_builder, + consensus_builder, _marker, } } @@ -181,7 +207,7 @@ where pub fn payload( self, payload_builder: PB, - ) -> ComponentsBuilder + ) -> ComponentsBuilder where PB: PayloadServiceBuilder, { @@ -190,6 +216,7 @@ where payload_builder: _, network_builder, executor_builder: evm_builder, + consensus_builder, _marker, } = self; ComponentsBuilder { @@ -197,6 +224,7 @@ where payload_builder, network_builder, executor_builder: evm_builder, + consensus_builder, _marker, } } @@ -208,32 +236,69 @@ where pub fn executor( self, executor_builder: EB, - ) -> ComponentsBuilder + ) -> ComponentsBuilder where EB: ExecutorBuilder, { - let Self { pool_builder, payload_builder, network_builder, executor_builder: _, _marker } = - self; + let Self { + pool_builder, + payload_builder, + network_builder, + executor_builder: _, + consensus_builder, + _marker, + } = self; ComponentsBuilder { pool_builder, payload_builder, network_builder, executor_builder, + consensus_builder, + _marker, + } + } + + /// Configures the consensus builder. + /// + /// This accepts a [`ConsensusBuilder`] instance that will be used to create the node's + /// components for consensus. + pub fn consensus( + self, + consensus_builder: CB, + ) -> ComponentsBuilder + where + CB: ConsensusBuilder, + { + let Self { + pool_builder, + payload_builder, + network_builder, + executor_builder, + consensus_builder: _, + _marker, + } = self; + ComponentsBuilder { + pool_builder, + payload_builder, + network_builder, + executor_builder, + consensus_builder, _marker, } } } -impl NodeComponentsBuilder - for ComponentsBuilder +impl NodeComponentsBuilder + for ComponentsBuilder where Node: FullNodeTypes, PoolB: PoolBuilder, NetworkB: NetworkBuilder, PayloadB: PayloadServiceBuilder, ExecB: ExecutorBuilder, + ConsB: ConsensusBuilder, { - type Components = Components; + type Components = Components; async fn build_components( self, @@ -244,6 +309,7 @@ where payload_builder, network_builder, executor_builder: evm_builder, + consensus_builder, _marker, } = self; @@ -251,18 +317,27 @@ where let pool = pool_builder.build_pool(context).await?; let network = network_builder.build_network(context, pool.clone()).await?; let payload_builder = payload_builder.spawn_payload_service(context, pool.clone()).await?; + let consensus = consensus_builder.build_consensus(context).await?; - Ok(Components { transaction_pool: pool, evm_config, network, payload_builder, executor }) + Ok(Components { + transaction_pool: pool, + evm_config, + network, + payload_builder, + executor, + consensus, + }) } } -impl Default for ComponentsBuilder<(), (), (), (), ()> { +impl Default for ComponentsBuilder<(), (), (), (), (), ()> { fn default() -> Self { Self { pool_builder: (), payload_builder: (), network_builder: (), executor_builder: (), + consensus_builder: (), _marker: Default::default(), } } @@ -288,16 +363,17 @@ pub trait NodeComponentsBuilder: Send { ) -> impl Future> + Send; } -impl NodeComponentsBuilder for F +impl NodeComponentsBuilder for F where Node: FullNodeTypes, F: FnOnce(&BuilderContext) -> Fut + Send, - Fut: Future>> + Send, + Fut: Future>> + Send, Pool: TransactionPool + Unpin + 'static, EVM: ConfigureEvm, Executor: BlockExecutorProvider, + Cons: Consensus + Clone + Unpin + 'static, { - type Components = Components; + type Components = Components; fn build_components( self, diff --git a/crates/node/builder/src/components/consensus.rs b/crates/node/builder/src/components/consensus.rs new file mode 100644 index 000000000000..6c90bda54752 --- /dev/null +++ b/crates/node/builder/src/components/consensus.rs @@ -0,0 +1,32 @@ +//! Consensus component for the node builder. +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; + + /// Creates the consensus implementation. + fn build_consensus( + self, + ctx: &BuilderContext, + ) -> impl Future> + Send; +} + +impl ConsensusBuilder for F +where + Node: FullNodeTypes, + Consensus: reth_consensus::Consensus + Clone + Unpin + 'static, + F: FnOnce(&BuilderContext) -> Fut + Send, + Fut: Future> + Send, +{ + type Consensus = Consensus; + + fn build_consensus( + self, + ctx: &BuilderContext, + ) -> impl Future> { + self(ctx) + } +} diff --git a/crates/node/builder/src/components/mod.rs b/crates/node/builder/src/components/mod.rs index ef5ea4995655..7b9c769ed81c 100644 --- a/crates/node/builder/src/components/mod.rs +++ b/crates/node/builder/src/components/mod.rs @@ -9,16 +9,19 @@ use crate::{ConfigureEvm, FullNodeTypes}; pub use builder::*; +pub use consensus::*; pub use execute::*; pub use network::*; pub use payload::*; pub use pool::*; +use reth_consensus::Consensus; use reth_evm::execute::BlockExecutorProvider; use reth_network::NetworkHandle; use reth_payload_builder::PayloadBuilderHandle; use reth_transaction_pool::TransactionPool; mod builder; +mod consensus; mod execute; mod network; mod payload; @@ -39,6 +42,9 @@ pub trait NodeComponents: Clone + Send + Sync + 'stati /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider; + /// The consensus type of the node. + type Consensus: Consensus + Clone + Unpin + 'static; + /// Returns the transaction pool of the node. fn pool(&self) -> &Self::Pool; @@ -48,6 +54,9 @@ pub trait NodeComponents: Clone + Send + Sync + 'stati /// Returns the node's executor type. fn block_executor(&self) -> &Self::Executor; + /// Returns the node's consensus type. + fn consensus(&self) -> &Self::Consensus; + /// Returns the handle to the network fn network(&self) -> &NetworkHandle; @@ -59,29 +68,34 @@ pub trait NodeComponents: Clone + Send + Sync + 'stati /// /// This provides access to all the components of the node. #[derive(Debug)] -pub struct Components { +pub struct Components { /// The transaction pool of the node. pub transaction_pool: Pool, /// The node's EVM configuration, defining settings for the Ethereum Virtual Machine. pub evm_config: EVM, /// The node's executor type used to execute individual blocks and batches of blocks. pub executor: Executor, + /// The consensus implementation of the node. + pub consensus: Consensus, /// The network implementation of the node. pub network: NetworkHandle, /// The handle to the payload builder service. pub payload_builder: PayloadBuilderHandle, } -impl NodeComponents for Components +impl NodeComponents + for Components where Node: FullNodeTypes, Pool: TransactionPool + Unpin + 'static, EVM: ConfigureEvm, Executor: BlockExecutorProvider, + Cons: Consensus + Clone + Unpin + 'static, { type Pool = Pool; type Evm = EVM; type Executor = Executor; + type Consensus = Cons; fn pool(&self) -> &Self::Pool { &self.transaction_pool @@ -95,6 +109,10 @@ where &self.executor } + fn consensus(&self) -> &Self::Consensus { + &self.consensus + } + fn network(&self) -> &NetworkHandle { &self.network } @@ -104,18 +122,20 @@ where } } -impl Clone for Components +impl Clone for Components where Node: FullNodeTypes, Pool: TransactionPool, EVM: ConfigureEvm, Executor: BlockExecutorProvider, + Cons: Consensus + Clone, { fn clone(&self) -> Self { Self { transaction_pool: self.transaction_pool.clone(), evm_config: self.evm_config.clone(), executor: self.executor.clone(), + consensus: self.consensus.clone(), network: self.network.clone(), payload_builder: self.payload_builder.clone(), } diff --git a/crates/node/builder/src/launch/mod.rs b/crates/node/builder/src/launch/mod.rs index b4381eadc09e..fde21ad9730e 100644 --- a/crates/node/builder/src/launch/mod.rs +++ b/crates/node/builder/src/launch/mod.rs @@ -8,10 +8,9 @@ use crate::{ BuilderContext, NodeBuilderWithComponents, NodeHandle, }; use futures::{future::Either, stream, stream_select, StreamExt}; -use reth_auto_seal_consensus::AutoSealConsensus; use reth_beacon_consensus::{ hooks::{EngineHooks, PruneHook, StaticFileHook}, - BeaconConsensusEngine, EthBeaconConsensus, + BeaconConsensusEngine, }; use reth_blockchain_tree::{ noop::NoopBlockchainTree, BlockchainTree, BlockchainTreeConfig, ShareableBlockchainTree, @@ -30,9 +29,6 @@ use reth_node_core::{ }; use reth_node_events::{cl::ConsensusLayerHealthEvents, node}; -#[cfg(feature = "optimism")] -use reth_optimism_consensus::OptimismBeaconConsensus; - use reth_primitives::format_ether; use reth_provider::providers::BlockchainProvider; use reth_rpc_engine_api::EngineApi; @@ -134,20 +130,6 @@ where info!(target: "reth::cli", "\n{}", this.chain_spec().display_hardforks()); }); - // setup the consensus instance - let consensus: Arc = if ctx.is_dev() { - Arc::new(AutoSealConsensus::new(ctx.chain_spec())) - } else { - #[cfg(feature = "optimism")] - if ctx.chain_spec().is_optimism() { - Arc::new(OptimismBeaconConsensus::new(ctx.chain_spec())) - } else { - Arc::new(EthBeaconConsensus::new(ctx.chain_spec())) - } - #[cfg(not(feature = "optimism"))] - Arc::new(EthBeaconConsensus::new(ctx.chain_spec())) - }; - debug!(target: "reth::cli", "Spawning stages metrics listener task"); let (sync_metrics_tx, sync_metrics_rx) = unbounded_channel(); let sync_metrics_listener = reth_stages::MetricsListener::new(sync_metrics_rx); @@ -180,6 +162,8 @@ where debug!(target: "reth::cli", "creating components"); let components = components_builder.build_components(&builder_ctx).await?; + let consensus: Arc = Arc::new(components.consensus().clone()); + let tree_externals = TreeExternals::new( ctx.provider_factory().clone(), consensus.clone(), @@ -269,7 +253,7 @@ where ctx.node_config(), &ctx.toml_config().stages, client.clone(), - Arc::clone(&consensus), + consensus.clone(), ctx.provider_factory().clone(), ctx.task_executor(), sync_metrics_tx, @@ -292,7 +276,7 @@ where ctx.node_config(), &ctx.toml_config().stages, network_client.clone(), - Arc::clone(&consensus), + consensus.clone(), ctx.provider_factory().clone(), ctx.task_executor(), sync_metrics_tx, diff --git a/crates/optimism/node/Cargo.toml b/crates/optimism/node/Cargo.toml index 5cd32f8f489f..a3ca76c1d0b9 100644 --- a/crates/optimism/node/Cargo.toml +++ b/crates/optimism/node/Cargo.toml @@ -29,6 +29,7 @@ reth-evm.workspace = true reth-revm.workspace = true reth-evm-optimism.workspace = true reth-beacon-consensus.workspace = true +reth-optimism-consensus.workspace = true revm-primitives.workspace = true # async diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 3ab287824428..5b1bcc32ee38 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -11,11 +11,13 @@ use reth_evm_optimism::{OpExecutorProvider, OptimismEvmConfig}; use reth_network::{NetworkHandle, NetworkManager}; use reth_node_builder::{ components::{ - ComponentsBuilder, ExecutorBuilder, NetworkBuilder, PayloadServiceBuilder, PoolBuilder, + ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, + PayloadServiceBuilder, PoolBuilder, }, node::{FullNodeTypes, NodeTypes}, BuilderContext, Node, PayloadBuilderConfig, }; +use reth_optimism_consensus::OptimismBeaconConsensus; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_provider::CanonStateSubscriptions; use reth_tracing::tracing::{debug, info}; @@ -47,6 +49,7 @@ impl OptimismNode { OptimismPayloadBuilder, OptimismNetworkBuilder, OptimismExecutorBuilder, + OptimismConsensusBuilder, > where Node: FullNodeTypes, @@ -61,6 +64,7 @@ impl OptimismNode { )) .network(OptimismNetworkBuilder { disable_txpool_gossip }) .executor(OptimismExecutorBuilder::default()) + .consensus(OptimismConsensusBuilder::default()) } } @@ -74,6 +78,7 @@ where OptimismPayloadBuilder, OptimismNetworkBuilder, OptimismExecutorBuilder, + OptimismConsensusBuilder, >; fn components_builder(self) -> Self::ComponentsBuilder { @@ -283,3 +288,19 @@ where Ok(handle) } } + +/// A basic optimism consensus builder. +#[derive(Debug, Default, Clone)] +#[non_exhaustive] +pub struct OptimismConsensusBuilder; + +impl ConsensusBuilder for OptimismConsensusBuilder +where + Node: FullNodeTypes, +{ + type Consensus = OptimismBeaconConsensus; + + async fn build_consensus(self, ctx: &BuilderContext) -> eyre::Result { + Ok(OptimismBeaconConsensus::new(ctx.chain_spec())) + } +} diff --git a/examples/custom-engine-types/src/main.rs b/examples/custom-engine-types/src/main.rs index de6d38870230..d13177e053ce 100644 --- a/examples/custom-engine-types/src/main.rs +++ b/examples/custom-engine-types/src/main.rs @@ -43,7 +43,7 @@ use reth_node_api::{ }; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; use reth_node_ethereum::node::{ - EthereumExecutorBuilder, EthereumNetworkBuilder, EthereumPoolBuilder, + EthereumConsensusBuilder, EthereumExecutorBuilder, EthereumNetworkBuilder, EthereumPoolBuilder, }; use reth_payload_builder::{ error::PayloadBuilderError, EthBuiltPayload, EthPayloadBuilderAttributes, PayloadBuilderHandle, @@ -204,6 +204,7 @@ where CustomPayloadServiceBuilder, EthereumNetworkBuilder, EthereumExecutorBuilder, + EthereumConsensusBuilder, >; fn components_builder(self) -> Self::ComponentsBuilder { @@ -213,6 +214,7 @@ where .payload(CustomPayloadServiceBuilder::default()) .network(EthereumNetworkBuilder::default()) .executor(EthereumExecutorBuilder::default()) + .consensus(EthereumConsensusBuilder::default()) } } From 9eb95ff670ca46c05e04ae79c65810aab3b7789e Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Mon, 10 Jun 2024 17:11:38 -0700 Subject: [PATCH 4/5] Fix import --- crates/exex/test-utils/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/exex/test-utils/Cargo.toml b/crates/exex/test-utils/Cargo.toml index ab14c21fc70b..5e00109d8abc 100644 --- a/crates/exex/test-utils/Cargo.toml +++ b/crates/exex/test-utils/Cargo.toml @@ -14,7 +14,7 @@ workspace = true ## reth reth-blockchain-tree.workspace = true reth-config.workspace = true -reth-consensus.workspace = true +reth-consensus = { workspace = true, features = ["test-utils"] } reth-db = { workspace = true, features = ["test-utils"] } reth-db-common.workspace = true reth-evm = { workspace = true, features = ["test-utils"] } From 5513a0747517136cd02976a7dcbcd1a1dbbdf9b6 Mon Sep 17 00:00:00 2001 From: Brian Bland Date: Tue, 11 Jun 2024 09:49:54 -0700 Subject: [PATCH 5/5] Remove unnecessary features --- bin/reth/Cargo.toml | 1 - crates/node/builder/Cargo.toml | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index 1c3c959597f3..38410737ecfb 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -146,7 +146,6 @@ optimism = [ "reth-beacon-consensus/optimism", "reth-blockchain-tree/optimism", "dep:reth-node-optimism", - "reth-node-builder/optimism", "reth-node-core/optimism", ] diff --git a/crates/node/builder/Cargo.toml b/crates/node/builder/Cargo.toml index 22566f8edef3..67714777f3f5 100644 --- a/crates/node/builder/Cargo.toml +++ b/crates/node/builder/Cargo.toml @@ -74,13 +74,3 @@ backon.workspace = true [dev-dependencies] tempfile.workspace = true - -[features] -optimism = [ - "reth-primitives/optimism", - "reth-rpc/optimism", - "reth-provider/optimism", - "reth-beacon-consensus/optimism", - "reth-blockchain-tree/optimism", - "reth-node-core/optimism", -]