linera_chain/certificate/
mod.rs1mod confirmed;
6mod generic;
7mod lite;
8mod timeout;
9mod validated;
10
11use std::collections::BTreeSet;
12
13pub use generic::GenericCertificate;
14use linera_base::{
15 crypto::{CryptoHash, ValidatorPublicKey, ValidatorSignature},
16 data_types::{BlockHeight, Round},
17 identifiers::{BlobId, ChainId},
18};
19use linera_execution::committee::Epoch;
20pub use lite::LiteCertificate;
21use serde::{Deserialize, Serialize};
22
23use crate::types::{ConfirmedBlock, Timeout, ValidatedBlock};
24
25pub type ValidatedBlockCertificate = GenericCertificate<ValidatedBlock>;
30
31pub type ConfirmedBlockCertificate = GenericCertificate<ConfirmedBlock>;
35
36pub type TimeoutCertificate = GenericCertificate<Timeout>;
39
40#[derive(Debug, Clone, Serialize, Deserialize)]
44#[cfg_attr(with_testing, derive(Eq, PartialEq))]
45pub enum Certificate {
46 Validated(ValidatedBlockCertificate),
48 Confirmed(ConfirmedBlockCertificate),
50 Timeout(TimeoutCertificate),
52}
53
54impl Certificate {
55 pub fn round(&self) -> Round {
56 match self {
57 Certificate::Validated(cert) => cert.round,
58 Certificate::Confirmed(cert) => cert.round,
59 Certificate::Timeout(cert) => cert.round,
60 }
61 }
62
63 pub fn height(&self) -> BlockHeight {
64 match self {
65 Certificate::Validated(cert) => cert.value().block().header.height,
66 Certificate::Confirmed(cert) => cert.value().block().header.height,
67 Certificate::Timeout(cert) => cert.value().height(),
68 }
69 }
70
71 pub fn chain_id(&self) -> ChainId {
72 match self {
73 Certificate::Validated(cert) => cert.value().block().header.chain_id,
74 Certificate::Confirmed(cert) => cert.value().block().header.chain_id,
75 Certificate::Timeout(cert) => cert.value().chain_id(),
76 }
77 }
78
79 pub fn signatures(&self) -> &Vec<(ValidatorPublicKey, ValidatorSignature)> {
80 match self {
81 Certificate::Validated(cert) => cert.signatures(),
82 Certificate::Confirmed(cert) => cert.signatures(),
83 Certificate::Timeout(cert) => cert.signatures(),
84 }
85 }
86}
87
88#[derive(Clone, Copy, Debug, Serialize, Deserialize, Hash, Eq, PartialEq)]
89#[repr(u8)]
90pub enum CertificateKind {
91 Timeout = 0,
92 Validated = 1,
93 Confirmed = 2,
94}
95
96pub trait CertificateValue: Clone {
97 const KIND: CertificateKind;
98
99 fn chain_id(&self) -> ChainId;
100
101 fn epoch(&self) -> Epoch;
102
103 fn height(&self) -> BlockHeight;
104
105 fn required_blob_ids(&self) -> BTreeSet<BlobId>;
106
107 fn hash(&self) -> CryptoHash;
108}
109
110impl CertificateValue for Timeout {
111 const KIND: CertificateKind = CertificateKind::Timeout;
112
113 fn chain_id(&self) -> ChainId {
114 self.chain_id()
115 }
116
117 fn epoch(&self) -> Epoch {
118 self.epoch()
119 }
120
121 fn height(&self) -> BlockHeight {
122 self.height()
123 }
124
125 fn required_blob_ids(&self) -> BTreeSet<BlobId> {
126 BTreeSet::new()
127 }
128
129 fn hash(&self) -> CryptoHash {
130 self.inner().hash()
131 }
132}
133
134impl CertificateValue for ValidatedBlock {
135 const KIND: CertificateKind = CertificateKind::Validated;
136
137 fn chain_id(&self) -> ChainId {
138 self.block().header.chain_id
139 }
140
141 fn epoch(&self) -> Epoch {
142 self.block().header.epoch
143 }
144
145 fn height(&self) -> BlockHeight {
146 self.block().header.height
147 }
148
149 fn required_blob_ids(&self) -> BTreeSet<BlobId> {
150 self.block().required_blob_ids()
151 }
152
153 fn hash(&self) -> CryptoHash {
154 self.inner().hash()
155 }
156}
157
158impl CertificateValue for ConfirmedBlock {
159 const KIND: CertificateKind = CertificateKind::Confirmed;
160
161 fn chain_id(&self) -> ChainId {
162 self.block().header.chain_id
163 }
164
165 fn epoch(&self) -> Epoch {
166 self.block().header.epoch
167 }
168
169 fn height(&self) -> BlockHeight {
170 self.block().header.height
171 }
172
173 fn required_blob_ids(&self) -> BTreeSet<BlobId> {
174 self.block().required_blob_ids()
175 }
176
177 fn hash(&self) -> CryptoHash {
178 self.inner().hash()
179 }
180}