From 108ac574bbd2b311e960be7fb7889e7a6bcc5565 Mon Sep 17 00:00:00 2001 From: Andreas Fackler Date: Thu, 27 Dec 2018 10:34:34 +0100 Subject: [PATCH] Migrate to rand 0.6. (#368) * Migrate to rand 0.6. * Prefer SliceRandom where it makes sense. --- Cargo.toml | 22 ++++----- examples/network/node.rs | 2 +- examples/simulation.rs | 10 ++-- src/binary_agreement/mod.rs | 11 +++-- src/binary_agreement/sbv_broadcast.rs | 11 +++-- src/broadcast/message.rs | 9 ++-- src/broadcast/mod.rs | 2 +- src/dynamic_honey_badger/builder.rs | 10 ++-- .../dynamic_honey_badger.rs | 12 ++--- src/dynamic_honey_badger/mod.rs | 5 +- src/dynamic_honey_badger/votes.rs | 2 +- src/honey_badger/builder.rs | 3 +- src/honey_badger/epoch_state.rs | 18 +++---- src/honey_badger/honey_badger.rs | 8 +-- src/honey_badger/message.rs | 46 ++++++++++++++--- src/queueing_honey_badger/mod.rs | 16 +++--- src/sender_queue/dynamic_honey_badger.rs | 13 ++--- src/sender_queue/honey_badger.rs | 12 ++--- src/sender_queue/message.rs | 12 ++--- src/sender_queue/queueing_honey_badger.rs | 12 +++-- src/subset/message.rs | 21 ++++++-- src/subset/proposal_state.rs | 5 +- src/subset/subset.rs | 10 ++-- src/sync_key_gen.rs | 6 +-- src/transaction_queue.rs | 9 ++-- tests/binary_agreement.rs | 2 +- tests/honey_badger.rs | 4 +- tests/net/mod.rs | 5 +- tests/net/proptest.rs | 6 +-- tests/net_dynamic_hb.rs | 7 +-- tests/net_util.rs | 49 +++---------------- tests/network/mod.rs | 10 ++-- tests/queueing_honey_badger.rs | 7 +-- 33 files changed, 183 insertions(+), 194 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c29595c..3d54113 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,32 +24,28 @@ travis-ci = { repository = "poanetwork/hbbft" } bincode = "1.0.0" byteorder = "1.2.3" derivative = "1.0.1" -env_logger = "0.5.10" +env_logger = "0.6.0" failure = "0.1" hex_fmt = "0.2" init_with = "1.1.0" log = "0.4.1" -rand = "0.4.2" -rand_derive = "0.3.1" +rand = "0.6.1" +rand_derive = "0.5.0" reed-solomon-erasure = "3.1.1" -serde = "1.0.55" -serde_derive = "1.0.55" -threshold_crypto = "0.2.1" +serde = "1.0.82" +serde_derive = "1.0.82" +threshold_crypto = "0.3.0" tiny-keccak = "1.4" [dev-dependencies] colored = "1.6" -crossbeam = "0.5" +crossbeam = "0.6" crossbeam-channel = "0.3" docopt = "1.0" -itertools = "0.7" -serde_derive = "1.0.55" +itertools = "0.8.0" +rand_xorshift = "0.1.0" signifix = "0.9" proptest = "0.8.7" -# Note: `rand_core` is solely used for the randomness adapter in `net_utils.rs` -# tests and should be removed as soon as a migration path to rand 0.5 -# appears. -rand_core = "0.2.1" integer-sqrt = "0.1.1" [[example]] diff --git a/examples/network/node.rs b/examples/network/node.rs index 2915cd4..8922c2e 100644 --- a/examples/network/node.rs +++ b/examples/network/node.rs @@ -108,7 +108,7 @@ impl + PartialEq + Send + Sync + From> + let tx_from_algo = messaging.tx_from_algo(); let stop_tx = messaging.stop_tx(); - let mut rng = rand::OsRng::new().unwrap(); + let mut rng = rand::rngs::OsRng::new().unwrap(); // All spawned threads will have exited by the end of the scope. crossbeam::scope(|scope| { diff --git a/examples/simulation.rs b/examples/simulation.rs index f61de04..2bd2650 100644 --- a/examples/simulation.rs +++ b/examples/simulation.rs @@ -5,7 +5,7 @@ use std::{cmp, u64}; use colored::*; use docopt::Docopt; use itertools::Itertools; -use rand::Rng; +use rand::{distributions::Standard, rngs::OsRng, seq::SliceRandom, Rng}; use rand_derive::Rand; use serde::de::DeserializeOwned; use serde::Serialize; @@ -305,7 +305,7 @@ where .filter(|(_, node)| node.next_event_time() == Some(min_time)) .map(|(id, _)| *id) .collect(); - let next_id = *rng.choose(&min_ids).unwrap(); + let next_id = *min_ids.choose(rng).unwrap(); let msgs: Vec<_> = { let node = self.nodes.get_mut(&next_id).unwrap(); node.handle_message(rng); @@ -400,7 +400,7 @@ fn parse_args() -> Result { fn main() { env_logger::init(); - let mut rng = rand::OsRng::new().expect("Could not initialize OS random number generator."); + let mut rng = OsRng::new().expect("Could not initialize OS random number generator."); let args = parse_args().unwrap_or_else(|e| e.exit()); if args.flag_n <= 3 * args.flag_f { @@ -423,10 +423,10 @@ fn main() { let num_good_nodes = args.flag_n - args.flag_f; let txs: Vec<_> = (0..args.flag_txs) - .map(|_| rng.gen_iter().take(args.flag_tx_size).collect()) + .map(|_| rng.sample_iter(&Standard).take(args.flag_tx_size).collect()) .collect(); - let new_honey_badger = |netinfo: NetworkInfo, rng: &mut rand::OsRng| { + let new_honey_badger = |netinfo: NetworkInfo, rng: &mut OsRng| { let our_id = *netinfo.our_id(); let peer_ids: Vec<_> = netinfo .all_ids() diff --git a/src/binary_agreement/mod.rs b/src/binary_agreement/mod.rs index 5448d6f..19069da 100644 --- a/src/binary_agreement/mod.rs +++ b/src/binary_agreement/mod.rs @@ -70,7 +70,8 @@ mod sbv_broadcast; use bincode; use failure::Fail; -use rand; +use rand::distributions::{Distribution, Standard}; +use rand::{seq::SliceRandom, Rng}; use rand_derive::Rand; use serde_derive::{Deserialize, Serialize}; @@ -148,11 +149,11 @@ pub struct Message { } // NOTE: Extending rand_derive to correctly generate random values from boxes would make this -// implementation obsolete; however at the time of this writing, `rand::Rand` is already deprecated +// implementation obsolete; however at the time of this writing, `rand_derive` is already deprecated // with no replacement in sight. -impl rand::Rand for MessageContent { - fn rand(rng: &mut R) -> Self { - let message_type = *rng.choose(&["sbvb", "conf", "term", "coin"]).unwrap(); +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> MessageContent { + let message_type = *["sbvb", "conf", "term", "coin"].choose(rng).unwrap(); match message_type { "sbvb" => MessageContent::SbvBroadcast(rng.gen()), diff --git a/src/binary_agreement/sbv_broadcast.rs b/src/binary_agreement/sbv_broadcast.rs index 46603b3..5c3c3e5 100644 --- a/src/binary_agreement/sbv_broadcast.rs +++ b/src/binary_agreement/sbv_broadcast.rs @@ -11,7 +11,8 @@ use std::sync::Arc; -use rand; +use rand::distributions::{Distribution, Standard}; +use rand::{seq::SliceRandom, Rng}; use serde_derive::{Deserialize, Serialize}; use super::bool_multimap::BoolMultimap; @@ -33,11 +34,11 @@ pub enum Message { } // NOTE: Extending rand_derive to correctly generate random values from boxes would make this -// implementation obsolete; however at the time of this writing, `rand::Rand` is already deprecated +// implementation obsolete; however at the time of this writing, `rand_derive` is already deprecated // with no replacement in sight. -impl rand::Rand for Message { - fn rand(rng: &mut R) -> Self { - let message_type = *rng.choose(&["bval", "aux"]).unwrap(); +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> Message { + let message_type = *["bval", "aux"].choose(rng).unwrap(); match message_type { "bval" => Message::BVal(rng.gen()), diff --git a/src/broadcast/message.rs b/src/broadcast/message.rs index 4ff19ef..2c43052 100644 --- a/src/broadcast/message.rs +++ b/src/broadcast/message.rs @@ -1,7 +1,8 @@ use std::fmt::{self, Debug}; use hex_fmt::HexFmt; -use rand; +use rand::distributions::{Distribution, Standard}; +use rand::{self, seq::SliceRandom, Rng}; use serde_derive::{Deserialize, Serialize}; use super::merkle::{Digest, MerkleTree, Proof}; @@ -20,9 +21,9 @@ pub enum Message { // A random generation impl is provided for test cases. Unfortunately `#[cfg(test)]` does not work // for integration tests. -impl rand::Rand for Message { - fn rand(rng: &mut R) -> Self { - let message_type = *rng.choose(&["value", "echo", "ready"]).unwrap(); +impl Distribution for Standard { + fn sample(&self, rng: &mut R) -> Message { + let message_type = *["value", "echo", "ready"].choose(rng).unwrap(); // Create a random buffer for our proof. let mut buffer: [u8; 32] = [0; 32]; diff --git a/src/broadcast/mod.rs b/src/broadcast/mod.rs index 82a340d..353c576 100644 --- a/src/broadcast/mod.rs +++ b/src/broadcast/mod.rs @@ -92,7 +92,7 @@ //! ``` //! use hbbft::broadcast::{Broadcast, Error, Step}; //! use hbbft::{NetworkInfo, SourcedMessage, Target, TargetedMessage}; -//! use rand::{OsRng, Rng}; +//! use rand::{OsRng, Rng, RngCore}; //! use std::collections::{BTreeMap, BTreeSet, VecDeque}; //! use std::iter::once; //! use std::sync::Arc; diff --git a/src/dynamic_honey_badger/builder.rs b/src/dynamic_honey_badger/builder.rs index 4d88ca9..1bf5700 100644 --- a/src/dynamic_honey_badger/builder.rs +++ b/src/dynamic_honey_badger/builder.rs @@ -4,7 +4,6 @@ use std::marker::PhantomData; use std::sync::Arc; use crate::crypto::{SecretKey, SecretKeySet}; -use rand::Rand; use serde::{de::DeserializeOwned, Serialize}; use super::{DynamicHoneyBadger, EncryptionSchedule, JoinPlan, Result, Step, VoteCounter}; @@ -21,10 +20,7 @@ pub struct DynamicHoneyBadgerBuilder { _phantom: PhantomData<(C, N)>, } -impl Default for DynamicHoneyBadgerBuilder -where - N: Ord, -{ +impl Default for DynamicHoneyBadgerBuilder { fn default() -> Self { DynamicHoneyBadgerBuilder { era: 0, @@ -37,7 +33,7 @@ where impl DynamicHoneyBadgerBuilder where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, { /// Returns a new `DynamicHoneyBadgerBuilder` configured to use the node IDs and cryptographic /// keys specified by `netinfo`. @@ -112,7 +108,7 @@ where let sk_set = SecretKeySet::random(0, rng); let pk_set = sk_set.public_keys(); let sks = sk_set.secret_key_share(0); - let sk: SecretKey = rng.gen(); + let sk = rng.gen::(); let pub_keys = once((our_id.clone(), sk.public_key())).collect(); let netinfo = NetworkInfo::new(our_id, sks, pk_set, sk, pub_keys); Ok(self.build(netinfo)) diff --git a/src/dynamic_honey_badger/dynamic_honey_badger.rs b/src/dynamic_honey_badger/dynamic_honey_badger.rs index 1baf79e..3f949db 100644 --- a/src/dynamic_honey_badger/dynamic_honey_badger.rs +++ b/src/dynamic_honey_badger/dynamic_honey_badger.rs @@ -6,7 +6,7 @@ use crate::crypto::{PublicKey, SecretKey, Signature}; use bincode; use derivative::Derivative; use log::debug; -use rand::{Rand, Rng}; +use rand::Rng; use serde::{de::DeserializeOwned, Serialize}; use super::votes::{SignedVote, VoteCounter}; @@ -25,7 +25,7 @@ use crate::{Contribution, DistAlgorithm, Epoched, NetworkInfo, NodeIdT, Target}; /// A Honey Badger instance that can handle adding and removing nodes. #[derive(Derivative)] #[derivative(Debug)] -pub struct DynamicHoneyBadger { +pub struct DynamicHoneyBadger { /// Shared network data. pub(super) netinfo: NetworkInfo, /// The maximum number of future epochs for which we handle messages simultaneously. @@ -45,7 +45,7 @@ pub struct DynamicHoneyBadger { impl DistAlgorithm for DynamicHoneyBadger where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, { type NodeId = N; type Input = Input; @@ -83,7 +83,7 @@ where impl DynamicHoneyBadger where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, { /// Returns a new `DynamicHoneyBadgerBuilder`. pub fn builder() -> DynamicHoneyBadgerBuilder { @@ -531,7 +531,7 @@ where impl fmt::Display for DynamicHoneyBadger where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, { fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { write!(f, "{:?} DHB(era: {})", self.our_id(), self.era) @@ -541,7 +541,7 @@ where impl Epoched for DynamicHoneyBadger where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, { type Epoch = (u64, u64); diff --git a/src/dynamic_honey_badger/mod.rs b/src/dynamic_honey_badger/mod.rs index c582be6..2dc920e 100644 --- a/src/dynamic_honey_badger/mod.rs +++ b/src/dynamic_honey_badger/mod.rs @@ -75,7 +75,6 @@ mod votes; use std::collections::BTreeMap; use crate::crypto::{PublicKey, PublicKeySet, Signature}; -use rand::Rand; use serde_derive::{Deserialize, Serialize}; use self::votes::{SignedVote, VoteCounter}; @@ -114,7 +113,7 @@ pub enum KeyGenMessage { /// A message sent to or received from another node's Honey Badger instance. #[derive(Serialize, Deserialize, Debug, Clone)] -pub enum Message { +pub enum Message { /// A message belonging to the `HoneyBadger` algorithm started in the given epoch. HoneyBadger(u64, HbMessage), /// A transaction to be committed, signed by a node. @@ -123,7 +122,7 @@ pub enum Message { SignedVote(SignedVote), } -impl Message { +impl Message { fn era(&self) -> u64 { match *self { Message::HoneyBadger(era, _) => era, diff --git a/src/dynamic_honey_badger/votes.rs b/src/dynamic_honey_badger/votes.rs index 5ce300e..0a1f6c6 100644 --- a/src/dynamic_honey_badger/votes.rs +++ b/src/dynamic_honey_badger/votes.rs @@ -201,7 +201,7 @@ mod tests { /// the vote by node `i` for making `j` the only validator. Each node signed this for nodes /// `0`, `1`, ... in order. fn setup(node_num: usize, era: u64) -> (Vec>, Vec>>) { - let mut rng = rand::OsRng::new().expect("could not initialize OsRng"); + let mut rng = rand::rngs::OsRng::new().expect("could not initialize OsRng"); // Create keys for threshold cryptography. let netinfos = NetworkInfo::generate_map(0..node_num, &mut rng) .expect("Failed to generate `NetworkInfo` map"); diff --git a/src/honey_badger/builder.rs b/src/honey_badger/builder.rs index 1611dd9..fde5ca1 100644 --- a/src/honey_badger/builder.rs +++ b/src/honey_badger/builder.rs @@ -2,7 +2,6 @@ use std::collections::BTreeMap; use std::marker::PhantomData; use std::sync::Arc; -use rand::Rand; use serde::{de::DeserializeOwned, Serialize}; use super::{EncryptionSchedule, HoneyBadger, Params, SubsetHandlingStrategy}; @@ -25,7 +24,7 @@ pub struct HoneyBadgerBuilder { impl HoneyBadgerBuilder where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Rand, + N: NodeIdT, { /// Returns a new `HoneyBadgerBuilder` configured to use the node IDs and cryptographic keys /// specified by `netinfo`. diff --git a/src/honey_badger/epoch_state.rs b/src/honey_badger/epoch_state.rs index e934ef0..660ac5a 100644 --- a/src/honey_badger/epoch_state.rs +++ b/src/honey_badger/epoch_state.rs @@ -9,7 +9,7 @@ use std::sync::Arc; use crate::crypto::Ciphertext; use bincode; use log::error; -use rand::{Rand, Rng}; +use rand::Rng; use serde::{de::DeserializeOwned, Serialize}; use serde_derive::{Deserialize, Serialize}; @@ -30,10 +30,7 @@ enum DecryptionState { Complete(Vec), } -impl DecryptionState -where - N: NodeIdT + Rand, -{ +impl DecryptionState { /// Creates a new `ThresholdDecrypt` instance, waiting for shares and a ciphertext. fn new(netinfo: Arc>) -> Self { DecryptionState::Ongoing(Box::new(ThresholdDecrypt::new(netinfo))) @@ -61,17 +58,14 @@ where /// The status of the subset algorithm. #[derive(Debug)] -enum SubsetState { +enum SubsetState { /// The algorithm is ongoing: the set of accepted contributions is still undecided. Ongoing(Subset), /// The algorithm is complete. This contains the set of accepted proposers. Complete(BTreeSet), } -impl SubsetState -where - N: NodeIdT + Rand, -{ +impl SubsetState { /// Provides input to the Subset instance, unless it has already completed. fn handle_input(&mut self, proposal: Vec) -> Result> { match self { @@ -181,7 +175,7 @@ impl From for SubsetHandler { /// The sub-algorithms and their intermediate results for a single epoch. #[derive(Debug)] -pub struct EpochState { +pub struct EpochState { /// Our epoch number. epoch: u64, /// Shared network data. @@ -202,7 +196,7 @@ pub struct EpochState { impl EpochState where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Rand, + N: NodeIdT, { /// Creates a new `Subset` instance. pub fn new( diff --git a/src/honey_badger/honey_badger.rs b/src/honey_badger/honey_badger.rs index 0141b65..5dae227 100644 --- a/src/honey_badger/honey_badger.rs +++ b/src/honey_badger/honey_badger.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use std::sync::Arc; use derivative::Derivative; -use rand::{Rand, Rng}; +use rand::Rng; use serde::{de::DeserializeOwned, Serialize}; use serde_derive::{Deserialize, Serialize}; @@ -16,7 +16,7 @@ use super::Params; /// An instance of the Honey Badger Byzantine fault tolerant consensus algorithm. #[derive(Derivative)] #[derivative(Debug)] -pub struct HoneyBadger { +pub struct HoneyBadger { /// Shared network data. pub(super) netinfo: Arc>, /// A session identifier. Different session IDs foil replay attacks in two instances with the @@ -38,7 +38,7 @@ pub type Step = crate::DaStep>; impl DistAlgorithm for HoneyBadger where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Rand, + N: NodeIdT, { type NodeId = N; type Input = C; @@ -71,7 +71,7 @@ where impl HoneyBadger where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Rand, + N: NodeIdT, { /// Returns a new `HoneyBadgerBuilder` configured to use the node IDs and cryptographic keys /// specified by `netinfo`. diff --git a/src/honey_badger/message.rs b/src/honey_badger/message.rs index d57cb8e..395a8c3 100644 --- a/src/honey_badger/message.rs +++ b/src/honey_badger/message.rs @@ -1,16 +1,16 @@ // `threshold_sign::Message` triggers this Clippy lint, but `Box` doesn't implement `Rand`. #![allow(clippy::large_enum_variant)] -use rand::Rand; -use rand_derive::Rand; +use rand::distributions::{Distribution, Standard}; +use rand::{seq::SliceRandom, Rng}; use serde_derive::{Deserialize, Serialize}; use crate::subset; use crate::threshold_decrypt; /// The content of a `HoneyBadger` message. It should be further annotated with an epoch. -#[derive(Clone, Debug, Deserialize, Rand, Serialize)] -pub enum MessageContent { +#[derive(Clone, Debug, Deserialize, Serialize)] +pub enum MessageContent { /// A message belonging to the subset algorithm in the given epoch. Subset(subset::Message), /// A decryption share of the output of `proposer_id`. @@ -22,7 +22,25 @@ pub enum MessageContent { }, } -impl MessageContent { +impl Distribution> for Standard +where + Standard: Distribution, +{ + fn sample(&self, rng: &mut R) -> MessageContent { + let message_type = *["subset", "dec_share"].choose(rng).unwrap(); + + match message_type { + "subset" => MessageContent::Subset(rng.gen::>()), + "dec_share" => MessageContent::DecryptionShare { + proposer_id: rng.gen::(), + share: rng.gen::(), + }, + _ => unreachable!(), + } + } +} + +impl MessageContent { /// Wraps this content in a `Message` with the given epoch. pub fn with_epoch(self, epoch: u64) -> Message { Message { @@ -33,13 +51,25 @@ impl MessageContent { } /// A message sent to or received from another node's Honey Badger instance. -#[derive(Clone, Debug, Deserialize, Rand, Serialize)] -pub struct Message { +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Message { pub(super) epoch: u64, pub(super) content: MessageContent, } -impl Message { +impl Distribution> for Standard +where + Standard: Distribution, +{ + fn sample(&self, rng: &mut R) -> Message { + Message { + epoch: rng.gen::(), + content: rng.gen::>(), + } + } +} + +impl Message { /// Returns this message's Honey Badger epoch. pub fn epoch(&self) -> u64 { self.epoch diff --git a/src/queueing_honey_badger/mod.rs b/src/queueing_honey_badger/mod.rs index a20bc95..b09dd34 100644 --- a/src/queueing_honey_badger/mod.rs +++ b/src/queueing_honey_badger/mod.rs @@ -27,7 +27,8 @@ use std::{cmp, iter}; use derivative::Derivative; use failure::Fail; -use rand::{Rand, Rng}; +use rand::distributions::{Distribution, Standard}; +use rand::Rng; use serde::{de::DeserializeOwned, Serialize}; use crate::crypto::{PublicKey, SecretKey}; @@ -64,7 +65,7 @@ pub type Result = ::std::result::Result; pub struct QueueingHoneyBadgerBuilder where T: Contribution + Serialize + DeserializeOwned + Clone, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, { /// Shared network data. dyn_hb: DynamicHoneyBadger, N>, @@ -82,8 +83,9 @@ type QueueingHoneyBadgerWithStep = (QueueingHoneyBadger, Step< impl QueueingHoneyBadgerBuilder where T: Contribution + Serialize + DeserializeOwned + Clone, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, Q: TransactionQueue, + Standard: Distribution, { /// Returns a new `QueueingHoneyBadgerBuilder` wrapping the given instance of /// `DynamicHoneyBadger`. @@ -150,7 +152,7 @@ where /// queue. #[derive(Derivative)] #[derivative(Debug)] -pub struct QueueingHoneyBadger { +pub struct QueueingHoneyBadger { /// The target number of transactions to be included in each batch. batch_size: usize, /// The internal managed `DynamicHoneyBadger` instance. @@ -165,8 +167,9 @@ pub type Step = crate::Step, Batch, N>; impl DistAlgorithm for QueueingHoneyBadger where T: Contribution + Serialize + DeserializeOwned + Clone, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, Q: TransactionQueue, + Standard: Distribution, { type NodeId = N; type Input = Input; @@ -205,8 +208,9 @@ where impl QueueingHoneyBadger where T: Contribution + Serialize + DeserializeOwned + Clone, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, Q: TransactionQueue, + Standard: Distribution, { /// Returns a new `QueueingHoneyBadgerBuilder` configured to use the node IDs and cryptographic /// keys specified by `netinfo`. diff --git a/src/sender_queue/dynamic_honey_badger.rs b/src/sender_queue/dynamic_honey_badger.rs index c048b63..3ac0afa 100644 --- a/src/sender_queue/dynamic_honey_badger.rs +++ b/src/sender_queue/dynamic_honey_badger.rs @@ -4,7 +4,7 @@ use std::collections::BTreeSet; use std::result; use crate::crypto::PublicKey; -use rand::{Rand, Rng}; +use rand::Rng; use serde::{de::DeserializeOwned, Serialize}; use super::{ @@ -19,7 +19,7 @@ use crate::dynamic_honey_badger::{ impl SenderQueueableOutput for Batch where C: Contribution, - N: NodeIdT + Rand, + N: NodeIdT, { fn participant_change(&self) -> Option> { if let ChangeState::InProgress(Change::NodeChange(pub_keys)) = self.change() { @@ -42,10 +42,7 @@ where } } -impl SenderQueueableMessage for Message -where - N: Rand + Ord, -{ +impl SenderQueueableMessage for Message { type Epoch = (u64, u64); fn is_premature(&self, (them_era, them): (u64, u64), max_future_epochs: u64) -> bool { @@ -80,7 +77,7 @@ where impl SenderQueueableDistAlgorithm for DynamicHoneyBadger where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, { fn max_future_epochs(&self) -> u64 { self.max_future_epochs() @@ -92,7 +89,7 @@ type Result = result::Result>> impl SenderQueue> where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, { /// Proposes a contribution in the current epoch. /// diff --git a/src/sender_queue/honey_badger.rs b/src/sender_queue/honey_badger.rs index 12f594f..e319072 100644 --- a/src/sender_queue/honey_badger.rs +++ b/src/sender_queue/honey_badger.rs @@ -1,6 +1,5 @@ use std::collections::BTreeSet; -use rand::Rand; use serde::{de::DeserializeOwned, Serialize}; use super::{SenderQueueableDistAlgorithm, SenderQueueableMessage, SenderQueueableOutput}; @@ -10,7 +9,7 @@ use crate::{Contribution, Epoched, NodeIdT}; impl SenderQueueableOutput for Batch where C: Contribution, - N: NodeIdT + Rand, + N: NodeIdT, { fn participant_change(&self) -> Option> { None @@ -21,10 +20,7 @@ where } } -impl SenderQueueableMessage for Message -where - N: Rand, -{ +impl SenderQueueableMessage for Message { type Epoch = u64; fn is_premature(&self, them: u64, max_future_epochs: u64) -> bool { @@ -43,7 +39,7 @@ where impl Epoched for HoneyBadger where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Rand, + N: NodeIdT, { type Epoch = u64; @@ -55,7 +51,7 @@ where impl SenderQueueableDistAlgorithm for HoneyBadger where C: Contribution + Serialize + DeserializeOwned, - N: NodeIdT + Rand, + N: NodeIdT, { fn max_future_epochs(&self) -> u64 { self.max_future_epochs() diff --git a/src/sender_queue/message.rs b/src/sender_queue/message.rs index db13f4b..46bd974 100644 --- a/src/sender_queue/message.rs +++ b/src/sender_queue/message.rs @@ -1,4 +1,5 @@ -use rand::{Rand, Rng}; +use rand::distributions::{Distribution, Standard}; +use rand::{seq::SliceRandom, Rng}; use serde_derive::{Deserialize, Serialize}; use super::SenderQueueableMessage; @@ -12,13 +13,12 @@ pub enum Message { Algo(M), } -impl Rand for Message +impl Distribution> for Standard where - M: SenderQueueableMessage + Rand, - M::Epoch: Rand, + Standard: Distribution + Distribution, { - fn rand(rng: &mut R) -> Self { - let message_type = *rng.choose(&["epoch", "algo"]).unwrap(); + fn sample(&self, rng: &mut R) -> Message { + let message_type = *["epoch", "algo"].choose(rng).unwrap(); match message_type { "epoch" => Message::EpochStarted(rng.gen()), diff --git a/src/sender_queue/queueing_honey_badger.rs b/src/sender_queue/queueing_honey_badger.rs index 2923312..b9b437e 100644 --- a/src/sender_queue/queueing_honey_badger.rs +++ b/src/sender_queue/queueing_honey_badger.rs @@ -3,7 +3,8 @@ use std::result; use crate::crypto::PublicKey; -use rand::{Rand, Rng}; +use rand::distributions::{Distribution, Standard}; +use rand::Rng; use serde::{de::DeserializeOwned, Serialize}; use super::{SenderQueue, SenderQueueableDistAlgorithm}; @@ -14,8 +15,9 @@ use crate::{Contribution, DaStep, Epoched, NodeIdT}; impl Epoched for QueueingHoneyBadger where T: Contribution + Serialize + DeserializeOwned + Clone, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, Q: TransactionQueue, + Standard: Distribution, { type Epoch = (u64, u64); @@ -27,8 +29,9 @@ where impl SenderQueueableDistAlgorithm for QueueingHoneyBadger where T: Contribution + Serialize + DeserializeOwned + Clone, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, Q: TransactionQueue, + Standard: Distribution, { fn max_future_epochs(&self) -> u64 { self.dyn_hb().max_future_epochs() @@ -40,8 +43,9 @@ type Result = result::Result SenderQueue> where T: Contribution + Serialize + DeserializeOwned + Clone, - N: NodeIdT + Serialize + DeserializeOwned + Rand, + N: NodeIdT + Serialize + DeserializeOwned, Q: TransactionQueue, + Standard: Distribution, { /// Adds a transaction to the queue. /// diff --git a/src/subset/message.rs b/src/subset/message.rs index f9350de..a4785c7 100644 --- a/src/subset/message.rs +++ b/src/subset/message.rs @@ -1,4 +1,5 @@ -use rand::Rand; +use rand::distributions::{Distribution, Standard}; +use rand::Rng; use rand_derive::Rand; use serde_derive::{Deserialize, Serialize}; @@ -6,14 +7,26 @@ use crate::binary_agreement; use crate::broadcast; /// Message from Subset to remote nodes. -#[derive(Serialize, Deserialize, Clone, Debug, Rand)] -pub struct Message { +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Message { /// The proposer whose contribution this message is about. pub proposer_id: N, /// The wrapped broadcast or agreement message. pub content: MessageContent, } +impl Distribution> for Standard +where + Standard: Distribution, +{ + fn sample(&self, rng: &mut R) -> Message { + Message { + proposer_id: rng.gen::(), + content: rng.gen::(), + } + } +} + /// A message about a particular proposer's contribution. #[derive(Serialize, Deserialize, Clone, Debug, Rand)] pub enum MessageContent { @@ -25,7 +38,7 @@ pub enum MessageContent { impl MessageContent { /// Returns a `Message` with this content and the specified proposer ID. - pub(super) fn with(self, proposer_id: N) -> Message { + pub(super) fn with(self, proposer_id: N) -> Message { Message { proposer_id, content: self, diff --git a/src/subset/proposal_state.rs b/src/subset/proposal_state.rs index a41488b..b618de0 100644 --- a/src/subset/proposal_state.rs +++ b/src/subset/proposal_state.rs @@ -6,7 +6,6 @@ use super::{Error, MessageContent, Result}; use crate::binary_agreement; use crate::broadcast::{self, Broadcast}; use crate::{NetworkInfo, NodeIdT, SessionIdT}; -use rand::Rand; type BaInstance = binary_agreement::BinaryAgreement>; type ValueAndStep = (Option>, Step); @@ -16,7 +15,7 @@ pub type Step = crate::Step, N>; /// The state of a proposal's broadcast and agreement process. #[derive(Debug)] -pub enum ProposalState { +pub enum ProposalState { /// We are still awaiting the value from the `Broadcast` protocol and the decision from /// `BinaryAgreement`. Ongoing(Broadcast, BaInstance), @@ -28,7 +27,7 @@ pub enum ProposalState { Complete(bool), } -impl ProposalState { +impl ProposalState { /// Creates a new `ProposalState::Ongoing`, with a fresh broadcast and agreement instance. pub fn new(netinfo: Arc>, ba_id: BaSessionId, prop_id: N) -> Result { let agreement = BaInstance::new(netinfo.clone(), ba_id).map_err(Error::NewAgreement)?; diff --git a/src/subset/subset.rs b/src/subset/subset.rs index 294e5fc..09d84fe 100644 --- a/src/subset/subset.rs +++ b/src/subset/subset.rs @@ -10,7 +10,7 @@ use serde_derive::Serialize; use super::proposal_state::{ProposalState, Step as ProposalStep}; use super::{Error, Message, MessageContent, Result}; use crate::{util, DistAlgorithm, NetworkInfo, NodeIdT, SessionIdT}; -use rand::{Rand, Rng}; +use rand::Rng; /// A `Subset` step, possibly containing several outputs. pub type Step = crate::Step, SubsetOutput, N>; @@ -30,7 +30,7 @@ pub enum SubsetOutput { /// Subset algorithm instance #[derive(Debug)] -pub struct Subset { +pub struct Subset { /// Shared network information. netinfo: Arc>, /// The session identifier. @@ -41,7 +41,7 @@ pub struct Subset { decided: bool, } -impl DistAlgorithm for Subset { +impl DistAlgorithm for Subset { type NodeId = N; type Input = Vec; type Output = SubsetOutput; @@ -70,7 +70,7 @@ impl DistAlgorithm for Subset { } } -impl Subset { +impl Subset { /// Creates a new `Subset` instance with the given session identifier. /// /// If multiple `Subset`s are instantiated within a single network, they must use different @@ -168,7 +168,7 @@ impl Subset { } } -impl fmt::Display for Subset { +impl fmt::Display for Subset { fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> { write!(f, "{:?} Subset({})", self.our_id(), self.session_id) } diff --git a/src/sync_key_gen.rs b/src/sync_key_gen.rs index 5e2d9dd..e3257cd 100644 --- a/src/sync_key_gen.rs +++ b/src/sync_key_gen.rs @@ -180,7 +180,7 @@ use std::fmt::{self, Debug, Formatter}; use crate::crypto::{ error::Error as CryptoError, poly::{BivarCommitment, BivarPoly, Poly}, - serde_impl::field_vec::FieldWrap, + serde_impl::FieldWrap, Ciphertext, Fr, G1Affine, PublicKey, PublicKeySet, SecretKey, SecretKeyShare, }; use crate::pairing::{CurveAffine, Field}; @@ -385,7 +385,7 @@ impl SyncKeyGen { let mut values = Vec::new(); for (idx, pk) in self.pub_keys.values().enumerate() { let val = row.evaluate(idx + 1); - let ser_val = bincode::serialize(&FieldWrap::new(val))?; + let ser_val = bincode::serialize(&FieldWrap(val))?; values.push(pk.encrypt_with_rng(rng, ser_val)); } Ok(PartOutcome::Valid(Some(Ack(sender_idx, values)))) @@ -536,7 +536,7 @@ impl SyncKeyGen { .sec_key .decrypt(&values[our_idx as usize]) .ok_or(AckFault::DecryptValue)?; - let val = bincode::deserialize::>(&ser_val) + let val = bincode::deserialize::>(&ser_val) .map_err(|_| AckFault::DeserializeValue)? .into_inner(); if part.commit.evaluate(our_idx + 1, sender_idx + 1) != G1Affine::one().mul(val) { diff --git a/src/transaction_queue.rs b/src/transaction_queue.rs index 91b274e..b8ed462 100644 --- a/src/transaction_queue.rs +++ b/src/transaction_queue.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use std::{cmp, fmt}; -use rand::{self, Rng}; +use rand::{self, seq::SliceRandom, Rng}; use crate::Contribution; @@ -47,10 +47,7 @@ where #[inline] fn choose(&mut self, rng: &mut R, amount: usize, batch_size: usize) -> Vec { let limit = cmp::min(batch_size, self.len()); - let sample = match rand::seq::sample_iter(rng, self.iter().take(limit), amount) { - Ok(choice) => choice, - Err(choice) => choice, // Fewer than `amount` were available, which is fine. - }; - sample.into_iter().cloned().collect() + let sample = self[..limit].choose_multiple(rng, amount); + sample.cloned().collect() } } diff --git a/tests/binary_agreement.rs b/tests/binary_agreement.rs index e6b32fa..51bfbe5 100644 --- a/tests/binary_agreement.rs +++ b/tests/binary_agreement.rs @@ -127,7 +127,7 @@ fn binary_agreement(cfg: TestConfig) { }) .build(&mut rng) .expect("Could not construct test network."); - net.test_binary_agreement(cfg.input, rng.gen::()); + net.test_binary_agreement(cfg.input, TestRng::from_seed(rng.gen::())); println!( "Test success: {} good nodes and {} faulty nodes, input: {:?}", num_good_nodes, num_faulty_nodes, cfg.input diff --git a/tests/honey_badger.rs b/tests/honey_badger.rs index 9a548ba..fc8660c 100644 --- a/tests/honey_badger.rs +++ b/tests/honey_badger.rs @@ -9,7 +9,7 @@ use std::sync::Arc; use itertools::Itertools; use log::info; -use rand::Rng; +use rand::{seq::SliceRandom, Rng}; use hbbft::honey_badger::{Batch, EncryptionSchedule, HoneyBadger, MessageContent}; use hbbft::sender_queue::{self, SenderQueue, Step}; @@ -139,7 +139,7 @@ where .filter(|(_, node)| !node.instance().algo().has_input()) .map(|(id, _)| *id) .collect(); - if let Some(id) = rng.choose(&input_ids) { + if let Some(id) = input_ids[..].choose(&mut rng) { let queue = queues.get_mut(id).unwrap(); queue.remove_multiple(network.nodes[id].outputs().iter().flat_map(Batch::iter)); network.input(*id, queue.choose(&mut rng, 3, 10)); diff --git a/tests/net/mod.rs b/tests/net/mod.rs index 565f480..49902be 100644 --- a/tests/net/mod.rs +++ b/tests/net/mod.rs @@ -23,8 +23,7 @@ use std::collections::{BTreeMap, BTreeSet, VecDeque}; use std::io::Write; use std::{cmp, env, fmt, fs, io, ops, process, time}; -use rand; -use rand::{Rand, Rng}; +use rand::{self, Rng}; use hbbft::dynamic_honey_badger::Batch; use hbbft::sender_queue::SenderQueueableOutput; @@ -61,7 +60,7 @@ fn open_trace() -> Result, io::Error> { .to_string_lossy() .into_owned(), process::id(), - u16::rand(&mut rng), + rng.gen::() ); Ok(io::BufWriter::new(fs::File::create(name)?)) diff --git a/tests/net/proptest.rs b/tests/net/proptest.rs index cd8fd6c..92e8c75 100644 --- a/tests/net/proptest.rs +++ b/tests/net/proptest.rs @@ -11,12 +11,10 @@ use proptest::test_runner::{Reason, TestRunner}; use rand::{self, SeedableRng}; /// Random number generator type used in testing. -pub type TestRng = rand::XorShiftRng; +pub type TestRng = rand_xorshift::XorShiftRng; /// Seed type of the random number generator used in testing. -// Note: In `rand` 0.5, this is an associated type of the `SeedableRng` trait, but for 0.4 and below -// we still need to alias this type. -pub type TestRngSeed = [u32; 4]; +pub type TestRngSeed = [u8; 16]; /// Generates a random instance of a random number generator. pub fn gen_rng() -> impl Strategy { diff --git a/tests/net_dynamic_hb.rs b/tests/net_dynamic_hb.rs index 7dcbacf..1578226 100644 --- a/tests/net_dynamic_hb.rs +++ b/tests/net_dynamic_hb.rs @@ -5,7 +5,7 @@ use std::{collections, time}; use hbbft::dynamic_honey_badger::{Change, ChangeState, DynamicHoneyBadger, Input, JoinPlan}; use hbbft::sender_queue::{Message, SenderQueue, Step}; use proptest::{prelude::ProptestConfig, prop_compose, proptest, proptest_helper}; -use rand::SeedableRng; +use rand::{seq::SliceRandom, SeedableRng}; use crate::net::adversary::{Adversary, ReorderingAdversary}; use crate::net::proptest::{gen_seed, NetworkDimension, TestRng, TestRngSeed}; @@ -37,7 +37,7 @@ where let n = queue.len().min(batch_size); let k = queue.len().min(contribution_size); - rand::seq::sample_slice(rng, &queue[0..n], k) + queue[0..n].choose_multiple(rng, k).cloned().collect() } /// Test configuration for dynamic honey badger tests. @@ -212,7 +212,8 @@ fn do_drop_and_readd(cfg: TestConfig) { batch_participants .iter() .all(|id| expected_participants.contains(id)), - "The batch at node {} contains a contribution from an unexpected participant: {:?}", + "The batch at node {} contains a contribution from an unexpected participant: \ + {:?}", node_id, batch ); diff --git a/tests/net_util.rs b/tests/net_util.rs index 017f2f3..807e1b1 100644 --- a/tests/net_util.rs +++ b/tests/net_util.rs @@ -2,49 +2,12 @@ pub mod net; use proptest::arbitrary::any; use proptest::strategy::{Strategy, ValueTree}; -use proptest::{prelude::RngCore, proptest, proptest_helper}; -use rand::{Rng as Rng4, SeedableRng as SeedableRng4}; +use proptest::{proptest, proptest_helper}; +use rand::SeedableRng; +use rand_xorshift::XorShiftRng; use crate::net::proptest::{max_sum, NetworkDimension, NetworkDimensionTree}; -struct RngAdapter4To5(pub T); - -impl Rng4 for RngAdapter4To5 -where - T: Rng4, -{ - #[inline] - fn next_u32(&mut self) -> u32 { - self.0.next_u32() - } -} - -impl RngCore for RngAdapter4To5 -where - T: Rng4, -{ - #[inline] - fn next_u32(&mut self) -> u32 { - self.0.next_u32() - } - - #[inline] - fn next_u64(&mut self) -> u64 { - self.0.next_u64() - } - - #[inline] - fn fill_bytes(&mut self, bytes: &mut [u8]) { - self.0.fill_bytes(bytes); - } - - #[inline] - fn try_fill_bytes(&mut self, bytes: &mut [u8]) -> Result<(), rand_core::Error> { - self.0.fill_bytes(bytes); - Ok(()) - } -} - proptest! { /// Ensures all generated network dimensions are actually sane. #[test] @@ -68,13 +31,13 @@ proptest! { #[test] fn network_dimensions_shrink_and_grow( // dim in NetworkDimension::range(1, 400).no_shrink(), - seed in any::<[u32; 4]>().no_shrink(), + seed in any::<[u8; 16]>().no_shrink(), // num_ops in 10..10000, ops in proptest::collection::vec(any_op(), 1..100) ) { - let mut rng5 = RngAdapter4To5(rand::XorShiftRng::from_seed(seed)); + let mut rng = XorShiftRng::from_seed(seed); - let mut tree = NetworkDimensionTree::gen(&mut rng5, 1, 40); + let mut tree = NetworkDimensionTree::gen(&mut rng, 1, 40); println!("Start: {:?}", tree); for op in ops { diff --git a/tests/network/mod.rs b/tests/network/mod.rs index 7b4ed88..a781d36 100644 --- a/tests/network/mod.rs +++ b/tests/network/mod.rs @@ -4,6 +4,7 @@ use std::mem; use std::sync::Arc; use log::{debug, warn}; +use rand::seq::{IteratorRandom, SliceRandom}; use rand::{self, Rng}; use rand_derive::Rand; use serde_derive::{Deserialize, Serialize}; @@ -118,12 +119,11 @@ impl MessageScheduler { .filter(|(_, node)| !node.queue.is_empty()) .map(|(id, _)| id.clone()); let rand_node = match *self { - MessageScheduler::First => rand::thread_rng().gen_weighted_bool(10), + MessageScheduler::First => rand::thread_rng().gen_bool(0.1), MessageScheduler::Random => true, }; if rand_node { - let ids: Vec = ids.collect(); - rand::thread_rng().choose(&ids).cloned() + ids.choose(&mut rand::thread_rng()) } else { ids.next() } @@ -319,7 +319,7 @@ impl TargetedMessage> Advers // Choose a new target to send the message to. The unwrap never fails, because we // ensured that `known_node_ids` is non-empty earlier. let mut rng = rand::thread_rng(); - let new_target_node = rng.choose(&self.known_node_ids).unwrap().clone(); + let new_target_node = self.known_node_ids.iter().choose(&mut rng).unwrap().clone(); // TODO: We could randomly broadcast it instead, if we had access to topology // information. @@ -344,7 +344,7 @@ impl TargetedMessage> Advers let mut rng = rand::thread_rng(); // Pick a random adversarial node and create a message using the generator. - if let Some(sender) = rng.choose(&self.known_adversarial_ids[..]) { + if let Some(sender) = self.known_adversarial_ids[..].choose(&mut rng) { let tm = (self.generator)(); // Add to outgoing queue. diff --git a/tests/queueing_honey_badger.rs b/tests/queueing_honey_badger.rs index 93e5743..7c05293 100644 --- a/tests/queueing_honey_badger.rs +++ b/tests/queueing_honey_badger.rs @@ -8,7 +8,8 @@ use std::iter; use std::sync::Arc; use log::info; -use rand::{Isaac64Rng, Rng}; +use rand::{Rng, SeedableRng}; +use rand_xorshift::XorShiftRng; use hbbft::dynamic_honey_badger::{DynamicHoneyBadger, JoinPlan}; use hbbft::queueing_honey_badger::{Change, ChangeState, Input, QueueingHoneyBadger}; @@ -161,7 +162,7 @@ where .chain(iter::once(observer)) .collect(); let secret_key = node.instance().algo().netinfo().secret_key().clone(); - let mut rng = rand::thread_rng().gen::(); + let mut rng = XorShiftRng::from_seed(rand::thread_rng().gen::<[u8; 16]>()); let (qhb, qhb_step) = QueueingHoneyBadger::builder_joining(our_id, secret_key, join_plan, &mut rng) .and_then(|builder| builder.batch_size(3).build(&mut rng)) @@ -186,7 +187,7 @@ fn new_queueing_hb( .cloned() .chain(iter::once(observer)); let dhb = DynamicHoneyBadger::builder().build((*netinfo).clone()); - let mut rng = rand::thread_rng().gen::(); + let mut rng = XorShiftRng::from_seed(rand::thread_rng().gen::<[u8; 16]>()); let (qhb, qhb_step) = QueueingHoneyBadger::builder(dhb) .batch_size(3) .build(&mut rng)