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