2018-10-10 06:05:04 -07:00
|
|
|
use std::collections::BTreeMap;
|
2018-08-02 11:11:32 -07:00
|
|
|
use std::sync::Arc;
|
2018-10-25 08:07:52 -07:00
|
|
|
use std::{fmt, result};
|
2018-08-02 11:11:32 -07:00
|
|
|
|
2018-12-11 05:44:36 -08:00
|
|
|
use crate::crypto::{PublicKey, SecretKey, Signature};
|
2018-08-02 11:11:32 -07:00
|
|
|
use bincode;
|
2018-10-29 07:36:56 -07:00
|
|
|
use derivative::Derivative;
|
2018-11-18 01:17:33 -08:00
|
|
|
use log::debug;
|
2018-12-27 01:34:34 -08:00
|
|
|
use rand::Rng;
|
2018-10-24 02:38:14 -07:00
|
|
|
use serde::{de::DeserializeOwned, Serialize};
|
2018-08-02 11:11:32 -07:00
|
|
|
|
|
|
|
use super::votes::{SignedVote, VoteCounter};
|
|
|
|
use super::{
|
2018-11-26 06:35:24 -08:00
|
|
|
Batch, Change, ChangeState, DynamicHoneyBadgerBuilder, EncryptionSchedule, Error, Input,
|
|
|
|
InternalContrib, JoinPlan, KeyGenMessage, KeyGenState, Message, Params, Result,
|
2018-11-19 05:51:32 -08:00
|
|
|
SignedKeyGenMsg, Step,
|
2018-08-02 11:11:32 -07:00
|
|
|
};
|
2018-12-11 05:44:36 -08:00
|
|
|
use crate::fault_log::{Fault, FaultKind, FaultLog};
|
|
|
|
use crate::honey_badger::{self, HoneyBadger, Message as HbMessage};
|
2018-10-25 11:41:56 -07:00
|
|
|
|
2018-12-11 05:44:36 -08:00
|
|
|
use crate::sync_key_gen::{Ack, AckOutcome, Part, PartOutcome, SyncKeyGen};
|
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::util;
|
2018-12-11 05:44:36 -08:00
|
|
|
use crate::{Contribution, DistAlgorithm, Epoched, NetworkInfo, NodeIdT, Target};
|
2018-08-02 11:11:32 -07:00
|
|
|
|
|
|
|
/// A Honey Badger instance that can handle adding and removing nodes.
|
2018-10-24 04:01:52 -07:00
|
|
|
#[derive(Derivative)]
|
|
|
|
#[derivative(Debug)]
|
2018-12-27 01:34:34 -08:00
|
|
|
pub struct DynamicHoneyBadger<C, N: Ord> {
|
2018-08-02 11:11:32 -07:00
|
|
|
/// Shared network data.
|
2018-08-02 14:27:55 -07:00
|
|
|
pub(super) netinfo: NetworkInfo<N>,
|
2018-08-02 11:11:32 -07:00
|
|
|
/// The maximum number of future epochs for which we handle messages simultaneously.
|
2018-10-25 08:07:52 -07:00
|
|
|
pub(super) max_future_epochs: u64,
|
2018-08-02 11:11:32 -07:00
|
|
|
/// The first epoch after the latest node change.
|
2018-10-25 08:07:52 -07:00
|
|
|
pub(super) era: u64,
|
2018-08-02 11:11:32 -07:00
|
|
|
/// The buffer and counter for the pending and committed change votes.
|
2018-08-02 14:27:55 -07:00
|
|
|
pub(super) vote_counter: VoteCounter<N>,
|
2018-08-02 11:11:32 -07:00
|
|
|
/// Pending node transactions that we will propose in the next epoch.
|
2018-08-02 14:27:55 -07:00
|
|
|
pub(super) key_gen_msg_buffer: Vec<SignedKeyGenMsg<N>>,
|
2018-08-02 11:11:32 -07:00
|
|
|
/// The `HoneyBadger` instance with the current set of nodes.
|
2018-08-02 14:27:55 -07:00
|
|
|
pub(super) honey_badger: HoneyBadger<InternalContrib<C, N>, N>,
|
2018-08-02 11:11:32 -07:00
|
|
|
/// The current key generation process, and the change it applies to.
|
2018-08-02 14:27:55 -07:00
|
|
|
pub(super) key_gen_state: Option<KeyGenState<N>>,
|
2018-10-02 07:24:51 -07:00
|
|
|
}
|
|
|
|
|
2018-08-02 14:27:55 -07:00
|
|
|
impl<C, N> DistAlgorithm for DynamicHoneyBadger<C, N>
|
2018-08-02 11:11:32 -07:00
|
|
|
where
|
2018-10-24 02:38:14 -07:00
|
|
|
C: Contribution + Serialize + DeserializeOwned,
|
2018-12-27 01:34:34 -08:00
|
|
|
N: NodeIdT + Serialize + DeserializeOwned,
|
2018-08-02 11:11:32 -07:00
|
|
|
{
|
2018-08-29 09:08:35 -07:00
|
|
|
type NodeId = N;
|
2018-08-02 14:27:55 -07:00
|
|
|
type Input = Input<C, N>;
|
|
|
|
type Output = Batch<C, N>;
|
|
|
|
type Message = Message<N>;
|
2018-08-02 11:11:32 -07:00
|
|
|
type Error = Error;
|
|
|
|
|
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<Step<C, N>> {
|
2018-08-02 11:11:32 -07:00
|
|
|
// User contributions are forwarded to `HoneyBadger` right away. Votes are signed and
|
|
|
|
// broadcast.
|
|
|
|
match input {
|
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
|
|
|
Input::User(contrib) => self.propose(contrib, rng),
|
2018-08-02 11:11:32 -07:00
|
|
|
Input::Change(change) => self.vote_for(change),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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>(
|
|
|
|
&mut self,
|
|
|
|
sender_id: &Self::NodeId,
|
|
|
|
msg: Self::Message,
|
|
|
|
rng: &mut R,
|
|
|
|
) -> Result<Step<C, N>> {
|
|
|
|
self.handle_message(sender_id, msg, rng)
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn terminated(&self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2018-08-02 14:27:55 -07:00
|
|
|
fn our_id(&self) -> &N {
|
2018-08-29 09:08:35 -07:00
|
|
|
self.netinfo.our_id()
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-02 14:27:55 -07:00
|
|
|
impl<C, N> DynamicHoneyBadger<C, N>
|
2018-08-02 11:11:32 -07:00
|
|
|
where
|
2018-10-24 02:38:14 -07:00
|
|
|
C: Contribution + Serialize + DeserializeOwned,
|
2018-12-27 01:34:34 -08:00
|
|
|
N: NodeIdT + Serialize + DeserializeOwned,
|
2018-08-02 11:11:32 -07:00
|
|
|
{
|
|
|
|
/// Returns a new `DynamicHoneyBadgerBuilder`.
|
2018-08-02 14:27:55 -07:00
|
|
|
pub fn builder() -> DynamicHoneyBadgerBuilder<C, N> {
|
2018-08-02 11:11:32 -07:00
|
|
|
DynamicHoneyBadgerBuilder::new()
|
|
|
|
}
|
|
|
|
|
2018-11-19 05:51:32 -08:00
|
|
|
/// Creates a new `DynamicHoneyBadger` ready to join the network specified in the `JoinPlan`.
|
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
|
|
|
pub fn new_joining<R: Rng>(
|
2018-11-19 05:51:32 -08:00
|
|
|
our_id: N,
|
|
|
|
secret_key: SecretKey,
|
|
|
|
join_plan: JoinPlan<N>,
|
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-19 05:51:32 -08:00
|
|
|
) -> Result<(Self, Step<C, N>)> {
|
|
|
|
let netinfo = NetworkInfo::new(
|
|
|
|
our_id,
|
2018-11-22 04:00:02 -08:00
|
|
|
None,
|
2018-11-19 05:51:32 -08:00
|
|
|
join_plan.pub_key_set,
|
|
|
|
secret_key,
|
|
|
|
join_plan.pub_keys,
|
|
|
|
);
|
|
|
|
let max_future_epochs = join_plan.params.max_future_epochs;
|
|
|
|
let arc_netinfo = Arc::new(netinfo.clone());
|
|
|
|
let honey_badger = HoneyBadger::builder(arc_netinfo.clone())
|
|
|
|
.session_id(join_plan.era)
|
|
|
|
.params(join_plan.params)
|
|
|
|
.build();
|
|
|
|
let mut dhb = DynamicHoneyBadger {
|
|
|
|
netinfo,
|
|
|
|
max_future_epochs,
|
|
|
|
era: join_plan.era,
|
|
|
|
vote_counter: VoteCounter::new(arc_netinfo, join_plan.era),
|
|
|
|
key_gen_msg_buffer: Vec::new(),
|
|
|
|
honey_badger,
|
|
|
|
key_gen_state: None,
|
|
|
|
};
|
|
|
|
let step = match join_plan.change {
|
|
|
|
ChangeState::InProgress(ref change) => match change {
|
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
|
|
|
Change::NodeChange(change) => dhb.update_key_gen(join_plan.era, change, rng)?,
|
2018-11-19 05:51:32 -08:00
|
|
|
_ => Step::default(),
|
|
|
|
},
|
|
|
|
ChangeState::None | ChangeState::Complete(..) => Step::default(),
|
|
|
|
};
|
|
|
|
Ok((dhb, step))
|
|
|
|
}
|
|
|
|
|
2018-08-02 11:11:32 -07:00
|
|
|
/// Returns `true` if input for the current epoch has already been provided.
|
|
|
|
pub fn has_input(&self) -> bool {
|
|
|
|
self.honey_badger.has_input()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Proposes a contribution in the current epoch.
|
2018-10-24 03:26:43 -07:00
|
|
|
///
|
|
|
|
/// Returns an error if we already made a proposal in this epoch.
|
|
|
|
///
|
|
|
|
/// If we are the only validator, this will immediately output a batch, containing our
|
|
|
|
/// proposal.
|
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
|
|
|
pub fn propose<R: Rng>(&mut self, contrib: C, rng: &mut R) -> Result<Step<C, N>> {
|
2018-10-22 07:09:00 -07:00
|
|
|
let key_gen_messages = self
|
|
|
|
.key_gen_msg_buffer
|
|
|
|
.iter()
|
2018-10-25 08:07:52 -07:00
|
|
|
.filter(|kg_msg| kg_msg.era() == self.era)
|
2018-10-22 07:09:00 -07:00
|
|
|
.cloned()
|
|
|
|
.collect();
|
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 contrib = InternalContrib {
|
|
|
|
contrib,
|
|
|
|
key_gen_messages,
|
|
|
|
votes: self.vote_counter.pending_votes().cloned().collect(),
|
|
|
|
};
|
|
|
|
|
2018-08-02 11:11:32 -07:00
|
|
|
let step = self
|
|
|
|
.honey_badger
|
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
|
|
|
.propose(&contrib, rng)
|
2018-12-11 05:44:36 -08:00
|
|
|
.map_err(Error::ProposeHoneyBadger)?;
|
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.process_output(step, rng)
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
|
2018-11-06 01:17:11 -08:00
|
|
|
/// Casts a vote to change the set of validators or parameters.
|
2018-10-24 03:26:43 -07:00
|
|
|
///
|
|
|
|
/// This stores a pending vote for the change. It will be included in some future batch, and
|
|
|
|
/// once enough validators have been voted for the same change, it will take effect.
|
2018-08-02 14:27:55 -07:00
|
|
|
pub fn vote_for(&mut self, change: Change<N>) -> Result<Step<C, N>> {
|
2018-08-02 11:11:32 -07:00
|
|
|
if !self.netinfo.is_validator() {
|
|
|
|
return Ok(Step::default()); // TODO: Return an error?
|
|
|
|
}
|
|
|
|
let signed_vote = self.vote_counter.sign_vote_for(change)?.clone();
|
|
|
|
let msg = Message::SignedVote(signed_vote);
|
|
|
|
Ok(Target::All.message(msg).into())
|
|
|
|
}
|
|
|
|
|
2018-11-06 01:17:11 -08:00
|
|
|
/// Casts a vote to add a node as a validator.
|
|
|
|
///
|
|
|
|
/// This stores a pending vote for the change. It will be included in some future batch, and
|
|
|
|
/// once enough validators have been voted for the same change, it will take effect.
|
|
|
|
pub fn vote_to_add(&mut self, node_id: N, pub_key: PublicKey) -> Result<Step<C, N>> {
|
2018-11-18 01:17:33 -08:00
|
|
|
let mut pub_keys = self.netinfo.public_key_map().clone();
|
|
|
|
pub_keys.insert(node_id, pub_key);
|
|
|
|
self.vote_for(Change::NodeChange(pub_keys))
|
2018-11-06 01:17:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Casts a vote to demote a validator to observer.
|
|
|
|
///
|
|
|
|
/// This stores a pending vote for the change. It will be included in some future batch, and
|
|
|
|
/// once enough validators have been voted for the same change, it will take effect.
|
2018-11-18 01:17:33 -08:00
|
|
|
pub fn vote_to_remove(&mut self, node_id: &N) -> Result<Step<C, N>> {
|
|
|
|
let mut pub_keys = self.netinfo.public_key_map().clone();
|
|
|
|
pub_keys.remove(node_id);
|
|
|
|
self.vote_for(Change::NodeChange(pub_keys))
|
2018-11-06 01:17:11 -08:00
|
|
|
}
|
|
|
|
|
2018-10-24 03:26:43 -07:00
|
|
|
/// Handles a message received from `sender_id`.
|
|
|
|
///
|
|
|
|
/// This must be called with every message we receive from another node.
|
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
|
|
|
pub fn handle_message<R: Rng>(
|
|
|
|
&mut self,
|
|
|
|
sender_id: &N,
|
|
|
|
message: Message<N>,
|
|
|
|
rng: &mut R,
|
|
|
|
) -> Result<Step<C, N>> {
|
2018-10-25 08:07:52 -07:00
|
|
|
if message.era() == self.era {
|
2018-10-23 06:38:42 -07:00
|
|
|
match message {
|
|
|
|
Message::HoneyBadger(_, hb_msg) => {
|
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.handle_honey_badger_message(sender_id, hb_msg, rng)
|
2018-10-23 06:38:42 -07:00
|
|
|
}
|
|
|
|
Message::KeyGen(_, kg_msg, sig) => self
|
|
|
|
.handle_key_gen_message(sender_id, kg_msg, *sig)
|
|
|
|
.map(FaultLog::into),
|
|
|
|
Message::SignedVote(signed_vote) => self
|
|
|
|
.vote_counter
|
|
|
|
.add_pending_vote(sender_id, signed_vote)
|
|
|
|
.map(FaultLog::into),
|
|
|
|
}
|
2018-10-25 08:07:52 -07:00
|
|
|
} else if message.era() > self.era {
|
|
|
|
Ok(Fault::new(sender_id.clone(), FaultKind::UnexpectedDhbMessageEra).into())
|
|
|
|
} else {
|
|
|
|
// The message is late; discard it.
|
|
|
|
Ok(Step::default())
|
2018-10-23 06:38:42 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-02 11:11:32 -07:00
|
|
|
/// Returns the information about the node IDs in the network, and the cryptographic keys.
|
2018-08-02 14:27:55 -07:00
|
|
|
pub fn netinfo(&self) -> &NetworkInfo<N> {
|
2018-08-02 11:11:32 -07:00
|
|
|
&self.netinfo
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `true` if we should make our contribution for the next epoch, even if we don't have
|
|
|
|
/// content ourselves, to avoid stalling the network.
|
|
|
|
///
|
|
|
|
/// By proposing only if this returns `true`, you can prevent an adversary from making the
|
|
|
|
/// network output empty baches indefinitely, but it also means that the network won't advance
|
|
|
|
/// if fewer than _f + 1_ nodes have pending contributions.
|
|
|
|
pub fn should_propose(&self) -> bool {
|
|
|
|
if self.has_input() {
|
|
|
|
return false; // We have already proposed.
|
|
|
|
}
|
|
|
|
if self.honey_badger.received_proposals() > self.netinfo.num_faulty() {
|
|
|
|
return true; // At least one correct node wants to move on to the next epoch.
|
|
|
|
}
|
|
|
|
let is_our_vote = |signed_vote: &SignedVote<_>| signed_vote.voter() == self.our_id();
|
|
|
|
if self.vote_counter.pending_votes().any(is_our_vote) {
|
|
|
|
return true; // We have pending input to vote for a validator change.
|
|
|
|
}
|
2018-11-18 01:17:33 -08:00
|
|
|
// If we have a pending key gen message, we should propose.
|
|
|
|
!self.key_gen_msg_buffer.is_empty()
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
|
2018-11-15 06:30:53 -08:00
|
|
|
/// The epoch of the next batch that will be output.
|
|
|
|
pub fn next_epoch(&self) -> u64 {
|
|
|
|
self.era + self.honey_badger.next_epoch()
|
|
|
|
}
|
|
|
|
|
2018-08-02 11:11:32 -07:00
|
|
|
/// Handles a message for the `HoneyBadger` instance.
|
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_honey_badger_message<R: Rng>(
|
2018-08-02 11:11:32 -07:00
|
|
|
&mut self,
|
2018-08-02 14:27:55 -07:00
|
|
|
sender_id: &N,
|
|
|
|
message: HbMessage<N>,
|
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-08-02 14:27:55 -07:00
|
|
|
) -> Result<Step<C, N>> {
|
2018-10-09 07:07:56 -07:00
|
|
|
if !self.netinfo.is_node_validator(sender_id) {
|
2018-11-26 06:35:24 -08:00
|
|
|
return Err(Error::UnknownSender);
|
2018-10-09 07:07:56 -07:00
|
|
|
}
|
2018-08-02 11:11:32 -07:00
|
|
|
// Handle the message.
|
|
|
|
let step = self
|
|
|
|
.honey_badger
|
|
|
|
.handle_message(sender_id, message)
|
2018-11-26 06:35:24 -08:00
|
|
|
.map_err(Error::HandleHoneyBadgerMessage)?;
|
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.process_output(step, rng)
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Handles a vote or key generation message and tries to commit it as a transaction. These
|
|
|
|
/// messages are only handled once they appear in a batch output from Honey Badger.
|
|
|
|
fn handle_key_gen_message(
|
|
|
|
&mut self,
|
2018-08-02 14:27:55 -07:00
|
|
|
sender_id: &N,
|
2018-08-02 11:11:32 -07:00
|
|
|
kg_msg: KeyGenMessage,
|
|
|
|
sig: Signature,
|
2018-08-02 14:27:55 -07:00
|
|
|
) -> Result<FaultLog<N>> {
|
2018-08-02 11:11:32 -07:00
|
|
|
if !self.verify_signature(sender_id, &sig, &kg_msg)? {
|
|
|
|
let fault_kind = FaultKind::InvalidKeyGenMessageSignature;
|
|
|
|
return Ok(Fault::new(sender_id.clone(), fault_kind).into());
|
|
|
|
}
|
|
|
|
let kgs = match self.key_gen_state {
|
|
|
|
Some(ref mut kgs) => kgs,
|
|
|
|
None => {
|
|
|
|
return Ok(Fault::new(sender_id.clone(), FaultKind::UnexpectedKeyGenMessage).into());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-10-23 02:13:55 -07:00
|
|
|
// If the sender is correct, it will send at most _N + 1_ key generation messages:
|
|
|
|
// one `Part`, and for each validator an `Ack`. _N_ is the node number _after_ the change.
|
|
|
|
if kgs.count_messages(sender_id) > kgs.key_gen.num_nodes() + 1 {
|
|
|
|
let fault_kind = FaultKind::TooManyKeyGenMessages;
|
|
|
|
return Ok(Fault::new(sender_id.clone(), fault_kind).into());
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
|
2018-10-25 08:07:52 -07:00
|
|
|
let tx = SignedKeyGenMsg(self.era, sender_id.clone(), kg_msg, sig);
|
2018-08-02 11:11:32 -07:00
|
|
|
self.key_gen_msg_buffer.push(tx);
|
|
|
|
Ok(FaultLog::default())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Processes all pending batches output by Honey Badger.
|
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 process_output<R: Rng>(
|
2018-08-02 11:11:32 -07:00
|
|
|
&mut self,
|
2018-08-02 14:27:55 -07:00
|
|
|
hb_step: honey_badger::Step<InternalContrib<C, N>, N>,
|
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-08-02 14:27:55 -07:00
|
|
|
) -> Result<Step<C, N>> {
|
|
|
|
let mut step: Step<C, N> = Step::default();
|
2018-10-25 08:07:52 -07:00
|
|
|
let output = step.extend_with(hb_step, |hb_msg| Message::HoneyBadger(self.era, hb_msg));
|
2018-08-02 11:11:32 -07:00
|
|
|
for hb_batch in output {
|
2018-10-25 08:07:52 -07:00
|
|
|
let batch_era = self.era;
|
2018-11-01 11:18:08 -07:00
|
|
|
let batch_epoch = hb_batch.epoch + batch_era;
|
2018-10-10 06:05:04 -07:00
|
|
|
let mut batch_contributions = BTreeMap::new();
|
2018-08-02 11:11:32 -07:00
|
|
|
|
|
|
|
// Add the user transactions to `batch` and handle votes and DKG messages.
|
|
|
|
for (id, int_contrib) in hb_batch.contributions {
|
|
|
|
let InternalContrib {
|
|
|
|
votes,
|
|
|
|
key_gen_messages,
|
|
|
|
contrib,
|
|
|
|
} = int_contrib;
|
|
|
|
step.fault_log
|
|
|
|
.extend(self.vote_counter.add_committed_votes(&id, votes)?);
|
2018-10-10 06:05:04 -07:00
|
|
|
batch_contributions.insert(id.clone(), contrib);
|
2018-08-02 11:11:32 -07:00
|
|
|
self.key_gen_msg_buffer
|
|
|
|
.retain(|skgm| !key_gen_messages.contains(skgm));
|
2018-10-25 08:07:52 -07:00
|
|
|
for SignedKeyGenMsg(era, s_id, kg_msg, sig) in key_gen_messages {
|
|
|
|
if era != self.era {
|
|
|
|
let fault_kind = FaultKind::InvalidKeyGenMessageEra;
|
2018-10-22 07:09:00 -07:00
|
|
|
step.fault_log.append(id.clone(), fault_kind);
|
|
|
|
} else if !self.verify_signature(&s_id, &sig, &kg_msg)? {
|
2018-08-02 11:11:32 -07:00
|
|
|
let fault_kind = FaultKind::InvalidKeyGenMessageSignature;
|
|
|
|
step.fault_log.append(id.clone(), fault_kind);
|
2018-10-22 07:09:00 -07:00
|
|
|
} else {
|
|
|
|
step.extend(match kg_msg {
|
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
|
|
|
KeyGenMessage::Part(part) => self.handle_part(&s_id, part, rng)?,
|
2018-10-24 12:23:54 -07:00
|
|
|
KeyGenMessage::Ack(ack) => self.handle_ack(&s_id, ack)?,
|
2018-10-22 07:09:00 -07:00
|
|
|
});
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-10-10 06:05:04 -07:00
|
|
|
let change = if let Some(kgs) = self.take_ready_key_gen() {
|
2018-08-02 11:11:32 -07:00
|
|
|
// If DKG completed, apply the change, restart Honey Badger, and inform the user.
|
2018-11-18 01:17:33 -08:00
|
|
|
debug!("{}: DKG for complete for: {:?}", self, kgs.public_keys());
|
2018-11-26 06:35:24 -08:00
|
|
|
self.netinfo = kgs.key_gen.into_network_info().map_err(Error::SyncKeyGen)?;
|
2018-11-19 05:51:32 -08:00
|
|
|
let params = self.honey_badger.params().clone();
|
|
|
|
self.restart_honey_badger(batch_epoch + 1, params);
|
2018-11-18 01:17:33 -08:00
|
|
|
ChangeState::Complete(Change::NodeChange(self.netinfo.public_key_map().clone()))
|
2018-08-02 11:11:32 -07:00
|
|
|
} else if let Some(change) = self.vote_counter.compute_winner().cloned() {
|
|
|
|
// If there is a new change, restart DKG. Inform the user about the current change.
|
2018-11-19 05:51:32 -08:00
|
|
|
match change {
|
2018-11-18 01:17:33 -08:00
|
|
|
Change::NodeChange(ref pub_keys) => {
|
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
|
|
|
step.extend(self.update_key_gen(batch_epoch + 1, pub_keys, rng)?);
|
2018-11-18 01:17:33 -08:00
|
|
|
}
|
2018-10-24 13:46:44 -07:00
|
|
|
Change::EncryptionSchedule(schedule) => {
|
2018-11-19 05:51:32 -08:00
|
|
|
self.update_encryption_schedule(batch_epoch + 1, schedule);
|
2018-10-23 22:18:18 -07:00
|
|
|
}
|
2018-11-19 05:51:32 -08:00
|
|
|
}
|
2018-10-27 15:44:08 -07:00
|
|
|
match change {
|
|
|
|
Change::NodeChange(_) => ChangeState::InProgress(change),
|
|
|
|
Change::EncryptionSchedule(_) => ChangeState::Complete(change),
|
|
|
|
}
|
2018-10-10 06:05:04 -07:00
|
|
|
} else {
|
|
|
|
ChangeState::None
|
|
|
|
};
|
2018-10-25 05:44:28 -07:00
|
|
|
step.output.push(Batch {
|
2018-11-01 11:18:08 -07:00
|
|
|
epoch: batch_epoch,
|
2018-10-25 08:07:52 -07:00
|
|
|
era: batch_era,
|
2018-10-10 06:05:04 -07:00
|
|
|
change,
|
|
|
|
netinfo: Arc::new(self.netinfo.clone()),
|
|
|
|
contributions: batch_contributions,
|
2018-11-19 05:51:32 -08:00
|
|
|
params: self.honey_badger.params().clone(),
|
2018-10-10 06:05:04 -07:00
|
|
|
});
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
Ok(step)
|
|
|
|
}
|
|
|
|
|
2018-11-19 05:51:32 -08:00
|
|
|
/// Restarts Honey Badger with the new encryption schedule.
|
|
|
|
pub(super) fn update_encryption_schedule(&mut self, era: u64, schedule: EncryptionSchedule) {
|
|
|
|
let mut params = self.honey_badger.params().clone();
|
|
|
|
params.encryption_schedule = schedule;
|
|
|
|
self.restart_honey_badger(era, params);
|
2018-10-21 13:47:44 -07:00
|
|
|
}
|
|
|
|
|
2018-08-02 11:11:32 -07:00
|
|
|
/// If the winner of the vote has changed, restarts Key Generation for the set of nodes implied
|
|
|
|
/// by the current change.
|
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
|
|
|
pub(super) fn update_key_gen<R: Rng>(
|
2018-10-23 22:18:18 -07:00
|
|
|
&mut self,
|
2018-10-25 08:07:52 -07:00
|
|
|
era: u64,
|
2018-11-18 01:17:33 -08:00
|
|
|
pub_keys: &BTreeMap<N, PublicKey>,
|
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-23 22:18:18 -07:00
|
|
|
) -> Result<Step<C, N>> {
|
2018-11-18 01:17:33 -08:00
|
|
|
if self.key_gen_state.as_ref().map(KeyGenState::public_keys) == Some(pub_keys) {
|
2018-08-02 11:11:32 -07:00
|
|
|
return Ok(Step::default()); // The change is the same as before. Continue DKG as is.
|
|
|
|
}
|
2018-11-18 01:17:33 -08:00
|
|
|
debug!("{}: Restarting DKG for {:?}.", self, pub_keys);
|
2018-11-19 05:51:32 -08:00
|
|
|
let params = self.honey_badger.params().clone();
|
|
|
|
self.restart_honey_badger(era, params);
|
2018-11-22 04:00:02 -08:00
|
|
|
let threshold = util::max_faulty(pub_keys.len());
|
2018-08-02 11:11:32 -07:00
|
|
|
let sk = self.netinfo.secret_key().clone();
|
2018-08-29 09:08:35 -07:00
|
|
|
let our_id = self.our_id().clone();
|
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 (key_gen, part) = SyncKeyGen::new(our_id, sk, pub_keys.clone(), threshold, rng)
|
|
|
|
.map_err(Error::SyncKeyGen)?;
|
2018-11-18 01:17:33 -08:00
|
|
|
self.key_gen_state = Some(KeyGenState::new(key_gen));
|
2018-08-02 11:11:32 -07:00
|
|
|
if let Some(part) = part {
|
2018-10-09 07:07:56 -07:00
|
|
|
self.send_transaction(KeyGenMessage::Part(part))
|
|
|
|
} else {
|
|
|
|
Ok(Step::default())
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Starts a new `HoneyBadger` instance and resets the vote counter.
|
2018-11-19 05:51:32 -08:00
|
|
|
fn restart_honey_badger(&mut self, era: u64, params: Params) {
|
2018-10-25 08:07:52 -07:00
|
|
|
self.era = era;
|
|
|
|
self.key_gen_msg_buffer.retain(|kg_msg| kg_msg.0 >= era);
|
2018-08-02 11:11:32 -07:00
|
|
|
let netinfo = Arc::new(self.netinfo.clone());
|
2018-10-25 08:07:52 -07:00
|
|
|
self.vote_counter = VoteCounter::new(netinfo.clone(), era);
|
2018-10-09 07:07:56 -07:00
|
|
|
self.honey_badger = HoneyBadger::builder(netinfo)
|
2018-10-25 08:07:52 -07:00
|
|
|
.session_id(era)
|
2018-11-19 05:51:32 -08:00
|
|
|
.params(params)
|
|
|
|
.build();
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Handles a `Part` message that was output by Honey Badger.
|
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_part<R: Rng>(
|
|
|
|
&mut self,
|
|
|
|
sender_id: &N,
|
|
|
|
part: Part,
|
|
|
|
rng: &mut R,
|
|
|
|
) -> Result<Step<C, N>> {
|
2018-10-03 04:21:59 -07:00
|
|
|
let outcome = if let Some(kgs) = self.key_gen_state.as_mut() {
|
2018-10-24 12:23:54 -07:00
|
|
|
kgs.key_gen
|
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_part(&sender_id, part, rng)
|
2018-11-26 06:35:24 -08:00
|
|
|
.map_err(Error::SyncKeyGen)?
|
2018-10-03 04:21:59 -07:00
|
|
|
} else {
|
2018-10-22 07:09:00 -07:00
|
|
|
// No key generation ongoing.
|
|
|
|
let fault_kind = FaultKind::UnexpectedKeyGenPart;
|
|
|
|
return Ok(Fault::new(sender_id.clone(), fault_kind).into());
|
2018-10-02 07:24:51 -07:00
|
|
|
};
|
|
|
|
|
2018-10-03 04:21:59 -07:00
|
|
|
match outcome {
|
2018-10-24 12:23:54 -07:00
|
|
|
PartOutcome::Valid(Some(ack)) => self.send_transaction(KeyGenMessage::Ack(ack)),
|
|
|
|
PartOutcome::Valid(None) => Ok(Step::default()),
|
|
|
|
PartOutcome::Invalid(fault) => {
|
|
|
|
let fault_kind = FaultKind::SyncKeyGenPart(fault);
|
|
|
|
Ok(Fault::new(sender_id.clone(), fault_kind).into())
|
|
|
|
}
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Handles an `Ack` message that was output by Honey Badger.
|
2018-10-24 12:23:54 -07:00
|
|
|
fn handle_ack(&mut self, sender_id: &N, ack: Ack) -> Result<Step<C, N>> {
|
|
|
|
let outcome = if let Some(kgs) = self.key_gen_state.as_mut() {
|
|
|
|
kgs.key_gen
|
|
|
|
.handle_ack(sender_id, ack)
|
2018-11-26 06:35:24 -08:00
|
|
|
.map_err(Error::SyncKeyGen)?
|
2018-08-02 11:11:32 -07:00
|
|
|
} else {
|
2018-10-22 07:09:00 -07:00
|
|
|
// No key generation ongoing.
|
|
|
|
let fault_kind = FaultKind::UnexpectedKeyGenAck;
|
|
|
|
return Ok(Fault::new(sender_id.clone(), fault_kind).into());
|
2018-10-24 12:23:54 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
match outcome {
|
|
|
|
AckOutcome::Valid => Ok(Step::default()),
|
|
|
|
AckOutcome::Invalid(fault) => {
|
|
|
|
let fault_kind = FaultKind::SyncKeyGenAck(fault);
|
|
|
|
Ok(Fault::new(sender_id.clone(), fault_kind).into())
|
|
|
|
}
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Signs and sends a `KeyGenMessage` and also tries to commit it.
|
2018-08-02 14:27:55 -07:00
|
|
|
fn send_transaction(&mut self, kg_msg: KeyGenMessage) -> Result<Step<C, N>> {
|
2018-11-26 06:35:24 -08:00
|
|
|
let ser = bincode::serialize(&kg_msg).map_err(|err| Error::SerializeKeyGen(*err))?;
|
2018-08-02 11:11:32 -07:00
|
|
|
let sig = Box::new(self.netinfo.secret_key().sign(ser));
|
|
|
|
if self.netinfo.is_validator() {
|
2018-10-25 05:44:28 -07:00
|
|
|
let our_id = self.our_id().clone();
|
2018-10-25 08:07:52 -07:00
|
|
|
let signed_msg = SignedKeyGenMsg(self.era, our_id, kg_msg.clone(), *sig.clone());
|
2018-08-02 11:11:32 -07:00
|
|
|
self.key_gen_msg_buffer.push(signed_msg);
|
|
|
|
}
|
2018-10-25 08:07:52 -07:00
|
|
|
let msg = Message::KeyGen(self.era, kg_msg, sig);
|
2018-08-02 11:11:32 -07:00
|
|
|
Ok(Target::All.message(msg).into())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// If the current Key Generation process is ready, returns the `KeyGenState`.
|
|
|
|
///
|
|
|
|
/// We require the minimum number of completed proposals (`SyncKeyGen::is_ready`) and if a new
|
|
|
|
/// node is joining, we require in addition that the new node's proposal is complete. That way
|
|
|
|
/// the new node knows that it's key is secret, without having to trust any number of nodes.
|
2018-08-02 14:27:55 -07:00
|
|
|
fn take_ready_key_gen(&mut self) -> Option<KeyGenState<N>> {
|
2018-08-02 11:11:32 -07:00
|
|
|
if self
|
|
|
|
.key_gen_state
|
|
|
|
.as_ref()
|
|
|
|
.map_or(false, KeyGenState::is_ready)
|
|
|
|
{
|
|
|
|
self.key_gen_state.take()
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `true` if the signature of `kg_msg` by the node with the specified ID is valid.
|
|
|
|
/// Returns an error if the payload fails to serialize.
|
|
|
|
///
|
2018-11-18 01:17:33 -08:00
|
|
|
/// This accepts signatures from both validators and currently joining candidates, if any.
|
2018-08-02 11:11:32 -07:00
|
|
|
fn verify_signature(
|
|
|
|
&self,
|
2018-08-02 14:27:55 -07:00
|
|
|
node_id: &N,
|
2018-08-02 11:11:32 -07:00
|
|
|
sig: &Signature,
|
|
|
|
kg_msg: &KeyGenMessage,
|
|
|
|
) -> Result<bool> {
|
2018-11-26 06:35:24 -08:00
|
|
|
let ser = bincode::serialize(kg_msg).map_err(|err| Error::SerializeKeyGen(*err))?;
|
2018-11-18 01:17:33 -08:00
|
|
|
let verify = |opt_pk: Option<&PublicKey>| opt_pk.map_or(false, |pk| pk.verify(&sig, &ser));
|
|
|
|
let kgs = self.key_gen_state.as_ref();
|
|
|
|
let current_key = self.netinfo.public_key(node_id);
|
|
|
|
let candidate_key = kgs.and_then(|kgs| kgs.public_keys().get(node_id));
|
|
|
|
Ok(verify(current_key) || verify(candidate_key))
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
2018-10-25 08:07:52 -07:00
|
|
|
|
|
|
|
/// Returns the maximum future epochs of the Honey Badger algorithm instance.
|
|
|
|
pub fn max_future_epochs(&self) -> u64 {
|
|
|
|
self.max_future_epochs
|
|
|
|
}
|
2018-08-02 11:11:32 -07:00
|
|
|
}
|
2018-11-01 03:22:40 -07:00
|
|
|
|
|
|
|
impl<C, N> fmt::Display for DynamicHoneyBadger<C, N>
|
|
|
|
where
|
|
|
|
C: Contribution + Serialize + DeserializeOwned,
|
2018-12-27 01:34:34 -08:00
|
|
|
N: NodeIdT + Serialize + DeserializeOwned,
|
2018-11-01 03:22:40 -07:00
|
|
|
{
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
|
2018-10-25 08:07:52 -07:00
|
|
|
write!(f, "{:?} DHB(era: {})", self.our_id(), self.era)
|
2018-11-01 03:22:40 -07:00
|
|
|
}
|
|
|
|
}
|
2018-11-07 08:21:24 -08:00
|
|
|
|
|
|
|
impl<C, N> Epoched for DynamicHoneyBadger<C, N>
|
|
|
|
where
|
|
|
|
C: Contribution + Serialize + DeserializeOwned,
|
2018-12-27 01:34:34 -08:00
|
|
|
N: NodeIdT + Serialize + DeserializeOwned,
|
2018-11-07 08:21:24 -08:00
|
|
|
{
|
|
|
|
type Epoch = (u64, u64);
|
|
|
|
|
|
|
|
fn epoch(&self) -> (u64, u64) {
|
|
|
|
(self.era, self.honey_badger.epoch())
|
|
|
|
}
|
|
|
|
}
|