mirror of https://github.com/poanetwork/hbbft.git
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:
parent
5735cf23a1
commit
c2a76add5d
|
@ -3,8 +3,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use crypto::Signature;
|
use crypto::Signature;
|
||||||
|
|
||||||
use super::EncryptionSchedule;
|
use super::{ChangeState, JoinPlan, Params};
|
||||||
use super::{ChangeState, JoinPlan};
|
|
||||||
use {NetworkInfo, NodeIdT};
|
use {NetworkInfo, NodeIdT};
|
||||||
|
|
||||||
/// A batch of transactions the algorithm has output.
|
/// A batch of transactions the algorithm has output.
|
||||||
|
@ -23,8 +22,8 @@ pub struct Batch<C, N: Ord> {
|
||||||
pub(super) change: ChangeState<N>,
|
pub(super) change: ChangeState<N>,
|
||||||
/// The network info that applies to the _next_ epoch.
|
/// The network info that applies to the _next_ epoch.
|
||||||
pub(super) netinfo: Arc<NetworkInfo<N>>,
|
pub(super) netinfo: Arc<NetworkInfo<N>>,
|
||||||
/// The current encryption schedule for threshold cryptography.
|
/// Parameters controlling Honey Badger's behavior and performance.
|
||||||
pub(super) encryption_schedule: EncryptionSchedule,
|
pub(super) params: Params,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, N: NodeIdT> Batch<C, N> {
|
impl<C, N: NodeIdT> Batch<C, N> {
|
||||||
|
@ -105,8 +104,7 @@ impl<C, N: NodeIdT> Batch<C, N> {
|
||||||
change: self.change.clone(),
|
change: self.change.clone(),
|
||||||
pub_key_set: self.netinfo.public_key_set().clone(),
|
pub_key_set: self.netinfo.public_key_set().clone(),
|
||||||
pub_keys: self.netinfo.public_key_map().clone(),
|
pub_keys: self.netinfo.public_key_map().clone(),
|
||||||
encryption_schedule: self.encryption_schedule,
|
params: self.params.clone(),
|
||||||
random_value: self.random_value.is_some(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +120,7 @@ impl<C, N: NodeIdT> Batch<C, N> {
|
||||||
&& self.change == other.change
|
&& self.change == other.change
|
||||||
&& self.netinfo.public_key_set() == other.netinfo.public_key_set()
|
&& self.netinfo.public_key_set() == other.netinfo.public_key_set()
|
||||||
&& self.netinfo.public_key_map() == other.netinfo.public_key_map()
|
&& 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.
|
/// Returns the signature that can be used as a pseudorandom value.
|
||||||
|
|
|
@ -3,14 +3,11 @@ use std::iter::once;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crypto::{SecretKey, SecretKeySet, SecretKeyShare};
|
use crypto::{SecretKey, SecretKeySet};
|
||||||
use rand::{self, Rand, Rng};
|
use rand::{self, Rand, Rng};
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
use super::{
|
use super::{DynamicHoneyBadger, EncryptionSchedule, JoinPlan, Result, Step, VoteCounter};
|
||||||
Change, ChangeState, DynamicHoneyBadger, EncryptionSchedule, JoinPlan, Result, Step,
|
|
||||||
VoteCounter,
|
|
||||||
};
|
|
||||||
use honey_badger::{HoneyBadger, Params, SubsetHandlingStrategy};
|
use honey_badger::{HoneyBadger, Params, SubsetHandlingStrategy};
|
||||||
use util::SubRng;
|
use util::SubRng;
|
||||||
use {Contribution, NetworkInfo, NodeIdT};
|
use {Contribution, NetworkInfo, NodeIdT};
|
||||||
|
@ -137,43 +134,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `DynamicHoneyBadger` configured to join the network at the epoch specified in
|
/// 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(
|
pub fn build_joining(
|
||||||
&mut self,
|
&mut self,
|
||||||
our_id: N,
|
our_id: N,
|
||||||
secret_key: SecretKey,
|
secret_key: SecretKey,
|
||||||
join_plan: JoinPlan<N>,
|
join_plan: JoinPlan<N>,
|
||||||
) -> Result<(DynamicHoneyBadger<C, N>, Step<C, N>)> {
|
) -> Result<(DynamicHoneyBadger<C, N>, Step<C, N>)> {
|
||||||
let netinfo = NetworkInfo::new(
|
DynamicHoneyBadger::new_joining(our_id, secret_key, join_plan, self.rng.sub_rng())
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,17 @@ use std::sync::Arc;
|
||||||
use std::{fmt, result};
|
use std::{fmt, result};
|
||||||
|
|
||||||
use bincode;
|
use bincode;
|
||||||
use crypto::{PublicKey, Signature};
|
use crypto::{PublicKey, SecretKey, SecretKeyShare, Signature};
|
||||||
use derivative::Derivative;
|
use derivative::Derivative;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use rand::{self, Rand};
|
use rand::{self, Rand, Rng};
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
use super::votes::{SignedVote, VoteCounter};
|
use super::votes::{SignedVote, VoteCounter};
|
||||||
use super::{
|
use super::{
|
||||||
Batch, Change, ChangeState, DynamicHoneyBadgerBuilder, EncryptionSchedule, Error, ErrorKind,
|
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 fault_log::{Fault, FaultKind, FaultLog};
|
||||||
use honey_badger::{self, HoneyBadger, Message as HbMessage};
|
use honey_badger::{self, HoneyBadger, Message as HbMessage};
|
||||||
|
@ -88,6 +89,47 @@ where
|
||||||
DynamicHoneyBadgerBuilder::new()
|
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.
|
/// Returns `true` if input for the current epoch has already been provided.
|
||||||
pub fn has_input(&self) -> bool {
|
pub fn has_input(&self) -> bool {
|
||||||
self.honey_badger.has_input()
|
self.honey_badger.has_input()
|
||||||
|
@ -296,18 +338,19 @@ where
|
||||||
// If DKG completed, apply the change, restart Honey Badger, and inform the user.
|
// If DKG completed, apply the change, restart Honey Badger, and inform the user.
|
||||||
debug!("{}: DKG for complete for: {:?}", self, kgs.public_keys());
|
debug!("{}: DKG for complete for: {:?}", self, kgs.public_keys());
|
||||||
self.netinfo = kgs.key_gen.into_network_info()?;
|
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()))
|
ChangeState::Complete(Change::NodeChange(self.netinfo.public_key_map().clone()))
|
||||||
} else if let Some(change) = self.vote_counter.compute_winner().cloned() {
|
} 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.
|
// 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) => {
|
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) => {
|
Change::EncryptionSchedule(schedule) => {
|
||||||
self.update_encryption_schedule(batch_epoch + 1, schedule)?
|
self.update_encryption_schedule(batch_epoch + 1, schedule);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
match change {
|
match change {
|
||||||
Change::NodeChange(_) => ChangeState::InProgress(change),
|
Change::NodeChange(_) => ChangeState::InProgress(change),
|
||||||
Change::EncryptionSchedule(_) => ChangeState::Complete(change),
|
Change::EncryptionSchedule(_) => ChangeState::Complete(change),
|
||||||
|
@ -322,19 +365,17 @@ where
|
||||||
netinfo: Arc::new(self.netinfo.clone()),
|
netinfo: Arc::new(self.netinfo.clone()),
|
||||||
contributions: batch_contributions,
|
contributions: batch_contributions,
|
||||||
random_value: hb_batch.random_value,
|
random_value: hb_batch.random_value,
|
||||||
encryption_schedule: self.honey_badger.get_encryption_schedule(),
|
params: self.honey_badger.params().clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(step)
|
Ok(step)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn update_encryption_schedule(
|
/// Restarts Honey Badger with the new encryption schedule.
|
||||||
&mut self,
|
pub(super) fn update_encryption_schedule(&mut self, era: u64, schedule: EncryptionSchedule) {
|
||||||
era: u64,
|
let mut params = self.honey_badger.params().clone();
|
||||||
encryption_schedule: EncryptionSchedule,
|
params.encryption_schedule = schedule;
|
||||||
) -> Result<Step<C, N>> {
|
self.restart_honey_badger(era, params);
|
||||||
self.restart_honey_badger(era, Some(encryption_schedule));
|
|
||||||
Ok(Step::default())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the winner of the vote has changed, restarts Key Generation for the set of nodes implied
|
/// 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.
|
return Ok(Step::default()); // The change is the same as before. Continue DKG as is.
|
||||||
}
|
}
|
||||||
debug!("{}: Restarting DKG for {:?}.", self, pub_keys);
|
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_
|
// 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.
|
// `NetworkInfo` if the change goes through. It would be safer to deduplicate.
|
||||||
let threshold = (pub_keys.len() - 1) / 3;
|
let threshold = (pub_keys.len() - 1) / 3;
|
||||||
|
@ -365,18 +407,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts a new `HoneyBadger` instance and resets the vote counter.
|
/// 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.era = era;
|
||||||
self.key_gen_msg_buffer.retain(|kg_msg| kg_msg.0 >= era);
|
self.key_gen_msg_buffer.retain(|kg_msg| kg_msg.0 >= era);
|
||||||
let netinfo = Arc::new(self.netinfo.clone());
|
let netinfo = Arc::new(self.netinfo.clone());
|
||||||
self.vote_counter = VoteCounter::new(netinfo.clone(), era);
|
self.vote_counter = VoteCounter::new(netinfo.clone(), era);
|
||||||
self.honey_badger = HoneyBadger::builder(netinfo)
|
self.honey_badger = HoneyBadger::builder(netinfo)
|
||||||
.session_id(era)
|
.session_id(era)
|
||||||
.max_future_epochs(self.max_future_epochs)
|
|
||||||
.rng(self.rng.sub_rng())
|
.rng(self.rng.sub_rng())
|
||||||
.encryption_schedule(
|
.params(params)
|
||||||
encryption_schedule.unwrap_or_else(|| self.honey_badger.get_encryption_schedule()),
|
.build();
|
||||||
).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles a `Part` message that was output by Honey Badger.
|
/// Handles a `Part` message that was output by Honey Badger.
|
||||||
|
|
|
@ -79,7 +79,7 @@ use rand::Rand;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
use self::votes::{SignedVote, VoteCounter};
|
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 sync_key_gen::{Ack, Part, SyncKeyGen};
|
||||||
use NodeIdT;
|
use NodeIdT;
|
||||||
|
|
||||||
|
@ -145,10 +145,8 @@ pub struct JoinPlan<N: Ord> {
|
||||||
pub_key_set: PublicKeySet,
|
pub_key_set: PublicKeySet,
|
||||||
/// The public keys of the nodes taking part in key generation.
|
/// The public keys of the nodes taking part in key generation.
|
||||||
pub_keys: BTreeMap<N, PublicKey>,
|
pub_keys: BTreeMap<N, PublicKey>,
|
||||||
/// The current encryption schedule for threshold cryptography.
|
/// Parameters controlling Honey Badger's behavior and performance.
|
||||||
encryption_schedule: EncryptionSchedule,
|
params: Params,
|
||||||
/// Whether to generate a pseudorandom value in each epoch.
|
|
||||||
random_value: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Ord> JoinPlan<N> {
|
impl<N: Ord> JoinPlan<N> {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crypto::{Ciphertext, Signature};
|
||||||
use log::error;
|
use log::error;
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use serde_derive::Serialize;
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{Batch, ErrorKind, MessageContent, Result, Step};
|
use super::{Batch, ErrorKind, MessageContent, Result, Step};
|
||||||
use fault_log::{Fault, FaultKind, FaultLog};
|
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
|
/// A flag used when constructing an `EpochState` to determine which behavior to use when receiving
|
||||||
/// proposals from a `Subset` instance.
|
/// proposals from a `Subset` instance.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub enum SubsetHandlingStrategy {
|
pub enum SubsetHandlingStrategy {
|
||||||
/// Sets the `EpochState` to return proposals as they are contributed.
|
/// Sets the `EpochState` to return proposals as they are contributed.
|
||||||
Incremental,
|
Incremental,
|
||||||
|
|
|
@ -191,6 +191,11 @@ where
|
||||||
pub fn max_future_epochs(&self) -> u64 {
|
pub fn max_future_epochs(&self) -> u64 {
|
||||||
self.params.max_future_epochs
|
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.
|
/// How frequently Threshold Encryption should be used.
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{EncryptionSchedule, SubsetHandlingStrategy};
|
use super::{EncryptionSchedule, SubsetHandlingStrategy};
|
||||||
|
|
||||||
/// Parameters controlling Honey Badger's behavior and performance.
|
/// Parameters controlling Honey Badger's behavior and performance.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct Params {
|
pub struct Params {
|
||||||
/// The maximum number of future epochs for which we handle messages simultaneously.
|
/// The maximum number of future epochs for which we handle messages simultaneously.
|
||||||
pub max_future_epochs: u64,
|
pub max_future_epochs: u64,
|
||||||
|
|
Loading…
Reference in New Issue