Repository: paradigmxyz/reth (Rust)

Issue:
Replace Node associate types with `NodeComponentsBuilder`
### Describe the feature

the node trait is a helper trait to configure everything that's required to configure a node.

I think the associated types:

https://github.com/paradigmxyz/reth/blob/1f6753b84a3ea3f75a6bcb9134e03f7b286ea130/crates/node/builder/src/node.rs#L28-L33

can be replaced with a single associated type for `NodeComponentsBuilder`

https://github.com/paradigmxyz/reth/blob/1f6753b84a3ea3f75a6bcb9134e03f7b286ea130/crates/node/builder/src/node.rs#L35-L38


```rust
trait Node<T:FullNodeTypes> {
  type Builder: NodeComponentsBuilder<T>;

  fn builder(self) -> Self::Builder

```

it's possible that there are some issues with this, so this needs some tinkering, but this would allow us to simplify:

https://github.com/paradigmxyz/reth/blob/1f6753b84a3ea3f75a6bcb9134e03f7b286ea130/crates/node/builder/src/builder/mod.rs#L216-L226

### Additional context

_No response_



Fix (patch):
diff --git a/crates/node-ethereum/src/node.rs b/crates/node-ethereum/src/node.rs
index e7caa927a52..5a1a03554a0 100644
--- a/crates/node-ethereum/src/node.rs
+++ b/crates/node-ethereum/src/node.rs
@@ -5,8 +5,8 @@ use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGenera
 use reth_network::NetworkHandle;
 use reth_node_builder::{
     components::{ComponentsBuilder, NetworkBuilder, PayloadServiceBuilder, PoolBuilder},
-    node::{FullNodeTypes, Node, NodeTypes},
-    BuilderContext, PayloadBuilderConfig,
+    node::{FullNodeTypes, NodeTypes},
+    BuilderContext, Node, PayloadBuilderConfig,
 };
 use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
 use reth_provider::CanonStateSubscriptions;
@@ -50,18 +50,11 @@ impl<N> Node<N> for EthereumNode
 where
     N: FullNodeTypes<Engine = EthEngineTypes>,
 {
-    type PoolBuilder = EthereumPoolBuilder;
-    type NetworkBuilder = EthereumNetworkBuilder;
-    type PayloadBuilder = EthereumPayloadBuilder;
+    type ComponentsBuilder =
+        ComponentsBuilder<N, EthereumPoolBuilder, EthereumPayloadBuilder, EthereumNetworkBuilder>;
 
-    fn components(
-        self,
-    ) -> ComponentsBuilder<N, Self::PoolBuilder, Self::PayloadBuilder, Self::NetworkBuilder> {
-        ComponentsBuilder::default()
-            .node_types::<N>()
-            .pool(EthereumPoolBuilder::default())
-            .payload(EthereumPayloadBuilder::default())
-            .network(EthereumNetworkBuilder::default())
+    fn components_builder(self) -> Self::ComponentsBuilder {
+        Self::components()
     }
 }
 
diff --git a/crates/node/builder/src/builder/mod.rs b/crates/node/builder/src/builder/mod.rs
index 9649360ebe9..6365fca4de1 100644
--- a/crates/node/builder/src/builder/mod.rs
+++ b/crates/node/builder/src/builder/mod.rs
@@ -3,7 +3,7 @@
 #![allow(clippy::type_complexity, missing_debug_implementations)]
 
 use crate::{
-    components::{Components, ComponentsBuilder, NodeComponentsBuilder, PoolBuilder},
+    components::NodeComponentsBuilder,
     node::FullNode,
     rpc::{RethRpcServerHandles, RpcContext},
     DefaultNodeLauncher, Node, NodeHandle,
@@ -204,28 +204,11 @@ where
     pub fn node<N>(
         self,
         node: N,
-    ) -> NodeBuilderWithComponents<
-        RethFullAdapter<DB, N>,
-        ComponentsBuilder<
-            RethFullAdapter<DB, N>,
-            N::PoolBuilder,
-            N::PayloadBuilder,
-            N::NetworkBuilder,
-        >,
-    >
+    ) -> NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder>
     where
         N: Node<RethFullAdapter<DB, N>>,
-        N::PoolBuilder: PoolBuilder<RethFullAdapter<DB, N>>,
-        N::NetworkBuilder: crate::components::NetworkBuilder<
-            RethFullAdapter<DB, N>,
-            <N::PoolBuilder as PoolBuilder<RethFullAdapter<DB, N>>>::Pool,
-        >,
-        N::PayloadBuilder: crate::components::PayloadServiceBuilder<
-            RethFullAdapter<DB, N>,
-            <N::PoolBuilder as PoolBuilder<RethFullAdapter<DB, N>>>::Pool,
-        >,
     {
-        self.with_types(node.clone()).with_components(node.components())
+        self.with_types(node.clone()).with_components(node.components_builder())
     }
 }
 
