test(unhappy): mask `sender` when comparing timeout_qcs (#458)
This commit is contained in:
parent
39d45d3c09
commit
81c34036f7
|
@ -1,10 +1,12 @@
|
||||||
use consensus_engine::View;
|
use consensus_engine::{Block, NodeId, TimeoutQc, View};
|
||||||
use fraction::Fraction;
|
use fraction::Fraction;
|
||||||
use futures::stream::{self, StreamExt};
|
use futures::stream::{self, StreamExt};
|
||||||
|
use nomos_consensus::CarnotInfo;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use tests::{ConsensusConfig, MixNode, Node, NomosNode, SpawnConfig};
|
use tests::{ConsensusConfig, MixNode, Node, NomosNode, SpawnConfig};
|
||||||
|
|
||||||
const TARGET_VIEW: View = View::new(20);
|
const TARGET_VIEW: View = View::new(20);
|
||||||
|
const DUMMY_NODE_ID: NodeId = NodeId::new([0u8; 32]);
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ten_nodes_one_down() {
|
async fn ten_nodes_one_down() {
|
||||||
|
@ -46,30 +48,75 @@ async fn ten_nodes_one_down() {
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// check that they have the same block
|
let target_block = assert_block_consensus(&infos, TARGET_VIEW);
|
||||||
let target_blocks = infos
|
|
||||||
.iter()
|
// If no node has the target block, check that TARGET_VIEW was reached by timeout_qc.
|
||||||
.map(|i| i.safe_blocks.values().find(|b| b.view == TARGET_VIEW))
|
if target_block.is_none() {
|
||||||
|
println!("No node has the block with {TARGET_VIEW:?}. Checking timeout_qcs...");
|
||||||
|
assert_timeout_qc_consensus(&infos, TARGET_VIEW.prev());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all nodes have the same block at the specific view.
|
||||||
|
fn assert_block_consensus<'a>(
|
||||||
|
consensus_infos: impl IntoIterator<Item = &'a CarnotInfo>,
|
||||||
|
view: View,
|
||||||
|
) -> Option<Block> {
|
||||||
|
let blocks = consensus_infos
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| i.safe_blocks.values().find(|b| b.view == view))
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
// Every nodes must have the same target block (Some(block))
|
// Every nodes must have the same target block (Some(block))
|
||||||
// , or no node must have it (None).
|
// , or no node must have it (None).
|
||||||
assert_eq!(target_blocks.len(), 1);
|
assert_eq!(
|
||||||
|
blocks.len(),
|
||||||
|
1,
|
||||||
|
"multiple blocks found at {:?}: {:?}",
|
||||||
|
view,
|
||||||
|
blocks
|
||||||
|
);
|
||||||
|
|
||||||
// If no node has the target block, check that TARGET_VIEW was reached by timeout_qc.
|
blocks.iter().next().unwrap().cloned()
|
||||||
let target_block = target_blocks.iter().next().unwrap();
|
}
|
||||||
if target_block.is_none() {
|
|
||||||
println!("No node has the block with {TARGET_VIEW:?}. Checking timeout_qcs...");
|
|
||||||
|
|
||||||
let timeout_qcs = infos
|
// Check if all nodes have the same timeout_qc at the specific view.
|
||||||
.iter()
|
fn assert_timeout_qc_consensus<'a>(
|
||||||
.map(|i| i.last_view_timeout_qc.clone())
|
consensus_infos: impl IntoIterator<Item = &'a CarnotInfo>,
|
||||||
|
view: View,
|
||||||
|
) -> TimeoutQc {
|
||||||
|
let timeout_qcs = consensus_infos
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| {
|
||||||
|
i.last_view_timeout_qc.clone().map(|timeout_qc| {
|
||||||
|
// Masking the `sender` field because we want timeout_qcs from different
|
||||||
|
// senders to be considered the same if all other fields are the same.
|
||||||
|
TimeoutQc::new(
|
||||||
|
timeout_qc.view(),
|
||||||
|
timeout_qc.high_qc().clone(),
|
||||||
|
DUMMY_NODE_ID,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
assert_eq!(timeout_qcs.len(), 1);
|
assert_eq!(
|
||||||
|
timeout_qcs.len(),
|
||||||
|
1,
|
||||||
|
"multiple timeout_qcs found at {:?}: {:?}",
|
||||||
|
view,
|
||||||
|
timeout_qcs
|
||||||
|
);
|
||||||
|
|
||||||
let timeout_qc = timeout_qcs.iter().next().unwrap().clone();
|
let timeout_qc = timeout_qcs
|
||||||
assert!(timeout_qc.is_some());
|
.iter()
|
||||||
// NOTE: This check could be failed if other timeout_qc had occured before `infos` were gathered.
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.clone()
|
||||||
|
.expect("collected timeout_qc shouldn't be None");
|
||||||
|
|
||||||
|
// NOTE: This check could be failed if other timeout_qcs had occured
|
||||||
|
// before `consensus_infos` were gathered.
|
||||||
// But it should be okay as long as the `timeout` is not too short.
|
// But it should be okay as long as the `timeout` is not too short.
|
||||||
assert_eq!(timeout_qc.unwrap().view(), TARGET_VIEW.prev());
|
assert_eq!(timeout_qc.view(), view);
|
||||||
}
|
|
||||||
|
timeout_qc
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue