Skip to content

Commit d601fe9

Browse files
committed
fix: reuse the epoch of previous state when transition from ReadyToSign to ReadyToSign
1 parent baf5431 commit d601fe9

File tree

1 file changed

+58
-38
lines changed

1 file changed

+58
-38
lines changed

mithril-signer/src/runtime/state_machine.rs

Lines changed: 58 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ pub enum SignerState {
2525

2626
/// `ReadyToSign` state. The signer is registered and ready to sign new messages.
2727
ReadyToSign {
28-
/// Time point when signer transited to the state.
29-
time_point: TimePoint,
30-
28+
/// Epoch when signer transited to the state.
29+
epoch: Epoch,
3130
/// Last signed entity type that the signer signed since beginning of this state.
3231
last_signed_entity_type: Option<SignedEntityType>,
3332
},
@@ -55,7 +54,7 @@ impl SignerState {
5554
matches!(
5655
*self,
5756
SignerState::ReadyToSign {
58-
time_point: _,
57+
epoch: _,
5958
last_signed_entity_type: _
6059
}
6160
)
@@ -76,13 +75,10 @@ impl Display for SignerState {
7675
write!(f, "RegisteredNotAbleToSign - {epoch}")
7776
}
7877
Self::ReadyToSign {
79-
time_point,
78+
epoch,
8079
last_signed_entity_type,
8180
} => {
82-
write!(
83-
f,
84-
"ReadyToSign - {time_point} - {last_signed_entity_type:?}"
85-
)
81+
write!(f, "ReadyToSign - {epoch} - {last_signed_entity_type:?}")
8682
}
8783
}
8884
}
@@ -173,7 +169,9 @@ impl StateMachine {
173169
info!("new Epoch found");
174170
info!(" ⋅ transiting to REGISTERED");
175171
*state = self
176-
.transition_from_unregistered_to_registered_state(epoch_settings)
172+
.transition_from_unregistered_to_one_of_registered_states(
173+
epoch_settings,
174+
)
177175
.await?;
178176
} else {
179177
info!(
@@ -198,7 +196,7 @@ impl StateMachine {
198196
}
199197

200198
SignerState::ReadyToSign {
201-
time_point,
199+
epoch,
202200
last_signed_entity_type,
203201
} => {
204202
fn is_same_signed_entity_type(
@@ -209,7 +207,7 @@ impl StateMachine {
209207
== last_signed_entity_type.as_ref()
210208
}
211209

212-
if let Some(new_epoch) = self.has_epoch_changed(time_point.epoch).await? {
210+
if let Some(new_epoch) = self.has_epoch_changed(*epoch).await? {
213211
info!("→ Epoch has changed, transiting to UNREGISTERED");
214212
*state = self
215213
.transition_from_ready_to_sign_to_unregistered(new_epoch)
@@ -244,6 +242,7 @@ impl StateMachine {
244242
info!(" → we can sign this certificate, transiting to READY_TO_SIGN");
245243
*state = self
246244
.transition_from_ready_to_sign_to_ready_to_sign(
245+
*epoch,
247246
&pending_certificate,
248247
)
249248
.await?;
@@ -306,7 +305,7 @@ impl StateMachine {
306305
}
307306

308307
/// Launch the transition process from the `Unregistered` to `ReadyToSign` or `RegisteredNotAbleToSign` state.
309-
async fn transition_from_unregistered_to_registered_state(
308+
async fn transition_from_unregistered_to_one_of_registered_states(
310309
&self,
311310
epoch_settings: EpochSettings,
312311
) -> Result<SignerState, RuntimeError> {
@@ -365,7 +364,7 @@ impl StateMachine {
365364
message: "Failed to check if signer can sign in the current epoch in 'unregistered → ?' phase".to_string(),
366365
nested_error: Some(e),
367366
})? {
368-
true => Ok(SignerState::ReadyToSign { time_point, last_signed_entity_type: None }),
367+
true => Ok(SignerState::ReadyToSign { epoch, last_signed_entity_type: None }),
369368
false => Ok(SignerState::RegisteredNotAbleToSign { epoch }),
370369
}
371370
}
@@ -393,6 +392,7 @@ impl StateMachine {
393392
/// Launch the transition process from the `ReadyToSign` to the `ReadyToSign` state.
394393
async fn transition_from_ready_to_sign_to_ready_to_sign(
395394
&self,
395+
state_epoch: Epoch,
396396
pending_certificate: &CertificatePending,
397397
) -> Result<SignerState, RuntimeError> {
398398
let current_epoch = pending_certificate.epoch;
@@ -440,9 +440,7 @@ impl StateMachine {
440440
.signature_registration_success_last_epoch_gauge_set(current_epoch);
441441

442442
Ok(SignerState::ReadyToSign {
443-
time_point: self
444-
.get_current_time_point("ready to sign → ready to sign")
445-
.await?,
443+
epoch: state_epoch,
446444
last_signed_entity_type: Some(pending_certificate.to_owned().signed_entity_type),
447445
})
448446
}
@@ -658,12 +656,7 @@ mod tests {
658656
.await
659657
.expect("Cycling the state machine should not fail");
660658

661-
if let SignerState::ReadyToSign {
662-
time_point: _,
663-
last_signed_entity_type: _,
664-
} = state_machine.get_state().await
665-
{
666-
} else {
659+
if !state_machine.get_state().await.is_ready_to_sign() {
667660
panic!(
668661
"state machine did not return a ReadyToSign state but {:?}",
669662
state_machine.get_state().await
@@ -735,7 +728,7 @@ mod tests {
735728

736729
let state_machine = init_state_machine(
737730
SignerState::ReadyToSign {
738-
time_point: TimePoint::new(0, 100, ChainPoint::dummy()),
731+
epoch: Epoch(0),
739732
last_signed_entity_type: None,
740733
},
741734
runner,
@@ -759,7 +752,7 @@ mod tests {
759752
chain_point: ChainPoint::dummy(),
760753
};
761754
let state = SignerState::ReadyToSign {
762-
time_point: time_point.clone(),
755+
epoch: time_point.epoch,
763756
last_signed_entity_type: None,
764757
};
765758

@@ -790,7 +783,7 @@ mod tests {
790783

791784
assert_eq!(
792785
SignerState::ReadyToSign {
793-
time_point,
786+
epoch: time_point.epoch,
794787
last_signed_entity_type: None
795788
},
796789
state_machine.get_state().await,
@@ -808,7 +801,7 @@ mod tests {
808801
};
809802
let certificate_pending_clone = certificate_pending.clone();
810803
let state = SignerState::ReadyToSign {
811-
time_point: time_point.clone(),
804+
epoch: time_point.epoch,
812805
last_signed_entity_type: Some(certificate_pending.signed_entity_type.clone()),
813806
};
814807
let time_point_clone = time_point.clone();
@@ -832,7 +825,7 @@ mod tests {
832825

833826
assert_eq!(
834827
SignerState::ReadyToSign {
835-
time_point,
828+
epoch: time_point.epoch,
836829
last_signed_entity_type: Some(certificate_pending_clone.signed_entity_type)
837830
},
838831
state_machine.get_state().await,
@@ -845,7 +838,7 @@ mod tests {
845838
async fn ready_to_sign_to_ready_to_sign_when_can_sign_the_first_signed_entity_type() {
846839
let time_point = TimePoint::dummy();
847840
let state = SignerState::ReadyToSign {
848-
time_point: time_point.clone(),
841+
epoch: time_point.epoch,
849842
last_signed_entity_type: None,
850843
};
851844
let certificate_pending = CertificatePending {
@@ -864,7 +857,7 @@ mod tests {
864857
async fn ready_to_sign_to_ready_to_sign_when_different_state_than_previous_one() {
865858
let time_point = TimePoint::dummy();
866859
let state = SignerState::ReadyToSign {
867-
time_point: time_point.clone(),
860+
epoch: time_point.epoch,
868861
last_signed_entity_type: Some(SignedEntityType::CardanoStakeDistribution(
869862
time_point.epoch,
870863
)),
@@ -882,24 +875,51 @@ mod tests {
882875
.await
883876
}
884877

878+
#[tokio::test]
879+
async fn ready_to_sign_to_ready_to_sign_when_different_state_than_previous_return_state_with_same_epoch(
880+
) {
881+
let time_point = TimePoint::dummy();
882+
let state = SignerState::ReadyToSign {
883+
epoch: time_point.epoch,
884+
last_signed_entity_type: Some(SignedEntityType::CardanoStakeDistribution(
885+
time_point.epoch,
886+
)),
887+
};
888+
let certificate_pending = CertificatePending {
889+
epoch: time_point.epoch + 10, // Check that the epoch
890+
signed_entity_type: SignedEntityType::MithrilStakeDistribution(time_point.epoch),
891+
..fake_data::certificate_pending()
892+
};
893+
894+
assert_ready_to_sign_to_ready_to_sign_when_different_state_than_previous_one(
895+
state,
896+
certificate_pending,
897+
)
898+
.await
899+
}
900+
885901
async fn assert_ready_to_sign_to_ready_to_sign_when_different_state_than_previous_one(
886-
state: SignerState,
902+
initial_state: SignerState,
887903
certificate_pending: CertificatePending,
888904
) {
889-
let time_point = match state.clone() {
905+
let initial_state_epoch = match initial_state.clone() {
890906
SignerState::ReadyToSign {
891-
time_point,
907+
epoch,
892908
last_signed_entity_type: _,
893-
} => time_point,
909+
} => epoch,
894910
_ => panic!("Invalid state, use only ReadyToSign"),
895911
};
912+
let time_point = TimePoint {
913+
epoch: initial_state_epoch,
914+
..TimePoint::dummy()
915+
};
896916

897917
let certificate_pending_clone = certificate_pending.clone();
898-
let time_point_clone = time_point.clone();
899918
let mut runner = MockSignerRunner::new();
900919
runner
901920
.expect_get_current_time_point()
902-
.returning(move || Ok(time_point_clone.to_owned()));
921+
.once()
922+
.returning(move || Ok(time_point.to_owned()));
903923
runner
904924
.expect_get_pending_certificate()
905925
.once()
@@ -921,15 +941,15 @@ mod tests {
921941
.once()
922942
.returning(move |_| true);
923943

924-
let state_machine = init_state_machine(state, runner);
944+
let state_machine = init_state_machine(initial_state.clone(), runner);
925945
state_machine
926946
.cycle()
927947
.await
928948
.expect("Cycling the state machine should not fail");
929949

930950
assert_eq!(
931951
SignerState::ReadyToSign {
932-
time_point,
952+
epoch: initial_state_epoch,
933953
last_signed_entity_type: Some(certificate_pending_clone.signed_entity_type)
934954
},
935955
state_machine.get_state().await,

0 commit comments

Comments
 (0)