1
1
//! Rollup Node Driver
2
2
3
- use std:: sync:: Arc ;
3
+ use std:: { fmt :: Debug , sync:: Arc } ;
4
4
5
5
use async_trait:: async_trait;
6
6
use eyre:: { bail, Result } ;
7
+ use kona_derive:: {
8
+ online:: { AlloyChainProvider , AlloyL2ChainProvider , OnlineBlobProviderBuilder } ,
9
+ traits:: { BlobProvider , ChainProvider , L2ChainProvider } ,
10
+ } ;
11
+ use kona_primitives:: BlockInfo ;
12
+ use kona_providers:: {
13
+ blob_provider:: DurableBlobProvider , InMemoryChainProvider , LayeredBlobProvider ,
14
+ } ;
7
15
use reth_exex:: { ExExContext , ExExEvent , ExExNotification } ;
8
16
use reth_node_api:: FullNodeComponents ;
9
17
use superchain_registry:: RollupConfig ;
10
18
use tokio:: sync:: mpsc:: error:: SendError ;
11
19
use tracing:: { debug, info} ;
12
20
13
- use crate :: cli :: HeraArgsExt ;
21
+ use crate :: { new_rollup_pipeline , HeraArgsExt , RollupPipeline } ;
14
22
15
23
#[ async_trait]
16
24
pub trait DriverContext {
@@ -30,22 +38,76 @@ impl<N: FullNodeComponents> DriverContext for ExExContext<N> {
30
38
}
31
39
}
32
40
41
+ #[ derive( Debug ) ]
42
+ pub struct StandaloneContext ;
43
+
44
+ #[ async_trait]
45
+ impl DriverContext for StandaloneContext {
46
+ async fn recv_notification ( & mut self ) -> Option < ExExNotification > {
47
+ // TODO: we will need a background task to listen for new blocks
48
+ // (either polling or via websocket), parse them into ExExNotifications
49
+ // and handle reorgs for the driver to react to.
50
+ todo ! ( )
51
+ }
52
+
53
+ fn send_event ( & mut self , _event : ExExEvent ) -> Result < ( ) , SendError < ExExEvent > > {
54
+ // TODO: When we have a better background notifier abstraction, sending
55
+ // FinishedHeight events will be useful to make the pipeline advance
56
+ // safely through reorgs (as it is currently done for ExExContext).
57
+ Ok ( ( ) )
58
+ }
59
+ }
60
+
33
61
/// The Rollup Driver entrypoint.
34
62
#[ derive( Debug ) ]
35
- pub struct Driver < DC : DriverContext > {
63
+ pub struct Driver < DC , CP , BP , L2CP > {
36
64
/// The rollup configuration
37
65
cfg : Arc < RollupConfig > ,
38
66
/// The context of the node
39
67
ctx : DC ,
68
+ /// The L1 chain provider
69
+ chain_provider : CP ,
70
+ /// The L1 blob provider
71
+ blob_provider : BP ,
72
+ /// The L2 chain provider
73
+ l2_chain_provider : L2CP ,
40
74
}
41
75
42
- #[ allow( unused) ]
43
- impl < DC : DriverContext > Driver < DC > {
44
- /// Creates a new instance of the Hera Execution Extension.
45
- pub async fn new ( ctx : DC , args : HeraArgsExt , cfg : Arc < RollupConfig > ) -> Self {
46
- Self { ctx, cfg }
76
+ impl < N > Driver < ExExContext < N > , InMemoryChainProvider , LayeredBlobProvider , AlloyL2ChainProvider >
77
+ where
78
+ N : FullNodeComponents ,
79
+ {
80
+ /// Create a new Hera Execution Extension Driver
81
+ pub fn exex ( ctx : ExExContext < N > , args : HeraArgsExt , cfg : Arc < RollupConfig > ) -> Self {
82
+ let cp = InMemoryChainProvider :: with_capacity ( 1024 ) ;
83
+ let bp = LayeredBlobProvider :: new ( args. l1_beacon_client_url , args. l1_blob_archiver_url ) ;
84
+ let l2_cp = AlloyL2ChainProvider :: new_http ( args. l2_rpc_url , cfg. clone ( ) ) ;
85
+
86
+ Self { cfg, ctx, chain_provider : cp, blob_provider : bp, l2_chain_provider : l2_cp }
47
87
}
88
+ }
89
+
90
+ impl Driver < StandaloneContext , AlloyChainProvider , DurableBlobProvider , AlloyL2ChainProvider > {
91
+ /// Create a new standalone Hera Driver
92
+ pub fn standalone ( ctx : StandaloneContext , args : HeraArgsExt , cfg : Arc < RollupConfig > ) -> Self {
93
+ let cp = AlloyChainProvider :: new_http ( args. l1_rpc_url ) ;
94
+ let l2_cp = AlloyL2ChainProvider :: new_http ( args. l2_rpc_url , cfg. clone ( ) ) ;
95
+ let bp = OnlineBlobProviderBuilder :: new ( )
96
+ . with_primary ( args. l1_beacon_client_url . to_string ( ) )
97
+ . with_fallback ( args. l1_blob_archiver_url . map ( |url| url. to_string ( ) ) )
98
+ . build ( ) ;
48
99
100
+ Self { cfg, ctx, chain_provider : cp, blob_provider : bp, l2_chain_provider : l2_cp }
101
+ }
102
+ }
103
+
104
+ impl < DC , CP , BP , L2CP > Driver < DC , CP , BP , L2CP >
105
+ where
106
+ DC : DriverContext ,
107
+ CP : ChainProvider + Clone + Send + Sync + Debug + ' static ,
108
+ BP : BlobProvider + Clone + Send + Sync + Debug + ' static ,
109
+ L2CP : L2ChainProvider + Clone + Send + Sync + Debug + ' static ,
110
+ {
49
111
/// Wait for the L2 genesis L1 block (aka "origin block") to be available in the L1 chain.
50
112
async fn wait_for_l2_genesis_l1_block ( & mut self ) -> Result < ( ) > {
51
113
loop {
@@ -69,12 +131,30 @@ impl<DC: DriverContext> Driver<DC> {
69
131
}
70
132
}
71
133
134
+ /// Initialize the rollup pipeline from the driver's components.
135
+ fn init_pipeline ( & mut self ) -> RollupPipeline < CP , BP , L2CP > {
136
+ new_rollup_pipeline (
137
+ self . cfg . clone ( ) ,
138
+ self . chain_provider . clone ( ) ,
139
+ self . blob_provider . clone ( ) ,
140
+ self . l2_chain_provider . clone ( ) ,
141
+ // TODO: use a dynamic "tip" block instead of genesis
142
+ BlockInfo {
143
+ hash : self . cfg . genesis . l2 . hash ,
144
+ number : self . cfg . genesis . l2 . number ,
145
+ ..Default :: default ( )
146
+ } ,
147
+ )
148
+ }
149
+
72
150
/// Starts the Hera Execution Extension loop.
73
151
pub async fn start ( mut self ) -> Result < ( ) > {
74
152
// Step 1: Wait for the L2 origin block to be available
75
153
self . wait_for_l2_genesis_l1_block ( ) . await ?;
76
154
info ! ( "Chain synced to rollup genesis" ) ;
77
155
78
- todo ! ( "init pipeline and start processing events" ) ;
156
+ let _pipeline = self . init_pipeline ( ) ;
157
+
158
+ todo ! ( "start processing events" ) ;
79
159
}
80
160
}
0 commit comments