fix(fuzz): apply `ReceiveSafeBlock` & `ReceiveUnsafeBlock` only when parent exists (#222)

This commit is contained in:
Youngjoon Lee 2023-06-26 20:20:55 +09:00 committed by GitHub
parent deeb3eeba0
commit feb428bf18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 19 additions and 3 deletions

View File

@ -1,6 +1,8 @@
use std::collections::{BTreeMap, HashSet}; use std::collections::{BTreeMap, HashSet};
use consensus_engine::{AggregateQc, Block, LeaderProof, NodeId, Qc, StandardQc, TimeoutQc, View}; use consensus_engine::{
AggregateQc, Block, BlockId, LeaderProof, NodeId, Qc, StandardQc, TimeoutQc, View,
};
use proptest::prelude::*; use proptest::prelude::*;
use proptest::strategy::BoxedStrategy; use proptest::strategy::BoxedStrategy;
use proptest_state_machine::ReferenceStateMachine; use proptest_state_machine::ReferenceStateMachine;
@ -90,8 +92,12 @@ impl ReferenceStateMachine for RefState {
// because some transitions may no longer be valid after some shrinking is applied. // because some transitions may no longer be valid after some shrinking is applied.
match transition { match transition {
Transition::Nop => true, Transition::Nop => true,
Transition::ReceiveSafeBlock(block) => block.view >= state.current_view(), Transition::ReceiveSafeBlock(block) => {
Transition::ReceiveUnsafeBlock(block) => block.view < state.current_view(), state.contains_parent_of(block) && block.view >= state.current_view()
}
Transition::ReceiveUnsafeBlock(block) => {
state.contains_parent_of(block) && block.view < state.current_view()
}
Transition::ApproveBlock(block) => state.highest_voted_view < block.view, Transition::ApproveBlock(block) => state.highest_voted_view < block.view,
Transition::ApprovePastBlock(block) => state.highest_voted_view >= block.view, Transition::ApprovePastBlock(block) => state.highest_voted_view >= block.view,
Transition::LocalTimeout => true, Transition::LocalTimeout => true,
@ -352,6 +358,16 @@ impl RefState {
} }
} }
fn contains_parent_of(&self, block: &Block) -> bool {
self.contains_block(block.parent_qc.block())
}
fn contains_block(&self, block_id: BlockId) -> bool {
self.chain
.iter()
.any(|(_, entry)| entry.blocks.iter().any(|block| block.id == block_id))
}
fn consecutive_block(parent: &Block) -> Block { fn consecutive_block(parent: &Block) -> Block {
Block { Block {
// use rand because we don't want this to be shrinked by proptest // use rand because we don't want this to be shrinked by proptest