1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0
// Copyright 2021 Conflux Foundation. All rights reserved.
// Conflux is free software and distributed under GNU General Public License.
// See http://www.gnu.org/licenses/
use diem_crypto_derive::{BCSCryptoHash, CryptoHasher};
use diem_types::block_info::BlockInfo;
use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter};
/// VoteData keeps the information about the block, and its parent.
#[derive(
Deserialize,
Serialize,
Clone,
Debug,
PartialEq,
Eq,
CryptoHasher,
BCSCryptoHash,
)]
pub struct VoteData {
/// Contains all the block information needed for voting for the proposed
/// round.
proposed: BlockInfo,
/// Contains all the block information for the block the proposal is
/// extending.
parent: BlockInfo,
}
impl Display for VoteData {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(
f,
"VoteData: [block id: {}, epoch: {}, round: {:02}, parent_block_id: {}, parent_block_round: {:02}]",
self.proposed().id(), self.proposed().epoch(), self.proposed().round(), self.parent().id(), self.parent().round(),
)
}
}
impl VoteData {
/// Constructs a new VoteData from the block information of a proposed block
/// and the block it extends.
pub fn new(proposed: BlockInfo, parent: BlockInfo) -> Self {
Self { proposed, parent }
}
/// Returns block information associated to the block being extended by the
/// proposal.
pub fn parent(&self) -> &BlockInfo { &self.parent }
/// Returns block information associated to the block being voted on.
pub fn proposed(&self) -> &BlockInfo { &self.proposed }
/// Well-formedness checks that are independent of the current state.
pub fn verify(&self) -> anyhow::Result<()> {
anyhow::ensure!(
self.parent.epoch() == self.proposed.epoch(),
"Parent and proposed epochs do not match",
);
anyhow::ensure!(
self.parent.round() < self.proposed.round(),
"Proposed round is less than parent round",
);
anyhow::ensure!(
self.parent.timestamp_usecs() <= self.proposed.timestamp_usecs(),
"Proposed happened before parent",
);
anyhow::ensure!(
self.parent.version() <= self.proposed.version(),
"Proposed version is less than parent version",
);
Ok(())
}
}