use vrf_pbft::pbft::stage::validate_transition;
use vrf_pbft::pbft::{Message, Round};
use vrf_pbft::types::Block;
use vrf_pbft::{Role, Stage};
#[test]
fn valid_stage_transitions() {
assert!(validate_transition(Stage::Idle, Stage::PrePrepare).is_ok());
assert!(validate_transition(Stage::PrePrepare, Stage::Prepare).is_ok());
assert!(validate_transition(Stage::Prepare, Stage::Commit).is_ok());
assert!(validate_transition(Stage::Commit, Stage::Reply).is_ok());
assert!(validate_transition(Stage::Reply, Stage::Done).is_ok());
}
#[test]
fn invalid_stage_transitions() {
assert!(validate_transition(Stage::Idle, Stage::Commit).is_err());
assert!(validate_transition(Stage::Prepare, Stage::PrePrepare).is_err());
assert!(validate_transition(Stage::Reply, Stage::Prepare).is_err());
assert!(validate_transition(Stage::Done, Stage::Idle).is_err());
}
#[test]
fn round_vote_counting() {
let mut round = Round::new(1, Role::Proposer, 3);
assert_eq!(round.prepare_count(), 0);
assert!(!round.has_prepare_quorum());
round.add_prepare_vote(1);
round.add_prepare_vote(2);
assert_eq!(round.prepare_count(), 2);
assert!(!round.has_prepare_quorum());
round.add_prepare_vote(3);
assert_eq!(round.prepare_count(), 3);
assert!(round.has_prepare_quorum());
}
#[test]
fn round_commit_quorum() {
let mut round = Round::new(1, Role::Proposer, 2);
round.add_commit_vote(1);
assert!(!round.has_commit_quorum());
round.add_commit_vote(2);
assert!(round.has_commit_quorum());
}
#[test]
fn round_stage_advancement() {
let mut round = Round::new(1, Role::Proposer, 3);
assert_eq!(round.stage(), Stage::PrePrepare);
round.advance(Stage::Prepare).unwrap();
assert_eq!(round.stage(), Stage::Prepare);
round.advance(Stage::Commit).unwrap();
assert_eq!(round.stage(), Stage::Commit);
round.advance(Stage::Reply).unwrap();
assert_eq!(round.stage(), Stage::Reply);
round.advance(Stage::Done).unwrap();
assert_eq!(round.stage(), Stage::Done);
}
#[test]
fn message_pre_prepare_contains_block() {
let block = Block::genesis();
let msg = Message::pre_prepare(1, 1, block.clone());
assert_eq!(msg.source, 1);
assert_eq!(msg.round, 1);
assert!(msg.block.is_some());
assert!(msg.vote.is_none());
}
#[test]
fn message_prepare_contains_vote() {
let block = Block::genesis();
let msg = Message::prepare(2, 1, block.hash(), true);
assert_eq!(msg.source, 2);
assert!(msg.vote.as_ref().unwrap().approve);
assert!(msg.block.is_none());
}
#[test]
fn message_hashing_is_deterministic() {
let block = Block::genesis();
let msg1 = Message::pre_prepare(1, 1, block.clone());
let msg2 = Message::pre_prepare(1, 1, block);
assert_eq!(msg1.hash(), msg2.hash());
}