diem_types/
epoch_state.rs1use crate::{
9 epoch_change::Verifier,
10 ledger_info::{LedgerInfo, LedgerInfoWithSignatures},
11 on_chain_config::OnChainConfig,
12 validator_verifier::ValidatorVerifier,
13};
14use anyhow::ensure;
15use once_cell::sync::OnceCell;
16#[cfg(any(test, feature = "fuzzing"))]
17use proptest_derive::Arbitrary;
18use serde::{Deserialize, Serialize};
19use std::{collections::BTreeMap, fmt};
20
21pub static HARDCODED_COMMITTEE_FOR_EPOCH: OnceCell<
22 BTreeMap<u64, ValidatorVerifier>,
23> = OnceCell::new();
24
25#[derive(Clone, Deserialize, Eq, PartialEq, Serialize)]
28#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
29pub struct EpochState {
30 pub epoch: u64,
31
32 verifier: ValidatorVerifier,
33
34 pub vrf_seed: Vec<u8>,
35}
36
37impl EpochState {
38 pub fn empty() -> Self {
39 Self {
40 epoch: 0,
41 verifier: ValidatorVerifier::new(BTreeMap::new()),
42 vrf_seed: vec![],
43 }
44 }
45
46 pub fn new(
47 epoch: u64, verifier: ValidatorVerifier, vrf_seed: Vec<u8>,
48 ) -> Self {
49 Self {
50 epoch,
51 verifier,
52 vrf_seed,
53 }
54 }
55
56 pub fn verifier(&self) -> &ValidatorVerifier {
57 if let Some(verifier) = HARDCODED_COMMITTEE_FOR_EPOCH
58 .get()
59 .and_then(|m| m.get(&self.epoch))
60 {
61 verifier
62 } else {
63 &self.verifier
64 }
65 }
66}
67
68impl OnChainConfig for EpochState {
69 const IDENTIFIER: &'static str = "DiemSystem";
70}
71
72impl Verifier for EpochState {
73 fn verify(
74 &self, ledger_info: &LedgerInfoWithSignatures,
75 ) -> anyhow::Result<()> {
76 ensure!(
77 self.epoch == ledger_info.ledger_info().epoch(),
78 "LedgerInfo has unexpected epoch {}, expected {}",
79 ledger_info.ledger_info().epoch(),
80 self.epoch
81 );
82 ledger_info.verify_signatures(&self.verifier())?;
83 Ok(())
84 }
85
86 fn epoch_change_verification_required(&self, epoch: u64) -> bool {
87 self.epoch < epoch
88 }
89
90 fn is_ledger_info_stale(&self, ledger_info: &LedgerInfo) -> bool {
91 ledger_info.epoch() < self.epoch
92 }
93}
94
95impl fmt::Debug for EpochState {
97 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
98 write!(f, "{}", self)
99 }
100}
101
102impl fmt::Display for EpochState {
103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104 write!(
105 f,
106 "EpochState [epoch: {}, validator: {}]",
107 self.epoch,
108 self.verifier()
109 )
110 }
111}