diff --git a/examples/network/node.rs b/examples/network/node.rs index 5e71324..40bfbac 100644 --- a/examples/network/node.rs +++ b/examples/network/node.rs @@ -32,7 +32,7 @@ //! the consensus `result` is not an error then every successfully terminated //! consensus node will be the same `result`. -use std::collections::{BTreeSet, HashSet}; +use std::collections::HashSet; use std::fmt::Debug; use std::marker::{Send, Sync}; use std::net::SocketAddr; @@ -45,8 +45,7 @@ use log::{debug, error}; use crate::network::messaging::Messaging; use crate::network::{commst, connection}; use hbbft::broadcast::{Broadcast, Message}; -use hbbft::crypto::{poly::Poly, SecretKey, SecretKeySet}; -use hbbft::{ConsensusProtocol, NetworkInfo, SourcedMessage}; +use hbbft::{ConsensusProtocol, SourcedMessage}; /// This is a structure to start a consensus node. pub struct Node { @@ -79,29 +78,14 @@ impl + PartialEq + Send + Sync + From> + .collect(); node_strs.sort(); let our_id = node_strs.binary_search(&our_str).unwrap(); - let all_ids: BTreeSet<_> = (0..node_strs.len()).collect(); - - // FIXME: This example doesn't call algorithms that use cryptography. However the keys are - // required by the interface to all algorithms in Honey Badger. Therefore we set placeholder - // keys here. A fully-featured application would need to take appropriately initialized keys - // from elsewhere. - let secret_key_set = SecretKeySet::from(Poly::zero()); - let sk_share = secret_key_set.secret_key_share(our_id); - let pub_key_set = secret_key_set.public_keys(); - let sk = SecretKey::default(); - let pub_keys = all_ids - .iter() - .map(|id| (*id, SecretKey::default().public_key())) - .collect(); - - let netinfo = NetworkInfo::new(our_id, sk_share, pub_key_set, sk, pub_keys); + let num_nodes = node_strs.len(); if value.is_some() != (our_id == 0) { panic!("Exactly the first node must propose a value."); } // Initialise the message delivery system and obtain TX and RX handles. - let messaging: Messaging = Messaging::new(all_ids.len()); + let messaging: Messaging = Messaging::new(num_nodes); let rxs_to_comms = messaging.rxs_to_comms(); let tx_from_comms = messaging.tx_from_comms(); let rx_to_algo = messaging.rx_to_algo(); @@ -120,8 +104,9 @@ impl + PartialEq + Send + Sync + From> + // corresponding to this instance, and no dedicated comms task. The // node index is 0. let broadcast_handle = scope.spawn(move |_| { - let mut broadcast = - Broadcast::new(Arc::new(netinfo), 0).expect("failed to instantiate broadcast"); + let validators = (0..num_nodes).into(); + let mut broadcast = Broadcast::new(our_id, Arc::new(validators), 0) + .expect("failed to instantiate broadcast"); if let Some(v) = value { // FIXME: Use the output. diff --git a/src/broadcast/broadcast.rs b/src/broadcast/broadcast.rs index 1c33978..1687911 100644 --- a/src/broadcast/broadcast.rs +++ b/src/broadcast/broadcast.rs @@ -14,15 +14,18 @@ use super::merkle::{Digest, MerkleTree, Proof}; use super::message::HexProof; use super::{Error, FaultKind, Message, Result}; use crate::fault_log::Fault; -use crate::{ConsensusProtocol, NetworkInfo, NodeIdT, Target}; +use crate::{ConsensusProtocol, NodeIdT, Target, ValidatorSet}; type RseResult = result::Result; /// Broadcast algorithm instance. #[derive(Debug)] pub struct Broadcast { - /// Shared network data. - netinfo: Arc>, + /// Our ID. + // TODO: Make optional for observers? + our_id: N, + /// The set of validator IDs. + val_set: Arc>, /// The ID of the sending node. proposer_id: N, /// The Reed-Solomon erasure coding configuration. @@ -40,6 +43,7 @@ pub struct Broadcast { /// Whether we have already output a value. decided: bool, /// Number of faulty nodes to optimize performance for. + // TODO: Make this configurable: Allow numbers between 0 and N/3? fault_estimate: usize, /// The hashes and proofs we have received via `Echo` and `EchoHash` messages, by sender ID. echos: BTreeMap, @@ -79,22 +83,27 @@ impl ConsensusProtocol for Broadcast { } fn our_id(&self) -> &N { - self.netinfo.our_id() + &self.our_id } } impl Broadcast { /// Creates a new broadcast instance to be used by node `our_id` which expects a value proposal /// from node `proposer_id`. - pub fn new(netinfo: Arc>, proposer_id: N) -> Result { - let parity_shard_num = 2 * netinfo.num_faulty(); - let data_shard_num = netinfo.num_nodes() - parity_shard_num; + pub fn new(our_id: N, val_set: V, proposer_id: N) -> Result + where + V: Into>>, + { + let val_set: Arc> = val_set.into(); + let parity_shard_num = 2 * val_set.num_faulty(); + let data_shard_num = val_set.num() - parity_shard_num; let coding = Coding::new(data_shard_num, parity_shard_num).map_err(|_| Error::InvalidNodeCount)?; - let fault_estimate = netinfo.num_faulty(); + let fault_estimate = val_set.num_faulty(); Ok(Broadcast { - netinfo, + our_id, + val_set, proposer_id, coding, value_sent: false, @@ -131,7 +140,7 @@ impl Broadcast { /// /// This must be called with every message we receive from another node. pub fn handle_message(&mut self, sender_id: &N, message: Message) -> Result> { - if !self.netinfo.is_node_validator(sender_id) { + if !self.val_set.contains(sender_id) { return Err(Error::UnknownSender); } match message { @@ -148,6 +157,11 @@ impl Broadcast { &self.proposer_id } + /// Returns the set of all validator IDs. + pub fn validator_set(&self) -> &Arc> { + &self.val_set + } + /// Breaks the input value into shards of equal length and encodes them -- /// and some extra parity shards -- with a Reed-Solomon erasure coding /// scheme. The returned value contains the shard assigned to this @@ -191,12 +205,12 @@ impl Broadcast { // Default result in case of `proof` error. let mut result = Err(Error::ProofConstructionFailed); - assert_eq!(self.netinfo.num_nodes(), mtree.values().len()); + assert_eq!(self.val_set.num(), mtree.values().len()); let mut step = Step::default(); // Send each proof to a node. - for (index, id) in self.netinfo.all_ids().enumerate() { - let proof = mtree.proof(index).ok_or(Error::ProofConstructionFailed)?; + for (id, index) in self.val_set.all_indices() { + let proof = mtree.proof(*index).ok_or(Error::ProofConstructionFailed)?; if *id == *self.our_id() { // The proof is addressed to this node. result = Ok(proof); @@ -293,7 +307,7 @@ impl Broadcast { } // Upon receiving `N - f` `Echo`s with this root hash, multicast `Ready`. - if !self.ready_sent && self.count_echos(&hash) >= self.netinfo.num_correct() { + if !self.ready_sent && self.count_echos(&hash) >= self.val_set.num_correct() { step.extend(self.send_ready(&hash)?); } @@ -333,7 +347,7 @@ impl Broadcast { self.echos .insert(sender_id.clone(), EchoContent::Hash(*hash)); - if self.ready_sent || self.count_echos(&hash) < self.netinfo.num_correct() { + if self.ready_sent || self.count_echos(&hash) < self.val_set.num_correct() { return self.compute_output(&hash); } // Upon receiving `N - f` `Echo`s with this root hash, multicast `Ready`. @@ -382,13 +396,13 @@ impl Broadcast { let mut step = Step::default(); // Upon receiving f + 1 matching Ready(h) messages, if Ready // has not yet been sent, multicast Ready(h). - if self.count_readys(hash) == self.netinfo.num_faulty() + 1 && !self.ready_sent { + if self.count_readys(hash) == self.val_set.num_faulty() + 1 && !self.ready_sent { // Enqueue a broadcast of a Ready message. step.extend(self.send_ready(hash)?); } // Upon receiving 2f + 1 matching Ready(h) messages, send full // `Echo` message to every node who hasn't sent us a `CanDecode` - if self.count_readys(hash) == 2 * self.netinfo.num_faulty() + 1 { + if self.count_readys(hash) == 2 * self.val_set.num_faulty() + 1 { step.extend(self.send_echo_remaining(hash)?); } @@ -397,7 +411,7 @@ impl Broadcast { /// Sends `Echo` message to all left nodes and handles it. fn send_echo_left(&mut self, p: Proof>) -> Result> { - if !self.netinfo.is_validator() { + if !self.val_set.contains(&self.our_id) { return Ok(Step::default()); } let echo_msg = Message::Echo(p.clone()); @@ -413,7 +427,7 @@ impl Broadcast { /// Sends `Echo` message to remaining nodes who haven't sent `CanDecode` fn send_echo_remaining(&mut self, hash: &Digest) -> Result> { self.echo_sent = true; - if !self.netinfo.is_validator() { + if !self.val_set.contains(&self.our_id) { return Ok(Step::default()); } @@ -441,7 +455,7 @@ impl Broadcast { /// Sends an `EchoHash` message and handles it. Does nothing if we are only an observer. fn send_echo_hash(&mut self, hash: &Digest) -> Result> { self.echo_hash_sent = true; - if !self.netinfo.is_validator() { + if !self.val_set.contains(&self.our_id) { return Ok(Step::default()); } let echo_hash_msg = Message::EchoHash(*hash); @@ -462,18 +476,18 @@ impl Broadcast { fn right_nodes(&self) -> impl Iterator { let our_id = self.our_id().clone(); let not_us = move |x: &&N| **x != our_id; - self.netinfo + self.val_set .all_ids() .cycle() .skip_while(not_us.clone()) - .skip(self.netinfo.num_correct() - self.netinfo.num_faulty() + self.fault_estimate) + .skip(self.val_set.num_correct() - self.val_set.num_faulty() + self.fault_estimate) .take_while(not_us) } /// Sends a `CanDecode` message and handles it. Does nothing if we are only an observer. fn send_can_decode(&mut self, hash: &Digest) -> Result> { self.can_decode_sent.insert(hash.clone()); - if !self.netinfo.is_validator() { + if !self.val_set.contains(&self.our_id) { return Ok(Step::default()); } @@ -481,7 +495,7 @@ impl Broadcast { let mut step = Step::default(); let recipients = self - .netinfo + .val_set .all_ids() .filter(|id| match self.echos.get(id) { Some(EchoContent::Hash(_)) | None => true, @@ -498,7 +512,7 @@ impl Broadcast { /// Sends a `Ready` message and handles it. Does nothing if we are only an observer. fn send_ready(&mut self, hash: &Digest) -> Result> { self.ready_sent = true; - if !self.netinfo.is_validator() { + if !self.val_set.contains(&self.our_id) { return Ok(Step::default()); } let ready_msg = Message::Ready(*hash); @@ -511,7 +525,7 @@ impl Broadcast { /// value. fn compute_output(&mut self, hash: &Digest) -> Result> { if self.decided - || self.count_readys(hash) <= 2 * self.netinfo.num_faulty() + || self.count_readys(hash) <= 2 * self.val_set.num_faulty() || self.count_echos_full(hash) < self.coding.data_shard_count() { return Ok(Step::default()); @@ -519,7 +533,7 @@ impl Broadcast { // Upon receiving 2f + 1 matching Ready(h) messages, wait for N − 2f Echo messages. let mut leaf_values: Vec>> = self - .netinfo + .val_set .all_ids() .map(|id| { self.echos @@ -588,7 +602,7 @@ impl Broadcast { /// Returns `true` if the proof is valid and has the same index as the node ID. fn validate_proof(&self, p: &Proof>, id: &N) -> bool { - self.netinfo.node_index(id) == Some(p.index()) && p.validate(self.netinfo.num_nodes()) + self.val_set.index(id) == Some(p.index()) && p.validate(self.val_set.num()) } /// Returns the number of nodes that have sent us a full `Echo` message with this hash. diff --git a/src/broadcast/mod.rs b/src/broadcast/mod.rs index 927b7ae..191c75c 100644 --- a/src/broadcast/mod.rs +++ b/src/broadcast/mod.rs @@ -139,8 +139,8 @@ //! //! ``` //! use hbbft::broadcast::{Broadcast, Error, Step}; -//! use hbbft::{NetworkInfo, SourcedMessage, Target, TargetedMessage}; -//! use rand::{OsRng, Rng, RngCore}; +//! use hbbft::{ValidatorSet, SourcedMessage, Target, TargetedMessage}; +//! use rand::{rngs::OsRng, Rng, RngCore}; //! use std::collections::{BTreeMap, BTreeSet, VecDeque}; //! use std::iter::once; //! use std::sync::Arc; @@ -152,14 +152,12 @@ //! //! let mut rng = OsRng::new().expect("Could not initialize OS random number generator."); //! -//! // Create a random set of keys for testing. -//! let netinfos = NetworkInfo::generate_map(0..NUM_NODES, &mut rng) -//! .expect("Failed to create `NetworkInfo` map"); +//! let validators = Arc::new(ValidatorSet::from(0..NUM_NODES)); //! //! // Create initial nodes by instantiating a `Broadcast` for each. //! let mut nodes = BTreeMap::new(); -//! for (i, netinfo) in netinfos { -//! let bc = Broadcast::new(Arc::new(netinfo), PROPOSER_ID)?; +//! for i in 0..NUM_NODES { +//! let bc = Broadcast::new(i, validators.clone(), PROPOSER_ID)?; //! nodes.insert(i, bc); //! } //! diff --git a/src/lib.rs b/src/lib.rs index 668ae30..ebf50dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -142,7 +142,7 @@ pub mod util; pub use crate::crypto::pairing; pub use crate::fault_log::{Fault, FaultLog}; pub use crate::messaging::{SourcedMessage, Target, TargetedMessage}; -pub use crate::network_info::NetworkInfo; +pub use crate::network_info::{NetworkInfo, ValidatorSet}; pub use crate::traits::{ ConsensusProtocol, Contribution, CpStep, Epoched, Message, NodeIdT, SessionIdT, Step, }; diff --git a/src/network_info.rs b/src/network_info.rs index 0e812e7..e65528f 100644 --- a/src/network_info.rs +++ b/src/network_info.rs @@ -1,19 +1,92 @@ +use std::borrow::Borrow; use std::collections::{BTreeMap, BTreeSet}; +use std::sync::Arc; use crate::crypto::{self, PublicKey, PublicKeySet, PublicKeyShare, SecretKey, SecretKeyShare}; use rand; use crate::{util, NodeIdT}; +/// The set of all node IDs of the network's validators. +#[derive(Debug, Clone)] +pub struct ValidatorSet { + num_faulty: usize, + indices: BTreeMap, +} + +impl From for ValidatorSet +where + I: IntoIterator, + I::Item: Borrow, + N: NodeIdT, +{ + fn from(i: I) -> Self { + let indices: BTreeMap = i + .into_iter() + .enumerate() + .map(|(n, id)| (id.borrow().clone(), n)) + .collect(); + let num_faulty = util::max_faulty(indices.len()); + assert!(3 * num_faulty < indices.len(), "3 f >= N. This is a bug!"); + ValidatorSet { + num_faulty, + indices, + } + } +} + +impl ValidatorSet { + /// Returns `true` if the given ID belongs to a known validator. + #[inline] + pub fn contains(&self, id: &N) -> bool { + self.indices.contains_key(id) + } + + /// Returns the validators index in the ordered list of all IDs. + #[inline] + pub fn index(&self, id: &N) -> Option { + self.indices.get(id).cloned() + } + + /// The total number _N_ of validators. + #[inline] + pub fn num(&self) -> usize { + self.indices.len() + } + + /// The maximum number _f_ of faulty, Byzantine validators up to which Honey Badger is + /// guaranteed to be correct. + #[inline] + pub fn num_faulty(&self) -> usize { + self.num_faulty + } + + /// The minimum number _N - f_ of correct validators with which Honey Badger is guaranteed to + /// be correct. + #[inline] + pub fn num_correct(&self) -> usize { + // As asserted in `new`, `num_faulty` is never greater than `num`. + self.num() - self.num_faulty + } + + /// IDs of all validators in the network. + #[inline] + pub fn all_ids(&self) -> impl Iterator + Clone { + self.indices.keys() + } + + /// IDs and indices of all validators in the network. + #[inline] + pub fn all_indices(&self) -> impl Iterator + Clone { + self.indices.iter() + } +} + /// Common data shared between algorithms: the nodes' IDs and key shares. #[derive(Debug, Clone)] pub struct NetworkInfo { /// This node's ID. our_id: N, - /// The number _N_ of nodes in the network. Equal to the size of `public_keys`. - num_nodes: usize, - /// The number _f_ of faulty nodes that can be tolerated. Less than a third of _N_. - num_faulty: usize, /// Whether this node is a validator. This is true if `public_keys` contains our own ID. is_validator: bool, /// This node's secret key share. Only validators have one. @@ -27,7 +100,7 @@ pub struct NetworkInfo { /// The validators' public keys. public_keys: BTreeMap, /// The indices in the list of sorted validator IDs. - node_indices: BTreeMap, + val_set: Arc>, } impl NetworkInfo { @@ -47,29 +120,21 @@ impl NetworkInfo { secret_key: SecretKey, public_keys: BTreeMap, ) -> Self { - let num_nodes = public_keys.len(); - let num_faulty = util::max_faulty(num_nodes); - assert!(3 * num_faulty < num_nodes, " 3 f >= N. This is a bug!"); - let is_validator = public_keys.contains_key(&our_id); - let node_indices: BTreeMap = public_keys + let val_set = Arc::new(ValidatorSet::from(public_keys.keys())); + let is_validator = val_set.contains(&our_id); + let public_key_shares = public_keys .keys() .enumerate() - .map(|(n, id)| (id.clone(), n)) - .collect(); - let public_key_shares = node_indices - .iter() - .map(|(id, idx)| (id.clone(), public_key_set.public_key_share(*idx))) + .map(|(idx, id)| (id.clone(), public_key_set.public_key_share(idx))) .collect(); NetworkInfo { our_id, - num_nodes, - num_faulty, is_validator, secret_key_share: secret_key_share.into(), secret_key, public_key_set, public_key_shares, - node_indices, + val_set, public_keys, } } @@ -83,35 +148,34 @@ impl NetworkInfo { /// ID of all nodes in the network. #[inline] pub fn all_ids(&self) -> impl Iterator + Clone { - self.public_keys.keys() + self.val_set.all_ids() } /// ID of all nodes in the network except this one. #[inline] pub fn other_ids(&self) -> impl Iterator + Clone { let our_id = self.our_id.clone(); - self.public_keys.keys().filter(move |id| **id != our_id) + self.all_ids().filter(move |id| **id != our_id) } /// The total number _N_ of nodes. #[inline] pub fn num_nodes(&self) -> usize { - self.num_nodes + self.val_set.num() } /// The maximum number _f_ of faulty, Byzantine nodes up to which Honey Badger is guaranteed to /// be correct. #[inline] pub fn num_faulty(&self) -> usize { - self.num_faulty + self.val_set.num_faulty() } /// The minimum number _N - f_ of correct nodes with which Honey Badger is guaranteed to be /// correct. #[inline] pub fn num_correct(&self) -> usize { - // As asserted in `new`, `num_faulty` is never greater than `num_nodes`. - self.num_nodes - self.num_faulty + self.val_set.num_correct() } /// Returns our secret key share for threshold cryptography, or `None` if not a validator. @@ -160,7 +224,7 @@ impl NetworkInfo { /// node appears in `all_ids`. #[inline] pub fn node_index(&self, id: &N) -> Option { - self.node_indices.get(id).cloned() + self.val_set.index(id) } /// Returns `true` if this node takes part in the consensus itself. If not, it is only an @@ -177,6 +241,11 @@ impl NetworkInfo { self.public_keys.contains_key(id) } + /// Returns the set of validator IDs. + pub fn validator_set(&self) -> &Arc> { + &self.val_set + } + /// Generates a map of matching `NetworkInfo`s for testing. pub fn generate_map( ids: I, diff --git a/src/subset/proposal_state.rs b/src/subset/proposal_state.rs index 473986b..e913040 100644 --- a/src/subset/proposal_state.rs +++ b/src/subset/proposal_state.rs @@ -30,8 +30,10 @@ pub enum 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)?; - let broadcast = Broadcast::new(netinfo, prop_id).map_err(Error::NewBroadcast)?; + let our_id = netinfo.our_id().clone(); + let validators = netinfo.validator_set().clone(); + let agreement = BaInstance::new(netinfo, ba_id).map_err(Error::NewAgreement)?; + let broadcast = Broadcast::new(our_id, validators, prop_id).map_err(Error::NewBroadcast)?; Ok(ProposalState::Ongoing(broadcast, agreement)) } diff --git a/tests/broadcast.rs b/tests/broadcast.rs index 0d29ce4..5d4855d 100644 --- a/tests/broadcast.rs +++ b/tests/broadcast.rs @@ -1,8 +1,6 @@ -use std::collections::BTreeMap; use std::iter::once; -use std::sync::{Arc, Mutex}; -use hbbft::{broadcast::Broadcast, util, ConsensusProtocol, CpStep, NetworkInfo}; +use hbbft::{broadcast::Broadcast, util, ConsensusProtocol, CpStep}; use hbbft_testing::adversary::{ sort_ascending, swap_random, Adversary, NetMutHandle, NodeOrderAdversary, RandomAdversary, ReorderingAdversary, @@ -14,7 +12,6 @@ use proptest::{prelude::ProptestConfig, proptest}; use rand::{Rng, SeedableRng}; type NodeId = u16; -type NetworkInfoMap = BTreeMap>>; /// A strategy for picking the next node to handle a message. /// The sorting algorithm used is stable - preserves message @@ -37,26 +34,16 @@ pub struct ProposeAdversary { message_strategy: MessageSorting, has_sent: bool, drop_messages: bool, - // TODO this is really hacky but there's no better way to get this value - // Solution taken from binary_agreement_mitm test - ideally the new network simulator - // should be altered to store the netinfo structure alongside nodes similar to - // the way the old network simulator did it. - netinfo_mutex: Arc>, } impl ProposeAdversary { /// Creates a new `ProposeAdversary`. #[inline] - pub fn new( - message_strategy: MessageSorting, - netinfo_mutex: Arc>, - drop_messages: bool, - ) -> Self { + pub fn new(message_strategy: MessageSorting, drop_messages: bool) -> Self { ProposeAdversary { message_strategy, has_sent: false, drop_messages, - netinfo_mutex, } } } @@ -97,15 +84,8 @@ impl Adversary> for ProposeAdversary { // Instantiate a temporary broadcast consensus protocol for each faulty node // and add the generated messages to the current step. for faulty_node in faulty_nodes { - let netinfo = self - .netinfo_mutex - .lock() - .unwrap() - .get(faulty_node.id()) - .cloned() - .expect("Adversary netinfo mutex not populated"); - - let fake_step = Broadcast::new(netinfo, *faulty_node.id()) + let validators = faulty_node.algorithm().validator_set().clone(); + let fake_step = Broadcast::new(*faulty_node.id(), validators, *faulty_node.id()) .expect("broadcast instance") .handle_input(b"Fake news".to_vec(), &mut rng) .expect("propose"); @@ -166,12 +146,8 @@ fn test_broadcast>>( } } -fn test_broadcast_different_sizes( - new_adversary: F, - proposed_value: &[u8], - seed: TestRngSeed, - adversary_netinfo: &Arc>, -) where +fn test_broadcast_different_sizes(new_adversary: F, proposed_value: &[u8], seed: TestRngSeed) +where A: Adversary>, F: Fn() -> A, { @@ -181,7 +157,6 @@ fn test_broadcast_different_sizes( .chain(once(rng.gen_range(30, 50))); for size in sizes { // cloning since it gets moved into a closure - let cloned_netinfo_map = adversary_netinfo.clone(); let num_faulty_nodes = util::max_faulty(size); info!( "Network size: {} good nodes, {} faulty nodes", @@ -197,12 +172,9 @@ fn test_broadcast_different_sizes( .no_time_limit() .adversary(new_adversary()) .using(move |info| { - let netinfo = Arc::new(info.netinfo); - cloned_netinfo_map - .lock() - .unwrap() - .insert(info.id, netinfo.clone()); - Broadcast::new(netinfo, proposer_id) + let validators = info.netinfo.validator_set().clone(); + let id = *info.netinfo.our_id(); + Broadcast::new(id, validators, proposer_id) .expect("Failed to create a Broadcast instance.") }) .build(&mut rng) @@ -272,7 +244,9 @@ fn do_test_8_broadcast_equal_leaves_silent(seed: TestRngSeed) { .no_time_limit() .adversary(ReorderingAdversary::new()) .using(move |node_info: NewNodeInfo<_>| { - Broadcast::new(Arc::new(node_info.netinfo), proposer_id) + let id = *node_info.netinfo.our_id(); + let validators = node_info.netinfo.validator_set().clone(); + Broadcast::new(id, validators, proposer_id) .expect("Failed to create a Broadcast instance.") }) .build(&mut rng) @@ -284,40 +258,29 @@ fn do_test_8_broadcast_equal_leaves_silent(seed: TestRngSeed) { } fn do_test_broadcast_random_delivery_silent(seed: TestRngSeed) { - test_broadcast_different_sizes(ReorderingAdversary::new, b"Foo", seed, &Default::default()); + test_broadcast_different_sizes(ReorderingAdversary::new, b"Foo", seed); } fn do_test_broadcast_first_delivery_silent(seed: TestRngSeed) { - test_broadcast_different_sizes(NodeOrderAdversary::new, b"Foo", seed, &Default::default()); + test_broadcast_different_sizes(NodeOrderAdversary::new, b"Foo", seed); } fn do_test_broadcast_first_delivery_adv_propose(seed: TestRngSeed) { - let adversary_netinfo: Arc> = Default::default(); - let new_adversary = || { - ProposeAdversary::new( - MessageSorting::SortAscending, - adversary_netinfo.clone(), - false, - ) - }; - test_broadcast_different_sizes(new_adversary, b"Foo", seed, &adversary_netinfo); + let new_adversary = || ProposeAdversary::new(MessageSorting::SortAscending, false); + test_broadcast_different_sizes(new_adversary, b"Foo", seed); } fn do_test_broadcast_random_delivery_adv_propose(seed: TestRngSeed) { - let adversary_netinfo: Arc> = Default::default(); - let new_adversary = - || ProposeAdversary::new(MessageSorting::RandomPick, adversary_netinfo.clone(), false); - test_broadcast_different_sizes(new_adversary, b"Foo", seed, &adversary_netinfo); + let new_adversary = || ProposeAdversary::new(MessageSorting::RandomPick, false); + test_broadcast_different_sizes(new_adversary, b"Foo", seed); } fn do_test_broadcast_random_delivery_adv_propose_and_drop(seed: TestRngSeed) { - let adversary_netinfo: Arc> = Default::default(); - let new_adversary = - || ProposeAdversary::new(MessageSorting::RandomPick, adversary_netinfo.clone(), true); - test_broadcast_different_sizes(new_adversary, b"Foo", seed, &adversary_netinfo); + let new_adversary = || ProposeAdversary::new(MessageSorting::RandomPick, true); + test_broadcast_different_sizes(new_adversary, b"Foo", seed); } fn do_test_broadcast_random_adversary(seed: TestRngSeed) { let new_adversary = || RandomAdversary::new(0.2, 0.2); - test_broadcast_different_sizes(new_adversary, b"RandomFoo", seed, &Default::default()); + test_broadcast_different_sizes(new_adversary, b"RandomFoo", seed); }