@@ -9,14 +9,15 @@ use init4_bin_base::{
9
9
} ;
10
10
use signet_sim:: { BlockBuild , BuiltBlock , SimCache } ;
11
11
use signet_types:: constants:: SignetSystemConstants ;
12
- use std:: time:: { Duration , Instant } ;
12
+ use std:: time:: { Duration , Instant , SystemTime , UNIX_EPOCH } ;
13
13
use tokio:: {
14
14
sync:: {
15
15
mpsc:: { self } ,
16
16
watch,
17
17
} ,
18
18
task:: JoinHandle ,
19
19
} ;
20
+ use tracing:: trace;
20
21
use trevm:: revm:: {
21
22
context:: BlockEnv ,
22
23
database:: { AlloyDB , WrapDatabaseAsync } ,
@@ -34,18 +35,27 @@ pub struct Simulator {
34
35
pub config : BuilderConfig ,
35
36
/// A provider that cannot sign transactions, used for interacting with the rollup.
36
37
pub ru_provider : RuProvider ,
37
-
38
38
/// The block configuration environment on which to simulate
39
39
pub block_env : watch:: Receiver < Option < BlockEnv > > ,
40
40
}
41
41
42
+ /// SimResult bundles a BuiltBlock to the BlockEnv it was simulated against.
43
+ #[ derive( Debug , Clone ) ]
44
+ pub struct SimResult {
45
+ /// The block built with the successfully simulated transactions
46
+ pub block : BuiltBlock ,
47
+ /// The block environment the transactions were simulated against.
48
+ pub env : BlockEnv ,
49
+ }
50
+
42
51
impl Simulator {
43
52
/// Creates a new `Simulator` instance.
44
53
///
45
54
/// # Arguments
46
55
///
47
56
/// - `config`: The configuration for the builder.
48
57
/// - `ru_provider`: A provider for interacting with the rollup.
58
+ /// - `block_env`: A receiver for the block environment to simulate against.
49
59
///
50
60
/// # Returns
51
61
///
@@ -70,6 +80,7 @@ impl Simulator {
70
80
/// - `constants`: The system constants for the rollup.
71
81
/// - `sim_items`: The simulation cache containing transactions and bundles.
72
82
/// - `finish_by`: The deadline by which the block must be built.
83
+ /// - `block_env`: The block environment to simulate against.
73
84
///
74
85
/// # Returns
75
86
///
@@ -79,22 +90,34 @@ impl Simulator {
79
90
constants : SignetSystemConstants ,
80
91
sim_items : SimCache ,
81
92
finish_by : Instant ,
82
- block : BlockEnv ,
93
+ block_env : BlockEnv ,
83
94
) -> eyre:: Result < BuiltBlock > {
95
+ debug ! (
96
+ block_number = block_env. number,
97
+ deadline = ?self . instant_to_timestamp( finish_by) ,
98
+ tx_count= sim_items. len( ) ,
99
+ "starting block build" ,
100
+ ) ;
101
+
84
102
let db = self . create_db ( ) . await . unwrap ( ) ;
103
+
85
104
let block_build: BlockBuild < _ , NoOpInspector > = BlockBuild :: new (
86
105
db,
87
106
constants,
88
107
self . config . cfg_env ( ) ,
89
- block ,
108
+ block_env ,
90
109
finish_by,
91
110
self . config . concurrency_limit ,
92
111
sim_items,
93
112
self . config . rollup_block_gas_limit ,
94
113
) ;
95
114
96
115
let built_block = block_build. build ( ) . await ;
97
- debug ! ( block_number = ?built_block. block_number( ) , "finished building block" ) ;
116
+ debug ! (
117
+ tx_count = built_block. tx_count( ) ,
118
+ block_number = ?built_block. block_number( ) ,
119
+ "block simulation completed" ,
120
+ ) ;
98
121
99
122
Ok ( built_block)
100
123
}
@@ -115,7 +138,7 @@ impl Simulator {
115
138
self ,
116
139
constants : SignetSystemConstants ,
117
140
cache : SimCache ,
118
- submit_sender : mpsc:: UnboundedSender < BuiltBlock > ,
141
+ submit_sender : mpsc:: UnboundedSender < SimResult > ,
119
142
) -> JoinHandle < ( ) > {
120
143
debug ! ( "starting simulator task" ) ;
121
144
@@ -140,26 +163,23 @@ impl Simulator {
140
163
mut self ,
141
164
constants : SignetSystemConstants ,
142
165
cache : SimCache ,
143
- submit_sender : mpsc:: UnboundedSender < BuiltBlock > ,
166
+ submit_sender : mpsc:: UnboundedSender < SimResult > ,
144
167
) {
145
168
loop {
146
- let sim_cache = cache. clone ( ) ;
147
- let finish_by = self . calculate_deadline ( ) ;
148
-
149
169
// Wait for the block environment to be set
150
170
if self . block_env . changed ( ) . await . is_err ( ) {
151
171
error ! ( "block_env channel closed" ) ;
152
172
return ;
153
173
}
154
174
155
- // If no env, skip this run
156
175
let Some ( block_env) = self . block_env . borrow_and_update ( ) . clone ( ) else { return } ;
157
- debug ! ( block_env = ?block_env, "building on block env" ) ;
158
176
159
- match self . handle_build ( constants, sim_cache, finish_by, block_env) . await {
177
+ let finish_by = self . calculate_deadline ( ) ;
178
+ let sim_cache = cache. clone ( ) ;
179
+ match self . handle_build ( constants, sim_cache, finish_by, block_env. clone ( ) ) . await {
160
180
Ok ( block) => {
161
- debug ! ( block = ?block, "built block" ) ;
162
- let _ = submit_sender. send ( block) ;
181
+ debug ! ( block = ?block. block_number ( ) , tx_count = block . transactions ( ) . len ( ) , "built block" ) ;
182
+ let _ = submit_sender. send ( SimResult { block, env : block_env } ) ;
163
183
}
164
184
Err ( e) => {
165
185
error ! ( err = %e, "failed to build block" ) ;
@@ -178,17 +198,25 @@ impl Simulator {
178
198
pub fn calculate_deadline ( & self ) -> Instant {
179
199
// Get the current timepoint within the slot.
180
200
let timepoint = self . slot_calculator ( ) . current_timepoint_within_slot ( ) ;
201
+ trace ! ( timepoint, "current timepoint within slot" ) ;
181
202
182
203
// We have the timepoint in seconds into the slot. To find out what's
183
204
// remaining, we need to subtract it from the slot duration
184
205
let remaining = self . slot_calculator ( ) . slot_duration ( ) - timepoint;
206
+ trace ! ( remaining, "time remaining in slot" ) ;
185
207
186
208
// We add a 1500 ms buffer to account for sequencer stopping signing.
187
-
188
- let candidate =
209
+ let deadline =
189
210
Instant :: now ( ) + Duration :: from_secs ( remaining) - Duration :: from_millis ( 1500 ) ;
211
+ trace ! ( deadline = ?self . instant_to_timestamp( deadline) , "calculated deadline for block simulation" ) ;
212
+
213
+ let buffered_deadline = deadline. max ( Instant :: now ( ) ) ;
214
+ trace ! ( ?buffered_deadline, "final deadline for block simulation" ) ;
190
215
191
- candidate. max ( Instant :: now ( ) )
216
+ let timestamp = self . instant_to_timestamp ( buffered_deadline) ;
217
+ trace ! ( ?timestamp, "deadline converted to timestamp" ) ;
218
+
219
+ buffered_deadline
192
220
}
193
221
194
222
/// Creates an `AlloyDB` instance from the rollup provider.
@@ -217,4 +245,23 @@ impl Simulator {
217
245
let wrapped_db: AlloyDatabaseProvider = WrapDatabaseAsync :: new ( alloy_db) . unwrap ( ) ;
218
246
Some ( wrapped_db)
219
247
}
248
+
249
+ /// Converts an `Instant` to a UNIX timestamp in seconds and milliseconds.
250
+ pub fn instant_to_timestamp ( & self , instant : Instant ) -> ( u64 , u128 ) {
251
+ let now_instant = Instant :: now ( ) ;
252
+ let now_system = SystemTime :: now ( ) ;
253
+
254
+ let duration_from_now = now_instant. duration_since ( instant) ;
255
+
256
+ // Subtract that duration from the system time
257
+ let target_system_time = now_system - duration_from_now;
258
+
259
+ let duration_since_epoch =
260
+ target_system_time. duration_since ( UNIX_EPOCH ) . expect ( "Time went backwards" ) ;
261
+
262
+ let seconds = duration_since_epoch. as_secs ( ) ;
263
+ let milliseconds = duration_since_epoch. as_millis ( ) ;
264
+
265
+ ( seconds, milliseconds)
266
+ }
220
267
}
0 commit comments