hotmint_consensus/
state.rs1use hotmint_types::{
2 DoubleCertificate, Epoch, Height, QuorumCertificate, ValidatorId, ValidatorSet, ViewNumber,
3};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum ViewRole {
8 Leader,
9 Replica,
10}
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum ViewStep {
15 Entered,
16 WaitingForStatus,
17 Proposed,
18 WaitingForProposal,
19 Voted,
20 CollectingVotes,
21 Prepared,
22 SentVote2,
23 Done,
24}
25
26pub struct ConsensusState {
28 pub validator_id: ValidatorId,
29 pub validator_set: ValidatorSet,
30 pub current_view: ViewNumber,
31 pub role: ViewRole,
32 pub step: ViewStep,
33 pub locked_qc: Option<QuorumCertificate>,
34 pub highest_double_cert: Option<DoubleCertificate>,
35 pub highest_qc: Option<QuorumCertificate>,
36 pub last_committed_height: Height,
37 pub current_epoch: Epoch,
38}
39
40impl ConsensusState {
41 pub fn new(validator_id: ValidatorId, validator_set: ValidatorSet) -> Self {
42 let current_epoch = Epoch::genesis(validator_set.clone());
43 Self {
44 validator_id,
45 validator_set,
46 current_view: ViewNumber::GENESIS,
47 role: ViewRole::Replica,
48 step: ViewStep::Entered,
49 locked_qc: None,
50 highest_double_cert: None,
51 highest_qc: None,
52 last_committed_height: Height::GENESIS,
53 current_epoch,
54 }
55 }
56
57 pub fn is_leader(&self) -> bool {
58 self.role == ViewRole::Leader
59 }
60
61 pub fn update_highest_qc(&mut self, qc: &QuorumCertificate) {
62 let dominated = self.highest_qc.as_ref().is_none_or(|h| qc.view > h.view);
63 if dominated {
64 self.highest_qc = Some(qc.clone());
65 }
66 }
67
68 pub fn update_locked_qc(&mut self, qc: &QuorumCertificate) {
69 let dominated = self.locked_qc.as_ref().is_none_or(|h| qc.view > h.view);
70 if dominated {
71 self.locked_qc = Some(qc.clone());
72 }
73 }
74}