Include the full Params in JoinPlan.

This ensures that a new node runs with exactly the same parameters as
the rest of the network.
This commit is contained in:
Andreas Fackler 2018-11-19 14:51:32 +01:00 committed by Andreas Fackler
parent 5735cf23a1
commit c2a76add5d
7 changed files with 87 additions and 74 deletions

View File

@ -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<C, N: Ord> {
pub(super) change: ChangeState<N>,
/// The network info that applies to the _next_ epoch.
pub(super) netinfo: Arc<NetworkInfo<N>>,
/// 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<C, N: NodeIdT> Batch<C, N> {
@ -105,8 +104,7 @@ impl<C, N: NodeIdT> Batch<C, N> {
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<C, N: NodeIdT> Batch<C, N> {
&& 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.

View File

@ -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<N>,
) -> Result<(DynamicHoneyBadger<C, N>, Step<C, N>)> {
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())
}
}

View File

@ -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<R: Rng + Send + Sync + 'static>(
our_id: N,
secret_key: SecretKey,
join_plan: JoinPlan<N>,
mut rng: R,
) -> Result<(Self, Step<C, N>)> {
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<Step<C, N>> {
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<EncryptionSchedule>) {
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.

View File

@ -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<N: Ord> {
pub_key_set: PublicKeySet,
/// The public keys of the nodes taking part in key generation.
pub_keys: BTreeMap<N, PublicKey>,
/// 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<N: Ord> JoinPlan<N> {

View File

@ -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,

View File

@ -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.

View File

@ -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,