2018-10-16 10:31:30 -07:00
|
|
|
#![deny(unused_must_use)]
|
|
|
|
//! Tests the BinaryAgreement protocol with a MTIM adversary.
|
|
|
|
|
|
|
|
pub mod net;
|
|
|
|
|
|
|
|
use std::iter;
|
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
|
|
|
use hbbft::binary_agreement::{BinaryAgreement, MessageContent, SbvMessage};
|
|
|
|
use hbbft::threshold_sign::ThresholdSign;
|
2019-01-08 00:30:37 -08:00
|
|
|
use hbbft::{ConsensusProtocol, CpStep, NetworkInfo};
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
use proptest::{proptest, proptest_helper};
|
|
|
|
use rand::{Rng, SeedableRng};
|
2018-10-16 10:31:30 -07:00
|
|
|
|
2018-12-11 05:44:36 -08:00
|
|
|
use crate::net::adversary::{NetMutHandle, QueuePosition};
|
|
|
|
use crate::net::err::CrankError;
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
use crate::net::proptest::{gen_seed, TestRng, TestRngSeed};
|
2018-12-11 05:44:36 -08:00
|
|
|
use crate::net::{Adversary, NetBuilder, NetMessage};
|
2018-10-16 10:31:30 -07:00
|
|
|
|
|
|
|
type NodeId = usize;
|
|
|
|
type SessionId = u8;
|
|
|
|
type Algo = BinaryAgreement<NodeId, SessionId>;
|
|
|
|
|
|
|
|
/// The state of the current epoch's coin. In some epochs this is fixed, in others it starts
|
|
|
|
/// with in `InProgress`.
|
|
|
|
#[derive(Debug)]
|
|
|
|
enum CoinState<N> {
|
|
|
|
/// The value was fixed in the current epoch, or the coin has already terminated.
|
|
|
|
Decided(bool),
|
|
|
|
/// The coin value is not known yet.
|
|
|
|
InProgress(Box<ThresholdSign<N>>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N> CoinState<N> {
|
|
|
|
/// Returns the value, if this coin has already decided.
|
|
|
|
fn value(&self) -> Option<bool> {
|
|
|
|
match self {
|
|
|
|
CoinState::Decided(value) => Some(*value),
|
|
|
|
CoinState::InProgress(_) => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N> From<bool> for CoinState<N> {
|
|
|
|
fn from(value: bool) -> Self {
|
|
|
|
CoinState::Decided(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
|
|
enum MessageType {
|
|
|
|
BVal,
|
|
|
|
Aux,
|
|
|
|
Coin,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn message_type_and_content(msg: &MessageContent) -> Option<(MessageType, Option<bool>)> {
|
|
|
|
match msg {
|
|
|
|
MessageContent::SbvBroadcast(sbv_msg) => match sbv_msg {
|
|
|
|
SbvMessage::BVal(v) => Some((MessageType::BVal, Some(*v))),
|
|
|
|
SbvMessage::Aux(v) => Some((MessageType::Aux, Some(*v))),
|
|
|
|
},
|
|
|
|
MessageContent::Coin(_) => Some((MessageType::Coin, None)),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A boolean XOR a value from the state.
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
|
|
enum BoolFromState {
|
|
|
|
AEstimated(bool),
|
|
|
|
CoinValue(bool),
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Stage {
|
|
|
|
source_groups: &'static [usize],
|
|
|
|
dest_groups: &'static [usize],
|
|
|
|
msg_type: MessageType,
|
|
|
|
msg_contents: Option<BoolFromState>,
|
|
|
|
msg_count: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Group IDs
|
|
|
|
const A0: usize = 0;
|
|
|
|
const A1: usize = 1;
|
|
|
|
const B: usize = 2;
|
|
|
|
const F: usize = 3;
|
|
|
|
|
|
|
|
// Comments from https://github.com/amiller/HoneyBadgerBFT/issues/59#issue-310368284
|
|
|
|
const STAGES: &[Stage] = &[
|
|
|
|
// x sends BVAL(\neg v) to the nodes in A0
|
|
|
|
Stage {
|
|
|
|
source_groups: &[F],
|
|
|
|
dest_groups: &[A0],
|
|
|
|
msg_type: MessageType::BVal,
|
|
|
|
msg_contents: Some(BoolFromState::AEstimated(true)),
|
|
|
|
msg_count: NODES_PER_GROUP,
|
|
|
|
},
|
|
|
|
// and BVAL(v) to the nodes in A1.
|
|
|
|
Stage {
|
|
|
|
source_groups: &[F],
|
|
|
|
dest_groups: &[A1],
|
|
|
|
msg_type: MessageType::BVal,
|
|
|
|
msg_contents: Some(BoolFromState::AEstimated(false)),
|
|
|
|
msg_count: NODES_PER_GROUP,
|
|
|
|
},
|
|
|
|
// Also, all votes from nodes in B are delivered to all nodes in A.
|
|
|
|
Stage {
|
|
|
|
source_groups: &[B],
|
|
|
|
dest_groups: &[A0, A1],
|
|
|
|
msg_type: MessageType::BVal,
|
|
|
|
msg_contents: None,
|
|
|
|
msg_count: NODES_PER_GROUP * (NODES_PER_GROUP * 2),
|
|
|
|
},
|
|
|
|
// Messages within A0 are delivered.
|
|
|
|
// Thus nodes in A0 see |B|+|F|=f+1 votes for \neg v;
|
|
|
|
// so all nodes in A0 broadcast BVAL(\neg v)
|
|
|
|
// and all nodes in A0 see |A0|+|B|+|F|=2f+1 votes for \neg v;
|
|
|
|
// so all nodes in A0 broadcast AUX(\neg v).
|
|
|
|
Stage {
|
|
|
|
source_groups: &[A0],
|
|
|
|
dest_groups: &[A0],
|
|
|
|
msg_type: MessageType::BVal,
|
|
|
|
msg_contents: None,
|
|
|
|
msg_count: NODES_PER_GROUP * (NODES_PER_GROUP - 1),
|
|
|
|
},
|
|
|
|
// Then all messages within A1 are delivered,
|
|
|
|
Stage {
|
|
|
|
source_groups: &[A1],
|
|
|
|
dest_groups: &[A1],
|
|
|
|
msg_type: MessageType::BVal,
|
|
|
|
msg_contents: None,
|
|
|
|
msg_count: NODES_PER_GROUP * (NODES_PER_GROUP - 1),
|
|
|
|
},
|
|
|
|
// as well as the BVAL(v) messages from A0 to A1.
|
|
|
|
// Thus the nodes in A1 see |A0|+|A1|+|F|=2f+1 votes for v and broadcast AUX(v).
|
|
|
|
Stage {
|
|
|
|
source_groups: &[A0],
|
|
|
|
dest_groups: &[A1],
|
|
|
|
msg_type: MessageType::BVal,
|
|
|
|
msg_contents: Some(BoolFromState::AEstimated(false)),
|
|
|
|
msg_count: NODES_PER_GROUP * NODES_PER_GROUP,
|
|
|
|
},
|
|
|
|
// After this all messages within A are delivered
|
|
|
|
Stage {
|
|
|
|
source_groups: &[A0, A1],
|
|
|
|
dest_groups: &[A0, A1],
|
|
|
|
msg_type: MessageType::BVal,
|
|
|
|
msg_contents: None,
|
|
|
|
msg_count: (NODES_PER_GROUP * 2) * (NODES_PER_GROUP * 2 - 1),
|
|
|
|
},
|
|
|
|
Stage {
|
|
|
|
source_groups: &[A0, A1],
|
|
|
|
dest_groups: &[A0, A1],
|
|
|
|
msg_type: MessageType::Aux,
|
|
|
|
msg_contents: None,
|
|
|
|
msg_count: (NODES_PER_GROUP * 2) * (NODES_PER_GROUP * 2 - 1),
|
|
|
|
},
|
|
|
|
// and x sends both BVAL(0) and BVAL(1) to every node in A.
|
|
|
|
// Thus every node in A broadcasts both BVAL(0) and BVAL(1) and sets bin_values=\{0,1\}.
|
|
|
|
Stage {
|
|
|
|
source_groups: &[F],
|
|
|
|
dest_groups: &[A0, A1],
|
|
|
|
msg_type: MessageType::BVal,
|
|
|
|
msg_contents: Some(BoolFromState::AEstimated(false)),
|
|
|
|
msg_count: NODES_PER_GROUP * 2,
|
|
|
|
},
|
|
|
|
Stage {
|
|
|
|
source_groups: &[F],
|
|
|
|
dest_groups: &[A0, A1],
|
|
|
|
msg_type: MessageType::BVal,
|
|
|
|
msg_contents: Some(BoolFromState::AEstimated(true)),
|
|
|
|
msg_count: NODES_PER_GROUP * 2,
|
|
|
|
},
|
|
|
|
// !! Not mentioned in the GitHub issue, but seems necessary.
|
|
|
|
// F sends Aux(_) to A, because nodes in A need 2f+1 Aux messages
|
|
|
|
// before they broadcast their coins.
|
|
|
|
Stage {
|
|
|
|
source_groups: &[F],
|
|
|
|
dest_groups: &[A0, A1],
|
|
|
|
msg_type: MessageType::Aux,
|
|
|
|
msg_contents: Some(BoolFromState::AEstimated(false)),
|
|
|
|
msg_count: NODES_PER_GROUP * 2,
|
|
|
|
},
|
|
|
|
// Now all nodes in A broadcast their threshold shares over the coin,
|
|
|
|
// so since |A|+|F|=2f+1, the adversary can construct the random coin value s.
|
|
|
|
Stage {
|
|
|
|
source_groups: &[A0, A1],
|
|
|
|
dest_groups: &[F],
|
|
|
|
msg_type: MessageType::Coin,
|
|
|
|
msg_contents: None,
|
|
|
|
msg_count: NODES_PER_GROUP * 2,
|
|
|
|
},
|
|
|
|
// The nodes in F send BVAL(\neg s) to all the nodes in B,
|
|
|
|
// and all the BVAL(\neg s) messages from nodes in A are delivered to all nodes in B.
|
|
|
|
// Thus all the nodes in B broadcast AUX(\neg s).
|
|
|
|
Stage {
|
|
|
|
source_groups: &[A0, A1, F],
|
|
|
|
dest_groups: &[B],
|
|
|
|
msg_type: MessageType::BVal,
|
|
|
|
msg_contents: Some(BoolFromState::CoinValue(true)),
|
|
|
|
msg_count: (NODES_PER_GROUP * 2 + 1) * NODES_PER_GROUP,
|
|
|
|
},
|
|
|
|
// Deliver all AUX(\neg s) messages; there are 2f+1 of them,
|
|
|
|
// since either every node in A0 broadcast AUX(\neg s)
|
|
|
|
// or every node in A1 broadcast AUX(\neg s).
|
|
|
|
// Thus all nodes in B see 2f+1 AUX(\neg s) messages
|
|
|
|
// and get to the end of the round with bin_values=\neg s.
|
|
|
|
// Thus the nodes in B continue to the next round voting \neg s
|
|
|
|
// while the nodes in A continue to the next round voting s.
|
|
|
|
Stage {
|
|
|
|
source_groups: &[A0, A1, B, F],
|
|
|
|
dest_groups: &[B],
|
|
|
|
msg_type: MessageType::Aux,
|
|
|
|
msg_contents: Some(BoolFromState::CoinValue(true)),
|
|
|
|
msg_count: (NODES_PER_GROUP + 1) * (NODES_PER_GROUP)
|
|
|
|
+ (NODES_PER_GROUP * (NODES_PER_GROUP - 1)),
|
|
|
|
},
|
|
|
|
// At this point all messages from the round are delivered, and the process repeats.
|
|
|
|
];
|
|
|
|
|
|
|
|
/// An adversary for the reordering attack.
|
|
|
|
/// Described here: https://github.com/amiller/HoneyBadgerBFT/issues/59#issue-310368284
|
|
|
|
/// Excluding the first node, which is F,
|
|
|
|
/// A0 is the first third of nodes, A1 is the second third, and the rest are B.
|
|
|
|
struct AbaCommonCoinAdversary {
|
|
|
|
stage: usize,
|
|
|
|
stage_progress: usize,
|
|
|
|
sent_stage_messages: bool,
|
2018-11-12 03:15:02 -08:00
|
|
|
epoch: u64,
|
2018-10-16 10:31:30 -07:00
|
|
|
coin_state: CoinState<NodeId>,
|
|
|
|
/// The estimated value for nodes in A.
|
|
|
|
a_estimated: bool,
|
|
|
|
// TODO this is really hacky but there's no better way to get this value
|
|
|
|
netinfo_mutex: Arc<Mutex<Option<Arc<NetworkInfo<NodeId>>>>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
const NODES_PER_GROUP: usize = 2;
|
|
|
|
const NUM_NODES: usize = (NODES_PER_GROUP * 3 + 1);
|
|
|
|
|
|
|
|
impl AbaCommonCoinAdversary {
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
fn new<R: Rng>(
|
|
|
|
netinfo_mutex: Arc<Mutex<Option<Arc<NetworkInfo<NodeId>>>>>,
|
|
|
|
rng: &mut R,
|
|
|
|
) -> Self {
|
|
|
|
Self::new_with_epoch(netinfo_mutex, 0, false, rng)
|
2018-10-16 10:31:30 -07:00
|
|
|
}
|
|
|
|
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
fn new_with_epoch<R: Rng>(
|
2018-10-16 10:31:30 -07:00
|
|
|
netinfo_mutex: Arc<Mutex<Option<Arc<NetworkInfo<NodeId>>>>>,
|
2018-11-12 03:15:02 -08:00
|
|
|
epoch: u64,
|
2018-10-16 10:31:30 -07:00
|
|
|
a_estimated: bool,
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
rng: &mut R,
|
2018-10-16 10:31:30 -07:00
|
|
|
) -> Self {
|
|
|
|
AbaCommonCoinAdversary {
|
|
|
|
stage: 0,
|
|
|
|
stage_progress: 0,
|
|
|
|
sent_stage_messages: false,
|
|
|
|
epoch,
|
|
|
|
coin_state: match epoch % 3 {
|
|
|
|
0 => CoinState::Decided(true),
|
|
|
|
1 => CoinState::Decided(false),
|
|
|
|
2 => {
|
|
|
|
let netinfo = netinfo_mutex
|
|
|
|
.lock()
|
|
|
|
.unwrap()
|
|
|
|
.as_ref()
|
|
|
|
.cloned()
|
|
|
|
.expect("Adversary netinfo mutex not populated");
|
|
|
|
let coin_id = bincode::serialize(&(0 as SessionId, epoch))
|
|
|
|
.expect("Failed to serialize coin_id");
|
2018-11-06 08:26:48 -08:00
|
|
|
let mut coin = ThresholdSign::new_with_document(netinfo, coin_id)
|
|
|
|
.expect("Failed to set the coin's ID");
|
2018-10-16 10:31:30 -07:00
|
|
|
let _ = coin
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
.handle_input((), rng)
|
2018-10-16 10:31:30 -07:00
|
|
|
.expect("Calling handle_input on Coin failed");
|
|
|
|
CoinState::InProgress(Box::new(coin))
|
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
},
|
|
|
|
netinfo_mutex,
|
|
|
|
a_estimated,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn eval_state_bool(&self, state_bool: BoolFromState) -> bool {
|
|
|
|
match state_bool {
|
|
|
|
BoolFromState::AEstimated(v) => self.a_estimated ^ v,
|
|
|
|
BoolFromState::CoinValue(v) => {
|
|
|
|
self.coin_state
|
|
|
|
.value()
|
|
|
|
.expect("State relied upon coin value before it was known")
|
|
|
|
^ v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-09 02:56:40 -08:00
|
|
|
fn inject_stage_messages(&mut self, net: &mut NetMutHandle<'_, Algo, Self>) {
|
2018-10-16 10:31:30 -07:00
|
|
|
if self.sent_stage_messages {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
self.sent_stage_messages = true;
|
|
|
|
if let Some(stage) = STAGES.get(self.stage) {
|
|
|
|
if stage.source_groups.iter().any(|&x| x == F) {
|
|
|
|
let contents = self.eval_state_bool(
|
|
|
|
stage
|
|
|
|
.msg_contents
|
|
|
|
.expect("Stage has adversary as source but no contents"),
|
|
|
|
);
|
|
|
|
let message_content = match stage.msg_type {
|
|
|
|
MessageType::BVal => MessageContent::SbvBroadcast(SbvMessage::BVal(contents)),
|
|
|
|
MessageType::Aux => MessageContent::SbvBroadcast(SbvMessage::Aux(contents)),
|
|
|
|
MessageType::Coin => {
|
|
|
|
panic!("Stage expected adversary node to send Coin message");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let message = message_content.with_epoch(self.epoch);
|
|
|
|
for &dst_grp in stage.dest_groups {
|
|
|
|
if dst_grp == F {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for i in 0..NODES_PER_GROUP {
|
|
|
|
let dst = 1 + NODES_PER_GROUP * dst_grp + i;
|
|
|
|
net.inject_message(
|
|
|
|
QueuePosition::Front,
|
|
|
|
NetMessage::<Algo>::new(0, message.clone(), dst),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Should be called whenever stage_progress is changed.
|
|
|
|
fn on_stage_progress_update(&mut self) {
|
|
|
|
let stage_finished = STAGES
|
|
|
|
.get(self.stage)
|
|
|
|
.map(|x| {
|
|
|
|
(x.msg_type == MessageType::Coin && self.coin_state.value().is_some())
|
|
|
|
|| self.stage_progress >= x.msg_count
|
2018-12-11 05:44:36 -08:00
|
|
|
})
|
|
|
|
.unwrap_or(false);
|
2018-10-16 10:31:30 -07:00
|
|
|
if stage_finished {
|
|
|
|
self.stage += 1;
|
|
|
|
self.stage_progress = 0;
|
|
|
|
self.sent_stage_messages = false;
|
|
|
|
self.on_stage_progress_update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn stage_matches_msg(&self, message: &NetMessage<Algo>) -> bool {
|
|
|
|
if let Some(stage) = STAGES.get(self.stage) {
|
|
|
|
let from = *message.from();
|
|
|
|
let src_group = if from == 0 {
|
|
|
|
3
|
|
|
|
} else {
|
|
|
|
(from - 1) / NODES_PER_GROUP
|
|
|
|
};
|
|
|
|
let to = *message.to();
|
|
|
|
let dst_group = if to == 0 {
|
|
|
|
3
|
|
|
|
} else {
|
|
|
|
(to - 1) / NODES_PER_GROUP
|
|
|
|
};
|
|
|
|
if let Some((ty, content)) = message_type_and_content(&message.payload().content) {
|
|
|
|
let content_matches = match (stage.msg_contents, content) {
|
|
|
|
(Some(x), Some(y)) => self.eval_state_bool(x) == y,
|
|
|
|
_ => true,
|
|
|
|
};
|
|
|
|
return stage.source_groups.iter().any(|&x| x == src_group)
|
|
|
|
&& stage.dest_groups.iter().any(|&x| x == dst_group)
|
|
|
|
&& stage.msg_type == ty
|
|
|
|
&& content_matches;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Adversary<Algo> for AbaCommonCoinAdversary {
|
2019-01-09 02:56:40 -08:00
|
|
|
fn pre_crank<R: Rng>(&mut self, mut net: NetMutHandle<'_, Algo, Self>, rng: &mut R) {
|
2018-10-16 10:31:30 -07:00
|
|
|
self.inject_stage_messages(&mut net);
|
|
|
|
net.sort_messages_by(|a, b| {
|
|
|
|
a.payload()
|
|
|
|
.epoch
|
|
|
|
.cmp(&b.payload().epoch)
|
|
|
|
.then_with(|| self.stage_matches_msg(b).cmp(&self.stage_matches_msg(a)))
|
|
|
|
});
|
|
|
|
let mut redo_crank = false;
|
|
|
|
if let Some(msg) = net.get_messages().front() {
|
|
|
|
if msg.payload().epoch == self.epoch && self.stage_matches_msg(&msg) {
|
|
|
|
self.stage_progress += 1;
|
|
|
|
self.on_stage_progress_update();
|
|
|
|
}
|
|
|
|
if msg.payload().epoch > self.epoch {
|
|
|
|
// This assert should fail if the attack is prevented:
|
|
|
|
// assert_eq!(self.stage, STAGES.len());
|
|
|
|
let netinfo = self.netinfo_mutex.clone();
|
|
|
|
*self = Self::new_with_epoch(
|
|
|
|
netinfo,
|
|
|
|
msg.payload().epoch,
|
|
|
|
self.coin_state
|
|
|
|
.value()
|
|
|
|
.expect("Coin value not known at end of epoch"),
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
rng,
|
2018-10-16 10:31:30 -07:00
|
|
|
);
|
|
|
|
redo_crank = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if redo_crank {
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
self.pre_crank(net, rng);
|
2018-10-16 10:31:30 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
fn tamper<R: Rng>(
|
2018-10-16 10:31:30 -07:00
|
|
|
&mut self,
|
2019-01-09 02:56:40 -08:00
|
|
|
_: NetMutHandle<'_, Algo, Self>,
|
2018-10-16 10:31:30 -07:00
|
|
|
msg: NetMessage<Algo>,
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
_rng: &mut R,
|
2019-01-08 00:30:37 -08:00
|
|
|
) -> Result<CpStep<Algo>, CrankError<Algo>> {
|
2018-10-16 10:31:30 -07:00
|
|
|
if let MessageContent::Coin(ref coin_msg) = msg.payload().content {
|
|
|
|
let mut new_coin_state = None;
|
|
|
|
if let CoinState::InProgress(ref mut coin) = self.coin_state {
|
|
|
|
let res = coin.handle_message(msg.from(), *coin_msg.clone());
|
|
|
|
if let Ok(step) = res {
|
|
|
|
if let Some(coin) = step.output.into_iter().next() {
|
|
|
|
new_coin_state = Some(coin.parity().into());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if let Some(new_coin_state) = new_coin_state {
|
|
|
|
self.coin_state = new_coin_state;
|
|
|
|
}
|
|
|
|
}
|
2019-01-08 00:30:37 -08:00
|
|
|
Ok(CpStep::<Algo>::default())
|
2018-10-16 10:31:30 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
proptest! {
|
|
|
|
#[test]
|
|
|
|
#[allow(clippy::unnecessary_operation)]
|
|
|
|
fn reordering_attack(seed in gen_seed()) {
|
|
|
|
do_reordering_attack(seed)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn do_reordering_attack(seed: TestRngSeed) {
|
2018-10-16 10:31:30 -07:00
|
|
|
let _ = env_logger::try_init();
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
let mut rng: TestRng = TestRng::from_seed(seed);
|
2018-10-16 10:31:30 -07:00
|
|
|
let ids: Vec<NodeId> = (0..NUM_NODES).collect();
|
|
|
|
let adversary_netinfo: Arc<Mutex<Option<Arc<NetworkInfo<NodeId>>>>> = Default::default();
|
2018-12-11 00:12:38 -08:00
|
|
|
let (mut net, _) = NetBuilder::new(ids.iter().cloned())
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
.adversary(AbaCommonCoinAdversary::new(
|
|
|
|
adversary_netinfo.clone(),
|
|
|
|
&mut rng,
|
|
|
|
))
|
2018-10-16 10:31:30 -07:00
|
|
|
.crank_limit(10000)
|
|
|
|
.using(move |info| {
|
|
|
|
let netinfo = Arc::new(info.netinfo);
|
|
|
|
if info.id == 0 {
|
|
|
|
*adversary_netinfo.lock().unwrap() = Some(netinfo.clone());
|
|
|
|
}
|
|
|
|
BinaryAgreement::new(netinfo, 0).expect("failed to create BinaryAgreement instance")
|
2018-12-11 05:44:36 -08:00
|
|
|
})
|
|
|
|
.num_faulty(1)
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
.build(&mut rng)
|
2018-10-16 10:31:30 -07:00
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
for id in ids {
|
|
|
|
if id == 0 {
|
|
|
|
// This is the faulty node.
|
|
|
|
} else if id < (1 + NODES_PER_GROUP * 2) {
|
|
|
|
// Group A
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
let _ = net.send_input(id, false, &mut rng).unwrap();
|
2018-10-16 10:31:30 -07:00
|
|
|
} else {
|
|
|
|
// Group B
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
let _ = net.send_input(id, true, &mut rng).unwrap();
|
2018-10-16 10:31:30 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while !net.nodes().skip(1).all(|n| n.algorithm().terminated()) {
|
OsRng / external RNG Refactoring (#357)
* Use `OsRng` in place of `thread_rng`.
This changes the defaults of any builder by instantiating an `OsRng` instead of
a `thread_rng`, the former being much more secure than the latter.
Additionally, all the unit tests that still instantiate RNGs manually used `OsRng`s
as well; while there is no actual need for this level of security in tests, the performance overhead is very small and random number generation complexity has such a small impact on these tests that the convenience of being able to ban `thread_rng` from the codebase altogether, setting a good example and avoid issues when refactoring later greatly outweigh the negatives.
* Instead of storing random number generators in the various consensus algorithm instances, pass them in from the outside whenever they are needed.
This changes a large amount of interfaces (and in this commit is only partially done, since `DistAlgorithm` needs to be fundamentally altered as well.
It also obsoletes parts of the `util` module.
* Added an `R: Rng` type parameter to both methods of `DistAlgorithm`, forcing callers to pass in their own Rngs.
* Fixed documentation grammar and spelling in some of the altered interfaces due to RNG refactoring.
* Move `rng` argument to the end of the argument for most functions.
Also includes a reformatting due to Rust 1.30.
* Updated tests, accomodate `rng`-API changes.
* Fixed remaining compilation issues with new RNG code.
* Fix illegal `self` import outside curly braces.
* Cleaned up comments and fixed broken definition of `broadcast_input`.
* Updated existing test cases to properly work with static dispatch randomness.
* Do not use boxed `Rng`s for key generation in test networks.
* Use the passed-in `Rng` in `ReorderingAdversary`, instead of storing a boxed one.
* Fixed clippy lints after refactoring.
* Removed some no-longer necessary manual `fmt::Debug` implementations in test framework.
* Use `OsRng` even in tests in `binary_agreement_mitm`.
* Use a proper deterministic RNG in tests `binary_agreement_mitm`.
* Refactor `examples/simulation.rs` by not using `ThreadRng`, passing generic `Rng` parameters throughout and using a type alias instead of a newtype as the `Transaction`.
* Remove `thread_rng` use from `examples/node.rs`.
* Explicitly construct `InternalContrib` in `DynamicHoneyBadger::propose`.
* Fixed typo in description of `DistAlgorithm` trait.
2018-12-14 04:51:09 -08:00
|
|
|
net.crank_expect(&mut rng);
|
2018-10-16 10:31:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Verify that all instances output the same value.
|
|
|
|
let mut estimated = None;
|
|
|
|
for node in net.nodes().skip(1) {
|
|
|
|
if let Some(b) = estimated {
|
|
|
|
assert!(iter::once(&b).eq(node.outputs()));
|
|
|
|
} else {
|
|
|
|
assert_eq!(1, node.outputs().len());
|
|
|
|
estimated = Some(node.outputs()[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|