2018-10-10 07:11:27 -07:00
|
|
|
//! Common supertraits for distributed algorithms.
|
|
|
|
|
2018-11-01 11:18:08 -07:00
|
|
|
use std::collections::BTreeMap;
|
2018-10-24 00:42:59 -07:00
|
|
|
use std::fmt::{Debug, Display};
|
2018-10-10 07:11:27 -07:00
|
|
|
use std::hash::Hash;
|
|
|
|
use std::iter::once;
|
|
|
|
|
|
|
|
use failure::Fail;
|
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 rand::Rng;
|
2018-10-25 08:07:52 -07:00
|
|
|
use serde::{de::DeserializeOwned, Serialize};
|
2018-10-10 07:11:27 -07:00
|
|
|
|
2018-12-11 05:44:36 -08:00
|
|
|
use crate::fault_log::{Fault, FaultLog};
|
|
|
|
use crate::sender_queue::SenderQueueableMessage;
|
|
|
|
use crate::{Target, TargetedMessage};
|
2018-10-10 07:11:27 -07:00
|
|
|
|
2018-10-30 03:31:50 -07:00
|
|
|
/// A transaction, user message, or other user data.
|
2018-10-10 07:11:27 -07:00
|
|
|
pub trait Contribution: Eq + Debug + Hash + Send + Sync {}
|
|
|
|
impl<C> Contribution for C where C: Eq + Debug + Hash + Send + Sync {}
|
|
|
|
|
|
|
|
/// A peer node's unique identifier.
|
|
|
|
pub trait NodeIdT: Eq + Ord + Clone + Debug + Hash + Send + Sync {}
|
|
|
|
impl<N> NodeIdT for N where N: Eq + Ord + Clone + Debug + Hash + Send + Sync {}
|
|
|
|
|
|
|
|
/// Messages.
|
|
|
|
pub trait Message: Debug + Send + Sync {}
|
|
|
|
impl<M> Message for M where M: Debug + Send + Sync {}
|
|
|
|
|
2018-10-24 00:42:59 -07:00
|
|
|
/// Session identifiers.
|
2018-11-03 04:31:36 -07:00
|
|
|
pub trait SessionIdT: Display + Serialize + Send + Sync + Clone + Debug {}
|
|
|
|
impl<S> SessionIdT for S where S: Display + Serialize + Send + Sync + Clone + Debug {}
|
2018-10-24 00:42:59 -07:00
|
|
|
|
2018-11-01 14:37:41 -07:00
|
|
|
/// Epochs.
|
|
|
|
pub trait EpochT: Copy + Message + Default + Eq + Ord + Serialize + DeserializeOwned {}
|
|
|
|
impl<E> EpochT for E where E: Copy + Message + Default + Eq + Ord + Serialize + DeserializeOwned {}
|
|
|
|
|
2018-10-30 03:31:50 -07:00
|
|
|
/// Single algorithm step outcome.
|
|
|
|
///
|
|
|
|
/// Each time input (typically in the form of user input or incoming network messages) is provided
|
|
|
|
/// to an instance of an algorithm, a `Step` is produced, potentially containing output values,
|
|
|
|
/// a fault log, and network messages.
|
|
|
|
///
|
|
|
|
/// Any `Step` **must always be used** by the client application; at the very least the resulting
|
|
|
|
/// messages must be queued.
|
|
|
|
///
|
|
|
|
/// ## Handling unused Steps
|
|
|
|
///
|
|
|
|
/// In the (rare) case of a `Step` not being of any interest at all, instead of discarding it
|
|
|
|
/// through `let _ = ...` or similar constructs, the implicit assumption should explicitly be
|
|
|
|
/// checked instead:
|
|
|
|
///
|
|
|
|
/// ```ignore
|
|
|
|
/// assert!(alg.propose(123).expect("Could not propose value").is_empty(),
|
|
|
|
/// "Algorithm will never output anything on first proposal");
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// If an edge case occurs and outgoing messages are generated as a result, the `assert!` will
|
|
|
|
/// catch it, instead of potentially stalling the algorithm.
|
2018-10-10 07:11:27 -07:00
|
|
|
#[must_use = "The algorithm step result must be used."]
|
|
|
|
#[derive(Debug)]
|
2018-11-07 05:26:14 -08:00
|
|
|
pub struct Step<M, O, N> {
|
2018-11-26 06:35:24 -08:00
|
|
|
/// The algorithm's output, after consensus has been reached. This is guaranteed to be the same
|
|
|
|
/// in all nodes.
|
2018-11-07 05:26:14 -08:00
|
|
|
pub output: Vec<O>,
|
2018-11-26 06:35:24 -08:00
|
|
|
/// A list of nodes that are not following consensus, together with information about the
|
|
|
|
/// detected misbehavior.
|
2018-11-07 05:26:14 -08:00
|
|
|
pub fault_log: FaultLog<N>,
|
2018-11-26 06:35:24 -08:00
|
|
|
/// A list of messages that must be sent to other nodes. Each entry contains a message and a
|
|
|
|
/// `Target`.
|
2018-11-07 05:26:14 -08:00
|
|
|
pub messages: Vec<TargetedMessage<M, N>>,
|
2018-10-10 07:11:27 -07:00
|
|
|
}
|
|
|
|
|
2018-11-07 05:26:14 -08:00
|
|
|
impl<M, O, N> Default for Step<M, O, N> {
|
|
|
|
fn default() -> Self {
|
2018-10-10 07:11:27 -07:00
|
|
|
Step {
|
2018-10-25 05:44:28 -07:00
|
|
|
output: Vec::default(),
|
2018-10-10 07:11:27 -07:00
|
|
|
fault_log: FaultLog::default(),
|
2018-10-25 05:44:28 -07:00
|
|
|
messages: Vec::default(),
|
2018-10-10 07:11:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-07 05:26:14 -08:00
|
|
|
impl<M, O, N> Step<M, O, N> {
|
2018-10-10 07:11:27 -07:00
|
|
|
/// Creates a new `Step` from the given collections.
|
|
|
|
pub fn new(
|
2018-11-07 05:26:14 -08:00
|
|
|
output: Vec<O>,
|
|
|
|
fault_log: FaultLog<N>,
|
|
|
|
messages: Vec<TargetedMessage<M, N>>,
|
2018-10-10 07:11:27 -07:00
|
|
|
) -> Self {
|
|
|
|
Step {
|
|
|
|
output,
|
|
|
|
fault_log,
|
|
|
|
messages,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the same step, with the given additional output.
|
2018-11-07 05:26:14 -08:00
|
|
|
pub fn with_output<T: Into<Option<O>>>(mut self, output: T) -> Self {
|
2018-10-25 05:44:28 -07:00
|
|
|
self.output.extend(output.into());
|
2018-10-10 07:11:27 -07:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts `self` into a step of another type, given conversion methods for output and
|
|
|
|
/// messages.
|
2018-11-07 05:26:14 -08:00
|
|
|
pub fn map<M2, O2, FO, FM>(self, f_out: FO, f_msg: FM) -> Step<M2, O2, N>
|
2018-10-10 07:11:27 -07:00
|
|
|
where
|
2018-11-07 05:26:14 -08:00
|
|
|
FO: Fn(O) -> O2,
|
|
|
|
FM: Fn(M) -> M2,
|
2018-10-10 07:11:27 -07:00
|
|
|
{
|
|
|
|
Step {
|
|
|
|
output: self.output.into_iter().map(f_out).collect(),
|
|
|
|
fault_log: self.fault_log,
|
|
|
|
messages: self.messages.into_iter().map(|tm| tm.map(&f_msg)).collect(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Extends `self` with `other`s messages and fault logs, and returns `other.output`.
|
2018-12-11 03:59:54 -08:00
|
|
|
#[must_use]
|
2018-11-07 05:26:14 -08:00
|
|
|
pub fn extend_with<M2, O2, FM>(&mut self, other: Step<M2, O2, N>, f_msg: FM) -> Vec<O2>
|
2018-10-10 07:11:27 -07:00
|
|
|
where
|
2018-11-07 05:26:14 -08:00
|
|
|
FM: Fn(M2) -> M,
|
2018-10-10 07:11:27 -07:00
|
|
|
{
|
|
|
|
self.fault_log.extend(other.fault_log);
|
|
|
|
let msgs = other.messages.into_iter().map(|tm| tm.map(&f_msg));
|
|
|
|
self.messages.extend(msgs);
|
|
|
|
other.output
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Adds the outputs, fault logs and messages of `other` to `self`.
|
|
|
|
pub fn extend(&mut self, other: Self) {
|
|
|
|
self.output.extend(other.output);
|
|
|
|
self.fault_log.extend(other.fault_log);
|
|
|
|
self.messages.extend(other.messages);
|
|
|
|
}
|
|
|
|
|
2018-10-25 05:44:28 -07:00
|
|
|
/// Extends this step with `other` and returns the result.
|
|
|
|
pub fn join(mut self, other: Self) -> Self {
|
|
|
|
self.extend(other);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-10-30 03:31:50 -07:00
|
|
|
/// Returns `true` if there are no messages, faults or outputs.
|
2018-10-10 07:11:27 -07:00
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
self.output.is_empty() && self.fault_log.is_empty() && self.messages.is_empty()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-07 05:26:14 -08:00
|
|
|
impl<M, O, N> From<FaultLog<N>> for Step<M, O, N> {
|
|
|
|
fn from(fault_log: FaultLog<N>) -> Self {
|
2018-10-10 07:11:27 -07:00
|
|
|
Step {
|
|
|
|
fault_log,
|
|
|
|
..Step::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-07 05:26:14 -08:00
|
|
|
impl<M, O, N> From<Fault<N>> for Step<M, O, N> {
|
|
|
|
fn from(fault: Fault<N>) -> Self {
|
2018-10-10 07:11:27 -07:00
|
|
|
Step {
|
|
|
|
fault_log: fault.into(),
|
|
|
|
..Step::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-07 05:26:14 -08:00
|
|
|
impl<M, O, N> From<TargetedMessage<M, N>> for Step<M, O, N> {
|
|
|
|
fn from(msg: TargetedMessage<M, N>) -> Self {
|
2018-10-10 07:11:27 -07:00
|
|
|
Step {
|
|
|
|
messages: once(msg).collect(),
|
|
|
|
..Step::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-07 05:26:14 -08:00
|
|
|
impl<I, M, O, N> From<I> for Step<M, O, N>
|
2018-10-25 08:07:52 -07:00
|
|
|
where
|
2018-11-07 05:26:14 -08:00
|
|
|
I: IntoIterator<Item = TargetedMessage<M, N>>,
|
2018-10-25 08:07:52 -07:00
|
|
|
{
|
|
|
|
fn from(msgs: I) -> Self {
|
|
|
|
Step {
|
|
|
|
messages: msgs.into_iter().collect(),
|
|
|
|
..Step::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An interface to objects with epoch numbers. Different algorithms may have different internal
|
|
|
|
/// notion of _epoch_. This interface summarizes the properties that are essential for the message
|
|
|
|
/// sender queue.
|
|
|
|
pub trait Epoched {
|
2018-11-07 08:21:24 -08:00
|
|
|
/// Type of epoch.
|
2018-11-01 14:37:41 -07:00
|
|
|
type Epoch: EpochT;
|
2018-10-25 08:07:52 -07:00
|
|
|
|
|
|
|
/// Returns the object's epoch number.
|
|
|
|
fn epoch(&self) -> Self::Epoch;
|
|
|
|
}
|
|
|
|
|
2018-11-07 05:26:14 -08:00
|
|
|
/// An alias for the type of `Step` returned by `D`'s methods.
|
|
|
|
pub type DaStep<D> =
|
|
|
|
Step<<D as DistAlgorithm>::Message, <D as DistAlgorithm>::Output, <D as DistAlgorithm>::NodeId>;
|
|
|
|
|
|
|
|
impl<'i, M, O, N> Step<M, O, N>
|
2018-10-25 08:07:52 -07:00
|
|
|
where
|
2018-11-07 08:21:24 -08:00
|
|
|
N: NodeIdT,
|
|
|
|
M: 'i + Clone + SenderQueueableMessage,
|
2018-10-25 08:07:52 -07:00
|
|
|
{
|
|
|
|
/// Removes and returns any messages that are not yet accepted by remote nodes according to the
|
|
|
|
/// mapping `remote_epochs`. This way the returned messages are postponed until later, and the
|
|
|
|
/// remaining messages can be sent to remote nodes without delay.
|
|
|
|
pub fn defer_messages(
|
|
|
|
&mut self,
|
2018-11-08 03:03:48 -08:00
|
|
|
peer_epochs: &BTreeMap<N, M::Epoch>,
|
2018-10-25 08:07:52 -07:00
|
|
|
max_future_epochs: u64,
|
2018-11-07 06:05:30 -08:00
|
|
|
) -> Vec<(N, M)> {
|
2018-11-07 05:26:14 -08:00
|
|
|
let mut deferred_msgs: Vec<(N, M)> = Vec::new();
|
2018-11-01 11:18:08 -07:00
|
|
|
let mut passed_msgs: Vec<_> = Vec::new();
|
2018-11-07 06:05:30 -08:00
|
|
|
for msg in self.messages.drain(..) {
|
2018-11-05 05:38:02 -08:00
|
|
|
match msg.target.clone() {
|
|
|
|
Target::Node(id) => {
|
|
|
|
if let Some(&them) = peer_epochs.get(&id) {
|
2018-11-07 08:21:24 -08:00
|
|
|
if msg.message.is_premature(them, max_future_epochs) {
|
2018-11-05 05:38:02 -08:00
|
|
|
deferred_msgs.push((id, msg.message));
|
2018-11-07 08:21:24 -08:00
|
|
|
} else if !msg.message.is_obsolete(them) {
|
|
|
|
passed_msgs.push(msg);
|
2018-11-01 11:18:08 -07:00
|
|
|
}
|
2018-10-25 08:07:52 -07:00
|
|
|
}
|
2018-11-05 05:38:02 -08:00
|
|
|
}
|
|
|
|
Target::All => {
|
|
|
|
if peer_epochs
|
|
|
|
.values()
|
|
|
|
.all(|&them| msg.message.is_accepted(them, max_future_epochs))
|
|
|
|
{
|
|
|
|
passed_msgs.push(msg);
|
|
|
|
} else {
|
|
|
|
// The `Target::All` message is split into two sets of point messages: those
|
|
|
|
// which can be sent without delay and those which should be postponed.
|
2018-11-01 11:18:08 -07:00
|
|
|
for (id, &them) in peer_epochs {
|
2018-11-07 08:21:24 -08:00
|
|
|
if msg.message.is_premature(them, max_future_epochs) {
|
|
|
|
deferred_msgs.push((id.clone(), msg.message.clone()));
|
|
|
|
} else if !msg.message.is_obsolete(them) {
|
2018-11-05 05:38:02 -08:00
|
|
|
passed_msgs
|
|
|
|
.push(Target::Node(id.clone()).message(msg.message.clone()));
|
2018-11-01 11:18:08 -07:00
|
|
|
}
|
2018-10-25 08:07:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-11-07 06:05:30 -08:00
|
|
|
self.messages.extend(passed_msgs);
|
2018-10-25 08:07:52 -07:00
|
|
|
deferred_msgs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-10 07:11:27 -07:00
|
|
|
/// A distributed algorithm that defines a message flow.
|
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
|
|
|
///
|
|
|
|
/// Many algorithms require an RNG which must be supplied on each call. It is up to the caller to
|
|
|
|
/// ensure that this random number generator is cryptographically secure.
|
2018-10-10 07:11:27 -07:00
|
|
|
pub trait DistAlgorithm: Send + Sync {
|
|
|
|
/// Unique node identifier.
|
|
|
|
type NodeId: NodeIdT;
|
|
|
|
/// The input provided by the user.
|
|
|
|
type Input;
|
|
|
|
/// The output type. Some algorithms return an output exactly once, others return multiple
|
|
|
|
/// times.
|
|
|
|
type Output;
|
|
|
|
/// The messages that need to be exchanged between the instances in the participating nodes.
|
|
|
|
type Message: Message;
|
|
|
|
/// The errors that can occur during execution.
|
|
|
|
type Error: Fail;
|
|
|
|
|
|
|
|
/// Handles an input provided by the user, and returns
|
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 handle_input<R: Rng>(
|
|
|
|
&mut self,
|
|
|
|
input: Self::Input,
|
|
|
|
rng: &mut R,
|
|
|
|
) -> Result<DaStep<Self>, Self::Error>
|
2018-10-10 07:11:27 -07:00
|
|
|
where
|
|
|
|
Self: Sized;
|
|
|
|
|
|
|
|
/// Handles a message received from node `sender_id`.
|
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 handle_message<R: Rng>(
|
2018-10-10 07:11:27 -07:00
|
|
|
&mut self,
|
|
|
|
sender_id: &Self::NodeId,
|
|
|
|
message: Self::Message,
|
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-11-07 05:26:14 -08:00
|
|
|
) -> Result<DaStep<Self>, Self::Error>
|
2018-10-10 07:11:27 -07:00
|
|
|
where
|
|
|
|
Self: Sized;
|
|
|
|
|
|
|
|
/// Returns `true` if execution has completed and this instance can be dropped.
|
|
|
|
fn terminated(&self) -> bool;
|
|
|
|
|
|
|
|
/// Returns this node's own ID.
|
|
|
|
fn our_id(&self) -> &Self::NodeId;
|
|
|
|
}
|