diff --git a/Code/common/src/context.rs b/Code/common/src/context.rs index 565f6b7c4..ede49af46 100644 --- a/Code/common/src/context.rs +++ b/Code/common/src/context.rs @@ -1,5 +1,5 @@ use crate::{ - Address, Height, Proposal, PublicKey, Round, SignedVote, SigningScheme, Validator, + Address, Height, NilOrVal, Proposal, PublicKey, Round, SignedVote, SigningScheme, Validator, ValidatorSet, Value, ValueId, Vote, }; @@ -42,7 +42,7 @@ where fn new_prevote( height: Self::Height, round: Round, - value_id: Option>, + value_id: NilOrVal>, address: Self::Address, ) -> Self::Vote; @@ -51,7 +51,7 @@ where fn new_precommit( height: Self::Height, round: Round, - value_id: Option>, + value_id: NilOrVal>, address: Self::Address, ) -> Self::Vote; } diff --git a/Code/common/src/lib.rs b/Code/common/src/lib.rs index bc0a00429..d9a7b3403 100644 --- a/Code/common/src/lib.rs +++ b/Code/common/src/lib.rs @@ -40,5 +40,5 @@ pub use signed_vote::SignedVote; pub use signing::SigningScheme; pub use timeout::{Timeout, TimeoutStep}; pub use validator_set::{Address, Validator, ValidatorSet, VotingPower}; -pub use value::Value; +pub use value::{NilOrVal, Value}; pub use vote::{Vote, VoteType}; diff --git a/Code/common/src/value.rs b/Code/common/src/value.rs index f1a6a656e..e17062ba3 100644 --- a/Code/common/src/value.rs +++ b/Code/common/src/value.rs @@ -1,5 +1,50 @@ use core::fmt::Debug; +/// Represents either `Nil` or a value of type `Value`. +/// +/// This type is isomorphic to `Option` but is more explicit about its intent. +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub enum NilOrVal { + #[default] + Nil, + + Val(Value), +} + +impl NilOrVal { + pub fn is_nil(&self) -> bool { + matches!(self, Self::Nil) + } + + pub fn is_val(&self) -> bool { + matches!(self, Self::Val(_)) + } + + pub fn map NewValue>(self, f: F) -> NilOrVal { + match self { + NilOrVal::Nil => NilOrVal::Nil, + NilOrVal::Val(value) => NilOrVal::Val(f(value)), + } + } + + pub fn as_ref(&self) -> NilOrVal<&Value> { + match self { + NilOrVal::Nil => NilOrVal::Nil, + NilOrVal::Val(value) => NilOrVal::Val(value), + } + } + + pub fn value_or_default(self) -> Value + where + Value: Default, + { + match self { + NilOrVal::Nil => Value::default(), + NilOrVal::Val(value) => value, + } + } +} + /// Defines the requirements for the type of value to decide on. pub trait Value where diff --git a/Code/common/src/vote.rs b/Code/common/src/vote.rs index 84bd6969b..572beea45 100644 --- a/Code/common/src/vote.rs +++ b/Code/common/src/vote.rs @@ -1,6 +1,6 @@ use core::fmt::Debug; -use crate::{Context, Round, Value}; +use crate::{Context, NilOrVal, Round, Value}; /// A type of vote. #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -28,10 +28,10 @@ where fn round(&self) -> Round; /// Get a reference to the value being voted for. - fn value(&self) -> &Option<::Id>; + fn value(&self) -> &NilOrVal<::Id>; /// Take ownership of the value being voted for. - fn take_value(self) -> Option<::Id>; + fn take_value(self) -> NilOrVal<::Id>; /// The type of vote. fn vote_type(&self) -> VoteType; diff --git a/Code/itf/tests/votekeeper/runner.rs b/Code/itf/tests/votekeeper/runner.rs index fbc9633b2..c21eaa906 100644 --- a/Code/itf/tests/votekeeper/runner.rs +++ b/Code/itf/tests/votekeeper/runner.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use malachite_common::{Context, Round, Value}; +use malachite_common::{Context, NilOrVal, Round, Value}; use malachite_itf::types::{Value as ModelValue, VoteType}; use malachite_itf::votekeeper::VoteKeeperOutput::*; use malachite_itf::votekeeper::{State, WeightedVote}; @@ -82,7 +82,7 @@ impl ItfRunner for VoteKeeperRunner { (Output::PolkaAny, PolkaAny(_expected_round)) => (), (Output::PolkaValue(value), PolkaValue(_expected_round, expected_value)) => { assert_eq!( - Some(value), + NilOrVal::Val(value), value_from_model(&ModelValue::Val(expected_value.to_string())).as_ref() ); } @@ -92,7 +92,7 @@ impl ItfRunner for VoteKeeperRunner { PrecommitValue(_expected_round, expected_value), ) => { assert_eq!( - Some(value), + NilOrVal::Val(value), value_from_model(&ModelValue::Val(expected_value.to_string())).as_ref() ); } diff --git a/Code/itf/tests/votekeeper/utils.rs b/Code/itf/tests/votekeeper/utils.rs index 1a75fbe44..17fff6215 100644 --- a/Code/itf/tests/votekeeper/utils.rs +++ b/Code/itf/tests/votekeeper/utils.rs @@ -1,17 +1,18 @@ use std::collections::HashMap; +use malachite_common::NilOrVal; use malachite_itf::types::Value; use malachite_test::{Address, ValueId}; pub const ADDRESSES: [&str; 3] = ["alice", "bob", "john"]; -pub fn value_from_model(value: &Value) -> Option { +pub fn value_from_model(value: &Value) -> NilOrVal { match value { - Value::Nil => None, + Value::Nil => NilOrVal::Nil, Value::Val(v) => match v.as_str() { - "v1" => Some(1.into()), - "v2" => Some(2.into()), - "v3" => Some(3.into()), + "v1" => NilOrVal::Val(1.into()), + "v2" => NilOrVal::Val(2.into()), + "v3" => NilOrVal::Val(3.into()), _ => unimplemented!("unknown value {value:?}"), }, } diff --git a/Code/round/src/output.rs b/Code/round/src/output.rs index a7f586015..c79feb2e3 100644 --- a/Code/round/src/output.rs +++ b/Code/round/src/output.rs @@ -1,6 +1,6 @@ use core::fmt; -use malachite_common::{Context, Round, Timeout, TimeoutStep, ValueId}; +use malachite_common::{Context, NilOrVal, Round, Timeout, TimeoutStep, ValueId}; use crate::state::RoundValue; @@ -29,7 +29,7 @@ impl Output { pub fn prevote( height: Ctx::Height, round: Round, - value_id: Option>, + value_id: NilOrVal>, address: Ctx::Address, ) -> Self { Output::Vote(Ctx::new_prevote(height, round, value_id, address)) @@ -38,7 +38,7 @@ impl Output { pub fn precommit( height: Ctx::Height, round: Round, - value_id: Option>, + value_id: NilOrVal>, address: Ctx::Address, ) -> Self { Output::Vote(Ctx::new_precommit(height, round, value_id, address)) diff --git a/Code/round/src/state_machine.rs b/Code/round/src/state_machine.rs index 82fbd1ded..09d42aeed 100644 --- a/Code/round/src/state_machine.rs +++ b/Code/round/src/state_machine.rs @@ -1,4 +1,4 @@ -use malachite_common::{Context, Proposal, Round, TimeoutStep, Value}; +use malachite_common::{Context, NilOrVal, Proposal, Round, TimeoutStep, Value}; use crate::input::Input; use crate::output::Output; @@ -259,10 +259,10 @@ where let vr = proposal.round(); let proposed = proposal.value().id(); let value = match &state.locked { - Some(locked) if locked.round <= vr => Some(proposed), // unlock and prevote - Some(locked) if locked.value.id() == proposed => Some(proposed), // already locked on value - Some(_) => None, // we're locked on a higher round with a different value, prevote nil - None => Some(proposed), // not locked, prevote the value + Some(locked) if locked.round <= vr => NilOrVal::Val(proposed), // unlock and prevote + Some(locked) if locked.value.id() == proposed => NilOrVal::Val(proposed), // already locked on value + Some(_) => NilOrVal::Nil, // we're locked on a higher round with a different value, prevote nil + None => NilOrVal::Val(proposed), // not locked, prevote the value }; let output = Output::prevote(state.height.clone(), state.round, value, address.clone()); @@ -276,7 +276,13 @@ pub fn prevote_nil(state: State, address: &Ctx::Address) -> Transition where Ctx: Context, { - let output = Output::prevote(state.height.clone(), state.round, None, address.clone()); + let output = Output::prevote( + state.height.clone(), + state.round, + NilOrVal::Nil, + address.clone(), + ); + Transition::to(state.with_step(Step::Prevote)).with_output(output) } @@ -306,7 +312,7 @@ where let output = Output::precommit( state.height.clone(), state.round, - Some(value.id()), + NilOrVal::Val(value.id()), address.clone(), ); @@ -325,7 +331,12 @@ pub fn precommit_nil(state: State, address: &Ctx::Address) -> Transiti where Ctx: Context, { - let output = Output::precommit(state.height.clone(), state.round, None, address.clone()); + let output = Output::precommit( + state.height.clone(), + state.round, + NilOrVal::Nil, + address.clone(), + ); Transition::to(state.with_step(Step::Precommit)).with_output(output) } diff --git a/Code/test/src/context.rs b/Code/test/src/context.rs index 28ff263be..9bfbdca95 100644 --- a/Code/test/src/context.rs +++ b/Code/test/src/context.rs @@ -1,4 +1,5 @@ use malachite_common::Context; +use malachite_common::NilOrVal; use malachite_common::Round; use malachite_common::SignedVote; @@ -50,7 +51,7 @@ impl Context for TestContext { fn new_prevote( height: Height, round: Round, - value_id: Option, + value_id: NilOrVal, address: Address, ) -> Vote { Vote::new_prevote(height, round, value_id, address) @@ -59,7 +60,7 @@ impl Context for TestContext { fn new_precommit( height: Height, round: Round, - value_id: Option, + value_id: NilOrVal, address: Address, ) -> Vote { Vote::new_precommit(height, round, value_id, address) diff --git a/Code/test/src/utils.rs b/Code/test/src/utils.rs index a77367496..0a783a46d 100644 --- a/Code/test/src/utils.rs +++ b/Code/test/src/utils.rs @@ -1,7 +1,7 @@ use rand::rngs::StdRng; use rand::SeedableRng; -use malachite_common::{Round, Timeout, VotingPower}; +use malachite_common::{NilOrVal, Round, Timeout, VotingPower}; use malachite_driver::{Input, Output, ProposerSelector, Validity}; use malachite_round::state::{RoundValue, State, Step}; @@ -87,7 +87,7 @@ pub fn prevote_output( let value = Value::new(9999); Some(Output::Vote( - Vote::new_prevote(Height::new(1), round, Some(value.id()), *addr).signed(sk), + Vote::new_prevote(Height::new(1), round, NilOrVal::Val(value.id()), *addr).signed(sk), )) } @@ -97,7 +97,7 @@ pub fn prevote_nil_output( sk: &PrivateKey, ) -> Option> { Some(Output::Vote( - Vote::new_prevote(Height::new(1), round, None, *addr).signed(sk), + Vote::new_prevote(Height::new(1), round, NilOrVal::Nil, *addr).signed(sk), )) } @@ -105,18 +105,26 @@ pub fn prevote_input(addr: &Address, sk: &PrivateKey) -> Input { let value = Value::new(9999); Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), *addr).signed(sk), + Vote::new_prevote( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + *addr, + ) + .signed(sk), ) } pub fn prevote_nil_input(addr: &Address, sk: &PrivateKey) -> Input { - Input::Vote(Vote::new_prevote(Height::new(1), Round::new(0), None, *addr).signed(sk)) + Input::Vote(Vote::new_prevote(Height::new(1), Round::new(0), NilOrVal::Nil, *addr).signed(sk)) } pub fn prevote_input_at(round: Round, addr: &Address, sk: &PrivateKey) -> Input { let value = Value::new(9999); - Input::Vote(Vote::new_prevote(Height::new(1), round, Some(value.id()), *addr).signed(sk)) + Input::Vote( + Vote::new_prevote(Height::new(1), round, NilOrVal::Val(value.id()), *addr).signed(sk), + ) } pub fn precommit_output( @@ -126,7 +134,7 @@ pub fn precommit_output( sk: &PrivateKey, ) -> Option> { Some(Output::Vote( - Vote::new_precommit(Height::new(1), round, Some(value.id()), *addr).signed(sk), + Vote::new_precommit(Height::new(1), round, NilOrVal::Val(value.id()), *addr).signed(sk), )) } @@ -136,7 +144,7 @@ pub fn precommit_nil_output( sk: &PrivateKey, ) -> Option> { Some(Output::Vote( - Vote::new_precommit(Height::new(1), round, None, *addr).signed(sk), + Vote::new_precommit(Height::new(1), round, NilOrVal::Nil, *addr).signed(sk), )) } @@ -146,7 +154,9 @@ pub fn precommit_input( addr: &Address, sk: &PrivateKey, ) -> Input { - Input::Vote(Vote::new_precommit(Height::new(1), round, Some(value.id()), *addr).signed(sk)) + Input::Vote( + Vote::new_precommit(Height::new(1), round, NilOrVal::Val(value.id()), *addr).signed(sk), + ) } pub fn decide_output(round: Round, value: Value) -> Option> { diff --git a/Code/test/src/vote.rs b/Code/test/src/vote.rs index 35ae1117f..dc2ee249b 100644 --- a/Code/test/src/vote.rs +++ b/Code/test/src/vote.rs @@ -1,6 +1,6 @@ use signature::Signer; -use malachite_common::{Round, SignedVote, VoteType}; +use malachite_common::{NilOrVal, Round, SignedVote, VoteType}; use crate::{Address, Height, PrivateKey, TestContext, ValueId}; @@ -10,7 +10,7 @@ pub struct Vote { pub typ: VoteType, pub height: Height, pub round: Round, - pub value: Option, + pub value: NilOrVal, pub validator_address: Address, } @@ -18,7 +18,7 @@ impl Vote { pub fn new_prevote( height: Height, round: Round, - value: Option, + value: NilOrVal, validator_address: Address, ) -> Self { Self { @@ -33,7 +33,7 @@ impl Vote { pub fn new_precommit( height: Height, round: Round, - value: Option, + value: NilOrVal, address: Address, ) -> Self { Self { @@ -55,10 +55,11 @@ impl Vote { let mut bytes = vec![vtpe]; bytes.extend_from_slice(&self.round.as_i64().to_be_bytes()); bytes.extend_from_slice( - &self - .value + self.value + .as_ref() .map(|v| v.as_u64().to_be_bytes()) - .unwrap_or_default(), + .value_or_default() + .as_slice(), ); bytes } @@ -82,11 +83,11 @@ impl malachite_common::Vote for Vote { self.round } - fn value(&self) -> &Option { + fn value(&self) -> &NilOrVal { &self.value } - fn take_value(self) -> Option { + fn take_value(self) -> NilOrVal { self.value } diff --git a/Code/test/tests/driver.rs b/Code/test/tests/driver.rs index 69cf3cb7e..5d264217b 100644 --- a/Code/test/tests/driver.rs +++ b/Code/test/tests/driver.rs @@ -1,7 +1,7 @@ use futures::executor::block_on; use malachite_test::utils::{make_validators, FixedProposer, RotateProposer}; -use malachite_common::{Round, Timeout, TimeoutStep}; +use malachite_common::{NilOrVal, Round, Timeout, TimeoutStep}; use malachite_driver::{Driver, Error, Input, Output, Validity}; use malachite_round::state::{RoundValue, State, Step}; use malachite_test::{Height, Proposal, TestContext, ValidatorSet, Value, Vote}; @@ -75,8 +75,13 @@ fn driver_steps_proposer() { desc: "Receive our own proposal, prevote for it (v1)", input: None, expected_output: Some(Output::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), my_addr) - .signed(&my_sk), + Vote::new_prevote( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + my_addr, + ) + .signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -103,8 +108,13 @@ fn driver_steps_proposer() { TestStep { desc: "v2 prevotes for our proposal", input: Some(Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), v2.address) - .signed(&sk2), + Vote::new_prevote( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v2.address, + ) + .signed(&sk2), )), expected_output: None, expected_round: Round::new(0), @@ -119,12 +129,22 @@ fn driver_steps_proposer() { TestStep { desc: "v3 prevotes for our proposal, we get +2/3 prevotes, precommit for it (v1)", input: Some(Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), v3.address) - .signed(&sk3), + Vote::new_prevote( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v3.address, + ) + .signed(&sk3), )), expected_output: Some(Output::Vote( - Vote::new_precommit(Height::new(1), Round::new(0), Some(value.id()), my_addr) - .signed(&my_sk), + Vote::new_precommit( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + my_addr, + ) + .signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -163,8 +183,13 @@ fn driver_steps_proposer() { TestStep { desc: "v2 precommits for our proposal", input: Some(Input::Vote( - Vote::new_precommit(Height::new(1), Round::new(0), Some(value.id()), v2.address) - .signed(&sk2), + Vote::new_precommit( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v2.address, + ) + .signed(&sk2), )), expected_output: None, expected_round: Round::new(0), @@ -185,8 +210,13 @@ fn driver_steps_proposer() { TestStep { desc: "v3 precommits for our proposal, we get +2/3 precommits, decide it (v1)", input: Some(Input::Vote( - Vote::new_precommit(Height::new(1), Round::new(0), Some(value.id()), v3.address) - .signed(&sk3), + Vote::new_precommit( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v3.address, + ) + .signed(&sk3), )), expected_output: Some(Output::Decide(Round::new(0), value)), expected_round: Round::new(0), @@ -241,7 +271,8 @@ fn driver_steps_proposer_timeout_get_value() { desc: "Receive a propose timeout", input: Some(Input::TimeoutElapsed(Timeout::propose(Round::new(0)))), expected_output: Some(Output::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), None, my_addr).signed(&my_sk), + Vote::new_prevote(Height::new(1), Round::new(0), NilOrVal::Nil, my_addr) + .signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -292,8 +323,13 @@ fn driver_steps_not_proposer_valid() { desc: "Receive a proposal, prevote for it (v2)", input: Some(Input::Proposal(proposal.clone(), Validity::Valid)), expected_output: Some(Output::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), my_addr) - .signed(&my_sk), + Vote::new_prevote( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + my_addr, + ) + .signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -320,8 +356,13 @@ fn driver_steps_not_proposer_valid() { TestStep { desc: "v1 prevotes for its own proposal", input: Some(Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), v1.address) - .signed(&sk1), + Vote::new_prevote( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v1.address, + ) + .signed(&sk1), )), expected_output: None, expected_round: Round::new(0), @@ -336,12 +377,22 @@ fn driver_steps_not_proposer_valid() { TestStep { desc: "v3 prevotes for v1's proposal, it gets +2/3 prevotes, precommit for it (v2)", input: Some(Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), v3.address) - .signed(&sk3), + Vote::new_prevote( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v3.address, + ) + .signed(&sk3), )), expected_output: Some(Output::Vote( - Vote::new_precommit(Height::new(1), Round::new(0), Some(value.id()), my_addr) - .signed(&my_sk), + Vote::new_precommit( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + my_addr, + ) + .signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -380,8 +431,13 @@ fn driver_steps_not_proposer_valid() { TestStep { desc: "v1 precommits its proposal", input: Some(Input::Vote( - Vote::new_precommit(Height::new(1), Round::new(0), Some(value.id()), v1.address) - .signed(&sk1), + Vote::new_precommit( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v1.address, + ) + .signed(&sk1), )), expected_output: None, expected_round: Round::new(0), @@ -402,8 +458,13 @@ fn driver_steps_not_proposer_valid() { TestStep { desc: "v3 precommits for v1's proposal, it gets +2/3 precommits, decide it", input: Some(Input::Vote( - Vote::new_precommit(Height::new(1), Round::new(0), Some(value.id()), v3.address) - .signed(&sk3), + Vote::new_precommit( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v3.address, + ) + .signed(&sk3), )), expected_output: Some(Output::Decide(Round::new(0), value)), expected_round: Round::new(0), @@ -461,7 +522,7 @@ fn driver_steps_not_proposer_invalid() { desc: "Receive an invalid proposal, prevote for nil (v2)", input: Some(Input::Proposal(proposal.clone(), Validity::Invalid)), expected_output: Some(Output::Vote( - Vote::new_prevote(Height::new(1),Round::new(0), None, my_addr).signed(&my_sk), + Vote::new_prevote(Height::new(1),Round::new(0), NilOrVal::Nil, my_addr).signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -488,7 +549,7 @@ fn driver_steps_not_proposer_invalid() { TestStep { desc: "v1 prevotes for its own proposal", input: Some(Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), v1.address).signed(&sk1), + Vote::new_prevote(Height::new(1), Round::new(0), NilOrVal::Val(value.id()), v1.address).signed(&sk1), )), expected_output: None, expected_round: Round::new(0), @@ -503,7 +564,7 @@ fn driver_steps_not_proposer_invalid() { TestStep { desc: "v3 prevotes for v1's proposal, we have polka for any, schedule prevote timeout (v2)", input: Some(Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), v3.address).signed(&sk3), + Vote::new_prevote(Height::new(1), Round::new(0), NilOrVal::Val(value.id()), v3.address).signed(&sk3), )), expected_output: Some(Output::ScheduleTimeout(Timeout::prevote(Round::new(0)))), expected_round: Round::new(0), @@ -519,7 +580,7 @@ fn driver_steps_not_proposer_invalid() { desc: "prevote timeout elapses, we precommit for nil (v2)", input: Some(Input::TimeoutElapsed(Timeout::prevote(Round::new(0)))), expected_output: Some(Output::Vote( - Vote::new_precommit(Height::new(1), Round::new(0), None, my_addr).signed(&my_sk), + Vote::new_precommit(Height::new(1), Round::new(0), NilOrVal::Nil, my_addr).signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -670,7 +731,8 @@ fn driver_steps_not_proposer_timeout_multiple_rounds() { desc: "Receive a propose timeout, prevote for nil (v3)", input: Some(Input::TimeoutElapsed(Timeout::propose(Round::new(0)))), expected_output: Some(Output::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), None, my_addr).signed(&my_sk), + Vote::new_prevote(Height::new(1), Round::new(0), NilOrVal::Nil, my_addr) + .signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -699,8 +761,13 @@ fn driver_steps_not_proposer_timeout_multiple_rounds() { TestStep { desc: "v1 prevotes for its own proposal", input: Some(Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), v1.address) - .signed(&sk1), + Vote::new_prevote( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v1.address, + ) + .signed(&sk1), )), expected_output: None, expected_round: Round::new(0), @@ -716,10 +783,12 @@ fn driver_steps_not_proposer_timeout_multiple_rounds() { TestStep { desc: "v2 prevotes for nil, we get +2/3 prevotes, precommit for nil", input: Some(Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), None, v2.address).signed(&sk2), + Vote::new_prevote(Height::new(1), Round::new(0), NilOrVal::Nil, v2.address) + .signed(&sk2), )), expected_output: Some(Output::Vote( - Vote::new_precommit(Height::new(1), Round::new(0), None, my_addr).signed(&my_sk), + Vote::new_precommit(Height::new(1), Round::new(0), NilOrVal::Nil, my_addr) + .signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -748,8 +817,13 @@ fn driver_steps_not_proposer_timeout_multiple_rounds() { TestStep { desc: "v1 precommits its proposal", input: Some(Input::Vote( - Vote::new_precommit(Height::new(1), Round::new(0), Some(value.id()), v1.address) - .signed(&sk1), + Vote::new_precommit( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v1.address, + ) + .signed(&sk1), )), expected_output: None, expected_round: Round::new(0), @@ -765,7 +839,8 @@ fn driver_steps_not_proposer_timeout_multiple_rounds() { TestStep { desc: "v2 precommits for nil", input: Some(Input::Vote( - Vote::new_precommit(Height::new(1), Round::new(0), None, v2.address).signed(&sk2), + Vote::new_precommit(Height::new(1), Round::new(0), NilOrVal::Nil, v2.address) + .signed(&sk2), )), expected_output: Some(Output::ScheduleTimeout(Timeout::precommit(Round::new(0)))), expected_round: Round::new(0), @@ -875,9 +950,17 @@ fn driver_steps_validator_not_found() { .expect("execute succeeded"); // v2 prevotes for some proposal, we cannot find it in the validator set => error - let output = block_on(driver.process(Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), v2.address).signed(&sk2), - ))); + let output = block_on( + driver.process(Input::Vote( + Vote::new_prevote( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v2.address, + ) + .signed(&sk2), + )), + ); assert_eq!(output, Err(Error::ValidatorNotFound(v2.address))); } @@ -902,9 +985,17 @@ fn driver_steps_invalid_signature() { // v2 prevotes for some proposal, with an invalid signature, // ie. signed by v1 instead of v2, just a way of forging an invalid signature - let output = block_on(driver.process(Input::Vote( - Vote::new_prevote(Height::new(1), Round::new(0), Some(value.id()), v2.address).signed(&sk1), - ))); + let output = block_on( + driver.process(Input::Vote( + Vote::new_prevote( + Height::new(1), + Round::new(0), + NilOrVal::Val(value.id()), + v2.address, + ) + .signed(&sk1), + )), + ); assert!(matches!(output, Err(Error::InvalidVoteSignature(_, _)))); } @@ -946,7 +1037,7 @@ fn driver_steps_skip_round_skip_threshold() { desc: "Receive a propose timeout, prevote for nil (v3)", input: Some(Input::TimeoutElapsed(Timeout::propose(Round::new(0)))), expected_output: Some(Output::Vote( - Vote::new_prevote(height, Round::new(0), None, my_addr).signed(&my_sk), + Vote::new_prevote(height, Round::new(0), NilOrVal::Nil, my_addr).signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -975,7 +1066,8 @@ fn driver_steps_skip_round_skip_threshold() { TestStep { desc: "v1 prevotes for its own proposal in round 1", input: Some(Input::Vote( - Vote::new_prevote(height, Round::new(1), Some(value.id()), v1.address).signed(&sk1), + Vote::new_prevote(height, Round::new(1), NilOrVal::Val(value.id()), v1.address) + .signed(&sk1), )), expected_output: None, expected_round: Round::new(0), @@ -991,7 +1083,8 @@ fn driver_steps_skip_round_skip_threshold() { TestStep { desc: "v2 prevotes for v1 proposal, we get +1/3 messages from future round", input: Some(Input::Vote( - Vote::new_prevote(height, Round::new(1), Some(value.id()), v2.address).signed(&sk2), + Vote::new_prevote(height, Round::new(1), NilOrVal::Val(value.id()), v2.address) + .signed(&sk2), )), expected_output: Some(Output::NewRound(height, Round::new(1))), expected_round: Round::new(1), @@ -1045,7 +1138,7 @@ fn driver_steps_skip_round_quorum_threshold() { desc: "Receive a propose timeout, prevote for nil (v3)", input: Some(Input::TimeoutElapsed(Timeout::propose(Round::new(0)))), expected_output: Some(Output::Vote( - Vote::new_prevote(height, Round::new(0), None, my_addr).signed(&my_sk), + Vote::new_prevote(height, Round::new(0), NilOrVal::Nil, my_addr).signed(&my_sk), )), expected_round: Round::new(0), new_state: State { @@ -1074,7 +1167,8 @@ fn driver_steps_skip_round_quorum_threshold() { TestStep { desc: "v1 prevotes for its own proposal in round 1", input: Some(Input::Vote( - Vote::new_prevote(height, Round::new(1), Some(value.id()), v1.address).signed(&sk1), + Vote::new_prevote(height, Round::new(1), NilOrVal::Val(value.id()), v1.address) + .signed(&sk1), )), expected_output: None, expected_round: Round::new(0), @@ -1090,7 +1184,8 @@ fn driver_steps_skip_round_quorum_threshold() { TestStep { desc: "v2 prevotes for v1 proposal, we get +1/3 messages from future round", input: Some(Input::Vote( - Vote::new_prevote(height, Round::new(1), Some(value.id()), v2.address).signed(&sk2), + Vote::new_prevote(height, Round::new(1), NilOrVal::Val(value.id()), v2.address) + .signed(&sk2), )), expected_output: Some(Output::NewRound(height, Round::new(1))), expected_round: Round::new(1), diff --git a/Code/test/tests/round.rs b/Code/test/tests/round.rs index 246194a7a..0cc47f9a8 100644 --- a/Code/test/tests/round.rs +++ b/Code/test/tests/round.rs @@ -1,6 +1,6 @@ use malachite_test::{Address, Height, Proposal, TestContext, Value}; -use malachite_common::{Round, Timeout, TimeoutStep}; +use malachite_common::{NilOrVal, Round, Timeout, TimeoutStep}; use malachite_round::input::Input; use malachite_round::output::Output; use malachite_round::state::{State, Step}; @@ -85,6 +85,11 @@ fn test_prevote() { assert_eq!(transition.next_state.step, Step::Prevote); assert_eq!( transition.output.unwrap(), - Output::prevote(Height::new(1), Round::new(1), Some(value.id()), ADDRESS) + Output::prevote( + Height::new(1), + Round::new(1), + NilOrVal::Val(value.id()), + ADDRESS + ) ); } diff --git a/Code/test/tests/round_votes.rs b/Code/test/tests/round_votes.rs index 6132734c9..0a08413f3 100644 --- a/Code/test/tests/round_votes.rs +++ b/Code/test/tests/round_votes.rs @@ -1,4 +1,4 @@ -use malachite_common::VoteType; +use malachite_common::{NilOrVal, VoteType}; use malachite_vote::round_votes::RoundVotes; use malachite_test::{Address, ValueId}; @@ -14,20 +14,20 @@ const ADDRESS6: Address = Address::new([46; 20]); fn add_votes_nil() { let mut round_votes: RoundVotes<_, ValueId> = RoundVotes::new(); - let w = round_votes.add_vote(VoteType::Prevote, ADDRESS1, None, 1); + let w = round_votes.add_vote(VoteType::Prevote, ADDRESS1, NilOrVal::Nil, 1); assert_eq!(w, 1); - let w = round_votes.add_vote(VoteType::Prevote, ADDRESS2, None, 1); + let w = round_votes.add_vote(VoteType::Prevote, ADDRESS2, NilOrVal::Nil, 1); assert_eq!(w, 2); - let w = round_votes.add_vote(VoteType::Prevote, ADDRESS3, None, 1); + let w = round_votes.add_vote(VoteType::Prevote, ADDRESS3, NilOrVal::Nil, 1); assert_eq!(w, 3); } #[test] fn add_votes_single_value() { let v = ValueId::new(1); - let val = Some(v); + let val = NilOrVal::Val(v); let weight = 1; let mut round_votes: RoundVotes<_, ValueId> = RoundVotes::new(); @@ -41,7 +41,7 @@ fn add_votes_single_value() { assert_eq!(w, 2); // add a vote for nil, get w::Any - let w = round_votes.add_vote(VoteType::Prevote, ADDRESS3, None, weight); + let w = round_votes.add_vote(VoteType::Prevote, ADDRESS3, NilOrVal::Nil, weight); assert_eq!(w, 1); // add vote for value, get w::Value @@ -53,8 +53,8 @@ fn add_votes_single_value() { fn add_votes_multi_values() { let v1 = ValueId::new(1); let v2 = ValueId::new(2); - let val1 = Some(v1); - let val2 = Some(v2); + let val1 = NilOrVal::Val(v1); + let val2 = NilOrVal::Val(v2); let mut round_votes: RoundVotes<_, ValueId> = RoundVotes::new(); @@ -64,7 +64,7 @@ fn add_votes_multi_values() { let w = round_votes.add_vote(VoteType::Precommit, ADDRESS2, val2, 1); assert_eq!(w, 1); - let w = round_votes.add_vote(VoteType::Precommit, ADDRESS3, None, 1); + let w = round_votes.add_vote(VoteType::Precommit, ADDRESS3, NilOrVal::Nil, 1); assert_eq!(w, 1); let w = round_votes.add_vote(VoteType::Precommit, ADDRESS4, val1, 1); diff --git a/Code/test/tests/vote_keeper.rs b/Code/test/tests/vote_keeper.rs index f3cd9df3f..64bd8fbca 100644 --- a/Code/test/tests/vote_keeper.rs +++ b/Code/test/tests/vote_keeper.rs @@ -1,4 +1,4 @@ -use malachite_common::Round; +use malachite_common::{NilOrVal, Round}; use malachite_vote::keeper::{Output, VoteKeeper}; use malachite_test::{Address, Height, TestContext, ValueId, Vote}; @@ -14,15 +14,15 @@ fn prevote_apply_nil() { let height = Height::new(1); let round = Round::new(0); - let vote = Vote::new_prevote(height, round, None, ADDRESS1); + let vote = Vote::new_prevote(height, round, NilOrVal::Nil, ADDRESS1); let msg = keeper.apply_vote(vote.clone(), 1, round); assert_eq!(msg, None); - let vote = Vote::new_prevote(height, round, None, ADDRESS2); + let vote = Vote::new_prevote(height, round, NilOrVal::Nil, ADDRESS2); let msg = keeper.apply_vote(vote.clone(), 1, round); assert_eq!(msg, None); - let vote = Vote::new_prevote(height, round, None, ADDRESS3); + let vote = Vote::new_prevote(height, round, NilOrVal::Nil, ADDRESS3); let msg = keeper.apply_vote(vote, 1, round); assert_eq!(msg, Some(Output::PolkaNil)); } @@ -33,15 +33,15 @@ fn precommit_apply_nil() { let height = Height::new(1); let round = Round::new(0); - let vote = Vote::new_precommit(height, round, None, ADDRESS1); + let vote = Vote::new_precommit(height, round, NilOrVal::Nil, ADDRESS1); let msg = keeper.apply_vote(vote.clone(), 1, round); assert_eq!(msg, None); - let vote = Vote::new_precommit(height, Round::new(0), None, ADDRESS2); + let vote = Vote::new_precommit(height, Round::new(0), NilOrVal::Nil, ADDRESS2); let msg = keeper.apply_vote(vote.clone(), 1, round); assert_eq!(msg, None); - let vote = Vote::new_precommit(height, Round::new(0), None, ADDRESS3); + let vote = Vote::new_precommit(height, Round::new(0), NilOrVal::Nil, ADDRESS3); let msg = keeper.apply_vote(vote, 1, round); assert_eq!(msg, Some(Output::PrecommitAny)); } @@ -51,7 +51,7 @@ fn prevote_apply_single_value() { let mut keeper: VoteKeeper = VoteKeeper::new(4, Default::default()); let id = ValueId::new(1); - let val = Some(id); + let val = NilOrVal::Val(id); let height = Height::new(1); let round = Round::new(0); @@ -63,7 +63,7 @@ fn prevote_apply_single_value() { let msg = keeper.apply_vote(vote.clone(), 1, round); assert_eq!(msg, None); - let vote_nil = Vote::new_prevote(height, Round::new(0), None, ADDRESS3); + let vote_nil = Vote::new_prevote(height, Round::new(0), NilOrVal::Nil, ADDRESS3); let msg = keeper.apply_vote(vote_nil, 1, round); assert_eq!(msg, Some(Output::PolkaAny)); @@ -77,7 +77,7 @@ fn precommit_apply_single_value() { let mut keeper: VoteKeeper = VoteKeeper::new(4, Default::default()); let id = ValueId::new(1); - let val = Some(id); + let val = NilOrVal::Val(id); let height = Height::new(1); let round = Round::new(0); @@ -89,7 +89,7 @@ fn precommit_apply_single_value() { let msg = keeper.apply_vote(vote.clone(), 1, round); assert_eq!(msg, None); - let vote_nil = Vote::new_precommit(height, Round::new(0), None, ADDRESS3); + let vote_nil = Vote::new_precommit(height, Round::new(0), NilOrVal::Nil, ADDRESS3); let msg = keeper.apply_vote(vote_nil, 1, round); assert_eq!(msg, Some(Output::PrecommitAny)); @@ -103,7 +103,7 @@ fn skip_round_small_quorum_prevotes_two_vals() { let mut keeper: VoteKeeper = VoteKeeper::new(4, Default::default()); let id = ValueId::new(1); - let val = Some(id); + let val = NilOrVal::Val(id); let height = Height::new(1); let cur_round = Round::new(0); let fut_round = Round::new(1); @@ -126,7 +126,7 @@ fn skip_round_small_quorum_with_prevote_precommit_two_vals() { let mut keeper: VoteKeeper = VoteKeeper::new(4, Default::default()); let id = ValueId::new(1); - let val = Some(id); + let val = NilOrVal::Val(id); let height = Height::new(1); let cur_round = Round::new(0); let fut_round = Round::new(1); @@ -149,7 +149,7 @@ fn skip_round_full_quorum_with_prevote_precommit_two_vals() { let mut keeper: VoteKeeper = VoteKeeper::new(5, Default::default()); let id = ValueId::new(1); - let val = Some(id); + let val = NilOrVal::Val(id); let height = Height::new(1); let cur_round = Round::new(0); let fut_round = Round::new(1); @@ -172,7 +172,7 @@ fn no_skip_round_small_quorum_with_same_val() { let mut keeper: VoteKeeper = VoteKeeper::new(4, Default::default()); let id = ValueId::new(1); - let val = Some(id); + let val = NilOrVal::Val(id); let height = Height::new(1); let cur_round = Round::new(0); let fut_round = Round::new(1); @@ -195,7 +195,7 @@ fn no_skip_round_full_quorum_with_same_val() { let mut keeper: VoteKeeper = VoteKeeper::new(5, Default::default()); let id = ValueId::new(1); - let val = Some(id); + let val = NilOrVal::Val(id); let height = Height::new(1); let cur_round = Round::new(0); let fut_round = Round::new(1); diff --git a/Code/vote/src/count.rs b/Code/vote/src/count.rs index dfb970773..e891c3c28 100644 --- a/Code/vote/src/count.rs +++ b/Code/vote/src/count.rs @@ -1,4 +1,5 @@ use alloc::collections::BTreeSet; +use malachite_common::NilOrVal; use crate::value_weights::ValuesWeights; use crate::{Threshold, ThresholdParam, Weight}; @@ -8,7 +9,7 @@ use crate::{Threshold, ThresholdParam, Weight}; #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct VoteCount { /// Weight of votes for the values, including nil - pub values_weights: ValuesWeights>, + pub values_weights: ValuesWeights>, /// Addresses of validators who voted for the values pub validator_addresses: BTreeSet
, @@ -24,7 +25,7 @@ impl VoteCount { /// Add vote for a value (or nil) to internal counters, but only if we haven't seen /// a vote from that particular validator yet. - pub fn add(&mut self, address: Address, value: Option, weight: Weight) -> Weight + pub fn add(&mut self, address: Address, value: NilOrVal, weight: Weight) -> Weight where Address: Clone + Ord, Value: Clone + Ord, @@ -38,7 +39,7 @@ impl VoteCount { } } - pub fn get(&self, value: &Option) -> Weight + pub fn get(&self, value: &NilOrVal) -> Weight where Value: Ord, { @@ -61,12 +62,12 @@ impl VoteCount { { match threshold { Threshold::Value(value) => { - let weight = self.values_weights.get(&Some(value)); + let weight = self.values_weights.get(&NilOrVal::Val(value)); param.is_met(weight, total_weight) } Threshold::Nil => { - let weight = self.values_weights.get(&None); + let weight = self.values_weights.get(&NilOrVal::Nil); param.is_met(weight, total_weight) } @@ -97,26 +98,26 @@ mod tests { let addr3 = [3]; let addr4 = [4]; - assert_eq!(vc.get(&None), 0); - assert_eq!(vc.get(&Some(1)), 0); + assert_eq!(vc.get(&NilOrVal::Nil), 0); + assert_eq!(vc.get(&NilOrVal::Val(1)), 0); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(1), q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); - assert_eq!(vc.add(addr1, None, 1), 1); - assert_eq!(vc.get(&None), 1); - assert_eq!(vc.get(&Some(1)), 0); + assert_eq!(vc.add(addr1, NilOrVal::Nil, 1), 1); + assert_eq!(vc.get(&NilOrVal::Nil), 1); + assert_eq!(vc.get(&NilOrVal::Val(1)), 0); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(1), q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); - assert_eq!(vc.add(addr2, None, 1), 2); - assert_eq!(vc.get(&None), 2); - assert_eq!(vc.get(&Some(1)), 0); + assert_eq!(vc.add(addr2, NilOrVal::Nil, 1), 2); + assert_eq!(vc.get(&NilOrVal::Nil), 2); + assert_eq!(vc.get(&NilOrVal::Val(1)), 0); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); @@ -124,27 +125,27 @@ mod tests { assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); // addr1 votes again, is ignored - assert_eq!(vc.add(addr1, None, 1), 2); - assert_eq!(vc.get(&None), 2); - assert_eq!(vc.get(&Some(1)), 0); + assert_eq!(vc.add(addr1, NilOrVal::Nil, 1), 2); + assert_eq!(vc.get(&NilOrVal::Nil), 2); + assert_eq!(vc.get(&NilOrVal::Val(1)), 0); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(1), q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); - assert_eq!(vc.add(addr3, None, 1), 3); - assert_eq!(vc.get(&None), 3); - assert_eq!(vc.get(&Some(1)), 0); + assert_eq!(vc.add(addr3, NilOrVal::Nil, 1), 3); + assert_eq!(vc.get(&NilOrVal::Nil), 3); + assert_eq!(vc.get(&NilOrVal::Val(1)), 0); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), true); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), true); assert_eq!(vc.is_threshold_met(Threshold::Value(1), q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); - assert_eq!(vc.add(addr4, Some(1), 1), 1); - assert_eq!(vc.get(&None), 3); - assert_eq!(vc.get(&Some(1)), 1); + assert_eq!(vc.add(addr4, NilOrVal::Val(1), 1), 1); + assert_eq!(vc.get(&NilOrVal::Nil), 3); + assert_eq!(vc.get(&NilOrVal::Val(1)), 1); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), true); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), true); @@ -164,26 +165,26 @@ mod tests { let addr3 = [3]; let addr4 = [4]; - assert_eq!(vc.get(&None), 0); - assert_eq!(vc.get(&Some(1)), 0); + assert_eq!(vc.get(&NilOrVal::Nil), 0); + assert_eq!(vc.get(&NilOrVal::Val(1)), 0); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(1), q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); - assert_eq!(vc.add(addr1, Some(1), 1), 1); - assert_eq!(vc.get(&None), 0); - assert_eq!(vc.get(&Some(1)), 1); + assert_eq!(vc.add(addr1, NilOrVal::Val(1), 1), 1); + assert_eq!(vc.get(&NilOrVal::Nil), 0); + assert_eq!(vc.get(&NilOrVal::Val(1)), 1); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(1), q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); - assert_eq!(vc.add(addr2, Some(1), 1), 2); - assert_eq!(vc.get(&None), 0); - assert_eq!(vc.get(&Some(1)), 2); + assert_eq!(vc.add(addr2, NilOrVal::Val(1), 1), 2); + assert_eq!(vc.get(&NilOrVal::Nil), 0); + assert_eq!(vc.get(&NilOrVal::Val(1)), 2); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); @@ -191,18 +192,18 @@ mod tests { assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); // addr1 votes again, for nil this time, is ignored - assert_eq!(vc.add(addr1, None, 1), 0); - assert_eq!(vc.get(&None), 0); - assert_eq!(vc.get(&Some(1)), 2); + assert_eq!(vc.add(addr1, NilOrVal::Nil, 1), 0); + assert_eq!(vc.get(&NilOrVal::Nil), 0); + assert_eq!(vc.get(&NilOrVal::Val(1)), 2); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(1), q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); - assert_eq!(vc.add(addr3, Some(1), 1), 3); - assert_eq!(vc.get(&None), 0); - assert_eq!(vc.get(&Some(1)), 3); + assert_eq!(vc.add(addr3, NilOrVal::Val(1), 1), 3); + assert_eq!(vc.get(&NilOrVal::Nil), 0); + assert_eq!(vc.get(&NilOrVal::Val(1)), 3); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), true); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); @@ -210,19 +211,19 @@ mod tests { assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); // addr2 votes again, for the same value, is ignored - assert_eq!(vc.add(addr2, Some(1), 1), 3); - assert_eq!(vc.get(&None), 0); - assert_eq!(vc.get(&Some(1)), 3); + assert_eq!(vc.add(addr2, NilOrVal::Val(1), 1), 3); + assert_eq!(vc.get(&NilOrVal::Nil), 0); + assert_eq!(vc.get(&NilOrVal::Val(1)), 3); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), true); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Value(1), q, t), true); assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); - assert_eq!(vc.add(addr4, Some(2), 1), 1); - assert_eq!(vc.get(&None), 0); - assert_eq!(vc.get(&Some(1)), 3); - assert_eq!(vc.get(&Some(2)), 1); + assert_eq!(vc.add(addr4, NilOrVal::Val(2), 1), 1); + assert_eq!(vc.get(&NilOrVal::Nil), 0); + assert_eq!(vc.get(&NilOrVal::Val(1)), 3); + assert_eq!(vc.get(&NilOrVal::Val(2)), 1); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), true); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); @@ -230,11 +231,11 @@ mod tests { assert_eq!(vc.is_threshold_met(Threshold::Value(2), q, t), false); // addr4 votes again, for a different value, is ignored - assert_eq!(vc.add(addr4, Some(3), 1), 0); - assert_eq!(vc.get(&None), 0); - assert_eq!(vc.get(&Some(1)), 3); - assert_eq!(vc.get(&Some(2)), 1); - assert_eq!(vc.get(&Some(3)), 0); + assert_eq!(vc.add(addr4, NilOrVal::Val(3), 1), 0); + assert_eq!(vc.get(&NilOrVal::Nil), 0); + assert_eq!(vc.get(&NilOrVal::Val(1)), 3); + assert_eq!(vc.get(&NilOrVal::Val(2)), 1); + assert_eq!(vc.get(&NilOrVal::Val(3)), 0); assert_eq!(vc.is_threshold_met(Threshold::Unreached, q, t), false); assert_eq!(vc.is_threshold_met(Threshold::Any, q, t), true); assert_eq!(vc.is_threshold_met(Threshold::Nil, q, t), false); diff --git a/Code/vote/src/keeper.rs b/Code/vote/src/keeper.rs index 15b3fdab1..5f5f9e1b5 100644 --- a/Code/vote/src/keeper.rs +++ b/Code/vote/src/keeper.rs @@ -2,7 +2,7 @@ use core::fmt; use alloc::collections::{BTreeMap, BTreeSet}; -use malachite_common::{Context, Round, ValueId, Vote, VoteType}; +use malachite_common::{Context, NilOrVal, Round, ValueId, Vote, VoteType}; use crate::round_votes::RoundVotes; use crate::round_weights::RoundWeights; @@ -191,7 +191,7 @@ where fn compute_threshold( vote_type: VoteType, round: &PerRound, - value: &Option>, + value: &NilOrVal>, quorum: ThresholdParam, total_weight: Weight, ) -> Threshold> @@ -201,9 +201,11 @@ where let weight = round.votes.get_weight(vote_type, value); match value { - Some(value) if quorum.is_met(weight, total_weight) => Threshold::Value(value.clone()), + NilOrVal::Val(value) if quorum.is_met(weight, total_weight) => { + Threshold::Value(value.clone()) + } - None if quorum.is_met(weight, total_weight) => Threshold::Nil, + NilOrVal::Nil if quorum.is_met(weight, total_weight) => Threshold::Nil, _ => { let weight_sum = round.votes.weight_sum(vote_type); diff --git a/Code/vote/src/round_votes.rs b/Code/vote/src/round_votes.rs index c54aab7f0..7d9223e5b 100644 --- a/Code/vote/src/round_votes.rs +++ b/Code/vote/src/round_votes.rs @@ -1,4 +1,4 @@ -use malachite_common::VoteType; +use malachite_common::{NilOrVal, VoteType}; use crate::count::VoteCount; use crate::{Threshold, ThresholdParam, Weight}; @@ -30,7 +30,7 @@ impl RoundVotes { &mut self, vote_type: VoteType, address: Address, - value: Option, + value: NilOrVal, weight: Weight, ) -> Weight where @@ -43,7 +43,7 @@ impl RoundVotes { } } - pub fn get_weight(&self, vote_type: VoteType, value: &Option) -> Weight + pub fn get_weight(&self, vote_type: VoteType, value: &NilOrVal) -> Weight where Value: Ord, { @@ -60,7 +60,7 @@ impl RoundVotes { } } - pub fn combined_weight(&self, value: &Option) -> Weight + pub fn combined_weight(&self, value: &NilOrVal) -> Weight where Value: Ord, {