hotmint_storage/
consensus_state.rs1use hotmint_types::{Epoch, Height, QuorumCertificate, ViewNumber};
2use serde::{Deserialize, Serialize};
3use vsdb::MapxOrd;
4
5const KEY_CURRENT_VIEW: u64 = 1;
7const KEY_LOCKED_QC: u64 = 2;
8const KEY_HIGHEST_QC: u64 = 3;
9const KEY_LAST_COMMITTED_HEIGHT: u64 = 4;
10const KEY_CURRENT_EPOCH: u64 = 5;
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14enum StateValue {
15 View(ViewNumber),
16 Height(Height),
17 Qc(QuorumCertificate),
18 Epoch(Epoch),
19}
20
21pub struct PersistentConsensusState {
23 store: MapxOrd<u64, StateValue>,
24}
25
26impl PersistentConsensusState {
27 pub fn new() -> Self {
28 Self {
29 store: MapxOrd::new(),
30 }
31 }
32
33 pub fn save_current_view(&mut self, view: ViewNumber) {
34 self.store
35 .insert(&KEY_CURRENT_VIEW, &StateValue::View(view));
36 }
37
38 pub fn load_current_view(&self) -> Option<ViewNumber> {
39 self.store.get(&KEY_CURRENT_VIEW).and_then(|v| match v {
40 StateValue::View(view) => Some(view),
41 _ => None,
42 })
43 }
44
45 pub fn save_locked_qc(&mut self, qc: &QuorumCertificate) {
46 self.store
47 .insert(&KEY_LOCKED_QC, &StateValue::Qc(qc.clone()));
48 }
49
50 pub fn load_locked_qc(&self) -> Option<QuorumCertificate> {
51 self.store.get(&KEY_LOCKED_QC).and_then(|v| match v {
52 StateValue::Qc(qc) => Some(qc),
53 _ => None,
54 })
55 }
56
57 pub fn save_highest_qc(&mut self, qc: &QuorumCertificate) {
58 self.store
59 .insert(&KEY_HIGHEST_QC, &StateValue::Qc(qc.clone()));
60 }
61
62 pub fn load_highest_qc(&self) -> Option<QuorumCertificate> {
63 self.store.get(&KEY_HIGHEST_QC).and_then(|v| match v {
64 StateValue::Qc(qc) => Some(qc),
65 _ => None,
66 })
67 }
68
69 pub fn save_last_committed_height(&mut self, height: Height) {
70 self.store
71 .insert(&KEY_LAST_COMMITTED_HEIGHT, &StateValue::Height(height));
72 }
73
74 pub fn load_last_committed_height(&self) -> Option<Height> {
75 self.store
76 .get(&KEY_LAST_COMMITTED_HEIGHT)
77 .and_then(|v| match v {
78 StateValue::Height(h) => Some(h),
79 _ => None,
80 })
81 }
82
83 pub fn save_current_epoch(&mut self, epoch: &Epoch) {
84 self.store
85 .insert(&KEY_CURRENT_EPOCH, &StateValue::Epoch(epoch.clone()));
86 }
87
88 pub fn load_current_epoch(&self) -> Option<Epoch> {
89 self.store.get(&KEY_CURRENT_EPOCH).and_then(|v| match v {
90 StateValue::Epoch(e) => Some(e),
91 _ => None,
92 })
93 }
94
95 pub fn flush(&self) {
96 vsdb::vsdb_flush();
97 }
98}
99
100impl Default for PersistentConsensusState {
101 fn default() -> Self {
102 Self::new()
103 }
104}