1
+ use anyhow:: Error ;
1
2
use slog:: { debug, info, Logger } ;
2
3
use std:: { fmt:: Display , ops:: Deref , sync:: Arc , time:: Duration } ;
3
4
use tokio:: { sync:: Mutex , time:: sleep} ;
@@ -8,8 +9,11 @@ use mithril_common::{
8
9
logging:: LoggerExtensions ,
9
10
} ;
10
11
11
- use crate :: entities:: { BeaconToSign , SignerEpochSettings } ;
12
12
use crate :: MetricsService ;
13
+ use crate :: {
14
+ entities:: { BeaconToSign , SignerEpochSettings } ,
15
+ services:: AggregatorClientError ,
16
+ } ;
13
17
14
18
use super :: { Runner , RuntimeError } ;
15
19
@@ -314,19 +318,36 @@ impl StateMachine {
314
318
nested_error : Some ( e) ,
315
319
} ) ?;
316
320
317
- self . runner . register_signer_to_aggregator ( )
318
- . await . map_err ( |e| {
319
- if e. downcast_ref :: < ProtocolInitializerError > ( ) . is_some ( ) {
320
- RuntimeError :: Critical { message : format ! ( "Could not register to aggregator in 'unregistered → registered' phase for epoch {:?}." , epoch) , nested_error : Some ( e) }
321
+ fn handle_registration_result (
322
+ register_result : Result < ( ) , Error > ,
323
+ epoch : Epoch ,
324
+ ) -> Result < Option < SignerState > , RuntimeError > {
325
+ if let Err ( e) = register_result {
326
+ if let Some ( AggregatorClientError :: RegistrationRoundNotYetOpened ( _) ) =
327
+ e. downcast_ref :: < AggregatorClientError > ( )
328
+ {
329
+ Ok ( Some ( SignerState :: Unregistered { epoch } ) )
330
+ } else if e. downcast_ref :: < ProtocolInitializerError > ( ) . is_some ( ) {
331
+ Err ( RuntimeError :: Critical { message : format ! ( "Could not register to aggregator in 'unregistered → registered' phase for epoch {:?}." , epoch) , nested_error : Some ( e) } )
332
+ } else {
333
+ Err ( RuntimeError :: KeepState { message : format ! ( "Could not register to aggregator in 'unregistered → registered' phase for epoch {:?}." , epoch) , nested_error : Some ( e) } )
334
+ }
321
335
} else {
322
- RuntimeError :: KeepState { message : format ! ( "Could not register to aggregator in 'unregistered → registered' phase for epoch {:?}." , epoch ) , nested_error : Some ( e ) }
336
+ Ok ( None )
323
337
}
324
- } ) ?;
338
+ }
339
+
340
+ let register_result = self . runner . register_signer_to_aggregator ( ) . await ;
341
+ let next_state_found = handle_registration_result ( register_result, epoch) ?;
325
342
326
343
self . metrics_service
327
344
. get_signer_registration_success_since_startup_counter ( )
328
345
. increment ( ) ;
329
346
347
+ if let Some ( state) = next_state_found {
348
+ return Ok ( state) ;
349
+ }
350
+
330
351
self . metrics_service
331
352
. get_signer_registration_success_last_epoch_gauge ( )
332
353
. record ( epoch) ;
@@ -452,13 +473,15 @@ impl StateMachine {
452
473
453
474
#[ cfg( test) ]
454
475
mod tests {
476
+ use anyhow:: anyhow;
455
477
use chrono:: DateTime ;
456
478
use mockall:: predicate;
457
479
458
480
use mithril_common:: entities:: { ChainPoint , Epoch , ProtocolMessage , SignedEntityType } ;
459
481
use mithril_common:: test_utils:: fake_data;
460
482
461
483
use crate :: runtime:: runner:: MockSignerRunner ;
484
+ use crate :: services:: AggregatorClientError ;
462
485
use crate :: test_tools:: TestLogger ;
463
486
464
487
use super :: * ;
@@ -645,6 +668,88 @@ mod tests {
645
668
} ,
646
669
state_machine. get_state( ) . await
647
670
) ;
671
+
672
+ let metrics_service = state_machine. metrics_service ;
673
+ let success_since_startup =
674
+ metrics_service. get_runtime_cycle_success_since_startup_counter ( ) ;
675
+ assert_eq ! ( 1 , success_since_startup. get( ) ) ;
676
+ }
677
+
678
+ #[ tokio:: test]
679
+ async fn unregistered_to_ready_to_sign_counter ( ) {
680
+ let mut runner = MockSignerRunner :: new ( ) ;
681
+
682
+ runner
683
+ . expect_get_epoch_settings ( )
684
+ . once ( )
685
+ . returning ( || Ok ( Some ( SignerEpochSettings :: dummy ( ) ) ) ) ;
686
+
687
+ runner
688
+ . expect_inform_epoch_settings ( )
689
+ . with ( predicate:: eq ( SignerEpochSettings :: dummy ( ) ) )
690
+ . once ( )
691
+ . returning ( |_| Ok ( ( ) ) ) ;
692
+
693
+ runner
694
+ . expect_get_current_time_point ( )
695
+ . times ( 2 )
696
+ . returning ( || Ok ( TimePoint :: dummy ( ) ) ) ;
697
+ runner
698
+ . expect_update_stake_distribution ( )
699
+ . once ( )
700
+ . returning ( |_| Ok ( ( ) ) ) ;
701
+ runner
702
+ . expect_register_signer_to_aggregator ( )
703
+ . once ( )
704
+ . returning ( || {
705
+ Err ( AggregatorClientError :: RegistrationRoundNotYetOpened (
706
+ anyhow ! ( "Not yet opened" ) ,
707
+ ) ) ?
708
+ } ) ;
709
+
710
+ runner. expect_upkeep ( ) . never ( ) ;
711
+ runner. expect_can_sign_current_epoch ( ) . never ( ) ;
712
+
713
+ let state_machine = init_state_machine (
714
+ SignerState :: Unregistered {
715
+ epoch : TimePoint :: dummy ( ) . epoch ,
716
+ } ,
717
+ runner,
718
+ ) ;
719
+
720
+ state_machine
721
+ . cycle ( )
722
+ . await
723
+ . expect ( "Cycling the state machine should not fail" ) ;
724
+
725
+ assert_eq ! (
726
+ SignerState :: Unregistered {
727
+ epoch: TimePoint :: dummy( ) . epoch,
728
+ } ,
729
+ state_machine. get_state( ) . await
730
+ ) ;
731
+
732
+ let metrics_service = state_machine. metrics_service ;
733
+ assert_eq ! (
734
+ 1 ,
735
+ metrics_service
736
+ . get_signer_registration_success_since_startup_counter( )
737
+ . get( )
738
+ ) ;
739
+
740
+ assert_eq ! (
741
+ 0 as f64 ,
742
+ metrics_service
743
+ . get_signer_registration_success_last_epoch_gauge( )
744
+ . get( )
745
+ ) ;
746
+
747
+ assert_eq ! (
748
+ 1 ,
749
+ metrics_service
750
+ . get_runtime_cycle_total_since_startup_counter( )
751
+ . get( )
752
+ ) ;
648
753
}
649
754
650
755
#[ tokio:: test]
0 commit comments