kona_node_service/service/standard/
builder.rs

1//! Contains the builder for the [`RollupNode`].
2
3use crate::{EngineBuilder, InteropMode, NetworkConfig, NodeMode, RollupNode, SequencerConfig};
4use alloy_primitives::Bytes;
5use alloy_provider::RootProvider;
6use alloy_rpc_client::RpcClient;
7use alloy_rpc_types_engine::JwtSecret;
8use alloy_transport_http::{
9    AuthLayer, Http, HyperClient,
10    hyper_util::{client::legacy::Client, rt::TokioExecutor},
11};
12use http_body_util::Full;
13use op_alloy_network::Optimism;
14use std::sync::Arc;
15use tower::ServiceBuilder;
16use url::Url;
17
18use kona_genesis::RollupConfig;
19use kona_providers_alloy::OnlineBeaconClient;
20use kona_rpc::RpcBuilder;
21
22/// The [`RollupNodeBuilder`] is used to construct a [`RollupNode`] service.
23#[derive(Debug, Default)]
24pub struct RollupNodeBuilder {
25    /// The rollup configuration.
26    config: RollupConfig,
27    /// The L1 EL provider RPC URL.
28    l1_provider_rpc_url: Option<Url>,
29    /// The L1 beacon API URL.
30    l1_beacon_api_url: Option<Url>,
31    /// The L2 engine RPC URL.
32    l2_engine_rpc_url: Option<Url>,
33    /// The JWT secret.
34    jwt_secret: Option<JwtSecret>,
35    /// The [`NetworkConfig`].
36    p2p_config: Option<NetworkConfig>,
37    /// An RPC Configuration.
38    rpc_config: Option<RpcBuilder>,
39    /// The [`SequencerConfig`].
40    sequencer_config: Option<SequencerConfig>,
41    /// The mode to run the node in.
42    mode: NodeMode,
43    /// Whether to run the node in interop mode.
44    interop_mode: InteropMode,
45}
46
47impl RollupNodeBuilder {
48    /// Creates a new [`RollupNodeBuilder`] with the given [`RollupConfig`].
49    pub fn new(config: RollupConfig) -> Self {
50        Self { config, ..Self::default() }
51    }
52
53    /// Sets the [`NodeMode`] on the [`RollupNodeBuilder`].
54    pub fn with_mode(self, mode: NodeMode) -> Self {
55        Self { mode, ..self }
56    }
57
58    /// Appends an L1 EL provider RPC URL to the builder.
59    pub fn with_l1_provider_rpc_url(self, l1_provider_rpc_url: Url) -> Self {
60        Self { l1_provider_rpc_url: Some(l1_provider_rpc_url), ..self }
61    }
62
63    /// Appends an L1 beacon API URL to the builder.
64    pub fn with_l1_beacon_api_url(self, l1_beacon_api_url: Url) -> Self {
65        Self { l1_beacon_api_url: Some(l1_beacon_api_url), ..self }
66    }
67
68    /// Appends an L2 engine RPC URL to the builder.
69    pub fn with_l2_engine_rpc_url(self, l2_engine_rpc_url: Url) -> Self {
70        Self { l2_engine_rpc_url: Some(l2_engine_rpc_url), ..self }
71    }
72
73    /// Appends a JWT secret to the builder.
74    pub fn with_jwt_secret(self, jwt_secret: JwtSecret) -> Self {
75        Self { jwt_secret: Some(jwt_secret), ..self }
76    }
77
78    /// Appends the P2P [`NetworkConfig`] to the builder.
79    pub fn with_p2p_config(self, config: NetworkConfig) -> Self {
80        Self { p2p_config: Some(config), ..self }
81    }
82
83    /// Sets the [`RpcBuilder`] on the [`RollupNodeBuilder`].
84    pub fn with_rpc_config(self, rpc_config: Option<RpcBuilder>) -> Self {
85        Self { rpc_config, ..self }
86    }
87
88    /// Appends the [`SequencerConfig`] to the builder.
89    pub fn with_sequencer_config(self, sequencer_config: SequencerConfig) -> Self {
90        Self { sequencer_config: Some(sequencer_config), ..self }
91    }
92
93    /// Assembles the [`RollupNode`] service.
94    ///
95    /// ## Panics
96    ///
97    /// Panics if:
98    /// - The L1 provider RPC URL is not set.
99    /// - The L1 beacon API URL is not set.
100    /// - The L2 provider RPC URL is not set.
101    /// - The L2 engine URL is not set.
102    /// - The jwt secret is not set.
103    /// - The P2P config is not set.
104    pub fn build(self) -> RollupNode {
105        let l1_rpc_url = self.l1_provider_rpc_url.expect("l1 provider rpc url not set");
106        let l1_provider = RootProvider::new_http(l1_rpc_url.clone());
107        let l1_beacon = OnlineBeaconClient::new_http(
108            self.l1_beacon_api_url.expect("l1 beacon api url not set").to_string(),
109        );
110
111        let engine_url = self.l2_engine_rpc_url.expect("l2 engine rpc url not set");
112        let jwt_secret = self.jwt_secret.expect("jwt secret not set");
113        let hyper_client = Client::builder(TokioExecutor::new()).build_http::<Full<Bytes>>();
114
115        let auth_layer = AuthLayer::new(jwt_secret);
116        let service = ServiceBuilder::new().layer(auth_layer).service(hyper_client);
117
118        let layer_transport = HyperClient::with_service(service);
119        let http_hyper = Http::with_client(layer_transport, engine_url.clone());
120        let rpc_client = RpcClient::new(http_hyper, false);
121        let l2_provider = RootProvider::<Optimism>::new(rpc_client);
122
123        let rollup_config = Arc::new(self.config);
124        let engine_builder = EngineBuilder {
125            config: Arc::clone(&rollup_config),
126            l1_rpc_url,
127            engine_url,
128            jwt_secret,
129            mode: self.mode,
130        };
131
132        let p2p_config = self.p2p_config.expect("P2P config not set");
133        let sequencer_config = self.sequencer_config.unwrap_or_default();
134
135        RollupNode {
136            config: rollup_config,
137            interop_mode: self.interop_mode,
138            l1_provider,
139            l1_beacon,
140            l2_provider,
141            engine_builder,
142            rpc_builder: self.rpc_config,
143            p2p_config,
144            sequencer_config,
145        }
146    }
147}