@@ -271,33 +254,16 @@ where
     }
 
     /// Preconfigures the node with a specific node implementation.
+    ///
+    /// This is a convenience method that sets the node's types and components in one call.
     pub fn node<N>(
         self,
         node: N,
-    ) -> WithLaunchContext<
-        NodeBuilderWithComponents<
-            RethFullAdapter<DB, N>,
-            ComponentsBuilder<
-                RethFullAdapter<DB, N>,
-                N::PoolBuilder,
-                N::PayloadBuilder,
-                N::NetworkBuilder,
-            >,
-        >,
-    >
+    ) -> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder>>
     where
         N: Node<RethFullAdapter<DB, N>>,
-        N::PoolBuilder: PoolBuilder<RethFullAdapter<DB, N>>,
-        N::NetworkBuilder: crate::components::NetworkBuilder<
-            RethFullAdapter<DB, N>,
-            <N::PoolBuilder as PoolBuilder<RethFullAdapter<DB, N>>>::Pool,
-        >,
-        N::PayloadBuilder: crate::components::PayloadServiceBuilder<
-            RethFullAdapter<DB, N>,
-            <N::PoolBuilder as PoolBuilder<RethFullAdapter<DB, N>>>::Pool,
-        >,
     {
-        self.with_types(node.clone()).with_components(node.components())
+        self.with_types(node.clone()).with_components(node.components_builder())
     }
 
     /// Launches a preconfigured [Node]
@@ -312,24 +278,12 @@ where
         NodeHandle<
             NodeAdapter<
                 RethFullAdapter<DB, N>,
-                Components<
-                    RethFullAdapter<DB, N>,
-                    <N::PoolBuilder as PoolBuilder<RethFullAdapter<DB, N>>>::Pool,
-                >,
+                <N::ComponentsBuilder as NodeComponentsBuilder<RethFullAdapter<DB, N>>>::Components,
             >,
         >,
     >
     where
         N: Node<RethFullAdapter<DB, N>>,
-        N::PoolBuilder: PoolBuilder<RethFullAdapter<DB, N>>,
-        N::NetworkBuilder: crate::components::NetworkBuilder<
-            RethFullAdapter<DB, N>,
-            <N::PoolBuilder as PoolBuilder<RethFullAdapter<DB, N>>>::Pool,
-        >,
-        N::PayloadBuilder: crate::components::PayloadServiceBuilder<
-            RethFullAdapter<DB, N>,
-            <N::PoolBuilder as PoolBuilder<RethFullAdapter<DB, N>>>::Pool,
-        >,
     {
         self.node(node).launch().await
     }
