consensus_types/
timeout_certificate.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8use crate::{
9    common::{Author, Round},
10    timeout::Timeout,
11};
12use anyhow::Context;
13use diem_types::{
14    validator_config::ConsensusSignature, validator_verifier::ValidatorVerifier,
15};
16use serde::{Deserialize, Serialize};
17use std::{collections::BTreeMap, fmt};
18
19#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]
20/// TimeoutCertificate is a proof that 2f+1 participants in epoch i
21/// have voted in round r and we can now move to round r+1.
22pub struct TimeoutCertificate {
23    timeout: Timeout,
24    signatures: BTreeMap<Author, ConsensusSignature>,
25}
26
27impl fmt::Display for TimeoutCertificate {
28    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29        write!(
30            f,
31            "TimeoutCertificate[epoch: {}, round: {}]",
32            self.timeout.epoch(),
33            self.timeout.round(),
34        )
35    }
36}
37
38impl TimeoutCertificate {
39    /// Creates new TimeoutCertificate
40    pub fn new(timeout: Timeout) -> Self {
41        Self {
42            timeout,
43            signatures: BTreeMap::new(),
44        }
45    }
46
47    /// Verifies the signatures for the round
48    pub fn verify(&self, validator: &ValidatorVerifier) -> anyhow::Result<()> {
49        validator
50            .verify_aggregated_struct_signature(&self.timeout, &self.signatures)
51            .context("Failed to verify TimeoutCertificate")?;
52        Ok(())
53    }
54
55    /// Returns the epoch of the timeout certificate
56    pub fn epoch(&self) -> u64 { self.timeout.epoch() }
57
58    /// Returns the round of the timeout certificate
59    pub fn round(&self) -> Round { self.timeout.round() }
60
61    /// Returns the signatures certifying the round
62    pub fn signatures(&self) -> &BTreeMap<Author, ConsensusSignature> {
63        &self.signatures
64    }
65
66    pub fn add_signature(
67        &mut self, author: Author, signature: ConsensusSignature,
68    ) {
69        self.signatures.entry(author).or_insert(signature);
70    }
71
72    pub fn remove_signature(&mut self, author: Author) {
73        self.signatures.remove(&author);
74    }
75}