hotmint_consensus/
state.rs1use hotmint_types::{
2 DoubleCertificate, 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}
38
39impl ConsensusState {
40 pub fn new(validator_id: ValidatorId, validator_set: ValidatorSet) -> Self {
41 Self {
42 validator_id,
43 validator_set,
44 current_view: ViewNumber::GENESIS,
45 role: ViewRole::Replica,
46 step: ViewStep::Entered,
47 locked_qc: None,
48 highest_double_cert: None,
49 highest_qc: None,
50 last_committed_height: Height::GENESIS,
51 }
52 }
53
54 pub fn is_leader(&self) -> bool {
55 self.role == ViewRole::Leader
56 }
57
58 pub fn update_highest_qc(&mut self, qc: &QuorumCertificate) {
59 let dominated = self.highest_qc.as_ref().is_none_or(|h| qc.view > h.view);
60 if dominated {
61 self.highest_qc = Some(qc.clone());
62 }
63 }
64
65 pub fn update_locked_qc(&mut self, qc: &QuorumCertificate) {
66 let dominated = self.locked_qc.as_ref().is_none_or(|h| qc.view > h.view);
67 if dominated {
68 self.locked_qc = Some(qc.clone());
69 }
70 }
71}