diff --git a/consensus-engine/tests/fuzz/ref_state.rs b/consensus-engine/tests/fuzz/ref_state.rs index 2d1c6158..fee04d67 100644 --- a/consensus-engine/tests/fuzz/ref_state.rs +++ b/consensus-engine/tests/fuzz/ref_state.rs @@ -17,14 +17,14 @@ use crate::fuzz::transition::Transition; // so that we don't need to replicate the logic implemented in consensus-engine. #[derive(Clone, Debug)] pub struct RefState { - chain: BTreeMap, - highest_voted_view: View, + pub chain: BTreeMap, + pub highest_voted_view: View, } #[derive(Clone, Debug, Default, PartialEq)] -struct ViewEntry { - blocks: HashSet, - timeout_qcs: HashSet, +pub struct ViewEntry { + pub blocks: HashSet, + pub timeout_qcs: HashSet, } const LEADER_PROOF: LeaderProof = LeaderProof::LeaderId { leader_id: [0; 32] }; @@ -315,10 +315,6 @@ impl RefState { .boxed() } - pub fn highest_voted_view(&self) -> View { - self.highest_voted_view - } - pub fn current_view(&self) -> View { let (&last_view, last_entry) = self.chain.last_key_value().unwrap(); if last_entry.timeout_qcs.is_empty() { @@ -333,7 +329,7 @@ impl RefState { timeout_qc.view + 1 } - fn high_qc(&self) -> StandardQc { + pub fn high_qc(&self) -> StandardQc { self.chain .iter() .rev() @@ -341,7 +337,7 @@ impl RefState { .unwrap() // doesn't fail because self.chain always contains at least a genesis block } - fn latest_timeout_qcs(&self) -> Vec { + pub fn latest_timeout_qcs(&self) -> Vec { let latest_timeout_qc_view_entry = self .chain .iter() diff --git a/consensus-engine/tests/fuzz/sut.rs b/consensus-engine/tests/fuzz/sut.rs index 476b0bdc..2d3d1cd0 100644 --- a/consensus-engine/tests/fuzz/sut.rs +++ b/consensus-engine/tests/fuzz/sut.rs @@ -1,4 +1,4 @@ -use std::panic; +use std::{collections::HashSet, panic}; use consensus_engine::{ overlay::{FlatOverlay, RoundRobin, Settings}, @@ -130,12 +130,24 @@ impl StateMachineTest for ConsensusEngineTest { ref_state: &::State, ) { assert_eq!(state.engine.current_view(), ref_state.current_view()); - assert_eq!( state.engine.highest_voted_view(), - ref_state.highest_voted_view() + ref_state.highest_voted_view ); + assert_eq!(state.engine.high_qc().view, ref_state.high_qc().view); - //TODO: add more invariants with more public functions of Carnot + match state.engine.last_view_timeout_qc() { + Some(timeout_qc) => assert!(ref_state.latest_timeout_qcs().contains(&timeout_qc)), + None => assert!(ref_state.latest_timeout_qcs().is_empty()), + } + + // Check if state and ref_state have the same blocks + let ref_blocks: HashSet<&Block> = ref_state + .chain + .values() + .flat_map(|entry| entry.blocks.iter()) + .collect(); + let blocks: HashSet<&Block> = state.engine.safe_blocks().values().collect(); + assert_eq!(blocks, ref_blocks); } }