diff --git a/crates/node/builder/src/node.rs b/crates/node/builder/src/node.rs
index 766bae14fe8..7831f29d0b0 100644
--- a/crates/node/builder/src/node.rs
+++ b/crates/node/builder/src/node.rs
@@ -1,7 +1,4 @@
-use crate::{
-    components::ComponentsBuilder,
-    rpc::{RethRpcServerHandles, RpcRegistry},
-};
+use crate::rpc::{RethRpcServerHandles, RpcRegistry};
 use reth_network::NetworkHandle;
 use reth_node_api::FullNodeComponents;
 use reth_node_core::{
@@ -19,23 +16,18 @@ use reth_tasks::TaskExecutor;
 use std::sync::Arc;
 
 // re-export the node api types
+use crate::components::NodeComponentsBuilder;
 pub use reth_node_api::{FullNodeTypes, NodeTypes};
 
-/// A [Node] is a [NodeTypes] that comes with preconfigured components.
+/// A [crate::Node] is a [NodeTypes] that comes with preconfigured components.
 ///
 /// This can be used to configure the builder with a preset of components.
-pub trait Node<N>: NodeTypes + Clone {
-    /// The type that builds the node's pool.
-    type PoolBuilder;
-    /// The type that builds the node's network.
-    type NetworkBuilder;
-    /// The type that builds the node's payload service.
-    type PayloadBuilder;
+pub trait Node<N: FullNodeTypes>: NodeTypes + Clone {
+    /// The type that builds the node's components.
+    type ComponentsBuilder: NodeComponentsBuilder<N>;
 
-    /// Returns the [ComponentsBuilder] for the node.
-    fn components(
-        self,
-    ) -> ComponentsBuilder<N, Self::PoolBuilder, Self::PayloadBuilder, Self::NetworkBuilder>;
+    /// Returns a [NodeComponentsBuilder] for the node.
+    fn components_builder(self) -> Self::ComponentsBuilder;
 }
 
 /// The launched node with all components including RPC handlers.
diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs
index 0d6e4996a60..8f6a3c19b47 100644
--- a/crates/optimism/node/src/node.rs
+++ b/crates/optimism/node/src/node.rs
@@ -55,13 +55,10 @@ impl<N> Node<N> for OptimismNode
 where
     N: FullNodeTypes<Engine = OptimismEngineTypes>,
 {
-    type PoolBuilder = OptimismPoolBuilder;
-    type NetworkBuilder = OptimismNetworkBuilder;
-    type PayloadBuilder = OptimismPayloadBuilder;
+    type ComponentsBuilder =
+        ComponentsBuilder<N, OptimismPoolBuilder, OptimismPayloadBuilder, OptimismNetworkBuilder>;
 
-    fn components(
-        self,
-    ) -> ComponentsBuilder<N, Self::PoolBuilder, Self::PayloadBuilder, Self::NetworkBuilder> {
+    fn components_builder(self) -> Self::ComponentsBuilder {
         let Self { args } = self;
         Self::components(args)
     }
diff --git a/examples/custom-engine-types/src/main.rs b/examples/custom-engine-types/src/main.rs
index a2ade9cc106..79639e1baa1 100644
--- a/examples/custom-engine-types/src/main.rs
+++ b/examples/custom-engine-types/src/main.rs
@@ -202,13 +202,14 @@ impl<N> Node<N> for MyCustomNode
 where
     N: FullNodeTypes<Engine = CustomEngineTypes>,
 {
-    type PoolBuilder = EthereumPoolBuilder;
-    type NetworkBuilder = EthereumNetworkBuilder;
-    type PayloadBuilder = CustomPayloadServiceBuilder;
-
-    fn components(
-        self,
-    ) -> ComponentsBuilder<N, Self::PoolBuilder, Self::PayloadBuilder, Self::NetworkBuilder> {
+    type ComponentsBuilder = ComponentsBuilder<
+        N,
+        EthereumPoolBuilder,
+        CustomPayloadServiceBuilder,
+        EthereumNetworkBuilder,
+    >;
+
+    fn components_builder(self) -> Self::ComponentsBuilder {
         ComponentsBuilder::default()
             .node_types::<N>()
             .pool(EthereumPoolBuilder::default())