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 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.
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue