diff --git a/Code/QUESTIONS.md b/Code/QUESTIONS.md index cd292d13e..700c9fae4 100644 --- a/Code/QUESTIONS.md +++ b/Code/QUESTIONS.md @@ -1,2 +1 @@ - How do we deal with errors? -- How do we parametrize over values, id(v), etc. diff --git a/Code/TODO.md b/Code/TODO.md index 44d4c2a0b..8a7878e9e 100644 --- a/Code/TODO.md +++ b/Code/TODO.md @@ -8,6 +8,4 @@ if complete proposal from a past round => to current one if we have some threshold (f+1) of votes for a future round => skip to that round context (get proposer, get value) -signing contextt - -abstract over values and validator sets +signing context diff --git a/Code/common/Cargo.toml b/Code/common/Cargo.toml index b46b5148e..37a2afea2 100644 --- a/Code/common/Cargo.toml +++ b/Code/common/Cargo.toml @@ -5,3 +5,5 @@ edition = "2021" publish = false [dependencies] +secrecy = "0.8.0" +signature = "2.1.0" diff --git a/Code/common/src/consensus.rs b/Code/common/src/consensus.rs index 0fc01eaac..7666c2eb1 100644 --- a/Code/common/src/consensus.rs +++ b/Code/common/src/consensus.rs @@ -1,5 +1,6 @@ use crate::{ - Address, Height, Proposal, PublicKey, Round, Validator, ValidatorSet, Value, ValueId, Vote, + Address, Height, PrivateKey, Proposal, PublicKey, Round, Signature, SignedVote, SigningScheme, + Validator, ValidatorSet, Value, ValueId, Vote, }; /// This trait allows to abstract over the various datatypes @@ -11,18 +12,23 @@ where type Address: Address; type Height: Height; type Proposal: Proposal; - type PublicKey: PublicKey; type Validator: Validator; type ValidatorSet: ValidatorSet; type Value: Value; type Vote: Vote; - - // FIXME: Remove this and thread it through where necessary - const DUMMY_ADDRESS: Self::Address; + type SigningScheme: SigningScheme; // TODO: Do we need to support multiple signing schemes? // FIXME: Remove altogether const DUMMY_VALUE: Self::Value; + /// Sign the given vote using the given private key. + /// TODO: Maybe move this as concrete methods in `SignedVote`? + fn sign_vote(vote: &Self::Vote, private_key: &PrivateKey) -> Signature; + + /// Verify the given vote's signature using the given public key. + /// TODO: Maybe move this as concrete methods in `SignedVote`? + fn verify_signed_vote(signed_vote: &SignedVote, public_key: &PublicKey) -> bool; + /// Build a new proposal for the given value at the given height, round and POL round. fn new_proposal( height: Self::Height, @@ -33,17 +39,9 @@ where /// Build a new prevote vote by the validator with the given address, /// for the value identified by the given value id, at the given round. - fn new_prevote( - round: Round, - value_id: Option>, - address: Self::Address, - ) -> Self::Vote; + fn new_prevote(round: Round, value_id: Option>) -> Self::Vote; /// Build a new precommit vote by the validator with the given address, /// for the value identified by the given value id, at the given round. - fn new_precommit( - round: Round, - value_id: Option>, - address: Self::Address, - ) -> Self::Vote; + fn new_precommit(round: Round, value_id: Option>) -> Self::Vote; } diff --git a/Code/common/src/lib.rs b/Code/common/src/lib.rs index 4da2130a2..9a0b76501 100644 --- a/Code/common/src/lib.rs +++ b/Code/common/src/lib.rs @@ -1,5 +1,6 @@ //! Common data types and abstractions for the consensus engine. +#![no_std] #![forbid(unsafe_code)] #![deny(unused_crate_dependencies, trivial_casts, trivial_numeric_casts)] #![warn( @@ -14,19 +15,29 @@ mod consensus; mod height; mod proposal; mod round; +mod signed_vote; +mod signing; mod timeout; mod validator_set; mod value; mod vote; +// Re-export `signature` crate for convenience +pub use ::signature; + /// Type alias to make it easier to refer the `ValueId` type of a given `Consensus` engine. pub type ValueId = <::Value as Value>::Id; +pub type PublicKey = <::SigningScheme as SigningScheme>::PublicKey; +pub type PrivateKey = <::SigningScheme as SigningScheme>::PrivateKey; +pub type Signature = <::SigningScheme as SigningScheme>::Signature; pub use consensus::Consensus; pub use height::Height; pub use proposal::Proposal; pub use round::Round; +pub use signed_vote::SignedVote; +pub use signing::SigningScheme; pub use timeout::{Timeout, TimeoutStep}; -pub use validator_set::{Address, PublicKey, Validator, ValidatorSet, VotingPower}; +pub use validator_set::{Address, Validator, ValidatorSet, VotingPower}; pub use value::Value; pub use vote::{Vote, VoteType}; diff --git a/Code/common/src/round.rs b/Code/common/src/round.rs index a281a95c5..79fd567a6 100644 --- a/Code/common/src/round.rs +++ b/Code/common/src/round.rs @@ -1,3 +1,5 @@ +use core::cmp; + /// A round number. /// /// Can be either: @@ -69,13 +71,13 @@ impl Round { } impl PartialOrd for Round { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for Round { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> cmp::Ordering { self.as_i64().cmp(&other.as_i64()) } } diff --git a/Code/common/src/signed_vote.rs b/Code/common/src/signed_vote.rs new file mode 100644 index 000000000..adfd4a268 --- /dev/null +++ b/Code/common/src/signed_vote.rs @@ -0,0 +1,26 @@ +use crate::{Consensus, Signature}; + +// TODO: Do we need to abstract over `SignedVote` as well? + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SignedVote +where + C: Consensus, +{ + pub vote: C::Vote, + pub address: C::Address, + pub signature: Signature, +} + +impl SignedVote +where + C: Consensus, +{ + pub fn new(vote: C::Vote, address: C::Address, signature: Signature) -> Self { + Self { + vote, + address, + signature, + } + } +} diff --git a/Code/common/src/signing.rs b/Code/common/src/signing.rs new file mode 100644 index 000000000..07abc4ae5 --- /dev/null +++ b/Code/common/src/signing.rs @@ -0,0 +1,20 @@ +use core::fmt::Debug; + +use secrecy::{CloneableSecret, DebugSecret, Zeroize}; +use signature::{Keypair, Signer, Verifier}; + +pub trait SigningScheme +where + Self: Clone + Debug + Eq, +{ + type Signature: Clone + Debug + Eq; + + type PublicKey: Clone + Debug + Eq + Verifier; + + type PrivateKey: Clone + + Signer + + Keypair + + Zeroize + + DebugSecret + + CloneableSecret; +} diff --git a/Code/common/src/validator_set.rs b/Code/common/src/validator_set.rs index cd58f1698..29b9b8c50 100644 --- a/Code/common/src/validator_set.rs +++ b/Code/common/src/validator_set.rs @@ -1,19 +1,12 @@ use core::fmt::Debug; -use crate::Consensus; +use crate::{Consensus, PublicKey}; /// Voting power held by a validator. /// /// TODO: Do we need to abstract over this as well? pub type VotingPower = u64; -/// Defines the requirements for a public key type. -pub trait PublicKey -where - Self: Clone + Debug + PartialEq + Eq, -{ -} - /// Defines the requirements for an address. /// /// TODO: Keep this trait or just add the bounds to Consensus::Address? @@ -33,7 +26,7 @@ where fn address(&self) -> &C::Address; /// The public key of the validator, used to verify signatures. - fn public_key(&self) -> &C::PublicKey; + fn public_key(&self) -> &PublicKey; /// The voting power held by the validaror. fn voting_power(&self) -> VotingPower; @@ -53,7 +46,7 @@ where fn get_proposer(&self) -> C::Validator; /// Get the validator with the given public key. - fn get_by_public_key(&self, public_key: &C::PublicKey) -> Option<&C::Validator>; + fn get_by_public_key(&self, public_key: &PublicKey) -> Option<&C::Validator>; /// Get the validator with the given address. fn get_by_address(&self, address: &C::Address) -> Option<&C::Validator>; diff --git a/Code/common/src/vote.rs b/Code/common/src/vote.rs index cb09c58c3..173f6c6a1 100644 --- a/Code/common/src/vote.rs +++ b/Code/common/src/vote.rs @@ -31,8 +31,4 @@ where /// The type of vote. fn vote_type(&self) -> VoteType; - - // FIXME: round message votes should not include address - fn address(&self) -> &C::Address; - fn set_address(&mut self, address: C::Address); } diff --git a/Code/consensus/Cargo.toml b/Code/consensus/Cargo.toml index 0ab2d7f27..b4c137a2b 100644 --- a/Code/consensus/Cargo.toml +++ b/Code/consensus/Cargo.toml @@ -8,3 +8,5 @@ publish = false malachite-common = { version = "0.1.0", path = "../common" } malachite-round = { version = "0.1.0", path = "../round" } malachite-vote = { version = "0.1.0", path = "../vote" } + +secrecy = "0.8.0" diff --git a/Code/consensus/src/executor.rs b/Code/consensus/src/executor.rs index 348359608..e8a14e96e 100644 --- a/Code/consensus/src/executor.rs +++ b/Code/consensus/src/executor.rs @@ -1,8 +1,11 @@ use std::collections::BTreeMap; +use secrecy::{ExposeSecret, Secret}; + +use malachite_common::signature::Keypair; use malachite_common::{ - Consensus, Proposal, Round, Timeout, TimeoutStep, Validator, ValidatorSet, Value, Vote, - VoteType, + Consensus, PrivateKey, Proposal, Round, SignedVote, Timeout, TimeoutStep, Validator, + ValidatorSet, Value, Vote, VoteType, }; use malachite_round::events::Event as RoundEvent; use malachite_round::message::Message as RoundMessage; @@ -10,37 +13,28 @@ use malachite_round::state::State as RoundState; use malachite_vote::count::Threshold; use malachite_vote::keeper::VoteKeeper; +use crate::message::Message; + #[derive(Clone, Debug)] pub struct Executor where C: Consensus, { height: C::Height, - key: C::PublicKey, + key: Secret>, validator_set: C::ValidatorSet, round: Round, votes: VoteKeeper, round_states: BTreeMap>, } -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum Message -where - C: Consensus, -{ - NewRound(Round), - Proposal(C::Proposal), - Vote(C::Vote), - Timeout(Timeout), -} - #[derive(Clone, Debug, PartialEq, Eq)] pub enum Output where C: Consensus, { Propose(C::Proposal), - Vote(C::Vote), + Vote(SignedVote), Decide(Round, C::Value), SetTimeout(Timeout), } @@ -49,7 +43,7 @@ impl Executor where C: Consensus, { - pub fn new(height: C::Height, validator_set: C::ValidatorSet, key: C::PublicKey) -> Self { + pub fn new(height: C::Height, validator_set: C::ValidatorSet, key: PrivateKey) -> Self { let votes = VoteKeeper::new( height.clone(), Round::INITIAL, @@ -58,7 +52,7 @@ where Self { height, - key, + key: Secret::new(key), validator_set, round: Round::INITIAL, votes, @@ -92,19 +86,17 @@ where Some(Output::Propose(proposal)) } - RoundMessage::Vote(mut v) => { - // sign the vote - - // FIXME: round message votes should not include address + RoundMessage::Vote(vote) => { let address = self .validator_set - .get_by_public_key(&self.key)? + .get_by_public_key(&self.key.expose_secret().verifying_key())? .address() .clone(); - v.set_address(address); + let signature = C::sign_vote(&vote, self.key.expose_secret()); + let signed_vote = SignedVote::new(vote, address, signature); - Some(Output::Vote(v)) + Some(Output::Vote(signed_vote)) } RoundMessage::Timeout(timeout) => Some(Output::SetTimeout(timeout)), @@ -120,7 +112,7 @@ where match msg { Message::NewRound(round) => self.apply_new_round(round), Message::Proposal(proposal) => self.apply_proposal(proposal), - Message::Vote(vote) => self.apply_vote(vote), + Message::Vote(signed_vote) => self.apply_vote(signed_vote), Message::Timeout(timeout) => self.apply_timeout(timeout), } } @@ -128,7 +120,7 @@ where fn apply_new_round(&mut self, round: Round) -> Option> { let proposer = self.validator_set.get_proposer(); - let event = if proposer.public_key() == &self.key { + let event = if proposer.public_key() == &self.key.expose_secret().verifying_key() { let value = self.get_value(); RoundEvent::NewRoundProposer(value) } else { @@ -185,18 +177,20 @@ where } } - fn apply_vote(&mut self, vote: C::Vote) -> Option> { - let Some(validator) = self.validator_set.get_by_address(vote.address()) else { - // TODO: Is this the correct behavior? How to log such "errors"? + fn apply_vote(&mut self, signed_vote: SignedVote) -> Option> { + // TODO: How to handle missing validator? + let validator = self.validator_set.get_by_address(&signed_vote.address)?; + + if !C::verify_signed_vote(&signed_vote, validator.public_key()) { + // TODO: How to handle invalid votes? return None; - }; + } - let round = vote.round(); + let round = signed_vote.vote.round(); - let event = match self.votes.apply_vote(vote, validator.voting_power()) { - Some(event) => event, - None => return None, - }; + let event = self + .votes + .apply_vote(signed_vote.vote, validator.voting_power())?; self.apply_event(round, event) } diff --git a/Code/consensus/src/lib.rs b/Code/consensus/src/lib.rs index 9f5b7756d..8c9bb9172 100644 --- a/Code/consensus/src/lib.rs +++ b/Code/consensus/src/lib.rs @@ -11,3 +11,4 @@ #![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::panic))] pub mod executor; +pub mod message; diff --git a/Code/consensus/src/message.rs b/Code/consensus/src/message.rs new file mode 100644 index 000000000..a82aa0de3 --- /dev/null +++ b/Code/consensus/src/message.rs @@ -0,0 +1,13 @@ +use malachite_common::{Consensus, Round, SignedVote, Timeout}; + +/// Messages that can be received and broadcast by the consensus executor. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Message +where + C: Consensus, +{ + NewRound(Round), + Proposal(C::Proposal), + Vote(SignedVote), + Timeout(Timeout), +} diff --git a/Code/round/src/message.rs b/Code/round/src/message.rs index 2f45c79c0..dd186fd10 100644 --- a/Code/round/src/message.rs +++ b/Code/round/src/message.rs @@ -37,12 +37,12 @@ where Message::Proposal(C::new_proposal(height, round, value, pol_round)) } - pub fn prevote(round: Round, value_id: Option>, address: C::Address) -> Self { - Message::Vote(C::new_prevote(round, value_id, address)) + pub fn prevote(round: Round, value_id: Option>) -> Self { + Message::Vote(C::new_prevote(round, value_id)) } - pub fn precommit(round: Round, value_id: Option>, address: C::Address) -> Self { - Message::Vote(C::new_precommit(round, value_id, address)) + pub fn precommit(round: Round, value_id: Option>) -> Self { + Message::Vote(C::new_precommit(round, value_id)) } pub fn timeout(round: Round, step: TimeoutStep) -> Self { diff --git a/Code/round/src/state_machine.rs b/Code/round/src/state_machine.rs index 884029d30..bc8bc6b69 100644 --- a/Code/round/src/state_machine.rs +++ b/Code/round/src/state_machine.rs @@ -171,7 +171,7 @@ where None => Some(proposed), // not locked, prevote the value }; - let message = Message::prevote(state.round, value, C::DUMMY_ADDRESS); + let message = Message::prevote(state.round, value); Transition::to(state.next_step()).with_message(message) } @@ -182,7 +182,7 @@ pub fn prevote_nil(state: State) -> Transition where C: Consensus, { - let message = Message::prevote(state.round, None, C::DUMMY_ADDRESS); + let message = Message::prevote(state.round, None); Transition::to(state.next_step()).with_message(message) } @@ -200,7 +200,7 @@ pub fn precommit(state: State, value_id: ValueId) -> Transition where C: Consensus, { - let message = Message::precommit(state.round, Some(value_id), C::DUMMY_ADDRESS); + let message = Message::precommit(state.round, Some(value_id)); let Some(value) = state .proposal @@ -223,7 +223,7 @@ pub fn precommit_nil(state: State) -> Transition where C: Consensus, { - let message = Message::precommit(state.round, None, C::DUMMY_ADDRESS); + let message = Message::precommit(state.round, None); Transition::to(state.next_step()).with_message(message) } diff --git a/Code/test/Cargo.toml b/Code/test/Cargo.toml index d8234efa7..f06726148 100644 --- a/Code/test/Cargo.toml +++ b/Code/test/Cargo.toml @@ -5,7 +5,13 @@ edition = "2021" publish = false [dependencies] -malachite-common = { version = "0.1.0", path = "../common" } +malachite-common = { version = "0.1.0", path = "../common" } malachite-consensus = { version = "0.1.0", path = "../consensus" } -malachite-round = { version = "0.1.0", path = "../round" } -malachite-vote = { version = "0.1.0", path = "../vote" } +malachite-round = { version = "0.1.0", path = "../round" } +malachite-vote = { version = "0.1.0", path = "../vote" } + +ed25519-consensus = "2.1.0" +signature = "2.1.0" +rand = { version = "0.8.5", features = ["std_rng"] } +sha2 = "0.10.8" +secrecy = "0.8.0" diff --git a/Code/test/src/consensus.rs b/Code/test/src/consensus.rs index ebe110c5d..80abb1035 100644 --- a/Code/test/src/consensus.rs +++ b/Code/test/src/consensus.rs @@ -1,8 +1,10 @@ use malachite_common::Consensus; use malachite_common::Round; +use malachite_common::SignedVote; use crate::height::*; use crate::proposal::*; +use crate::signing::{Ed25519, PrivateKey, PublicKey, Signature}; use crate::validator_set::*; use crate::value::*; use crate::vote::*; @@ -14,25 +16,35 @@ impl Consensus for TestConsensus { type Address = Address; type Height = Height; type Proposal = Proposal; - type PublicKey = PublicKey; type ValidatorSet = ValidatorSet; type Validator = Validator; type Value = Value; type Vote = Vote; - - const DUMMY_ADDRESS: Address = Address::new(42); + type SigningScheme = Ed25519; const DUMMY_VALUE: Self::Value = Value::new(9999); + fn sign_vote(vote: &Self::Vote, private_key: &PrivateKey) -> Signature { + use signature::Signer; + private_key.sign(&vote.to_bytes()) + } + + fn verify_signed_vote(signed_vote: &SignedVote, public_key: &PublicKey) -> bool { + use signature::Verifier; + public_key + .verify(&signed_vote.vote.to_bytes(), &signed_vote.signature) + .is_ok() + } + fn new_proposal(height: Height, round: Round, value: Value, pol_round: Round) -> Proposal { Proposal::new(height, round, value, pol_round) } - fn new_prevote(round: Round, value_id: Option, address: Address) -> Vote { - Vote::new_prevote(round, value_id, address) + fn new_prevote(round: Round, value_id: Option) -> Vote { + Vote::new_prevote(round, value_id) } - fn new_precommit(round: Round, value_id: Option, address: Address) -> Vote { - Vote::new_precommit(round, value_id, address) + fn new_precommit(round: Round, value_id: Option) -> Vote { + Vote::new_precommit(round, value_id) } } diff --git a/Code/test/src/lib.rs b/Code/test/src/lib.rs index 4e9cd3aeb..9da94495e 100644 --- a/Code/test/src/lib.rs +++ b/Code/test/src/lib.rs @@ -4,6 +4,7 @@ mod consensus; mod height; mod proposal; +mod signing; mod validator_set; mod value; mod vote; @@ -11,6 +12,7 @@ mod vote; pub use crate::consensus::*; pub use crate::height::*; pub use crate::proposal::*; +pub use crate::signing::*; pub use crate::validator_set::*; pub use crate::value::*; pub use crate::vote::*; diff --git a/Code/test/src/signing.rs b/Code/test/src/signing.rs new file mode 100644 index 000000000..af120d071 --- /dev/null +++ b/Code/test/src/signing.rs @@ -0,0 +1,89 @@ +use malachite_common::SigningScheme; +use rand::{CryptoRng, RngCore}; +use secrecy::{CloneableSecret, DebugSecret, Zeroize}; +use signature::{Keypair, Signer, Verifier}; + +pub use ed25519_consensus::Signature; + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct Ed25519; + +impl Ed25519 { + pub fn generate_keypair(rng: R) -> PrivateKey + where + R: RngCore + CryptoRng, + { + PrivateKey::generate(rng) + } +} + +impl SigningScheme for Ed25519 { + type Signature = Signature; + type PublicKey = PublicKey; + type PrivateKey = PrivateKey; +} + +#[derive(Clone, Debug)] +pub struct PrivateKey(ed25519_consensus::SigningKey); + +impl PrivateKey { + pub fn generate(rng: R) -> Self + where + R: RngCore + CryptoRng, + { + let signing_key = ed25519_consensus::SigningKey::new(rng); + + Self(signing_key) + } + + pub fn public_key(&self) -> PublicKey { + PublicKey::new(self.0.verification_key()) + } +} + +impl Signer for PrivateKey { + fn try_sign(&self, msg: &[u8]) -> Result { + Ok(self.0.sign(msg)) + } +} + +impl Keypair for PrivateKey { + type VerifyingKey = PublicKey; + + fn verifying_key(&self) -> Self::VerifyingKey { + self.public_key() + } +} + +impl Zeroize for PrivateKey { + fn zeroize(&mut self) { + self.0.zeroize() + } +} + +impl DebugSecret for PrivateKey {} +impl CloneableSecret for PrivateKey {} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct PublicKey(ed25519_consensus::VerificationKey); + +impl PublicKey { + pub fn new(key: impl Into) -> Self { + Self(key.into()) + } + + pub fn hash(&self) -> [u8; 32] { + use sha2::{Digest, Sha256}; + let mut hasher = Sha256::new(); + hasher.update(self.0.as_bytes()); + hasher.finalize().into() + } +} + +impl Verifier for PublicKey { + fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), signature::Error> { + self.0 + .verify(signature, msg) + .map_err(|_| signature::Error::new()) + } +} diff --git a/Code/test/src/validator_set.rs b/Code/test/src/validator_set.rs index e50b9a781..985da7d23 100644 --- a/Code/test/src/validator_set.rs +++ b/Code/test/src/validator_set.rs @@ -2,30 +2,24 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use malachite_common::VotingPower; -use crate::TestConsensus; - -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct PublicKey(Vec); - -impl PublicKey { - pub const fn new(value: Vec) -> Self { - Self(value) - } - - pub fn hash(&self) -> u64 { - self.0.iter().fold(0, |acc, x| acc ^ *x as u64) - } -} - -impl malachite_common::PublicKey for PublicKey {} +use crate::{signing::PublicKey, TestConsensus}; #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct Address(u64); +pub struct Address([u8; Self::LENGTH]); impl Address { - pub const fn new(value: u64) -> Self { + const LENGTH: usize = 20; + + pub const fn new(value: [u8; Self::LENGTH]) -> Self { Self(value) } + + pub fn from_public_key(public_key: &PublicKey) -> Self { + let hash = public_key.hash(); + let mut address = [0; Self::LENGTH]; + address.copy_from_slice(&hash[..Self::LENGTH]); + Self(address) + } } impl malachite_common::Address for Address {} @@ -41,15 +35,11 @@ pub struct Validator { impl Validator { pub fn new(public_key: PublicKey, voting_power: VotingPower) -> Self { Self { - address: Address(public_key.hash()), + address: Address::from_public_key(&public_key), public_key, voting_power, } } - - pub fn hash(&self) -> u64 { - self.public_key.hash() // TODO - } } impl malachite_common::Validator for Validator { @@ -108,9 +98,7 @@ impl ValidatorSet { v.voting_power = val.voting_power; } - dbg!(self.total_voting_power()); Self::sort_validators(&mut self.validators); - dbg!(self.total_voting_power()); } /// Remove a validator from the set @@ -131,11 +119,16 @@ impl ValidatorSet { /// In place sort and deduplication of a list of validators fn sort_validators(vals: &mut Vec) { - use core::cmp::Reverse; - // Sort the validators according to the current Tendermint requirements + // + // use core::cmp::Reverse; + // // (v. 0.34 -> first by validator power, descending, then by address, ascending) - vals.sort_unstable_by_key(|v| (Reverse(v.voting_power), v.address)); + // vals.sort_unstable_by(|v1, v2| { + // let a = (Reverse(v1.voting_power), &v1.address); + // let b = (Reverse(v2.voting_power), &v2.address); + // a.cmp(&b) + // }); vals.dedup(); } @@ -169,22 +162,36 @@ impl malachite_common::ValidatorSet for ValidatorSet { #[cfg(test)] mod tests { + use rand::rngs::StdRng; + use rand::SeedableRng; + use super::*; + use crate::PrivateKey; + #[test] fn add_update_remove() { - let v1 = Validator::new(PublicKey(vec![1]), 1); - let v2 = Validator::new(PublicKey(vec![2]), 2); - let v3 = Validator::new(PublicKey(vec![3]), 3); + let mut rng = StdRng::seed_from_u64(0x42); + + let sk1 = PrivateKey::generate(&mut rng); + let sk2 = PrivateKey::generate(&mut rng); + let sk3 = PrivateKey::generate(&mut rng); + let sk4 = PrivateKey::generate(&mut rng); + let sk5 = PrivateKey::generate(&mut rng); + let sk6 = PrivateKey::generate(&mut rng); + + let v1 = Validator::new(sk1.public_key(), 1); + let v2 = Validator::new(sk2.public_key(), 2); + let v3 = Validator::new(sk3.public_key(), 3); let mut vs = ValidatorSet::new(vec![v1, v2, v3]); assert_eq!(vs.total_voting_power(), 6); - let v4 = Validator::new(PublicKey(vec![4]), 4); + let v4 = Validator::new(sk4.public_key(), 4); vs.add(v4); assert_eq!(vs.total_voting_power(), 10); - let mut v5 = Validator::new(PublicKey(vec![5]), 5); + let mut v5 = Validator::new(sk5.public_key(), 5); vs.update(v5.clone()); // no effect assert_eq!(vs.total_voting_power(), 10); @@ -198,7 +205,7 @@ mod tests { vs.remove(&v5.address); assert_eq!(vs.total_voting_power(), 10); - let v6 = Validator::new(PublicKey(vec![6]), 6); + let v6 = Validator::new(sk6.public_key(), 6); vs.remove(&v6.address); // no effect assert_eq!(vs.total_voting_power(), 10); } diff --git a/Code/test/src/value.rs b/Code/test/src/value.rs index 2f45f6abe..3954d2868 100644 --- a/Code/test/src/value.rs +++ b/Code/test/src/value.rs @@ -5,6 +5,10 @@ impl ValueId { pub const fn new(id: u64) -> Self { Self(id) } + + pub const fn as_u64(&self) -> u64 { + self.0 + } } /// The value to decide on diff --git a/Code/test/src/vote.rs b/Code/test/src/vote.rs index 6ba30a3e0..5601b8a7e 100644 --- a/Code/test/src/vote.rs +++ b/Code/test/src/vote.rs @@ -1,6 +1,7 @@ -use malachite_common::{Round, VoteType}; +use malachite_common::{Round, SignedVote, VoteType}; +use signature::Signer; -use crate::{Address, TestConsensus, ValueId}; +use crate::{Address, PrivateKey, TestConsensus, ValueId}; /// A vote for a value in a round #[derive(Clone, Debug, PartialEq, Eq)] @@ -8,25 +9,51 @@ pub struct Vote { pub typ: VoteType, pub round: Round, pub value: Option, - pub address: Address, } impl Vote { - pub fn new_prevote(round: Round, value: Option, address: Address) -> Self { + pub fn new_prevote(round: Round, value: Option) -> Self { Self { typ: VoteType::Prevote, round, value, - address, } } - pub fn new_precommit(round: Round, value: Option, address: Address) -> Self { + pub fn new_precommit(round: Round, value: Option) -> Self { Self { typ: VoteType::Precommit, round, value, + } + } + + // TODO: Use the canonical vote + pub fn to_bytes(&self) -> Vec { + let vtpe = match self.typ { + VoteType::Prevote => 0, + VoteType::Precommit => 1, + }; + + let mut bytes = vec![vtpe]; + bytes.extend_from_slice(&self.round.as_i64().to_be_bytes()); + bytes.extend_from_slice( + &self + .value + .map(|v| v.as_u64().to_be_bytes()) + .unwrap_or_default(), + ); + bytes + } + + pub fn signed(self, private_key: &PrivateKey) -> SignedVote { + let address = Address::from_public_key(&private_key.public_key()); + let signature = private_key.sign(&self.to_bytes()); + + SignedVote { + vote: self, address, + signature, } } } @@ -47,12 +74,4 @@ impl malachite_common::Vote for Vote { fn vote_type(&self) -> VoteType { self.typ } - - fn address(&self) -> &Address { - &self.address - } - - fn set_address(&mut self, address: Address) { - self.address = address; - } } diff --git a/Code/test/tests/consensus_executor.rs b/Code/test/tests/consensus_executor.rs index 0f4ae491f..5dac360da 100644 --- a/Code/test/tests/consensus_executor.rs +++ b/Code/test/tests/consensus_executor.rs @@ -1,8 +1,11 @@ use malachite_common::{Consensus, Round, Timeout}; -use malachite_consensus::executor::{Executor, Message, Output}; +use malachite_consensus::executor::{Executor, Output}; +use malachite_consensus::message::Message; use malachite_round::state::{RoundValue, State, Step}; -use malachite_test::{Height, Proposal, PublicKey, TestConsensus, Validator, ValidatorSet, Vote}; +use malachite_test::{Height, PrivateKey, Proposal, TestConsensus, Validator, ValidatorSet, Vote}; +use rand::rngs::StdRng; +use rand::SeedableRng; struct TestStep { desc: &'static str, @@ -24,20 +27,26 @@ fn to_input_msg(output: Output) -> Option> fn executor_steps_proposer() { let value = TestConsensus::DUMMY_VALUE; // TODO: get value from external source let value_id = value.id(); - let v1 = Validator::new(PublicKey::new(vec![1]), 1); - let v2 = Validator::new(PublicKey::new(vec![2]), 1); - let v3 = Validator::new(PublicKey::new(vec![3]), 1); - let my_address = v1.address; - let key = v1.clone().public_key; // we are proposer + + let mut rng = StdRng::seed_from_u64(0x42); + + let sk1 = PrivateKey::generate(&mut rng); + let sk2 = PrivateKey::generate(&mut rng); + let sk3 = PrivateKey::generate(&mut rng); + + let v1 = Validator::new(sk1.public_key(), 1); + let v2 = Validator::new(sk2.public_key(), 2); + let v3 = Validator::new(sk3.public_key(), 3); + + let my_sk = sk1; let vs = ValidatorSet::new(vec![v1, v2.clone(), v3.clone()]); - let mut executor = Executor::new(Height::new(1), vs, key.clone()); + let mut executor = Executor::new(Height::new(1), vs, my_sk.clone()); let proposal = Proposal::new(Height::new(1), Round::new(0), value.clone(), Round::new(-1)); let steps = vec![ - // Start round 0, we are proposer, propose value TestStep { desc: "Start round 0, we are proposer, propose value", input_message: Some(Message::NewRound(Round::new(0))), @@ -51,15 +60,12 @@ fn executor_steps_proposer() { valid: None, }, }, - // Receive our own proposal, prevote for it (v1) TestStep { desc: "Receive our own proposal, prevote for it (v1)", input_message: None, - expected_output: Some(Output::Vote(Vote::new_prevote( - Round::new(0), - Some(value_id), - my_address, - ))), + expected_output: Some(Output::Vote( + Vote::new_prevote(Round::new(0), Some(value_id)).signed(&my_sk), + )), new_state: State { height: Height::new(1), round: Round::new(0), @@ -69,7 +75,6 @@ fn executor_steps_proposer() { valid: None, }, }, - // Receive our own prevote v1 TestStep { desc: "Receive our own prevote v1", input_message: None, @@ -83,14 +88,11 @@ fn executor_steps_proposer() { valid: None, }, }, - // v2 prevotes for our proposal TestStep { desc: "v2 prevotes for our proposal", - input_message: Some(Message::Vote(Vote::new_prevote( - Round::new(0), - Some(value_id), - v2.address, - ))), + input_message: Some(Message::Vote( + Vote::new_prevote(Round::new(0), Some(value_id)).signed(&sk2), + )), expected_output: None, new_state: State { height: Height::new(1), @@ -101,19 +103,14 @@ fn executor_steps_proposer() { valid: None, }, }, - // v3 prevotes for our proposal, we get +2/3 prevotes, precommit for it (v1) TestStep { desc: "v3 prevotes for our proposal, we get +2/3 prevotes, precommit for it (v1)", - input_message: Some(Message::Vote(Vote::new_prevote( - Round::new(0), - Some(value_id), - v3.address, - ))), - expected_output: Some(Output::Vote(Vote::new_precommit( - Round::new(0), - Some(value_id), - my_address, - ))), + input_message: Some(Message::Vote( + Vote::new_prevote(Round::new(0), Some(value_id)).signed(&sk3), + )), + expected_output: Some(Output::Vote( + Vote::new_precommit(Round::new(0), Some(value_id)).signed(&my_sk), + )), new_state: State { height: Height::new(1), round: Round::new(0), @@ -129,7 +126,6 @@ fn executor_steps_proposer() { }), }, }, - // v1 receives its own precommit TestStep { desc: "v1 receives its own precommit", input_message: None, @@ -149,14 +145,11 @@ fn executor_steps_proposer() { }), }, }, - // v2 precommits for our proposal TestStep { desc: "v2 precommits for our proposal", - input_message: Some(Message::Vote(Vote::new_precommit( - Round::new(0), - Some(value_id), - v2.address, - ))), + input_message: Some(Message::Vote( + Vote::new_precommit(Round::new(0), Some(value_id)).signed(&sk2), + )), expected_output: None, new_state: State { height: Height::new(1), @@ -173,14 +166,11 @@ fn executor_steps_proposer() { }), }, }, - // v3 precommits for our proposal, we get +2/3 precommits, decide it (v1) TestStep { desc: "v3 precommits for our proposal, we get +2/3 precommits, decide it (v1)", - input_message: Some(Message::Vote(Vote::new_precommit( - Round::new(0), - Some(value_id), - v2.address, - ))), + input_message: Some(Message::Vote( + Vote::new_precommit(Round::new(0), Some(value_id)).signed(&sk2), + )), expected_output: Some(Output::Decide(Round::new(0), value.clone())), new_state: State { height: Height::new(1), @@ -202,6 +192,8 @@ fn executor_steps_proposer() { let mut previous_message = None; for step in steps { + println!("Step: {}", step.desc); + let execute_message = step .input_message .unwrap_or_else(|| previous_message.unwrap()); @@ -221,21 +213,25 @@ fn executor_steps_not_proposer() { let value = TestConsensus::DUMMY_VALUE; // TODO: get value from external source let value_id = value.id(); - let v1 = Validator::new(PublicKey::new(vec![1]), 1); - let v2 = Validator::new(PublicKey::new(vec![2]), 1); - let v3 = Validator::new(PublicKey::new(vec![3]), 1); + let mut rng = StdRng::seed_from_u64(0x42); + + let sk1 = PrivateKey::generate(&mut rng); + let sk2 = PrivateKey::generate(&mut rng); + let sk3 = PrivateKey::generate(&mut rng); + + let v1 = Validator::new(sk1.public_key(), 1); + let v2 = Validator::new(sk2.public_key(), 2); + let v3 = Validator::new(sk3.public_key(), 3); // Proposer is v1, so we are not the proposer - let my_address = v2.address; - let my_key = v2.public_key.clone(); + let my_sk = &sk2; let vs = ValidatorSet::new(vec![v1.clone(), v2.clone(), v3.clone()]); - let mut executor = Executor::new(Height::new(1), vs, my_key); + let mut executor = Executor::new(Height::new(1), vs, my_sk.clone()); let proposal = Proposal::new(Height::new(1), Round::new(0), value.clone(), Round::new(-1)); let steps = vec![ - // Start round 0, we are not the proposer TestStep { desc: "Start round 0, we are not the proposer", input_message: Some(Message::NewRound(Round::new(0))), @@ -249,15 +245,12 @@ fn executor_steps_not_proposer() { valid: None, }, }, - // Receive a proposal, prevote for it (v1) TestStep { - desc: "Receive a proposal, prevote for it (v1)", + desc: "Receive a proposal, prevote for it (v2)", input_message: Some(Message::Proposal(proposal.clone())), - expected_output: Some(Output::Vote(Vote::new_prevote( - Round::new(0), - Some(value_id), - my_address, - ))), + expected_output: Some(Output::Vote( + Vote::new_prevote(Round::new(0), Some(value_id)).signed(my_sk), + )), new_state: State { height: Height::new(1), round: Round::new(0), @@ -267,9 +260,8 @@ fn executor_steps_not_proposer() { valid: None, }, }, - // Receive our own prevote v1 TestStep { - desc: "Receive our own prevote v1", + desc: "Receive our own prevote", input_message: None, expected_output: None, new_state: State { @@ -281,14 +273,11 @@ fn executor_steps_not_proposer() { valid: None, }, }, - // v2 prevotes for its own proposal TestStep { desc: "v2 prevotes for its own proposal", - input_message: Some(Message::Vote(Vote::new_prevote( - Round::new(0), - Some(value_id), - v2.address, - ))), + input_message: Some(Message::Vote( + Vote::new_prevote(Round::new(0), Some(value_id)).signed(&sk2), + )), expected_output: None, new_state: State { height: Height::new(1), @@ -299,19 +288,14 @@ fn executor_steps_not_proposer() { valid: None, }, }, - // v3 prevotes for v2's proposal, it gets +2/3 prevotes, precommit for it (v1) TestStep { - desc: "v3 prevotes for v2's proposal, it gets +2/3 prevotes, precommit for it (v1)", - input_message: Some(Message::Vote(Vote::new_prevote( - Round::new(0), - Some(value_id), - v3.address, - ))), - expected_output: Some(Output::Vote(Vote::new_precommit( - Round::new(0), - Some(value_id), - my_address, - ))), + desc: "v3 prevotes for v2's proposal, it gets +2/3 prevotes, precommit for it (v2)", + input_message: Some(Message::Vote( + Vote::new_prevote(Round::new(0), Some(value_id)).signed(&sk3), + )), + expected_output: Some(Output::Vote( + Vote::new_precommit(Round::new(0), Some(value_id)).signed(my_sk), + )), new_state: State { height: Height::new(1), round: Round::new(0), @@ -327,9 +311,8 @@ fn executor_steps_not_proposer() { }), }, }, - // v1 receives its own precommit TestStep { - desc: "v1 receives its own precommit", + desc: "we receive our own precommit", input_message: None, expected_output: None, new_state: State { @@ -347,14 +330,11 @@ fn executor_steps_not_proposer() { }), }, }, - // v2 precommits its proposal TestStep { - desc: "v2 precommits its proposal", - input_message: Some(Message::Vote(Vote::new_precommit( - Round::new(0), - Some(value_id), - v2.address, - ))), + desc: "v1 precommits its proposal", + input_message: Some(Message::Vote( + Vote::new_precommit(Round::new(0), Some(value_id)).signed(&sk1), + )), expected_output: None, new_state: State { height: Height::new(1), @@ -371,14 +351,11 @@ fn executor_steps_not_proposer() { }), }, }, - // v3 precommits for v2's proposal, it gets +2/3 precommits, decide it (v1) TestStep { - desc: "v3 precommits for v2's proposal, it gets +2/3 precommits, decide it (v1)", - input_message: Some(Message::Vote(Vote::new_precommit( - Round::new(0), - Some(value_id), - v2.address, - ))), + desc: "v3 precommits for v1's proposal, it gets +2/3 precommits, decide it", + input_message: Some(Message::Vote( + Vote::new_precommit(Round::new(0), Some(value_id)).signed(&sk3), + )), expected_output: Some(Output::Decide(Round::new(0), value.clone())), new_state: State { height: Height::new(1), @@ -421,16 +398,21 @@ fn executor_steps_not_proposer_timeout() { let value = TestConsensus::DUMMY_VALUE; // TODO: get value from external source let value_id = value.id(); - let v1 = Validator::new(PublicKey::new(vec![1]), 1); - let v2 = Validator::new(PublicKey::new(vec![2]), 1); - let v3 = Validator::new(PublicKey::new(vec![3]), 2); + let mut rng = StdRng::seed_from_u64(0x42); + + let sk1 = PrivateKey::generate(&mut rng); + let sk2 = PrivateKey::generate(&mut rng); + let sk3 = PrivateKey::generate(&mut rng); + + let v1 = Validator::new(sk1.public_key(), 1); + let v2 = Validator::new(sk2.public_key(), 1); + let v3 = Validator::new(sk3.public_key(), 3); // Proposer is v1, so we are not the proposer - let my_address = v2.address; - let my_key = v2.public_key.clone(); + let my_sk = sk2; let vs = ValidatorSet::new(vec![v1.clone(), v2.clone(), v3.clone()]); - let mut executor = Executor::new(Height::new(1), vs, my_key); + let mut executor = Executor::new(Height::new(1), vs, my_sk.clone()); let steps = vec![ // Start round 0, we are not the proposer @@ -451,11 +433,9 @@ fn executor_steps_not_proposer_timeout() { TestStep { desc: "Receive a propose timeout, prevote for nil (v1)", input_message: Some(Message::Timeout(Timeout::propose(Round::new(0)))), - expected_output: Some(Output::Vote(Vote::new_prevote( - Round::new(0), - None, - my_address, - ))), + expected_output: Some(Output::Vote( + Vote::new_prevote(Round::new(0), None).signed(&my_sk), + )), new_state: State { height: Height::new(1), round: Round::new(0), @@ -482,11 +462,9 @@ fn executor_steps_not_proposer_timeout() { // v2 prevotes for its own proposal TestStep { desc: "v2 prevotes for its own proposal", - input_message: Some(Message::Vote(Vote::new_prevote( - Round::new(0), - Some(value_id), - v2.address, - ))), + input_message: Some(Message::Vote( + Vote::new_prevote(Round::new(0), Some(value_id)).signed(&sk1), + )), expected_output: None, new_state: State { height: Height::new(1), @@ -500,16 +478,12 @@ fn executor_steps_not_proposer_timeout() { // v3 prevotes for nil, it gets +2/3 prevotes, precommit for it (v1) TestStep { desc: "v3 prevotes for nil, it gets +2/3 prevotes, precommit for it (v1)", - input_message: Some(Message::Vote(Vote::new_prevote( - Round::new(0), - None, - v3.address, - ))), - expected_output: Some(Output::Vote(Vote::new_precommit( - Round::new(0), - None, - my_address, - ))), + input_message: Some(Message::Vote( + Vote::new_prevote(Round::new(0), None).signed(&sk3), + )), + expected_output: Some(Output::Vote( + Vote::new_precommit(Round::new(0), None).signed(&my_sk), + )), new_state: State { height: Height::new(1), round: Round::new(0), @@ -536,11 +510,9 @@ fn executor_steps_not_proposer_timeout() { // v2 precommits its proposal TestStep { desc: "v2 precommits its proposal", - input_message: Some(Message::Vote(Vote::new_precommit( - Round::new(0), - Some(value_id), - v2.address, - ))), + input_message: Some(Message::Vote( + Vote::new_precommit(Round::new(0), Some(value_id)).signed(&sk1), + )), expected_output: None, new_state: State { height: Height::new(1), @@ -554,11 +526,9 @@ fn executor_steps_not_proposer_timeout() { // v3 precommits for nil TestStep { desc: "v3 precommits for nil", - input_message: Some(Message::Vote(Vote::new_precommit( - Round::new(0), - None, - v3.address, - ))), + input_message: Some(Message::Vote( + Vote::new_precommit(Round::new(0), None).signed(&sk3), + )), expected_output: None, new_state: State { height: Height::new(1), diff --git a/Code/test/tests/round.rs b/Code/test/tests/round.rs index 238e35b89..44757b921 100644 --- a/Code/test/tests/round.rs +++ b/Code/test/tests/round.rs @@ -1,6 +1,6 @@ use malachite_test::{Height, Proposal, TestConsensus, Value}; -use malachite_common::{Consensus, Round, Timeout, TimeoutStep}; +use malachite_common::{Round, Timeout, TimeoutStep}; use malachite_round::events::Event; use malachite_round::message::Message; use malachite_round::state::{State, Step}; @@ -54,10 +54,6 @@ fn test_prevote() { assert_eq!(transition.state.step, Step::Prevote); assert_eq!( transition.message.unwrap(), - Message::prevote( - Round::new(1), - Some(value.id()), - TestConsensus::DUMMY_ADDRESS - ) + Message::prevote(Round::new(1), Some(value.id()),) ); } diff --git a/Code/test/tests/round_votes.rs b/Code/test/tests/round_votes.rs index e1367e1c4..fcd164fcd 100644 --- a/Code/test/tests/round_votes.rs +++ b/Code/test/tests/round_votes.rs @@ -2,7 +2,7 @@ use malachite_common::Round; use malachite_vote::count::Threshold; use malachite_vote::RoundVotes; -use malachite_test::{Address, Height, TestConsensus, ValueId, Vote}; +use malachite_test::{Height, TestConsensus, ValueId, Vote}; #[test] fn add_votes_nil() { @@ -12,7 +12,7 @@ fn add_votes_nil() { RoundVotes::new(Height::new(1), Round::new(0), total); // add a vote for nil. nothing changes. - let vote = Vote::new_prevote(Round::new(0), None, Address::new(1)); + let vote = Vote::new_prevote(Round::new(0), None); let thresh = round_votes.add_vote(vote.clone(), 1); assert_eq!(thresh, Threshold::Init); @@ -36,7 +36,7 @@ fn add_votes_single_value() { RoundVotes::new(Height::new(1), Round::new(0), total); // add a vote. nothing changes. - let vote = Vote::new_prevote(Round::new(0), val, Address::new(1)); + let vote = Vote::new_prevote(Round::new(0), val); let thresh = round_votes.add_vote(vote.clone(), weight); assert_eq!(thresh, Threshold::Init); @@ -45,7 +45,7 @@ fn add_votes_single_value() { assert_eq!(thresh, Threshold::Init); // add a vote for nil, get Thresh::Any - let vote_nil = Vote::new_prevote(Round::new(0), None, Address::new(2)); + let vote_nil = Vote::new_prevote(Round::new(0), None); let thresh = round_votes.add_vote(vote_nil, weight); assert_eq!(thresh, Threshold::Any); @@ -66,17 +66,17 @@ fn add_votes_multi_values() { RoundVotes::new(Height::new(1), Round::new(0), total); // add a vote for v1. nothing changes. - let vote1 = Vote::new_precommit(Round::new(0), val1, Address::new(1)); + let vote1 = Vote::new_precommit(Round::new(0), val1); let thresh = round_votes.add_vote(vote1.clone(), 1); assert_eq!(thresh, Threshold::Init); // add a vote for v2. nothing changes. - let vote2 = Vote::new_precommit(Round::new(0), val2, Address::new(2)); + let vote2 = Vote::new_precommit(Round::new(0), val2); let thresh = round_votes.add_vote(vote2.clone(), 1); assert_eq!(thresh, Threshold::Init); // add a vote for nil. nothing changes. - let vote_nil = Vote::new_precommit(Round::new(0), None, Address::new(3)); + let vote_nil = Vote::new_precommit(Round::new(0), None); let thresh = round_votes.add_vote(vote_nil.clone(), 1); assert_eq!(thresh, Threshold::Init); diff --git a/Code/test/tests/vote_keeper.rs b/Code/test/tests/vote_keeper.rs index c5c207edb..ed976b9e5 100644 --- a/Code/test/tests/vote_keeper.rs +++ b/Code/test/tests/vote_keeper.rs @@ -2,13 +2,13 @@ use malachite_common::Round; use malachite_round::events::Event; use malachite_vote::keeper::VoteKeeper; -use malachite_test::{Address, Height, TestConsensus, ValueId, Vote}; +use malachite_test::{Height, TestConsensus, ValueId, Vote}; #[test] fn prevote_apply_nil() { let mut keeper: VoteKeeper = VoteKeeper::new(Height::new(1), Round::INITIAL, 3); - let vote = Vote::new_prevote(Round::new(0), None, Address::new(1)); + let vote = Vote::new_prevote(Round::new(0), None); let event = keeper.apply_vote(vote.clone(), 1); assert_eq!(event, None); @@ -24,7 +24,7 @@ fn prevote_apply_nil() { fn precommit_apply_nil() { let mut keeper: VoteKeeper = VoteKeeper::new(Height::new(1), Round::INITIAL, 3); - let vote = Vote::new_precommit(Round::new(0), None, Address::new(1)); + let vote = Vote::new_precommit(Round::new(0), None); let event = keeper.apply_vote(vote.clone(), 1); assert_eq!(event, None); @@ -42,7 +42,7 @@ fn prevote_apply_single_value() { let v = ValueId::new(1); let val = Some(v); - let vote = Vote::new_prevote(Round::new(0), val, Address::new(1)); + let vote = Vote::new_prevote(Round::new(0), val); let event = keeper.apply_vote(vote.clone(), 1); assert_eq!(event, None); @@ -50,7 +50,7 @@ fn prevote_apply_single_value() { let event = keeper.apply_vote(vote.clone(), 1); assert_eq!(event, None); - let vote_nil = Vote::new_prevote(Round::new(0), None, Address::new(2)); + let vote_nil = Vote::new_prevote(Round::new(0), None); let event = keeper.apply_vote(vote_nil, 1); assert_eq!(event, Some(Event::PolkaAny)); @@ -64,7 +64,7 @@ fn precommit_apply_single_value() { let v = ValueId::new(1); let val = Some(v); - let vote = Vote::new_precommit(Round::new(0), val, Address::new(1)); + let vote = Vote::new_precommit(Round::new(0), val); let event = keeper.apply_vote(vote.clone(), 1); assert_eq!(event, None); @@ -72,7 +72,7 @@ fn precommit_apply_single_value() { let event = keeper.apply_vote(vote.clone(), 1); assert_eq!(event, None); - let vote_nil = Vote::new_precommit(Round::new(0), None, Address::new(2)); + let vote_nil = Vote::new_precommit(Round::new(0), None); let event = keeper.apply_vote(vote_nil, 1); assert_eq!(event, Some(Event::PrecommitAny));