use std::collections::HashMap;
use hashgraph_like_consensus::{
protos::consensus::v1::Vote,
utils::{calculate_consensus_result, has_sufficient_votes},
};
#[test]
fn test_two_thirds_threshold_rounding() {
let threshold = 2.0 / 3.0;
assert!(has_sufficient_votes(1, 1, threshold));
assert!(!has_sufficient_votes(1, 2, threshold));
assert!(has_sufficient_votes(2, 2, threshold));
assert!(!has_sufficient_votes(1, 3, threshold));
assert!(has_sufficient_votes(2, 3, threshold));
assert!(!has_sufficient_votes(2, 4, threshold));
assert!(has_sufficient_votes(3, 4, threshold));
assert!(!has_sufficient_votes(3, 5, threshold));
assert!(has_sufficient_votes(4, 5, threshold));
assert!(!has_sufficient_votes(3, 6, threshold));
assert!(has_sufficient_votes(4, 6, threshold));
assert!(!has_sufficient_votes(66, 100, threshold));
assert!(has_sufficient_votes(67, 100, threshold));
}
#[test]
fn test_calculate_consensus_result_variants() {
let yes_vote = |id: u32| Vote {
vote_id: id,
vote_owner: vec![id as u8],
proposal_id: 1,
timestamp: 0,
vote: true,
parent_hash: vec![],
received_hash: vec![],
vote_hash: vec![id as u8],
signature: vec![],
};
let no_vote = |id: u32| Vote {
vote: false,
vote_hash: vec![id as u8],
..yes_vote(id)
};
let mut votes: HashMap<Vec<u8>, Vote> = HashMap::new();
votes.insert(vec![1], yes_vote(1));
votes.insert(vec![2], yes_vote(2));
votes.insert(vec![3], no_vote(3));
assert_eq!(
calculate_consensus_result(&votes, 3, 2.0 / 3.0, false, false),
Some(true)
);
votes.clear();
votes.insert(vec![1], yes_vote(1));
votes.insert(vec![2], no_vote(2));
votes.insert(vec![3], no_vote(3));
assert_eq!(
calculate_consensus_result(&votes, 3, 2.0 / 3.0, true, false),
Some(false)
);
votes.clear();
votes.insert(vec![1], yes_vote(1));
votes.insert(vec![2], no_vote(2));
assert_eq!(
calculate_consensus_result(&votes, 2, 2.0 / 3.0, true, false),
Some(false)
);
assert_eq!(
calculate_consensus_result(&votes, 2, 2.0 / 3.0, false, false),
Some(false)
);
votes.clear();
votes.insert(vec![1], yes_vote(1));
votes.insert(vec![2], yes_vote(2));
votes.insert(vec![3], yes_vote(3));
votes.insert(vec![4], no_vote(4));
votes.insert(vec![5], no_vote(5));
assert_eq!(
calculate_consensus_result(&votes, 5, 0.9, true, false),
None
);
votes.clear();
votes.insert(vec![1], yes_vote(1));
votes.insert(vec![2], yes_vote(2));
votes.insert(vec![3], no_vote(3));
assert_eq!(
calculate_consensus_result(&votes, 5, 0.5, true, false),
Some(true)
);
votes.clear();
votes.insert(vec![1], yes_vote(1));
assert_eq!(
calculate_consensus_result(&votes, 2, 2.0 / 3.0, true, true),
None
);
votes.clear();
votes.insert(vec![1], yes_vote(1));
votes.insert(vec![2], yes_vote(2));
assert_eq!(
calculate_consensus_result(&votes, 4, 2.0 / 3.0, true, false),
None
);
assert_eq!(
calculate_consensus_result(&votes, 4, 2.0 / 3.0, true, true),
Some(true)
);
assert_eq!(
calculate_consensus_result(&votes, 4, 2.0 / 3.0, false, true),
None
);
votes.clear();
votes.insert(vec![1], yes_vote(1));
votes.insert(vec![2], no_vote(2));
assert_eq!(
calculate_consensus_result(&votes, 4, 2.0 / 3.0, true, true),
Some(true)
);
votes.clear();
votes.insert(vec![1], yes_vote(1));
votes.insert(vec![2], no_vote(2));
votes.insert(vec![3], no_vote(3));
assert_eq!(
calculate_consensus_result(&votes, 4, 2.0 / 3.0, true, true),
None
);
}