hotmint_types/
certificate.rs1use serde::{Deserialize, Serialize};
2
3use crate::block::BlockHash;
4use crate::crypto::AggregateSignature;
5use crate::view::ViewNumber;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct QuorumCertificate {
10 pub block_hash: BlockHash,
11 pub view: ViewNumber,
12 pub aggregate_signature: AggregateSignature,
13}
14
15impl QuorumCertificate {
16 pub fn rank(&self) -> ViewNumber {
18 self.view
19 }
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct DoubleCertificate {
25 pub inner_qc: QuorumCertificate,
26 pub outer_qc: QuorumCertificate,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct TimeoutCertificate {
32 pub view: ViewNumber,
33 pub aggregate_signature: AggregateSignature,
34 pub highest_qcs: Vec<Option<QuorumCertificate>>,
36}
37
38impl TimeoutCertificate {
39 pub fn highest_qc(&self) -> Option<&QuorumCertificate> {
41 self.highest_qcs
42 .iter()
43 .filter_map(|qc| qc.as_ref())
44 .max_by_key(|qc| qc.view)
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 fn make_qc(view: u64, hash: [u8; 32]) -> QuorumCertificate {
53 QuorumCertificate {
54 block_hash: BlockHash(hash),
55 view: ViewNumber(view),
56 aggregate_signature: AggregateSignature::new(4),
57 }
58 }
59
60 #[test]
61 fn test_qc_rank() {
62 let qc = make_qc(5, [1u8; 32]);
63 assert_eq!(qc.rank(), ViewNumber(5));
64 }
65
66 #[test]
67 fn test_tc_highest_qc_some() {
68 let qc1 = make_qc(3, [1u8; 32]);
69 let qc2 = make_qc(7, [2u8; 32]);
70 let tc = TimeoutCertificate {
71 view: ViewNumber(8),
72 aggregate_signature: AggregateSignature::new(4),
73 highest_qcs: vec![Some(qc1), None, Some(qc2), None],
74 };
75 let highest = tc.highest_qc().unwrap();
76 assert_eq!(highest.view, ViewNumber(7));
77 }
78
79 #[test]
80 fn test_tc_highest_qc_all_none() {
81 let tc = TimeoutCertificate {
82 view: ViewNumber(5),
83 aggregate_signature: AggregateSignature::new(4),
84 highest_qcs: vec![None, None, None, None],
85 };
86 assert!(tc.highest_qc().is_none());
87 }
88
89 #[test]
90 fn test_tc_highest_qc_empty() {
91 let tc = TimeoutCertificate {
92 view: ViewNumber(5),
93 aggregate_signature: AggregateSignature::new(4),
94 highest_qcs: vec![],
95 };
96 assert!(tc.highest_qc().is_none());
97 }
98}