diff --git a/src/dynamic_honey_badger/batch.rs b/src/dynamic_honey_badger/batch.rs index 864b332..b88a3d0 100644 --- a/src/dynamic_honey_badger/batch.rs +++ b/src/dynamic_honey_badger/batch.rs @@ -3,8 +3,7 @@ use std::sync::Arc; use crypto::Signature; -use super::EncryptionSchedule; -use super::{ChangeState, JoinPlan}; +use super::{ChangeState, JoinPlan, Params}; use {NetworkInfo, NodeIdT}; /// A batch of transactions the algorithm has output. @@ -23,8 +22,8 @@ pub struct Batch { pub(super) change: ChangeState, /// The network info that applies to the _next_ epoch. pub(super) netinfo: Arc>, - /// The current encryption schedule for threshold cryptography. - pub(super) encryption_schedule: EncryptionSchedule, + /// Parameters controlling Honey Badger's behavior and performance. + pub(super) params: Params, } impl Batch { @@ -105,8 +104,7 @@ impl Batch { change: self.change.clone(), pub_key_set: self.netinfo.public_key_set().clone(), pub_keys: self.netinfo.public_key_map().clone(), - encryption_schedule: self.encryption_schedule, - random_value: self.random_value.is_some(), + params: self.params.clone(), }) } @@ -122,7 +120,7 @@ impl Batch { && self.change == other.change && self.netinfo.public_key_set() == other.netinfo.public_key_set() && self.netinfo.public_key_map() == other.netinfo.public_key_map() - && self.encryption_schedule == other.encryption_schedule + && self.params == other.params } /// Returns the signature that can be used as a pseudorandom value. diff --git a/src/dynamic_honey_badger/builder.rs b/src/dynamic_honey_badger/builder.rs index bca7724..76a7935 100644 --- a/src/dynamic_honey_badger/builder.rs +++ b/src/dynamic_honey_badger/builder.rs @@ -3,14 +3,11 @@ use std::iter::once; use std::marker::PhantomData; use std::sync::Arc; -use crypto::{SecretKey, SecretKeySet, SecretKeyShare}; +use crypto::{SecretKey, SecretKeySet}; use rand::{self, Rand, Rng}; use serde::{de::DeserializeOwned, Serialize}; -use super::{ - Change, ChangeState, DynamicHoneyBadger, EncryptionSchedule, JoinPlan, Result, Step, - VoteCounter, -}; +use super::{DynamicHoneyBadger, EncryptionSchedule, JoinPlan, Result, Step, VoteCounter}; use honey_badger::{HoneyBadger, Params, SubsetHandlingStrategy}; use util::SubRng; use {Contribution, NetworkInfo, NodeIdT}; @@ -137,43 +134,16 @@ where } /// Creates a new `DynamicHoneyBadger` configured to join the network at the epoch specified in - /// the `JoinPlan`. + /// the `JoinPlan`. This ignores the builder's configuration settings. + /// + /// **Deprecated**: Please use `DynamicHoneyBadger::new_joining` instead. + #[deprecated] pub fn build_joining( &mut self, our_id: N, secret_key: SecretKey, join_plan: JoinPlan, ) -> Result<(DynamicHoneyBadger, Step)> { - let netinfo = NetworkInfo::new( - our_id, - SecretKeyShare::default(), // TODO: Should be an option? - join_plan.pub_key_set, - secret_key, - join_plan.pub_keys, - ); - let arc_netinfo = Arc::new(netinfo.clone()); - let honey_badger = HoneyBadger::builder(arc_netinfo.clone()) - .max_future_epochs(self.params.max_future_epochs) - .encryption_schedule(join_plan.encryption_schedule) - .random_value(join_plan.random_value) - .build(); - let mut dhb = DynamicHoneyBadger { - netinfo, - max_future_epochs: self.params.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, - rng: Box::new(self.rng.sub_rng()), - }; - let step = match join_plan.change { - ChangeState::InProgress(ref change) => match change { - Change::NodeChange(change) => dhb.update_key_gen(join_plan.era, change)?, - _ => Step::default(), - }, - ChangeState::None | ChangeState::Complete(..) => Step::default(), - }; - Ok((dhb, step)) + DynamicHoneyBadger::new_joining(our_id, secret_key, join_plan, self.rng.sub_rng()) } } diff --git a/src/dynamic_honey_badger/dynamic_honey_badger.rs b/src/dynamic_honey_badger/dynamic_honey_badger.rs index f588b75..cb112c5 100644 --- a/src/dynamic_honey_badger/dynamic_honey_badger.rs +++ b/src/dynamic_honey_badger/dynamic_honey_badger.rs @@ -3,16 +3,17 @@ use std::sync::Arc; use std::{fmt, result}; use bincode; -use crypto::{PublicKey, Signature}; +use crypto::{PublicKey, SecretKey, SecretKeyShare, Signature}; use derivative::Derivative; use log::debug; -use rand::{self, Rand}; +use rand::{self, Rand, Rng}; use serde::{de::DeserializeOwned, Serialize}; use super::votes::{SignedVote, VoteCounter}; use super::{ Batch, Change, ChangeState, DynamicHoneyBadgerBuilder, EncryptionSchedule, Error, ErrorKind, - Input, InternalContrib, KeyGenMessage, KeyGenState, Message, Result, SignedKeyGenMsg, Step, + Input, InternalContrib, JoinPlan, KeyGenMessage, KeyGenState, Message, Params, Result, + SignedKeyGenMsg, Step, }; use fault_log::{Fault, FaultKind, FaultLog}; use honey_badger::{self, HoneyBadger, Message as HbMessage}; @@ -88,6 +89,47 @@ where DynamicHoneyBadgerBuilder::new() } + /// Creates a new `DynamicHoneyBadger` ready to join the network specified in the `JoinPlan`. + pub fn new_joining( + our_id: N, + secret_key: SecretKey, + join_plan: JoinPlan, + mut rng: R, + ) -> Result<(Self, Step)> { + let netinfo = NetworkInfo::new( + our_id, + SecretKeyShare::default(), // TODO: Should be an option? + 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) + .rng(rng.sub_rng()) + .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, + rng: Box::new(rng), + }; + let step = match join_plan.change { + ChangeState::InProgress(ref change) => match change { + Change::NodeChange(change) => dhb.update_key_gen(join_plan.era, change)?, + _ => Step::default(), + }, + ChangeState::None | ChangeState::Complete(..) => Step::default(), + }; + Ok((dhb, step)) + } + /// Returns `true` if input for the current epoch has already been provided. pub fn has_input(&self) -> bool { self.honey_badger.has_input() @@ -296,18 +338,19 @@ where // If DKG completed, apply the change, restart Honey Badger, and inform the user. debug!("{}: DKG for complete for: {:?}", self, kgs.public_keys()); self.netinfo = kgs.key_gen.into_network_info()?; - self.restart_honey_badger(batch_epoch + 1, None); + let params = self.honey_badger.params().clone(); + self.restart_honey_badger(batch_epoch + 1, params); ChangeState::Complete(Change::NodeChange(self.netinfo.public_key_map().clone())) } 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. - step.extend(match change { + match change { Change::NodeChange(ref pub_keys) => { - self.update_key_gen(batch_epoch + 1, pub_keys)? + step.extend(self.update_key_gen(batch_epoch + 1, pub_keys)?); } Change::EncryptionSchedule(schedule) => { - self.update_encryption_schedule(batch_epoch + 1, schedule)? + self.update_encryption_schedule(batch_epoch + 1, schedule); } - }); + } match change { Change::NodeChange(_) => ChangeState::InProgress(change), Change::EncryptionSchedule(_) => ChangeState::Complete(change), @@ -322,19 +365,17 @@ where netinfo: Arc::new(self.netinfo.clone()), contributions: batch_contributions, random_value: hb_batch.random_value, - encryption_schedule: self.honey_badger.get_encryption_schedule(), + params: self.honey_badger.params().clone(), }); } Ok(step) } - pub(super) fn update_encryption_schedule( - &mut self, - era: u64, - encryption_schedule: EncryptionSchedule, - ) -> Result> { - self.restart_honey_badger(era, Some(encryption_schedule)); - Ok(Step::default()) + /// 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); } /// If the winner of the vote has changed, restarts Key Generation for the set of nodes implied @@ -348,7 +389,8 @@ where return Ok(Step::default()); // The change is the same as before. Continue DKG as is. } debug!("{}: Restarting DKG for {:?}.", self, pub_keys); - self.restart_honey_badger(era, None); + let params = self.honey_badger.params().clone(); + self.restart_honey_badger(era, params); // TODO: This needs to be the same as `num_faulty` will be in the _new_ // `NetworkInfo` if the change goes through. It would be safer to deduplicate. let threshold = (pub_keys.len() - 1) / 3; @@ -365,18 +407,16 @@ where } /// Starts a new `HoneyBadger` instance and resets the vote counter. - fn restart_honey_badger(&mut self, era: u64, encryption_schedule: Option) { + fn restart_honey_badger(&mut self, era: u64, params: Params) { self.era = era; self.key_gen_msg_buffer.retain(|kg_msg| kg_msg.0 >= era); let netinfo = Arc::new(self.netinfo.clone()); self.vote_counter = VoteCounter::new(netinfo.clone(), era); self.honey_badger = HoneyBadger::builder(netinfo) .session_id(era) - .max_future_epochs(self.max_future_epochs) .rng(self.rng.sub_rng()) - .encryption_schedule( - encryption_schedule.unwrap_or_else(|| self.honey_badger.get_encryption_schedule()), - ).build(); + .params(params) + .build(); } /// Handles a `Part` message that was output by Honey Badger. diff --git a/src/dynamic_honey_badger/mod.rs b/src/dynamic_honey_badger/mod.rs index 8fdcab5..21fc766 100644 --- a/src/dynamic_honey_badger/mod.rs +++ b/src/dynamic_honey_badger/mod.rs @@ -79,7 +79,7 @@ use rand::Rand; use serde_derive::{Deserialize, Serialize}; use self::votes::{SignedVote, VoteCounter}; -use honey_badger::{EncryptionSchedule, Message as HbMessage}; +use honey_badger::{EncryptionSchedule, Message as HbMessage, Params}; use sync_key_gen::{Ack, Part, SyncKeyGen}; use NodeIdT; @@ -145,10 +145,8 @@ pub struct JoinPlan { pub_key_set: PublicKeySet, /// The public keys of the nodes taking part in key generation. pub_keys: BTreeMap, - /// The current encryption schedule for threshold cryptography. - encryption_schedule: EncryptionSchedule, - /// Whether to generate a pseudorandom value in each epoch. - random_value: bool, + /// Parameters controlling Honey Badger's behavior and performance. + params: Params, } impl JoinPlan { diff --git a/src/honey_badger/epoch_state.rs b/src/honey_badger/epoch_state.rs index e80c9b5..2888d29 100644 --- a/src/honey_badger/epoch_state.rs +++ b/src/honey_badger/epoch_state.rs @@ -11,7 +11,7 @@ use crypto::{Ciphertext, Signature}; use log::error; use rand::{Rand, Rng}; use serde::{de::DeserializeOwned, Serialize}; -use serde_derive::Serialize; +use serde_derive::{Deserialize, Serialize}; use super::{Batch, ErrorKind, MessageContent, Result, Step}; use fault_log::{Fault, FaultKind, FaultLog}; @@ -142,7 +142,7 @@ where /// A flag used when constructing an `EpochState` to determine which behavior to use when receiving /// proposals from a `Subset` instance. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum SubsetHandlingStrategy { /// Sets the `EpochState` to return proposals as they are contributed. Incremental, diff --git a/src/honey_badger/honey_badger.rs b/src/honey_badger/honey_badger.rs index ecb401c..03ad901 100644 --- a/src/honey_badger/honey_badger.rs +++ b/src/honey_badger/honey_badger.rs @@ -191,6 +191,11 @@ where pub fn max_future_epochs(&self) -> u64 { self.params.max_future_epochs } + + /// Returns the parameters controlling Honey Badger's behavior and performance. + pub fn params(&self) -> &Params { + &self.params + } } /// How frequently Threshold Encryption should be used. diff --git a/src/honey_badger/params.rs b/src/honey_badger/params.rs index 77d497f..d535d02 100644 --- a/src/honey_badger/params.rs +++ b/src/honey_badger/params.rs @@ -1,7 +1,9 @@ +use serde_derive::{Deserialize, Serialize}; + use super::{EncryptionSchedule, SubsetHandlingStrategy}; /// Parameters controlling Honey Badger's behavior and performance. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Params { /// The maximum number of future epochs for which we handle messages simultaneously. pub max_future_epochs: u64,