1pub mod addons;
7pub mod args;
8pub mod chainspec;
9pub mod coalesced_state;
10pub mod consensus;
11pub mod engine;
12pub mod error;
13pub mod genesis;
14pub mod launcher;
15pub mod network;
16pub mod payload;
17pub mod pool;
18pub mod producer;
19pub mod validator;
20
21use std::sync::Arc;
22
23use alloy_consensus::Header;
24use arb_evm::ArbEvmConfig;
25use arb_payload::ArbEngineTypes;
26use arb_primitives::{ArbPrimitives, ArbTransactionSigned};
27use arb_rpc::{
28 ArbApiHandler, ArbApiServer, ArbEthApiBuilder, NitroExecutionApiServer, NitroExecutionHandler,
29 stylus_debug::{StylusDebugHandler, StylusDebugServer},
30};
31pub use error::{GenesisError, LauncherError};
32use reth_chain_state::CanonicalInMemoryState;
33use reth_chainspec::ChainSpec;
34use reth_node_builder::{
35 BuilderContext, FullNodeComponents, FullNodeTypes, Node, NodeAdapter, NodeTypes,
36 components::{ComponentsBuilder, ConsensusBuilder, ExecutorBuilder},
37 rpc::{BasicEngineApiBuilder, BasicEngineValidatorBuilder, RpcAddOns, RpcContext},
38};
39use reth_provider::{BlockNumReader, BlockReaderIdExt, HeaderProvider, StateProviderFactory};
40use reth_storage_api::{CanonChainTracker, EthStorage};
41
42use crate::{
43 addons::ArbPayloadValidatorBuilder,
44 args::RollupArgs,
45 consensus::ArbConsensus,
46 network::ArbNetworkBuilder,
47 payload::ArbPayloadServiceBuilder,
48 pool::ArbPoolBuilder,
49 producer::{ArbBlockProducer, InMemoryStateAccess},
50};
51
52pub type ArbAddOns<N> = RpcAddOns<
54 N,
55 ArbEthApiBuilder,
56 ArbPayloadValidatorBuilder,
57 BasicEngineApiBuilder<ArbPayloadValidatorBuilder>,
58 BasicEngineValidatorBuilder<ArbPayloadValidatorBuilder>,
59>;
60
61pub type ArbStorage = EthStorage<ArbTransactionSigned>;
63
64#[derive(Debug, Clone, Default)]
66pub struct ArbNode {
67 pub args: RollupArgs,
69}
70
71impl ArbNode {
72 pub fn new(args: RollupArgs) -> Self {
74 Self { args }
75 }
76
77 pub fn components<N>() -> ComponentsBuilder<
79 N,
80 ArbPoolBuilder,
81 ArbPayloadServiceBuilder,
82 ArbNetworkBuilder,
83 ArbExecutorBuilder,
84 ArbConsensusBuilder,
85 >
86 where
87 N: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec, Primitives = ArbPrimitives>>,
88 {
89 ComponentsBuilder::default()
90 .node_types::<N>()
91 .pool(ArbPoolBuilder)
92 .executor(ArbExecutorBuilder)
93 .payload(ArbPayloadServiceBuilder)
94 .network(ArbNetworkBuilder)
95 .consensus(ArbConsensusBuilder)
96 }
97}
98
99impl NodeTypes for ArbNode {
100 type Primitives = ArbPrimitives;
101 type ChainSpec = ChainSpec;
102 type Storage = ArbStorage;
103 type Payload = ArbEngineTypes;
104}
105
106impl<N> Node<N> for ArbNode
107where
108 N: FullNodeTypes<Types = Self>,
109 N::Provider:
110 CanonChainTracker<Header = Header> + InMemoryStateAccess<Primitives = ArbPrimitives>,
111{
112 type ComponentsBuilder = ComponentsBuilder<
113 N,
114 ArbPoolBuilder,
115 ArbPayloadServiceBuilder,
116 ArbNetworkBuilder,
117 ArbExecutorBuilder,
118 ArbConsensusBuilder,
119 >;
120
121 type AddOns =
122 ArbAddOns<
123 NodeAdapter<
124 N,
125 <Self::ComponentsBuilder as reth_node_builder::components::NodeComponentsBuilder<
126 N,
127 >>::Components,
128 >,
129 >;
130
131 fn components_builder(&self) -> Self::ComponentsBuilder {
132 Self::components()
133 }
134
135 fn add_ons(&self) -> Self::AddOns {
136 RpcAddOns::new(
137 ArbEthApiBuilder::default(),
138 ArbPayloadValidatorBuilder,
139 BasicEngineApiBuilder::default(),
140 BasicEngineValidatorBuilder::default(),
141 Default::default(),
142 )
143 .extend_rpc_modules(register_arb_rpc)
144 }
145}
146
147pub fn cli_components(chain_spec: Arc<ChainSpec>) -> (ArbEvmConfig, Arc<ArbConsensus<ChainSpec>>) {
150 let allow_debug = chainspec::allow_debug_precompiles(&chain_spec);
151 (
152 ArbEvmConfig::for_offline_execution(chain_spec.clone(), allow_debug),
153 Arc::new(ArbConsensus::new_verifying(chain_spec)),
154 )
155}
156
157#[derive(Debug, Default, Clone, Copy)]
159pub struct ArbExecutorBuilder;
160
161impl<N> ExecutorBuilder<N> for ArbExecutorBuilder
162where
163 N: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec, Primitives = ArbPrimitives>>,
164{
165 type EVM = ArbEvmConfig;
166
167 async fn build_evm(self, ctx: &BuilderContext<N>) -> eyre::Result<Self::EVM> {
168 let chain_spec = ctx.chain_spec();
169 let allow_debug = chainspec::allow_debug_precompiles(&chain_spec);
170 Ok(ArbEvmConfig::with_allow_debug_precompiles(
171 chain_spec,
172 allow_debug,
173 ))
174 }
175}
176
177fn register_arb_rpc<N, EthApi>(ctx: RpcContext<'_, N, EthApi>) -> eyre::Result<()>
179where
180 N: FullNodeComponents<
181 Types: NodeTypes<ChainSpec = ChainSpec, Primitives = ArbPrimitives>,
182 Provider: BlockNumReader
183 + BlockReaderIdExt
184 + HeaderProvider
185 + StateProviderFactory
186 + InMemoryStateAccess<Primitives = ArbPrimitives>
187 + CanonChainTracker<Header = Header>,
188 >,
189 EthApi: reth_rpc_eth_api::FullEthApiTypes
190 + reth_rpc_eth_api::helpers::TraceExt
191 + Clone
192 + Send
193 + Sync
194 + 'static,
195{
196 let arb_api = ArbApiHandler::new(ctx.provider().clone());
197 ctx.modules.merge_configured(arb_api.into_rpc())?;
198
199 {
203 let debug_api = ctx.registry.debug_api();
204 let forwarder: arb_rpc::stylus_debug::DebugForwarder =
205 std::sync::Arc::new(move |tx_hash, opts| {
206 let api = debug_api.clone();
207 Box::pin(async move {
208 api.debug_trace_transaction(tx_hash, opts.unwrap_or_default())
209 .await
210 .map_err(Into::into)
211 })
212 });
213 let stylus_debug = StylusDebugHandler::new(forwarder);
214 ctx.modules
215 .add_or_replace_configured(stylus_debug.into_rpc())?;
216 }
217
218 let chain_spec: Arc<ChainSpec> = ctx.config().chain.clone();
219 let allow_debug = chainspec::allow_debug_precompiles(&chain_spec);
220 let evm_config = ArbEvmConfig::with_allow_debug_precompiles(chain_spec.clone(), allow_debug);
221
222 let in_memory_state: CanonicalInMemoryState<ArbPrimitives> =
223 ctx.provider().canonical_in_memory_state();
224
225 let genesis_block_num = chain_spec.genesis_header().number;
226
227 let flush_interval = std::env::var("ARB_FLUSH_INTERVAL")
228 .ok()
229 .and_then(|v| v.parse().ok())
230 .unwrap_or(producer::DEFAULT_FLUSH_INTERVAL);
231
232 let block_producer = Arc::new(ArbBlockProducer::new(
233 ctx.provider().clone(),
234 chain_spec,
235 evm_config,
236 in_memory_state,
237 flush_interval,
238 ));
239
240 let nitro_exec =
241 NitroExecutionHandler::new(ctx.provider().clone(), block_producer, genesis_block_num);
242 let nitro_rpc = nitro_exec.into_rpc();
243 ctx.modules.merge_configured(nitro_rpc.clone())?;
244 ctx.auth_module.merge_auth_methods(nitro_rpc)?;
245
246 Ok(())
247}
248
249#[derive(Debug, Default, Clone, Copy)]
251pub struct ArbConsensusBuilder;
252
253impl<N> ConsensusBuilder<N> for ArbConsensusBuilder
254where
255 N: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec, Primitives = ArbPrimitives>>,
256{
257 type Consensus = Arc<ArbConsensus<ChainSpec>>;
258
259 async fn build_consensus(self, ctx: &BuilderContext<N>) -> eyre::Result<Self::Consensus> {
260 Ok(Arc::new(ArbConsensus::new(ctx.chain_spec())))
261 }
262}