test(fuzz): add more invariant checks (#224)

This commit is contained in:
Youngjoon Lee 2023-06-26 20:34:12 +09:00 committed by GitHub
parent feb428bf18
commit 2c9d6b1401
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 15 deletions

View File

@ -17,14 +17,14 @@ use crate::fuzz::transition::Transition;
// so that we don't need to replicate the logic implemented in consensus-engine. // so that we don't need to replicate the logic implemented in consensus-engine.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct RefState { pub struct RefState {
chain: BTreeMap<View, ViewEntry>, pub chain: BTreeMap<View, ViewEntry>,
highest_voted_view: View, pub highest_voted_view: View,
} }
#[derive(Clone, Debug, Default, PartialEq)] #[derive(Clone, Debug, Default, PartialEq)]
struct ViewEntry { pub struct ViewEntry {
blocks: HashSet<Block>, pub blocks: HashSet<Block>,
timeout_qcs: HashSet<TimeoutQc>, pub timeout_qcs: HashSet<TimeoutQc>,
} }
const LEADER_PROOF: LeaderProof = LeaderProof::LeaderId { leader_id: [0; 32] }; const LEADER_PROOF: LeaderProof = LeaderProof::LeaderId { leader_id: [0; 32] };
@ -315,10 +315,6 @@ impl RefState {
.boxed() .boxed()
} }
pub fn highest_voted_view(&self) -> View {
self.highest_voted_view
}
pub fn current_view(&self) -> View { pub fn current_view(&self) -> View {
let (&last_view, last_entry) = self.chain.last_key_value().unwrap(); let (&last_view, last_entry) = self.chain.last_key_value().unwrap();
if last_entry.timeout_qcs.is_empty() { if last_entry.timeout_qcs.is_empty() {
@ -333,7 +329,7 @@ impl RefState {
timeout_qc.view + 1 timeout_qc.view + 1
} }
fn high_qc(&self) -> StandardQc { pub fn high_qc(&self) -> StandardQc {
self.chain self.chain
.iter() .iter()
.rev() .rev()
@ -341,7 +337,7 @@ impl RefState {
.unwrap() // doesn't fail because self.chain always contains at least a genesis block .unwrap() // doesn't fail because self.chain always contains at least a genesis block
} }
fn latest_timeout_qcs(&self) -> Vec<TimeoutQc> { pub fn latest_timeout_qcs(&self) -> Vec<TimeoutQc> {
let latest_timeout_qc_view_entry = self let latest_timeout_qc_view_entry = self
.chain .chain
.iter() .iter()

View File

@ -1,4 +1,4 @@
use std::panic; use std::{collections::HashSet, panic};
use consensus_engine::{ use consensus_engine::{
overlay::{FlatOverlay, RoundRobin, Settings}, overlay::{FlatOverlay, RoundRobin, Settings},
@ -130,12 +130,24 @@ impl StateMachineTest for ConsensusEngineTest {
ref_state: &<Self::Reference as ReferenceStateMachine>::State, ref_state: &<Self::Reference as ReferenceStateMachine>::State,
) { ) {
assert_eq!(state.engine.current_view(), ref_state.current_view()); assert_eq!(state.engine.current_view(), ref_state.current_view());
assert_eq!( assert_eq!(
state.engine.highest_voted_view(), 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);
} }
} }