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