1
- use std:: { fmt, fs:: File , path:: PathBuf , process:: Stdio , time:: Duration } ;
1
+ use std:: {
2
+ fmt,
3
+ fs:: File ,
4
+ path:: PathBuf ,
5
+ process:: Stdio ,
6
+ time:: { Duration , SystemTime } ,
7
+ } ;
2
8
3
- use anyhow:: Context ;
9
+ use anyhow:: { bail , Context } ;
4
10
use async_trait:: async_trait;
11
+ use log:: debug;
5
12
use serde:: Serialize ;
6
13
use tokio:: {
7
14
process:: Command ,
@@ -72,12 +79,12 @@ impl<C: Config> Node<C> {
72
79
let kind = C :: node_kind ( ) ;
73
80
74
81
config. node_config ( ) . map_or ( Ok ( Vec :: new ( ) ) , |node_config| {
75
- let config_path = dir. join ( format ! ( "{}_config.toml" , kind ) ) ;
82
+ let config_path = dir. join ( format ! ( "{kind }_config.toml" ) ) ;
76
83
config_to_file ( node_config, & config_path)
77
- . with_context ( || format ! ( "Error writing {} config to file" , kind ) ) ?;
84
+ . with_context ( || format ! ( "Error writing {kind } config to file" ) ) ?;
78
85
79
86
Ok ( vec ! [
80
- format!( "--{}-config-path" , kind ) ,
87
+ format!( "--{kind }-config-path" ) ,
81
88
config_path. display( ) . to_string( ) ,
82
89
] )
83
90
} )
@@ -97,7 +104,7 @@ impl<C: Config> Node<C> {
97
104
// Handle full node not having any node config
98
105
let node_config_args = Self :: get_node_config_args ( config) ?;
99
106
100
- let rollup_config_path = dir. join ( format ! ( "{}_rollup_config.toml" , kind ) ) ;
107
+ let rollup_config_path = dir. join ( format ! ( "{kind }_rollup_config.toml" ) ) ;
101
108
config_to_file ( & config. rollup_config ( ) , & rollup_config_path) ?;
102
109
103
110
Command :: new ( citrea)
@@ -115,9 +122,33 @@ impl<C: Config> Node<C> {
115
122
. stderr ( Stdio :: from ( stderr_file) )
116
123
. kill_on_drop ( true )
117
124
. spawn ( )
118
- . context ( format ! ( "Failed to spawn {} process" , kind ) )
125
+ . context ( format ! ( "Failed to spawn {kind } process" ) )
119
126
. map ( SpawnOutput :: Child )
120
127
}
128
+
129
+ pub async fn wait_for_l2_height ( & self , num : u64 , timeout : Option < Duration > ) -> Result < ( ) > {
130
+ let start = SystemTime :: now ( ) ;
131
+ let timeout = timeout. unwrap_or ( Duration :: from_secs ( 30 ) ) ; // Default 30 seconds timeout
132
+ loop {
133
+ debug ! ( "Waiting for soft confirmation {}" , num) ;
134
+ let latest_block = self
135
+ . client
136
+ . ledger_get_head_soft_confirmation_height ( )
137
+ . await ?;
138
+
139
+ if latest_block >= num {
140
+ break ;
141
+ }
142
+
143
+ let now = SystemTime :: now ( ) ;
144
+ if start + timeout <= now {
145
+ bail ! ( "Timeout. Latest L2 block is {:?}" , latest_block) ;
146
+ }
147
+
148
+ sleep ( Duration :: from_secs ( 1 ) ) . await ;
149
+ }
150
+ Ok ( ( ) )
151
+ }
121
152
}
122
153
123
154
#[ async_trait]
@@ -200,7 +231,7 @@ where
200
231
async fn start ( & mut self , new_config : Option < Self :: Config > ) -> Result < ( ) > {
201
232
let config = self . config_mut ( ) ;
202
233
if let Some ( new_config) = new_config {
203
- * config = new_config
234
+ * config = new_config;
204
235
}
205
236
* self . spawn_output ( ) = Self :: spawn ( config) ?;
206
237
self . wait_for_ready ( None ) . await
0 commit comments