use crate::{
common::{Author, Round},
timeout::Timeout,
};
use anyhow::Context;
use diem_types::{
validator_config::ConsensusSignature, validator_verifier::ValidatorVerifier,
};
use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, fmt};
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]
pub struct TimeoutCertificate {
timeout: Timeout,
signatures: BTreeMap<Author, ConsensusSignature>,
}
impl fmt::Display for TimeoutCertificate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"TimeoutCertificate[epoch: {}, round: {}]",
self.timeout.epoch(),
self.timeout.round(),
)
}
}
impl TimeoutCertificate {
pub fn new(timeout: Timeout) -> Self {
Self {
timeout,
signatures: BTreeMap::new(),
}
}
pub fn verify(&self, validator: &ValidatorVerifier) -> anyhow::Result<()> {
validator
.verify_aggregated_struct_signature(&self.timeout, &self.signatures)
.context("Failed to verify TimeoutCertificate")?;
Ok(())
}
pub fn epoch(&self) -> u64 { self.timeout.epoch() }
pub fn round(&self) -> Round { self.timeout.round() }
pub fn signatures(&self) -> &BTreeMap<Author, ConsensusSignature> {
&self.signatures
}
pub fn add_signature(
&mut self, author: Author, signature: ConsensusSignature,
) {
self.signatures.entry(author).or_insert(signature);
}
pub fn remove_signature(&mut self, author: Author) {
self.signatures.remove(&author);
}
}