Remove the random_value option.

This commit is contained in:
Andreas Fackler 2018-11-22 12:32:51 +01:00 committed by Andreas Fackler
parent a9c3f96047
commit ae37879239
13 changed files with 8 additions and 145 deletions

View File

@ -122,9 +122,9 @@
//! let mut payload: Vec<_> = vec![0; 128];
//! rng.fill_bytes(&mut payload[..]);
//!
//! // Define a function for handling one step of a `Broadcast` instance. This function appends new
//! // messages onto the message queue and checks whether each node outputs at most once and the
//! // output is correct.
//! // Define a function for handling one step of a `Broadcast` instance. This function appends
//! // new messages onto the message queue and checks whether each node outputs at most once
//! // and the output is correct.
//! let on_step = |id: u64,
//! step: Step<u64>,
//! messages: &mut VecDeque<SourcedMessage<TargetedMessage<_, _>, _>>,

View File

@ -1,8 +1,6 @@
use std::collections::BTreeMap;
use std::sync::Arc;
use crypto::Signature;
use super::{ChangeState, JoinPlan, Params};
use {NetworkInfo, NodeIdT};
@ -15,8 +13,6 @@ pub struct Batch<C, N: Ord> {
pub(super) era: u64,
/// The user contributions committed in this epoch.
pub(super) contributions: BTreeMap<N, C>,
/// The signature that can be used as a pseudorandom value.
pub(super) random_value: Option<Signature>,
/// The current state of adding or removing a node: whether any is in progress, or completed
/// this epoch.
pub(super) change: ChangeState<N>,
@ -122,15 +118,4 @@ impl<C, N: NodeIdT> Batch<C, N> {
&& self.netinfo.public_key_map() == other.netinfo.public_key_map()
&& self.params == other.params
}
/// Returns the signature that can be used as a pseudorandom value.
///
/// This value was only revealed to the validators after the set of contributions had been
/// decided. None of the validators knew it when they could still influence the contents of the
/// batch.
///
/// If the `random_value` option is `false` (default), this is `None`.
pub fn random_value(&self) -> Option<&Signature> {
self.random_value.as_ref()
}
}

View File

@ -78,12 +78,6 @@ where
self
}
/// Whether to generate a pseudorandom value in each epoch.
pub fn random_value(&mut self, random_value: bool) -> &mut Self {
self.params.random_value = random_value;
self
}
/// Sets the schedule to use for threshold encryption.
pub fn encryption_schedule(&mut self, encryption_schedule: EncryptionSchedule) -> &mut Self {
self.params.encryption_schedule = encryption_schedule;

View File

@ -364,7 +364,6 @@ where
change,
netinfo: Arc::new(self.netinfo.clone()),
contributions: batch_contributions,
random_value: hb_batch.random_value,
params: self.honey_badger.params().clone(),
});
}

View File

