@@ -136,34 +136,20 @@ impl AggregatorRuntime {
136
136
AggregatorState :: Idle ( state) => {
137
137
let chain_beacon = self . runner . get_beacon_from_chain ( ) . await ?;
138
138
139
- if state. current_beacon . is_none ( )
140
- || chain_beacon
141
- . compare_to_older ( state. current_beacon . as_ref ( ) . unwrap ( ) )
142
- . map_err ( |e|
143
- RuntimeError :: keep_state (
144
- & format ! ( "Beacon in the state ({:?}) is newer than the beacon read on chain '{:?})" , state. current_beacon, chain_beacon) , Some ( e. into ( ) ) ) ) ?
145
- . is_new_beacon ( )
146
- {
147
- info ! (
148
- "→ new Beacon settings found, trying to transition to READY" ;
149
- "new_beacon" => ?chain_beacon
150
- ) ;
139
+ info ! (
140
+ "→ new Beacon settings found, trying to transition to READY" ;
141
+ "new_beacon" => ?chain_beacon
142
+ ) ;
151
143
152
- if self
153
- . try_transition_from_idle_to_ready (
154
- state. current_beacon ,
155
- chain_beacon. clone ( ) ,
156
- )
157
- . await ?
158
- {
159
- self . state = AggregatorState :: Ready ( ReadyState {
160
- current_beacon : chain_beacon,
161
- } ) ;
162
- } else {
163
- info ! ( " ⋅ could not transition from IDLE to READY" ) ;
164
- }
144
+ if self
145
+ . try_transition_from_idle_to_ready ( state. current_beacon , chain_beacon. clone ( ) )
146
+ . await ?
147
+ {
148
+ self . state = AggregatorState :: Ready ( ReadyState {
149
+ current_beacon : chain_beacon,
150
+ } ) ;
165
151
} else {
166
- info ! ( " ⋅ Beacon didn't change, waiting…" )
152
+ info ! ( " ⋅ could not transition from IDLE to READY" ) ;
167
153
}
168
154
}
169
155
AggregatorState :: Ready ( state) => {
@@ -189,7 +175,7 @@ impl AggregatorRuntime {
189
175
// transition READY > SIGNING
190
176
info ! ( "→ transitioning to SIGNING" ) ;
191
177
let new_state = self
192
- . transition_from_ready_to_signing ( state . current_beacon , open_message)
178
+ . transition_from_ready_to_signing ( chain_beacon , open_message)
193
179
. await ?;
194
180
self . state = AggregatorState :: Signing ( new_state) ;
195
181
} else {
@@ -205,25 +191,37 @@ impl AggregatorRuntime {
205
191
}
206
192
AggregatorState :: Signing ( state) => {
207
193
let chain_beacon: Beacon = self . runner . get_beacon_from_chain ( ) . await ?;
208
-
209
- if chain_beacon
210
- . compare_to_older ( & state. current_beacon )
211
- . map_err ( |e|
212
- RuntimeError :: keep_state (
213
- & format ! ( "Beacon in the state ({:?}) is newer than the beacon read on chain '{:?})" , state. current_beacon, chain_beacon) , Some ( e. into ( ) ) ) ) ?
214
- . is_new_beacon ( )
194
+ let has_newer_open_message = if let Some ( open_message_new) = self
195
+ . runner
196
+ . get_current_non_certified_open_message_for_signed_entity_type (
197
+ & state. open_message . signed_entity_type ,
198
+ )
199
+ . await ?
215
200
{
216
- info ! ( "→ Beacon changed, transitioning to IDLE" ; "new_beacon" => ?chain_beacon) ;
201
+ open_message_new. signed_entity_type != state. open_message . signed_entity_type
202
+ } else {
203
+ false
204
+ } ;
205
+
206
+ if state. current_beacon . epoch < chain_beacon. epoch {
207
+ // SIGNING > IDLE
208
+ info ! ( "→ Epoch changed, transitioning to IDLE" ) ;
209
+ let new_state = self . transition_from_signing_to_idle ( state) . await ?;
210
+ self . state = AggregatorState :: Idle ( new_state) ;
211
+ } else if has_newer_open_message {
212
+ // SIGNING > READY
213
+ info ! ( "→ Open message changed, transitioning to READY" ) ;
217
214
let new_state = self
218
- . transition_from_signing_to_idle_new_beacon ( state)
215
+ . transition_from_signing_to_ready_new_open_message ( state)
219
216
. await ?;
220
- self . state = AggregatorState :: Idle ( new_state) ;
217
+ self . state = AggregatorState :: Ready ( new_state) ;
221
218
} else {
219
+ // SIGNING > READY
222
220
let new_state = self
223
- . transition_from_signing_to_idle_multisignature ( state)
224
- . await ?;
225
- info ! ( "→ a multi-signature have been created, build a snapshot & a certificate and transitioning back to IDLE " ) ;
226
- self . state = AggregatorState :: Idle ( new_state) ;
221
+ . transition_from_signing_to_ready_multisignature ( state)
222
+ . await ?;
223
+ info ! ( "→ a multi-signature have been created, build a snapshot & a certificate and transitioning back to READY " ) ;
224
+ self . state = AggregatorState :: Ready ( new_state) ;
227
225
}
228
226
}
229
227
}
@@ -267,13 +265,13 @@ impl AggregatorRuntime {
267
265
Ok ( is_chain_valid)
268
266
}
269
267
270
- /// Perform a transition from `SIGNING` state to `IDLE ` state when a new
268
+ /// Perform a transition from `SIGNING` state to `READY ` state when a new
271
269
/// multi-signature is issued.
272
- async fn transition_from_signing_to_idle_multisignature (
270
+ async fn transition_from_signing_to_ready_multisignature (
273
271
& self ,
274
272
state : SigningState ,
275
- ) -> Result < IdleState , RuntimeError > {
276
- trace ! ( "launching transition from SIGNING to IDLE state" ) ;
273
+ ) -> Result < ReadyState , RuntimeError > {
274
+ trace ! ( "launching transition from SIGNING to READY state" ) ;
277
275
let certificate = self
278
276
. runner
279
277
. create_certificate ( & state. open_message . signed_entity_type )
@@ -288,14 +286,14 @@ impl AggregatorRuntime {
288
286
. create_artifact ( & state. open_message . signed_entity_type , & certificate)
289
287
. await ?;
290
288
291
- Ok ( IdleState {
292
- current_beacon : Some ( state. current_beacon ) ,
289
+ Ok ( ReadyState {
290
+ current_beacon : state. current_beacon ,
293
291
} )
294
292
}
295
293
296
294
/// Perform a transition from `SIGNING` state to `IDLE` state when a new
297
- /// beacon is detected.
298
- async fn transition_from_signing_to_idle_new_beacon (
295
+ /// epoch is detected.
296
+ async fn transition_from_signing_to_idle (
299
297
& self ,
300
298
state : SigningState ,
301
299
) -> Result < IdleState , RuntimeError > {
@@ -307,6 +305,20 @@ impl AggregatorRuntime {
307
305
} )
308
306
}
309
307
308
+ /// Perform a transition from `SIGNING` state to `READY` state when a new
309
+ /// open message is detected.
310
+ async fn transition_from_signing_to_ready_new_open_message (
311
+ & self ,
312
+ state : SigningState ,
313
+ ) -> Result < ReadyState , RuntimeError > {
314
+ trace ! ( "launching transition from SIGNING to READY state" ) ;
315
+ self . runner . drop_pending_certificate ( ) . await ?;
316
+
317
+ Ok ( ReadyState {
318
+ current_beacon : state. current_beacon ,
319
+ } )
320
+ }
321
+
310
322
/// Perform a transition from `READY` state to `SIGNING` state when a new
311
323
/// beacon is detected.
312
324
async fn transition_from_ready_to_signing (
@@ -344,6 +356,7 @@ mod tests {
344
356
use super :: super :: runner:: MockAggregatorRunner ;
345
357
use super :: * ;
346
358
359
+ use mithril_common:: entities:: { Epoch , SignedEntityType } ;
347
360
use mithril_common:: era:: UnsupportedEraError ;
348
361
use mithril_common:: test_utils:: fake_data;
349
362
use mockall:: predicate;
@@ -357,25 +370,6 @@ mod tests {
357
370
. unwrap ( )
358
371
}
359
372
360
- #[ tokio:: test]
361
- pub async fn idle_check_no_new_beacon_with_current_beacon ( ) {
362
- let mut runner = MockAggregatorRunner :: new ( ) ;
363
- runner
364
- . expect_get_beacon_from_chain ( )
365
- . once ( )
366
- . returning ( || Ok ( fake_data:: beacon ( ) ) ) ;
367
- let mut runtime = init_runtime (
368
- Some ( AggregatorState :: Idle ( IdleState {
369
- current_beacon : Some ( fake_data:: beacon ( ) ) ,
370
- } ) ) ,
371
- runner,
372
- )
373
- . await ;
374
- runtime. cycle ( ) . await . unwrap ( ) ;
375
-
376
- assert_eq ! ( "idle" . to_string( ) , runtime. get_state( ) ) ;
377
- }
378
-
379
373
#[ tokio:: test]
380
374
pub async fn idle_check_certificate_chain_is_not_valid ( ) {
381
375
let mut runner = MockAggregatorRunner :: new ( ) ;
@@ -593,32 +587,37 @@ mod tests {
593
587
}
594
588
595
589
#[ tokio:: test]
596
- async fn signing_changing_beacon_to_idle ( ) {
590
+ async fn signing_changing_open_message_to_ready ( ) {
597
591
let mut runner = MockAggregatorRunner :: new ( ) ;
598
592
runner
599
593
. expect_get_beacon_from_chain ( )
600
594
. once ( )
601
595
. returning ( || Ok ( fake_data:: beacon ( ) ) ) ;
596
+ runner
597
+ . expect_get_current_non_certified_open_message_for_signed_entity_type ( )
598
+ . once ( )
599
+ . returning ( |_| {
600
+ Ok ( Some ( OpenMessage {
601
+ signed_entity_type : SignedEntityType :: MithrilStakeDistribution ( Epoch ( 1 ) ) ,
602
+ ..OpenMessage :: dummy ( )
603
+ } ) )
604
+ } ) ;
602
605
runner
603
606
. expect_drop_pending_certificate ( )
604
607
. once ( )
605
608
. returning ( || Ok ( Some ( fake_data:: certificate_pending ( ) ) ) ) ;
606
609
607
610
let state = SigningState {
608
- // this current beacon must be outdated so the state machine will
609
- // return to idle state
610
- current_beacon : {
611
- let mut beacon = fake_data:: beacon ( ) ;
612
- beacon. immutable_file_number -= 1 ;
613
-
614
- beacon
611
+ current_beacon : fake_data:: beacon ( ) ,
612
+ open_message : OpenMessage {
613
+ signed_entity_type : SignedEntityType :: MithrilStakeDistribution ( Epoch ( 2 ) ) ,
614
+ ..OpenMessage :: dummy ( )
615
615
} ,
616
- open_message : OpenMessage :: dummy ( ) ,
617
616
} ;
618
617
let mut runtime = init_runtime ( Some ( AggregatorState :: Signing ( state) ) , runner) . await ;
619
618
runtime. cycle ( ) . await . unwrap ( ) ;
620
619
621
- assert_eq ! ( "idle " . to_string( ) , runtime. get_state( ) ) ;
620
+ assert_eq ! ( "ready " . to_string( ) , runtime. get_state( ) ) ;
622
621
}
623
622
624
623
#[ tokio:: test]
@@ -628,6 +627,10 @@ mod tests {
628
627
. expect_get_beacon_from_chain ( )
629
628
. once ( )
630
629
. returning ( || Ok ( fake_data:: beacon ( ) ) ) ;
630
+ runner
631
+ . expect_get_current_non_certified_open_message_for_signed_entity_type ( )
632
+ . once ( )
633
+ . returning ( |_| Ok ( Some ( OpenMessage :: dummy ( ) ) ) ) ;
631
634
runner
632
635
. expect_create_certificate ( )
633
636
. once ( )
@@ -652,6 +655,10 @@ mod tests {
652
655
. expect_get_beacon_from_chain ( )
653
656
. once ( )
654
657
. returning ( || Ok ( fake_data:: beacon ( ) ) ) ;
658
+ runner
659
+ . expect_get_current_non_certified_open_message_for_signed_entity_type ( )
660
+ . once ( )
661
+ . returning ( |_| Ok ( Some ( OpenMessage :: dummy ( ) ) ) ) ;
655
662
runner
656
663
. expect_create_certificate ( )
657
664
. return_once ( move |_| Ok ( Some ( fake_data:: certificate ( "whatever" . to_string ( ) ) ) ) ) ;
@@ -671,7 +678,7 @@ mod tests {
671
678
let mut runtime = init_runtime ( Some ( AggregatorState :: Signing ( state) ) , runner) . await ;
672
679
runtime. cycle ( ) . await . unwrap ( ) ;
673
680
674
- assert_eq ! ( "idle " . to_string( ) , runtime. get_state( ) ) ;
681
+ assert_eq ! ( "ready " . to_string( ) , runtime. get_state( ) ) ;
675
682
}
676
683
677
684
#[ tokio:: test]
0 commit comments