linera_chain/certificate/
generic.rs1use custom_debug_derive::Debug;
6use linera_base::{
7 crypto::{CryptoHash, ValidatorPublicKey, ValidatorSignature},
8 data_types::Round,
9};
10use linera_execution::committee::Committee;
11
12use super::CertificateValue;
13use crate::{data_types::LiteValue, ChainError};
14
15#[derive(Debug)]
17pub struct GenericCertificate<T: CertificateValue> {
18 value: T,
19 pub round: Round,
20 signatures: Vec<(ValidatorPublicKey, ValidatorSignature)>,
21}
22
23impl<T: CertificateValue> GenericCertificate<T> {
24 pub fn new(
25 value: T,
26 round: Round,
27 mut signatures: Vec<(ValidatorPublicKey, ValidatorSignature)>,
28 ) -> Self {
29 signatures.sort_by_key(|&(validator_name, _)| validator_name);
30
31 Self {
32 value,
33 round,
34 signatures,
35 }
36 }
37
38 pub fn value(&self) -> &T {
40 &self.value
41 }
42
43 pub fn into_value(self) -> T {
45 self.value
46 }
47
48 pub fn inner(&self) -> &T {
50 &self.value
51 }
52
53 pub fn into_inner(self) -> T {
55 self.value
56 }
57
58 pub fn hash(&self) -> CryptoHash {
60 self.value.hash()
61 }
62
63 pub fn destructure(self) -> (T, Round, Vec<(ValidatorPublicKey, ValidatorSignature)>) {
64 (self.value, self.round, self.signatures)
65 }
66
67 pub fn signatures(&self) -> &Vec<(ValidatorPublicKey, ValidatorSignature)> {
68 &self.signatures
69 }
70
71 #[cfg(with_testing)]
72 pub fn signatures_mut(&mut self) -> &mut Vec<(ValidatorPublicKey, ValidatorSignature)> {
73 &mut self.signatures
74 }
75
76 pub fn add_signature(
79 &mut self,
80 signature: (ValidatorPublicKey, ValidatorSignature),
81 ) -> &Vec<(ValidatorPublicKey, ValidatorSignature)> {
82 let index = self
83 .signatures
84 .binary_search_by(|(name, _)| name.cmp(&signature.0))
85 .unwrap_or_else(std::convert::identity);
86 self.signatures.insert(index, signature);
87 &self.signatures
88 }
89
90 pub fn is_signed_by(&self, validator_name: &ValidatorPublicKey) -> bool {
92 self.signatures
93 .binary_search_by(|(name, _)| name.cmp(validator_name))
94 .is_ok()
95 }
96
97 pub fn check(&self, committee: &Committee) -> Result<(), ChainError>
99 where
100 T: CertificateValue,
101 {
102 crate::data_types::check_signatures(
103 self.hash(),
104 T::KIND,
105 self.round,
106 &self.signatures,
107 committee,
108 )?;
109 Ok(())
110 }
111
112 pub fn lite_certificate(&self) -> crate::certificate::LiteCertificate<'_>
113 where
114 T: CertificateValue,
115 {
116 crate::certificate::LiteCertificate {
117 value: LiteValue::new(&self.value),
118 round: self.round,
119 signatures: std::borrow::Cow::Borrowed(&self.signatures),
120 }
121 }
122}
123
124impl<T: CertificateValue> Clone for GenericCertificate<T> {
125 fn clone(&self) -> Self {
126 Self {
127 value: self.value.clone(),
128 round: self.round,
129 signatures: self.signatures.clone(),
130 }
131 }
132}
133
134#[cfg(with_testing)]
135impl<T: CertificateValue + Eq + PartialEq> Eq for GenericCertificate<T> {}
136#[cfg(with_testing)]
137impl<T: CertificateValue + Eq + PartialEq> PartialEq for GenericCertificate<T> {
138 fn eq(&self, other: &Self) -> bool {
139 self.hash() == other.hash()
140 && self.round == other.round
141 && self.signatures == other.signatures
142 }
143}