@ -22,8 +22,6 @@ pub enum FaultKind {
InvalidCiphertext,
/// `HoneyBadger` received a message with an invalid epoch.
UnexpectedHbMessageEpoch,
/// `HoneyBadger` received a signatures share for the random value even though it is disabled.
UnexpectedSignatureShare,
/// `ThresholdDecrypt` received multiple shares from the same sender.
MultipleDecryptionShares,
/// `Broadcast` received a `Value` from a node other than the proposer.

View File

@ -1,4 +1,3 @@
use crypto::Signature;
use std::collections::BTreeMap;
use NodeIdT;
@ -10,14 +9,6 @@ pub struct Batch<C, N> {
pub epoch: u64,
/// The set of agreed contributions, by the contributor's node ID.
pub contributions: BTreeMap<N, C>,
/// The signature that can be used as a pseudorandom value.
///
/// This value was only revealed to the validators after the set of contributions had been
/// decided. None of the validators knew it when they could still influence the contents of the
/// batch.
///
/// If the `random_value` option is `false` (default), this is `None`.
pub random_value: Option<Signature>,
}
impl<C, N: NodeIdT> Batch<C, N> {

View File

@ -79,12 +79,6 @@ where
self
}
/// Whether to generate a pseudorandom value in each epoch.
pub fn random_value(&mut self, random_value: bool) -> &mut Self {
self.params.random_value = random_value;
self
}
/// Sets the schedule to use for threshold encryption.
pub fn encryption_schedule(&mut self, encryption_schedule: EncryptionSchedule) -> &mut Self {
self.params.encryption_schedule = encryption_schedule;

View File

@ -7,7 +7,7 @@ use std::result;
use std::sync::Arc;
use bincode;
use crypto::{Ciphertext, Signature};
use crypto::Ciphertext;
use log::error;
use rand::{Rand, Rng};
use serde::{de::DeserializeOwned, Serialize};
@ -17,44 +17,10 @@ use super::{Batch, ErrorKind, MessageContent, Result, Step};
use fault_log::{Fault, FaultKind, FaultLog};
use subset::{self as cs, Subset, SubsetOutput};
use threshold_decrypt::{self as td, ThresholdDecrypt};
use threshold_sign::{self as ts, ThresholdSign};
use {Contribution, DistAlgorithm, NetworkInfo, NodeIdT};
type CsStep<N> = cs::Step<N>;
/// The status of the threshold signature for the random value.
#[derive(Debug)]
enum SigningState<N> {
/// No random value is required in this epoch.
None,
/// Signing is ongoing.
Ongoing(Box<ThresholdSign<N>>),
/// Signing is complete. This contains the signature.
Complete(Box<Signature>),
}
impl<N: NodeIdT> SigningState<N> {
/// Handles a message containing a decryption share.
fn handle_message(&mut self, sender_id: &N, msg: ts::Message) -> ts::Result<ts::Step<N>> {
match self {
SigningState::None => {
let fault_kind = FaultKind::UnexpectedSignatureShare;
Ok(Fault::new(sender_id.clone(), fault_kind).into())
}
SigningState::Ongoing(ref mut ts) => ts.handle_message(sender_id, msg),
SigningState::Complete(_) => Ok(ts::Step::default()),
}
}
/// Sends the signatures shares.
fn sign(&mut self) -> ts::Result<ts::Step<N>> {
match self {
SigningState::Ongoing(ref mut ts) => ts.sign(),
SigningState::None | SigningState::Complete(_) => Ok(ts::Step::default()),
}
}
}
/// The status of an encrypted contribution.
#[derive(Debug)]
enum DecryptionState<N> {
@ -222,8 +188,6 @@ pub struct EpochState<C, N: Rand> {
subset: SubsetState<N>,
/// The status of threshold decryption, by proposer.
decryption: BTreeMap<N, DecryptionState<N>>,
/// The status of the threshold signature for the random value.
signing: SigningState<N>,
/// Nodes found so far in `Subset` output.
accepted_proposers: BTreeSet<N>,
/// Determines the behavior upon receiving proposals from `subset`.
@ -244,26 +208,15 @@ where
hb_id: u64,
epoch: u64,
subset_handling_strategy: SubsetHandlingStrategy,
random_value: bool,
require_decryption: bool,
) -> Result<Self> {
let epoch_id = EpochId { hb_id, epoch };
let cs = Subset::new(netinfo.clone(), epoch_id).map_err(ErrorKind::CreateSubset)?;
let signing = if random_value {
let rand_id = ("random_value", hb_id, epoch);
let doc = bincode::serialize(&rand_id).map_err(|err| ErrorKind::RandBincode(*err))?;
let ts = ThresholdSign::new_with_document(netinfo.clone(), doc)
.map_err(ErrorKind::CreateThresholdSign)?;
SigningState::Ongoing(Box::new(ts))
} else {
SigningState::None
};
Ok(EpochState {
epoch,
netinfo,
subset: SubsetState::Ongoing(cs),
decryption: BTreeMap::default(),
signing,
accepted_proposers: Default::default(),
subset_handler: subset_handling_strategy.into(),
require_decryption,
@ -321,24 +274,12 @@ where
.map_err(ErrorKind::ThresholdDecrypt)?;
self.process_decryption(proposer_id, td_step)
}
MessageContent::SignatureShare(share) => {
let ts_step = self
.signing
.handle_message(sender_id, share)
.map_err(ErrorKind::ThresholdSign)?;
self.process_signing(ts_step)
}
}
}
/// When contributions of transactions have been decrypted for all valid proposers in this
/// epoch, moves those contributions into a batch, outputs the batch and updates the epoch.
pub fn try_output_batch(&self) -> Option<(Batch<C, N>, FaultLog<N>)> {
let random_value = match &self.signing {
SigningState::None => None,
SigningState::Ongoing(_) => return None,
SigningState::Complete(signature) => Some(*signature.clone()),
};
let proposer_ids = self.subset.accepted_ids()?;
let mut plaintexts = Vec::new();
// Collect accepted plaintexts. Return if some are not decrypted yet.
@ -353,7 +294,6 @@ where
let mut batch = Batch {
epoch: self.epoch,
contributions: BTreeMap::new(),
random_value,
};
// Deserialize the output. If it fails, the proposer of that item is faulty.
for (id, plaintext) in plaintexts {
@ -397,8 +337,6 @@ where
}
if is_done {
let ts_state = self.signing.sign().map_err(ErrorKind::ThresholdSign)?;
step.extend(self.process_signing(ts_state)?);
self.subset = SubsetState::Complete(self.accepted_proposers.clone());
let faulty_shares: Vec<_> = self
.decryption
@ -436,18 +374,6 @@ where
Ok(step)
}
/// Processes a Threshold Sign step.
fn process_signing(&mut self, ts_step: ts::Step<N>) -> Result<Step<C, N>> {
let mut step = Step::default();
let opt_output = step.extend_with(ts_step, |share| {
MessageContent::SignatureShare(share).with_epoch(self.epoch)
});
if let Some(output) = opt_output.into_iter().next() {
self.signing = SigningState::Complete(Box::new(output));
}
Ok(step)
}
/// Given the output of the Subset algorithm, inputs the ciphertexts into the Threshold
/// Decrypt instances and sends our own decryption shares.
fn send_decryption_share(&mut self, proposer_id: N, v: &[u8]) -> Result<Step<C, N>> {

View File

@ -5,27 +5,20 @@ use failure::{Backtrace, Context, Fail};
use subset;
use threshold_decrypt;
use threshold_sign;
/// Honey badger error variants.
#[derive(Debug, Fail)]
pub enum ErrorKind {
#[fail(display = "ProposeBincode error: {}", _0)]
ProposeBincode(bincode::ErrorKind),
#[fail(display = "Error serializing random value document: {}", _0)]
RandBincode(bincode::ErrorKind),
#[fail(display = "Failed to instantiate Subset: {}", _0)]
CreateSubset(subset::Error),
#[fail(display = "Failed to instantiate ThresholdSign: {}", _0)]
CreateThresholdSign(threshold_sign::Error),
#[fail(display = "Failed to input contribution to Subset: {}", _0)]
InputSubset(subset::Error),
#[fail(display = "Failed to handle Subset message: {}", _0)]
HandleSubsetMessage(subset::Error),
#[fail(display = "Threshold decryption error: {}", _0)]
ThresholdDecrypt(threshold_decrypt::Error),
#[fail(display = "Threshold signing error: {}", _0)]
ThresholdSign(threshold_sign::Error),
#[fail(display = "Unknown sender")]
UnknownSender,
}

View File

@ -181,7 +181,6 @@ where
self.session_id,
epoch,
self.params.subset_handling_strategy.clone(),
self.params.random_value,
self.params.encryption_schedule.use_on_epoch(epoch),
)?),
})

View File

@ -4,7 +4,6 @@ use serde_derive::{Deserialize, Serialize};
use subset;
use threshold_decrypt;
use threshold_sign;
/// The content of a `HoneyBadger` message. It should be further annotated with an epoch.
#[derive(Clone, Debug, Deserialize, Rand, Serialize)]
@ -18,8 +17,6 @@ pub enum MessageContent<N: Rand> {
proposer_id: N,
share: threshold_decrypt::Message,
},
/// A share of the signature used as a pseudorandom value.
SignatureShare(threshold_sign::Message),
}
impl<N: Rand> MessageContent<N> {

View File

@ -9,8 +9,6 @@ pub struct Params {
pub max_future_epochs: u64,
/// Strategy used to handle the output of the `Subset` algorithm.
pub subset_handling_strategy: SubsetHandlingStrategy,
/// Whether to generate a pseudorandom value in each epoch.
pub random_value: bool,
/// Schedule for adding threshold encryption to some percentage of rounds
pub encryption_schedule: EncryptionSchedule,
}
@ -20,7 +18,6 @@ impl Default for Params {
Params {
max_future_epochs: 3,
subset_handling_strategy: SubsetHandlingStrategy::Incremental,
random_value: false,
encryption_schedule: EncryptionSchedule::Always,
}
}

View File

@ -21,7 +21,6 @@ use itertools::Itertools;
use log::info;
use rand::Rng;
use hbbft::crypto::Signature;
use hbbft::honey_badger::{Batch, EncryptionSchedule, HoneyBadger, MessageContent};
use hbbft::sender_queue::{self, SenderQueue, Step};
use hbbft::transaction_queue::TransactionQueue;
@ -164,22 +163,14 @@ fn verify_output_sequence<A>(network: &TestNetwork<A, UsizeHoneyBadger>)
where
A: Adversary<UsizeHoneyBadger>,
{
let mut expected: Option<BTreeMap<&_, (&_, &_)>> = None;
let mut expected: Option<BTreeMap<u64, &_>> = None;
for node in network.nodes.values() {
assert!(!node.outputs().is_empty());
let outputs: BTreeMap<&u64, (&BTreeMap<NodeId, Vec<usize>>, &Signature)> = node
let outputs: BTreeMap<u64, &BTreeMap<NodeId, Vec<usize>>> = node
.outputs()
.iter()
.map(
|Batch {
epoch,
contributions,
random_value,
}| {
let random_value = random_value.as_ref().expect("missing random value");
(epoch, (contributions, random_value))
},
).collect();
.map(|batch| (batch.epoch, &batch.contributions))
.collect();
if expected.is_none() {
expected = Some(outputs);
} else if let Some(expected) = &expected {
@ -201,7 +192,6 @@ fn new_honey_badger(
.chain(iter::once(observer));
let hb = HoneyBadger::builder(netinfo)
.encryption_schedule(EncryptionSchedule::EveryNthEpoch(2))
.random_value(true)
.build();
SenderQueue::builder(hb, peer_ids).build(our_id)
}