cfxcore/pos/consensus/
metrics_safety_rules.rs1use super::persistent_liveness_storage::PersistentLivenessStorage;
9use consensus_types::{
10 block::Block, block_data::BlockData, timeout::Timeout, vote::Vote,
11 vote_proposal::MaybeSignedVoteProposal,
12};
13use diem_metrics::monitor;
14use diem_types::{
15 epoch_change::EpochChangeProof, validator_config::ConsensusSignature,
16};
17use safety_rules::{ConsensusState, Error, TSafetyRules};
18use std::sync::Arc;
19
20pub struct MetricsSafetyRules {
22 inner: Box<dyn TSafetyRules + Send + Sync>,
23 storage: Arc<dyn PersistentLivenessStorage>,
24}
25
26impl MetricsSafetyRules {
27 pub fn new(
28 inner: Box<dyn TSafetyRules + Send + Sync>,
29 storage: Arc<dyn PersistentLivenessStorage>,
30 ) -> Self {
31 Self { inner, storage }
32 }
33
34 pub fn perform_initialize(&mut self) -> Result<(), Error> {
35 let consensus_state = self.consensus_state()?;
36 let sr_waypoint = consensus_state.waypoint();
37 let proofs = self
38 .storage
39 .retrieve_epoch_change_proof(sr_waypoint.version())
40 .map_err(|e| {
41 Error::InternalError(format!(
42 "Unable to retrieve Waypoint state from storage, encountered Error:{}",
43 e
44 ))
45 })?;
46 self.initialize(&proofs)
47 }
48}
49
50impl TSafetyRules for MetricsSafetyRules {
51 fn consensus_state(&mut self) -> Result<ConsensusState, Error> {
52 monitor!("safety_rules", self.inner.consensus_state())
53 }
54
55 fn initialize(&mut self, proof: &EpochChangeProof) -> Result<(), Error> {
56 monitor!("safety_rules", self.inner.initialize(proof))
57 }
58
59 fn construct_and_sign_vote(
60 &mut self, vote_proposal: &MaybeSignedVoteProposal,
61 ) -> Result<Vote, Error> {
62 let mut result = monitor!(
63 "safety_rules",
64 self.inner.construct_and_sign_vote(vote_proposal)
65 );
66
67 if let Err(Error::NotInitialized(_res)) = result {
68 self.perform_initialize()?;
69 result = monitor!(
70 "safety_rules",
71 self.inner.construct_and_sign_vote(vote_proposal)
72 );
73 }
74 result
75 }
76
77 fn sign_proposal(&mut self, block_data: BlockData) -> Result<Block, Error> {
78 let mut result = monitor!(
79 "safety_rules",
80 self.inner.sign_proposal(block_data.clone())
81 );
82 if let Err(Error::NotInitialized(_res)) = result {
83 self.perform_initialize()?;
84 result =
85 monitor!("safety_rules", self.inner.sign_proposal(block_data));
86 }
87 result
88 }
89
90 fn sign_timeout(
91 &mut self, timeout: &Timeout,
92 ) -> Result<ConsensusSignature, Error> {
93 let mut result =
94 monitor!("safety_rules", self.inner.sign_timeout(timeout));
95 if let Err(Error::NotInitialized(_res)) = result {
96 self.perform_initialize()?;
97 result = monitor!("safety_rules", self.inner.sign_timeout(timeout));
98 }
99 result
100 }
101
102 fn start_voting(&mut self, initialize: bool) -> Result<(), Error> {
103 monitor!("safety_rules", self.inner.start_voting(initialize))
104 }
105
106 fn stop_voting(&mut self) -> Result<(), Error> {
107 monitor!("safety_rules", self.inner.stop_voting())
108 }
109}