mirror of https://github.com/poanetwork/hbbft.git
add configuration options for optional/periodic encryption scheduling
This commit is contained in:
parent
f8bf552165
commit
813a76bb5f
|
@ -7,10 +7,11 @@ use crypto::{SecretKey, SecretKeySet, SecretKeyShare};
|
|||
use rand::{self, Rand, Rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{ChangeState, DynamicHoneyBadger, JoinPlan, Result, Step, VoteCounter};
|
||||
use super::{Change, ChangeState, DynamicHoneyBadger, JoinPlan, Result, Step, VoteCounter};
|
||||
use honey_badger::{HoneyBadger, SubsetHandlingStrategy};
|
||||
use util::SubRng;
|
||||
use {Contribution, NetworkInfo, NodeIdT};
|
||||
use threshold_decryption::EncryptionSchedule;
|
||||
|
||||
/// A Dynamic Honey Badger builder, to configure the parameters and create new instances of
|
||||
/// `DynamicHoneyBadger`.
|
||||
|
@ -24,6 +25,8 @@ pub struct DynamicHoneyBadgerBuilder<C, N> {
|
|||
rng: Box<dyn rand::Rng>,
|
||||
/// Strategy used to handle the output of the `Subset` algorithm.
|
||||
subset_handling_strategy: SubsetHandlingStrategy,
|
||||
/// Schedule for adding threshold encryption to some percentage of rounds
|
||||
encryption_schedule: EncryptionSchedule,
|
||||
_phantom: PhantomData<(C, N)>,
|
||||
}
|
||||
|
||||
|
@ -35,6 +38,7 @@ impl<C, N> Default for DynamicHoneyBadgerBuilder<C, N> {
|
|||
max_future_epochs: 3,
|
||||
rng: Box::new(rand::thread_rng()),
|
||||
subset_handling_strategy: SubsetHandlingStrategy::Incremental,
|
||||
encryption_schedule: EncryptionSchedule::Always,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +82,12 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the schedule to use for threshold encryption.
|
||||
pub fn encryption_schedule(&mut self, encryption_schedule: EncryptionSchedule) -> &mut Self {
|
||||
self.encryption_schedule = encryption_schedule;
|
||||
self
|
||||
}
|
||||
|
||||
/// Creates a new Dynamic Honey Badger instance with an empty buffer.
|
||||
pub fn build(&mut self, netinfo: NetworkInfo<N>) -> DynamicHoneyBadger<C, N> {
|
||||
let DynamicHoneyBadgerBuilder {
|
||||
|
@ -85,6 +95,7 @@ where
|
|||
max_future_epochs,
|
||||
rng,
|
||||
subset_handling_strategy,
|
||||
encryption_schedule,
|
||||
_phantom,
|
||||
} = self;
|
||||
let epoch = *epoch;
|
||||
|
@ -94,6 +105,7 @@ where
|
|||
.max_future_epochs(max_future_epochs)
|
||||
.rng(rng.sub_rng())
|
||||
.subset_handling_strategy(subset_handling_strategy.clone())
|
||||
.encryption_schedule(*encryption_schedule)
|
||||
.build();
|
||||
DynamicHoneyBadger {
|
||||
netinfo,
|
||||
|
@ -150,7 +162,12 @@ where
|
|||
rng: Box::new(self.rng.sub_rng()),
|
||||
};
|
||||
let step = match join_plan.change {
|
||||
ChangeState::InProgress(ref change) => dhb.update_key_gen(join_plan.epoch, change)?,
|
||||
ChangeState::InProgress(ref change) => {
|
||||
match change {
|
||||
Change::Add(_,_) | Change::Remove(_) => dhb.update_key_gen(join_plan.epoch, change)?,
|
||||
_ => Step::default(),
|
||||
}
|
||||
},
|
||||
ChangeState::None | ChangeState::Complete(..) => Step::default(),
|
||||
};
|
||||
Ok((dhb, step))
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
use crypto::PublicKey;
|
||||
use threshold_decryption::EncryptionSchedule;
|
||||
|
||||
/// A node change action: adding or removing a node.
|
||||
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Hash, Debug)]
|
||||
pub enum Change<N> {
|
||||
// TODO: Refactor so that node changes are in a sub-enum of a Change.
|
||||
/// Add a node. The public key is used only temporarily, for key generation.
|
||||
Add(N, PublicKey),
|
||||
/// Remove a node.
|
||||
Remove(N),
|
||||
/// Change the threshold encryption schedule. i.e., to increase frequency to prevent censorship or decrease for performance.
|
||||
EncryptionSchedule(EncryptionSchedule),
|
||||
}
|
||||
|
||||
impl<N> Change<N> {
|
||||
|
@ -15,6 +19,7 @@ impl<N> Change<N> {
|
|||
match *self {
|
||||
Change::Add(ref id, _) => Some(id),
|
||||
Change::Remove(_) => None,
|
||||
Change::EncryptionSchedule(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -301,7 +301,10 @@ where
|
|||
ChangeState::Complete(kgs.change)
|
||||
} 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(self.update_key_gen(batch_epoch + 1, &change)?);
|
||||
step.extend(match change {
|
||||
Change::Add(_,_) | Change::Remove(_) => self.update_key_gen(batch_epoch + 1, &change)?,
|
||||
Change::EncryptionSchedule(_) => Step::default(), // TODO: Should this `step` contain something?
|
||||
});
|
||||
ChangeState::InProgress(change)
|
||||
} else {
|
||||
ChangeState::None
|
||||
|
@ -335,6 +338,7 @@ where
|
|||
if match *change {
|
||||
Change::Remove(ref id) => pub_keys.remove(id).is_none(),
|
||||
Change::Add(ref id, ref pk) => pub_keys.insert(id.clone(), pk.clone()).is_some(),
|
||||
_ => unreachable!(), // Unreachable by construction. Will be more clear once Change is refactored to have `NodeChange` so there won't be other variants.
|
||||
} {
|
||||
info!("{:?} No-op change: {:?}", self.our_id(), change);
|
||||
}
|
||||
|
|
|
@ -176,6 +176,7 @@ impl<N: NodeIdT> KeyGenState<N> {
|
|||
match self.change {
|
||||
Change::Add(ref id, ref pk) if id == node_id => Some(pk),
|
||||
Change::Add(_, _) | Change::Remove(_) => None,
|
||||
Change::EncryptionSchedule(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use super::HoneyBadger;
|
|||
use honey_badger::SubsetHandlingStrategy;
|
||||
use util::SubRng;
|
||||
use {Contribution, NetworkInfo, NodeIdT};
|
||||
use threshold_decryption::EncryptionSchedule;
|
||||
|
||||
/// A Honey Badger builder, to configure the parameters and create new instances of `HoneyBadger`.
|
||||
pub struct HoneyBadgerBuilder<C, N> {
|
||||
|
@ -22,6 +23,8 @@ pub struct HoneyBadgerBuilder<C, N> {
|
|||
rng: Box<dyn Rng>,
|
||||
/// Strategy used to handle the output of the `Subset` algorithm.
|
||||
subset_handling_strategy: SubsetHandlingStrategy,
|
||||
/// Schedule for adding threshold encryption to some percentage of rounds
|
||||
encryption_schedule: EncryptionSchedule,
|
||||
_phantom: PhantomData<C>,
|
||||
}
|
||||
|
||||
|
@ -39,6 +42,7 @@ where
|
|||
max_future_epochs: 3,
|
||||
rng: Box::new(rand::thread_rng()),
|
||||
subset_handling_strategy: SubsetHandlingStrategy::Incremental,
|
||||
encryption_schedule: EncryptionSchedule::Always,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +74,12 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the schedule to use for threshold encryption.
|
||||
pub fn encryption_schedule(&mut self, encryption_schedule: EncryptionSchedule) -> &mut Self {
|
||||
self.encryption_schedule = encryption_schedule;
|
||||
self
|
||||
}
|
||||
|
||||
/// Creates a new Honey Badger instance.
|
||||
pub fn build(&mut self) -> HoneyBadger<C, N> {
|
||||
HoneyBadger {
|
||||
|
@ -81,6 +91,7 @@ where
|
|||
incoming_queue: BTreeMap::new(),
|
||||
rng: Box::new(self.rng.sub_rng()),
|
||||
subset_handling_strategy: self.subset_handling_strategy.clone(),
|
||||
encryption_schedule: self.encryption_schedule,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use super::{Batch, Error, ErrorKind, HoneyBadgerBuilder, Message, MessageContent
|
|||
use {Contribution, DistAlgorithm, NetworkInfo, NodeIdT};
|
||||
|
||||
pub use super::epoch_state::SubsetHandlingStrategy;
|
||||
use threshold_decryption::EncryptionSchedule;
|
||||
|
||||
/// An instance of the Honey Badger Byzantine fault tolerant consensus algorithm.
|
||||
pub struct HoneyBadger<C, N: Rand> {
|
||||
|
@ -32,6 +33,8 @@ pub struct HoneyBadger<C, N: Rand> {
|
|||
pub(super) rng: Box<dyn Rng + Send + Sync>,
|
||||
/// Represents the optimization strategy to use for output of the `Subset` algorithm.
|
||||
pub(super) subset_handling_strategy: SubsetHandlingStrategy,
|
||||
/// The schedule for which rounds we should use threshold encryption.
|
||||
pub(super) encryption_schedule: EncryptionSchedule,
|
||||
}
|
||||
|
||||
impl<C, N> fmt::Debug for HoneyBadger<C, N>
|
||||
|
@ -48,6 +51,7 @@ where
|
|||
.field("max_future_epochs", &self.max_future_epochs)
|
||||
.field("incoming_queue", &self.incoming_queue)
|
||||
.field("rng", &"<RNG>")
|
||||
.field("encryption_schedule", &self.encryption_schedule)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,16 @@ use crypto::{self, Ciphertext, DecryptionShare};
|
|||
use fault_log::{Fault, FaultKind, FaultLog};
|
||||
use {DistAlgorithm, NetworkInfo, NodeIdT, Target};
|
||||
|
||||
/// How frequently Threshold Encryption should be used.
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Hash, Debug)]
|
||||
pub enum EncryptionSchedule {
|
||||
Always,
|
||||
Never,
|
||||
EveryNthEpoch(u32),
|
||||
/// How many with encryption, followed by how many without encryption.
|
||||
TickTock(u32, u32),
|
||||
}
|
||||
|
||||
/// A threshold decryption error.
|
||||
#[derive(Clone, Eq, PartialEq, Debug, Fail)]
|
||||
pub enum Error {
|
||||
|
|
Loading…
Reference in New Issue