mod confirmed;
mod generic;
mod lite;
mod timeout;
mod validated;
use std::collections::BTreeSet;
pub use generic::GenericCertificate;
use linera_base::{
crypto::{ValidatorPublicKey, ValidatorSignature},
data_types::{BlockHeight, Round},
identifiers::{BlobId, ChainId},
};
use linera_execution::committee::Epoch;
pub use lite::LiteCertificate;
use serde::{Deserialize, Serialize};
use crate::types::{ConfirmedBlock, Timeout, ValidatedBlock};
pub type ValidatedBlockCertificate = GenericCertificate<ValidatedBlock>;
pub type ConfirmedBlockCertificate = GenericCertificate<ConfirmedBlock>;
pub type TimeoutCertificate = GenericCertificate<Timeout>;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(with_testing, derive(Eq, PartialEq))]
pub enum Certificate {
Validated(ValidatedBlockCertificate),
Confirmed(ConfirmedBlockCertificate),
Timeout(TimeoutCertificate),
}
impl Certificate {
pub fn round(&self) -> Round {
match self {
Certificate::Validated(cert) => cert.round,
Certificate::Confirmed(cert) => cert.round,
Certificate::Timeout(cert) => cert.round,
}
}
pub fn height(&self) -> BlockHeight {
match self {
Certificate::Validated(cert) => cert.value().inner().block().header.height,
Certificate::Confirmed(cert) => cert.value().inner().block().header.height,
Certificate::Timeout(cert) => cert.inner().height,
}
}
pub fn chain_id(&self) -> ChainId {
match self {
Certificate::Validated(cert) => cert.value().inner().block().header.chain_id,
Certificate::Confirmed(cert) => cert.value().inner().block().header.chain_id,
Certificate::Timeout(cert) => cert.inner().chain_id,
}
}
pub fn signatures(&self) -> &Vec<(ValidatorPublicKey, ValidatorSignature)> {
match self {
Certificate::Validated(cert) => cert.signatures(),
Certificate::Confirmed(cert) => cert.signatures(),
Certificate::Timeout(cert) => cert.signatures(),
}
}
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Hash, Eq, PartialEq)]
#[repr(u8)]
pub enum CertificateKind {
Timeout = 0,
Validated = 1,
Confirmed = 2,
}
pub trait CertificateValue: Clone {
const KIND: CertificateKind;
fn chain_id(&self) -> ChainId;
fn epoch(&self) -> Epoch;
fn height(&self) -> BlockHeight;
fn required_blob_ids(&self) -> BTreeSet<BlobId>;
}
impl CertificateValue for Timeout {
const KIND: CertificateKind = CertificateKind::Timeout;
fn chain_id(&self) -> ChainId {
self.chain_id
}
fn epoch(&self) -> Epoch {
self.epoch
}
fn height(&self) -> BlockHeight {
self.height
}
fn required_blob_ids(&self) -> BTreeSet<BlobId> {
BTreeSet::new()
}
}
impl CertificateValue for ValidatedBlock {
const KIND: CertificateKind = CertificateKind::Validated;
fn chain_id(&self) -> ChainId {
self.block().header.chain_id
}
fn epoch(&self) -> Epoch {
self.block().header.epoch
}
fn height(&self) -> BlockHeight {
self.block().header.height
}
fn required_blob_ids(&self) -> BTreeSet<BlobId> {
self.block().required_blob_ids()
}
}
impl CertificateValue for ConfirmedBlock {
const KIND: CertificateKind = CertificateKind::Confirmed;
fn chain_id(&self) -> ChainId {
self.block().header.chain_id
}
fn epoch(&self) -> Epoch {
self.block().header.epoch
}
fn height(&self) -> BlockHeight {
self.block().header.height
}
fn required_blob_ids(&self) -> BTreeSet<BlobId> {
self.block().required_blob_ids()
}
}