Skip to content

Commit

Permalink
beefy rounds: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
acatangiu committed Feb 23, 2022
1 parent 0107be0 commit 8642cba
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 18 deletions.
101 changes: 84 additions & 17 deletions client/beefy/src/round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ where
&self.session_start
}

pub(crate) fn should_vote(&self, round: &(H, N)) -> bool {
pub(crate) fn should_self_vote(&self, round: &(H, N)) -> bool {
Some(round.1.clone()) > self.best_done &&
self.rounds.get(round).map(|tracker| !tracker.has_self_vote()).unwrap_or(true)
}
Expand Down Expand Up @@ -154,9 +154,49 @@ mod tests {

use beefy_primitives::{crypto::Public, ValidatorSet};

use super::Rounds;
use super::{threshold, RoundTracker, Rounds};
use crate::keystore::tests::Keyring;

#[test]
fn round_tracker() {
let mut rt = RoundTracker::default();
let bob_vote = (Keyring::Bob.public(), Keyring::Bob.sign(b"I am committed"));
let threshold = 2;

// self vote not added yet
assert!(!rt.has_self_vote());

// adding new vote allowed
assert!(rt.add_vote(bob_vote.clone(), false));
// adding existing vote not allowed
assert!(!rt.add_vote(bob_vote, false));

// self vote still not added yet
assert!(!rt.has_self_vote());

// vote is not done
assert!(!rt.is_done(threshold));

let alice_vote = (Keyring::Alice.public(), Keyring::Alice.sign(b"I am committed"));
// adding new vote (self vote this time) allowed
assert!(rt.add_vote(alice_vote, true));

// self vote registered
assert!(rt.has_self_vote());
// vote is now done
assert!(rt.is_done(threshold));
}

#[test]
fn vote_threshold() {
assert_eq!(threshold(1), 1);
assert_eq!(threshold(2), 2);
assert_eq!(threshold(3), 3);
assert_eq!(threshold(4), 3);
assert_eq!(threshold(100), 67);
assert_eq!(threshold(300), 201);
}

#[test]
fn new_rounds() {
sp_tracing::try_init_simple();
Expand All @@ -170,61 +210,88 @@ mod tests {
let rounds = Rounds::<H256, NumberFor<Block>>::new(1, validators);

assert_eq!(42, rounds.validator_set_id());

assert_eq!(1, *rounds.session_start());
assert_eq!(
&vec![Keyring::Alice.public(), Keyring::Bob.public(), Keyring::Charlie.public()],
rounds.validators()
);
}

#[test]
fn add_vote() {
fn add_and_conclude_votes() {
sp_tracing::try_init_simple();

let validators = ValidatorSet::<Public>::new(
vec![Keyring::Alice.public(), Keyring::Bob.public(), Keyring::Charlie.public()],
vec![
Keyring::Alice.public(),
Keyring::Bob.public(),
Keyring::Charlie.public(),
Keyring::Eve.public(),
],
Default::default(),
)
.unwrap();
let round = (H256::from_low_u64_le(1), 1);

let mut rounds = Rounds::<H256, NumberFor<Block>>::new(1, validators);

// no self vote yet, should self vote
assert!(rounds.should_self_vote(&round));

// add 1st good vote
assert!(rounds.add_vote(
&(H256::from_low_u64_le(1), 1),
&round,
(Keyring::Alice.public(), Keyring::Alice.sign(b"I am committed")),
true
));
// round not concluded
assert!(rounds.try_conclude(&round).is_none());
// self vote already present, should not self vote
assert!(!rounds.should_self_vote(&round));

assert!(rounds.try_conclude(&(H256::from_low_u64_le(1), 1)).is_none());
// double voting not allowed
assert!(!rounds.add_vote(
&round,
(Keyring::Alice.public(), Keyring::Alice.sign(b"I am committed")),
true
));

// invalid vote
// invalid vote (Dave is not a validator)
assert!(!rounds.add_vote(
&(H256::from_low_u64_le(1), 1),
&round,
(Keyring::Dave.public(), Keyring::Dave.sign(b"I am committed")),
false
));
assert!(rounds.try_conclude(&round).is_none());

assert!(rounds.try_conclude(&(H256::from_low_u64_le(1), 1)).is_none());

// add 2nd good vote
assert!(rounds.add_vote(
&(H256::from_low_u64_le(1), 1),
&round,
(Keyring::Bob.public(), Keyring::Bob.sign(b"I am committed")),
false
));
// round not concluded
assert!(rounds.try_conclude(&round).is_none());

assert!(rounds.try_conclude(&(H256::from_low_u64_le(1), 1)).is_none());

// add 3rd good vote
assert!(rounds.add_vote(
&(H256::from_low_u64_le(1), 1),
&round,
(Keyring::Charlie.public(), Keyring::Charlie.sign(b"I am committed")),
false
));
// round concluded
assert!(rounds.try_conclude(&round).is_some());

assert!(rounds.try_conclude(&(H256::from_low_u64_le(1), 1)).is_some());
// Eve is a validator, but round was concluded, adding vote disallowed
assert!(!rounds.add_vote(
&round,
(Keyring::Eve.public(), Keyring::Eve.sign(b"I am committed")),
false
));
}

#[test]
fn drop() {
fn multiple_rounds() {
sp_tracing::try_init_simple();

let validators = ValidatorSet::<Public>::new(
Expand Down
2 changes: 1 addition & 1 deletion client/beefy/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ where
let payload = Payload::new(known_payload_ids::MMR_ROOT_ID, mmr_root.encode());

if let Some(rounds) = &self.rounds {
if !rounds.should_vote(&(payload.clone(), target_number)) {
if !rounds.should_self_vote(&(payload.clone(), target_number)) {
debug!(target: "beefy", "🥩 Don't double vote for block number: {:?}", target_number);
return
}
Expand Down

0 comments on commit 8642cba

Please sign in to comment.