mirror of https://github.com/poanetwork/hbbft.git
Split up messaging module.
This commit is contained in:
parent
4cc35587c7
commit
8d1361e6ae
|
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
|||
use std::io;
|
||||
use std::net::TcpStream;
|
||||
|
||||
use hbbft::messaging::SourcedMessage;
|
||||
use hbbft::SourcedMessage;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
use crossbeam::{Scope, ScopedJoinHandle};
|
||||
use crossbeam_channel;
|
||||
use crossbeam_channel::{bounded, unbounded, Receiver, Sender};
|
||||
use hbbft::messaging::{SourcedMessage, Target, TargetedMessage};
|
||||
use hbbft::{SourcedMessage, Target, TargetedMessage};
|
||||
|
||||
/// The queue functionality for messages sent between algorithm instances.
|
||||
/// The messaging struct allows for targeted message exchange between comms
|
||||
|
|
|
@ -46,10 +46,9 @@ use crypto::poly::Poly;
|
|||
use crypto::{SecretKey, SecretKeySet};
|
||||
|
||||
use hbbft::broadcast::{Broadcast, Message};
|
||||
use hbbft::messaging::{DistAlgorithm, NetworkInfo, SourcedMessage};
|
||||
use network::commst;
|
||||
use network::connection;
|
||||
use hbbft::{DistAlgorithm, NetworkInfo, SourcedMessage};
|
||||
use network::messaging::Messaging;
|
||||
use network::{commst, connection};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
|
|
@ -25,8 +25,8 @@ use serde::Serialize;
|
|||
use signifix::{metric, TryFrom};
|
||||
|
||||
use hbbft::dynamic_honey_badger::DynamicHoneyBadger;
|
||||
use hbbft::messaging::{DistAlgorithm, NetworkInfo, Step, Target};
|
||||
use hbbft::queueing_honey_badger::{Batch, QueueingHoneyBadger};
|
||||
use hbbft::{DistAlgorithm, NetworkInfo, Step, Target};
|
||||
|
||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
const USAGE: &str = "
|
||||
|
|
|
@ -6,8 +6,7 @@ use super::bool_set::BoolSet;
|
|||
use super::sbv_broadcast::{self, SbvBroadcast};
|
||||
use super::{Error, Message, MessageContent, Nonce, Result, Step};
|
||||
use coin::{self, Coin, CoinMessage};
|
||||
use messaging::{DistAlgorithm, NetworkInfo, Target};
|
||||
use traits::NodeIdT;
|
||||
use {DistAlgorithm, NetworkInfo, NodeIdT, Target};
|
||||
|
||||
/// The state of the current epoch's coin. In some epochs this is fixed, in others it starts
|
||||
/// with in `InProgress`.
|
||||
|
|
|
@ -72,7 +72,6 @@ use rand;
|
|||
|
||||
use self::bool_set::BoolSet;
|
||||
use coin::{self, CoinMessage};
|
||||
use messaging;
|
||||
|
||||
pub use self::binary_agreement::BinaryAgreement;
|
||||
|
||||
|
@ -92,7 +91,7 @@ pub enum Error {
|
|||
/// An Binary Agreement result.
|
||||
pub type Result<T> = ::std::result::Result<T, Error>;
|
||||
|
||||
pub type Step<N> = messaging::Step<BinaryAgreement<N>>;
|
||||
pub type Step<N> = ::Step<BinaryAgreement<N>>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
pub enum MessageContent {
|
||||
|
|
|
@ -16,10 +16,9 @@ use super::bool_multimap::BoolMultimap;
|
|||
use super::bool_set::{self, BoolSet};
|
||||
use super::{Error, Result};
|
||||
use fault_log::{Fault, FaultKind};
|
||||
use messaging::{self, DistAlgorithm, NetworkInfo, Target};
|
||||
use traits::NodeIdT;
|
||||
use {DistAlgorithm, NetworkInfo, NodeIdT, Target};
|
||||
|
||||
pub type Step<N> = messaging::Step<SbvBroadcast<N>>;
|
||||
pub type Step<N> = ::Step<SbvBroadcast<N>>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||
pub enum Message {
|
||||
|
|
|
@ -11,8 +11,7 @@ use super::merkle::{Digest, MerkleTree, Proof};
|
|||
use super::{Error, Result};
|
||||
use fault_log::{Fault, FaultKind};
|
||||
use fmt::{HexBytes, HexList, HexProof};
|
||||
use messaging::{self, DistAlgorithm, NetworkInfo, Target};
|
||||
use traits::NodeIdT;
|
||||
use {DistAlgorithm, NetworkInfo, NodeIdT, Target};
|
||||
|
||||
/// The three kinds of message sent during the reliable broadcast stage of the
|
||||
/// consensus algorithm.
|
||||
|
@ -77,7 +76,7 @@ pub struct Broadcast<N> {
|
|||
readys: BTreeMap<N, Vec<u8>>,
|
||||
}
|
||||
|
||||
pub type Step<N> = messaging::Step<Broadcast<N>>;
|
||||
pub type Step<N> = ::Step<Broadcast<N>>;
|
||||
|
||||
impl<N: NodeIdT> DistAlgorithm for Broadcast<N> {
|
||||
type NodeId = N;
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
//! extern crate rand;
|
||||
//!
|
||||
//! use hbbft::broadcast::{Broadcast, Error, Step};
|
||||
//! use hbbft::messaging::{DistAlgorithm, NetworkInfo, SourcedMessage, Target, TargetedMessage};
|
||||
//! use hbbft::{DistAlgorithm, NetworkInfo, SourcedMessage, Target, TargetedMessage};
|
||||
//! use rand::{thread_rng, Rng};
|
||||
//! use std::collections::{BTreeMap, BTreeSet, VecDeque};
|
||||
//! use std::iter::once;
|
||||
|
|
10
src/coin.rs
10
src/coin.rs
|
@ -24,17 +24,15 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crypto::error as cerror;
|
||||
use crypto::{Signature, SignatureShare};
|
||||
use crypto::{self, Signature, SignatureShare};
|
||||
use fault_log::{Fault, FaultKind};
|
||||
use messaging::{self, DistAlgorithm, NetworkInfo, Target};
|
||||
use traits::NodeIdT;
|
||||
use {DistAlgorithm, NetworkInfo, NodeIdT, Target};
|
||||
|
||||
/// A coin error.
|
||||
#[derive(Clone, Eq, PartialEq, Debug, Fail)]
|
||||
pub enum Error {
|
||||
#[fail(display = "CombineAndVerifySigCrypto error: {}", _0)]
|
||||
CombineAndVerifySigCrypto(cerror::Error),
|
||||
CombineAndVerifySigCrypto(crypto::error::Error),
|
||||
#[fail(display = "Unknown sender")]
|
||||
UnknownSender,
|
||||
#[fail(display = "Signature verification failed")]
|
||||
|
@ -73,7 +71,7 @@ pub struct Coin<N, T> {
|
|||
terminated: bool,
|
||||
}
|
||||
|
||||
pub type Step<N, T> = messaging::Step<Coin<N, T>>;
|
||||
pub type Step<N, T> = ::Step<Coin<N, T>>;
|
||||
|
||||
impl<N, T> DistAlgorithm for Coin<N, T>
|
||||
where
|
||||
|
|
|
@ -4,8 +4,7 @@ use std::sync::Arc;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{ChangeState, JoinPlan};
|
||||
use messaging::NetworkInfo;
|
||||
use traits::NodeIdT;
|
||||
use {NetworkInfo, NodeIdT};
|
||||
|
||||
/// A batch of transactions the algorithm has output.
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -9,9 +9,8 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use super::{ChangeState, DynamicHoneyBadger, JoinPlan, Result, Step, VoteCounter};
|
||||
use honey_badger::{HoneyBadger, SubsetHandlingStrategy};
|
||||
use messaging::NetworkInfo;
|
||||
use traits::{Contribution, NodeIdT};
|
||||
use util::SubRng;
|
||||
use {Contribution, NetworkInfo, NodeIdT};
|
||||
|
||||
/// A Dynamic Honey Badger builder, to configure the parameters and create new instances of
|
||||
/// `DynamicHoneyBadger`.
|
||||
|
|
|
@ -14,10 +14,9 @@ use super::{
|
|||
};
|
||||
use fault_log::{Fault, FaultKind, FaultLog};
|
||||
use honey_badger::{self, HoneyBadger, Message as HbMessage};
|
||||
use messaging::{DistAlgorithm, NetworkInfo, Target};
|
||||
use sync_key_gen::{Ack, Part, PartOutcome, SyncKeyGen};
|
||||
use traits::{Contribution, NodeIdT};
|
||||
use util::SubRng;
|
||||
use {Contribution, DistAlgorithm, NetworkInfo, NodeIdT, Target};
|
||||
|
||||
/// A Honey Badger instance that can handle adding and removing nodes.
|
||||
pub struct DynamicHoneyBadger<C, N: Rand> {
|
||||
|
|
|
@ -68,9 +68,8 @@ use std::collections::BTreeMap;
|
|||
|
||||
use self::votes::{SignedVote, VoteCounter};
|
||||
use honey_badger::Message as HbMessage;
|
||||
use messaging;
|
||||
use sync_key_gen::{Ack, Part, SyncKeyGen};
|
||||
use traits::NodeIdT;
|
||||
use NodeIdT;
|
||||
|
||||
pub use self::batch::Batch;
|
||||
pub use self::builder::DynamicHoneyBadgerBuilder;
|
||||
|
@ -78,7 +77,7 @@ pub use self::change::{Change, ChangeState};
|
|||
pub use self::dynamic_honey_badger::DynamicHoneyBadger;
|
||||
pub use self::error::{Error, ErrorKind, Result};
|
||||
|
||||
pub type Step<C, N> = messaging::Step<DynamicHoneyBadger<C, N>>;
|
||||
pub type Step<C, N> = ::Step<DynamicHoneyBadger<C, N>>;
|
||||
|
||||
/// The user input for `DynamicHoneyBadger`.
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -7,8 +7,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use super::{Change, ErrorKind, Result};
|
||||
use fault_log::{FaultKind, FaultLog};
|
||||
use messaging::NetworkInfo;
|
||||
use traits::NodeIdT;
|
||||
use {NetworkInfo, NodeIdT};
|
||||
|
||||
/// A buffer and counter collecting pending and committed votes for validator set changes.
|
||||
///
|
||||
|
@ -192,7 +191,7 @@ mod tests {
|
|||
|
||||
use super::{Change, SignedVote, VoteCounter};
|
||||
use fault_log::{FaultKind, FaultLog};
|
||||
use messaging::NetworkInfo;
|
||||
use NetworkInfo;
|
||||
|
||||
/// Returns a vector of `node_num` `VoteCounter`s, and some signed example votes.
|
||||
///
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use traits::NodeIdT;
|
||||
use NodeIdT;
|
||||
|
||||
/// A batch of contributions the algorithm has output.
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -7,9 +7,8 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use super::HoneyBadger;
|
||||
use honey_badger::SubsetHandlingStrategy;
|
||||
use messaging::NetworkInfo;
|
||||
use traits::{Contribution, NodeIdT};
|
||||
use util::SubRng;
|
||||
use {Contribution, NetworkInfo, NodeIdT};
|
||||
|
||||
/// A Honey Badger builder, to configure the parameters and create new instances of `HoneyBadger`.
|
||||
pub struct HoneyBadgerBuilder<C, N> {
|
||||
|
|
|
@ -11,10 +11,9 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use super::{Batch, ErrorKind, MessageContent, Result, Step};
|
||||
use fault_log::{Fault, FaultKind, FaultLog};
|
||||
use messaging::{DistAlgorithm, NetworkInfo};
|
||||
use subset::{self as cs, Subset, SubsetOutput};
|
||||
use threshold_decryption::{self as td, ThresholdDecryption};
|
||||
use traits::{Contribution, NodeIdT};
|
||||
use {Contribution, DistAlgorithm, NetworkInfo, NodeIdT};
|
||||
|
||||
/// The status of an encrypted contribution.
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -9,8 +9,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use super::epoch_state::EpochState;
|
||||
use super::{Batch, Error, ErrorKind, HoneyBadgerBuilder, Message, MessageContent, Result};
|
||||
use messaging::{self, DistAlgorithm, NetworkInfo};
|
||||
use traits::{Contribution, NodeIdT};
|
||||
use {Contribution, DistAlgorithm, NetworkInfo, NodeIdT};
|
||||
|
||||
pub use super::epoch_state::SubsetHandlingStrategy;
|
||||
|
||||
|
@ -53,7 +52,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub type Step<C, N> = messaging::Step<HoneyBadger<C, N>>;
|
||||
pub type Step<C, N> = ::Step<HoneyBadger<C, N>>;
|
||||
|
||||
impl<C, N> DistAlgorithm for HoneyBadger<C, N>
|
||||
where
|
||||
|
|
24
src/lib.rs
24
src/lib.rs
|
@ -143,28 +143,16 @@ pub mod dynamic_honey_badger;
|
|||
pub mod fault_log;
|
||||
mod fmt;
|
||||
pub mod honey_badger;
|
||||
pub mod messaging;
|
||||
mod messaging;
|
||||
mod network_info;
|
||||
pub mod queueing_honey_badger;
|
||||
pub mod subset;
|
||||
pub mod sync_key_gen;
|
||||
pub mod threshold_decryption;
|
||||
mod traits;
|
||||
pub mod transaction_queue;
|
||||
pub mod util;
|
||||
|
||||
/// Common supertraits.
|
||||
pub mod traits {
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
/// A transaction, user message, etc.
|
||||
pub trait Contribution: Eq + Debug + Hash + Send + Sync {}
|
||||
impl<C> Contribution for C where C: Eq + Debug + Hash + Send + Sync {}
|
||||
|
||||
/// A peer node's unique identifier.
|
||||
pub trait NodeIdT: Eq + Ord + Clone + Debug + Hash + Send + Sync {}
|
||||
impl<N> NodeIdT for N where N: Eq + Ord + Clone + Debug + Hash + Send + Sync {}
|
||||
|
||||
/// Messages.
|
||||
pub trait Message: Debug + Send + Sync {}
|
||||
impl<M> Message for M where M: Debug + Send + Sync {}
|
||||
}
|
||||
pub use messaging::{SourcedMessage, Target, TargetedMessage};
|
||||
pub use network_info::NetworkInfo;
|
||||
pub use traits::{Contribution, DistAlgorithm, Message, NodeIdT, Step};
|
||||
|
|
359
src/messaging.rs
359
src/messaging.rs
|
@ -1,13 +1,3 @@
|
|||
use std::collections::{BTreeMap, BTreeSet, VecDeque};
|
||||
use std::iter::once;
|
||||
|
||||
use failure::Fail;
|
||||
use rand;
|
||||
|
||||
use crypto::{self, PublicKey, PublicKeySet, PublicKeyShare, SecretKey, SecretKeyShare};
|
||||
use fault_log::{Fault, FaultLog};
|
||||
use traits::{Message, NodeIdT};
|
||||
|
||||
/// Message sent by a given source.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SourcedMessage<M, N> {
|
||||
|
@ -52,352 +42,3 @@ impl<M, N> TargetedMessage<M, N> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Result of one step of the local state machine of a distributed algorithm. Such a result should
|
||||
/// be used and never discarded by the client of the algorithm.
|
||||
#[must_use = "The algorithm step result must be used."]
|
||||
#[derive(Debug)]
|
||||
pub struct Step<D>
|
||||
where
|
||||
D: DistAlgorithm,
|
||||
<D as DistAlgorithm>::NodeId: NodeIdT,
|
||||
{
|
||||
pub output: VecDeque<D::Output>,
|
||||
pub fault_log: FaultLog<D::NodeId>,
|
||||
pub messages: VecDeque<TargetedMessage<D::Message, D::NodeId>>,
|
||||
}
|
||||
|
||||
impl<D> Default for Step<D>
|
||||
where
|
||||
D: DistAlgorithm,
|
||||
<D as DistAlgorithm>::NodeId: NodeIdT,
|
||||
{
|
||||
fn default() -> Step<D> {
|
||||
Step {
|
||||
output: VecDeque::default(),
|
||||
fault_log: FaultLog::default(),
|
||||
messages: VecDeque::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DistAlgorithm> Step<D>
|
||||
where
|
||||
<D as DistAlgorithm>::NodeId: NodeIdT,
|
||||
{
|
||||
/// Creates a new `Step` from the given collections.
|
||||
pub fn new(
|
||||
output: VecDeque<D::Output>,
|
||||
fault_log: FaultLog<D::NodeId>,
|
||||
messages: VecDeque<TargetedMessage<D::Message, D::NodeId>>,
|
||||
) -> Self {
|
||||
Step {
|
||||
output,
|
||||
fault_log,
|
||||
messages,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the same step, with the given additional output.
|
||||
pub fn with_output(mut self, output: D::Output) -> Self {
|
||||
self.output.push_back(output);
|
||||
self
|
||||
}
|
||||
|
||||
/// Converts `self` into a step of another type, given conversion methods for output and
|
||||
/// messages.
|
||||
pub fn map<D2, FO, FM>(self, f_out: FO, f_msg: FM) -> Step<D2>
|
||||
where
|
||||
D2: DistAlgorithm<NodeId = D::NodeId>,
|
||||
FO: Fn(D::Output) -> D2::Output,
|
||||
FM: Fn(D::Message) -> D2::Message,
|
||||
{
|
||||
Step {
|
||||
output: self.output.into_iter().map(f_out).collect(),
|
||||
fault_log: self.fault_log,
|
||||
messages: self.messages.into_iter().map(|tm| tm.map(&f_msg)).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Extends `self` with `other`s messages and fault logs, and returns `other.output`.
|
||||
pub fn extend_with<D2, FM>(&mut self, other: Step<D2>, f_msg: FM) -> VecDeque<D2::Output>
|
||||
where
|
||||
D2: DistAlgorithm<NodeId = D::NodeId>,
|
||||
FM: Fn(D2::Message) -> D::Message,
|
||||
{
|
||||
self.fault_log.extend(other.fault_log);
|
||||
let msgs = other.messages.into_iter().map(|tm| tm.map(&f_msg));
|
||||
self.messages.extend(msgs);
|
||||
other.output
|
||||
}
|
||||
|
||||
/// Adds the outputs, fault logs and messages of `other` to `self`.
|
||||
pub fn extend(&mut self, other: Self) {
|
||||
self.output.extend(other.output);
|
||||
self.fault_log.extend(other.fault_log);
|
||||
self.messages.extend(other.messages);
|
||||
}
|
||||
|
||||
/// Converts this step into an equivalent step for a different `DistAlgorithm`.
|
||||
// This cannot be a `From` impl, because it would conflict with `impl From<T> for T`.
|
||||
pub fn convert<D2>(self) -> Step<D2>
|
||||
where
|
||||
D2: DistAlgorithm<NodeId = D::NodeId, Output = D::Output, Message = D::Message>,
|
||||
{
|
||||
Step {
|
||||
output: self.output,
|
||||
fault_log: self.fault_log,
|
||||
messages: self.messages,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if there are now messages, faults or outputs.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.output.is_empty() && self.fault_log.is_empty() && self.messages.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DistAlgorithm> From<FaultLog<D::NodeId>> for Step<D> {
|
||||
fn from(fault_log: FaultLog<D::NodeId>) -> Self {
|
||||
Step {
|
||||
fault_log,
|
||||
..Step::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DistAlgorithm> From<Fault<D::NodeId>> for Step<D> {
|
||||
fn from(fault: Fault<D::NodeId>) -> Self {
|
||||
Step {
|
||||
fault_log: fault.into(),
|
||||
..Step::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DistAlgorithm> From<TargetedMessage<D::Message, D::NodeId>> for Step<D> {
|
||||
fn from(msg: TargetedMessage<D::Message, D::NodeId>) -> Self {
|
||||
Step {
|
||||
messages: once(msg).collect(),
|
||||
..Step::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A distributed algorithm that defines a message flow.
|
||||
pub trait DistAlgorithm: Send + Sync {
|
||||
/// Unique node identifier.
|
||||
type NodeId: NodeIdT;
|
||||
/// The input provided by the user.
|
||||
type Input;
|
||||
/// The output type. Some algorithms return an output exactly once, others return multiple
|
||||
/// times.
|
||||
type Output;
|
||||
/// The messages that need to be exchanged between the instances in the participating nodes.
|
||||
type Message: Message;
|
||||
/// The errors that can occur during execution.
|
||||
type Error: Fail;
|
||||
|
||||
/// Handles an input provided by the user, and returns
|
||||
fn handle_input(&mut self, input: Self::Input) -> Result<Step<Self>, Self::Error>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Handles a message received from node `sender_id`.
|
||||
fn handle_message(
|
||||
&mut self,
|
||||
sender_id: &Self::NodeId,
|
||||
message: Self::Message,
|
||||
) -> Result<Step<Self>, Self::Error>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Returns `true` if execution has completed and this instance can be dropped.
|
||||
fn terminated(&self) -> bool;
|
||||
|
||||
/// Returns this node's own ID.
|
||||
fn our_id(&self) -> &Self::NodeId;
|
||||
}
|
||||
|
||||
/// Common data shared between algorithms: the nodes' IDs and key shares.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NetworkInfo<N> {
|
||||
our_id: N,
|
||||
num_nodes: usize,
|
||||
num_faulty: usize,
|
||||
is_validator: bool,
|
||||
// TODO: Should this be an option? It only makes sense for validators.
|
||||
secret_key_share: SecretKeyShare,
|
||||
secret_key: SecretKey,
|
||||
public_key_set: PublicKeySet,
|
||||
public_key_shares: BTreeMap<N, PublicKeyShare>,
|
||||
public_keys: BTreeMap<N, PublicKey>,
|
||||
node_indices: BTreeMap<N, usize>,
|
||||
}
|
||||
|
||||
impl<N: NodeIdT> NetworkInfo<N> {
|
||||
pub fn new(
|
||||
our_id: N,
|
||||
secret_key_share: SecretKeyShare,
|
||||
public_key_set: PublicKeySet,
|
||||
secret_key: SecretKey,
|
||||
public_keys: BTreeMap<N, PublicKey>,
|
||||
) -> Self {
|
||||
let num_nodes = public_keys.len();
|
||||
let is_validator = public_keys.contains_key(&our_id);
|
||||
let node_indices: BTreeMap<N, usize> = public_keys
|
||||
.keys()
|
||||
.enumerate()
|
||||
.map(|(n, id)| (id.clone(), n))
|
||||
.collect();
|
||||
let public_key_shares = node_indices
|
||||
.iter()
|
||||
.map(|(id, idx)| (id.clone(), public_key_set.public_key_share(*idx)))
|
||||
.collect();
|
||||
NetworkInfo {
|
||||
our_id,
|
||||
num_nodes,
|
||||
num_faulty: (num_nodes - 1) / 3,
|
||||
is_validator,
|
||||
secret_key_share,
|
||||
secret_key,
|
||||
public_key_set,
|
||||
public_key_shares,
|
||||
node_indices,
|
||||
public_keys,
|
||||
}
|
||||
}
|
||||
|
||||
/// The ID of the node the algorithm runs on.
|
||||
pub fn our_id(&self) -> &N {
|
||||
&self.our_id
|
||||
}
|
||||
|
||||
/// ID of all nodes in the network.
|
||||
pub fn all_ids(&self) -> impl Iterator<Item = &N> {
|
||||
self.public_keys.keys()
|
||||
}
|
||||
|
||||
/// The total number _N_ of nodes.
|
||||
pub fn num_nodes(&self) -> usize {
|
||||
self.num_nodes
|
||||
}
|
||||
|
||||
/// The maximum number _f_ of faulty, Byzantine nodes up to which Honey Badger is guaranteed to
|
||||
/// be correct.
|
||||
pub fn num_faulty(&self) -> usize {
|
||||
self.num_faulty
|
||||
}
|
||||
|
||||
/// The minimum number _N - f_ of correct nodes with which Honey Badger is guaranteed to be
|
||||
/// correct.
|
||||
pub fn num_correct(&self) -> usize {
|
||||
self.num_nodes - self.num_faulty
|
||||
}
|
||||
|
||||
/// Returns our secret key share for threshold cryptography.
|
||||
pub fn secret_key_share(&self) -> &SecretKeyShare {
|
||||
&self.secret_key_share
|
||||
}
|
||||
|
||||
/// Returns our secret key for encryption and signing.
|
||||
pub fn secret_key(&self) -> &SecretKey {
|
||||
&self.secret_key
|
||||
}
|
||||
|
||||
/// Returns the public key set for threshold cryptography.
|
||||
pub fn public_key_set(&self) -> &PublicKeySet {
|
||||
&self.public_key_set
|
||||
}
|
||||
|
||||
/// Returns the public key share if a node with that ID exists, otherwise `None`.
|
||||
pub fn public_key_share(&self, id: &N) -> Option<&PublicKeyShare> {
|
||||
self.public_key_shares.get(id)
|
||||
}
|
||||
|
||||
/// Returns a map of all node IDs to their public key shares.
|
||||
pub fn public_key_share_map(&self) -> &BTreeMap<N, PublicKeyShare> {
|
||||
&self.public_key_shares
|
||||
}
|
||||
|
||||
/// Returns a map of all node IDs to their public keys.
|
||||
pub fn public_key(&self, id: &N) -> Option<&PublicKey> {
|
||||
self.public_keys.get(id)
|
||||
}
|
||||
|
||||
/// Returns a map of all node IDs to their public keys.
|
||||
pub fn public_key_map(&self) -> &BTreeMap<N, PublicKey> {
|
||||
&self.public_keys
|
||||
}
|
||||
|
||||
/// The index of a node in a canonical numbering of all nodes.
|
||||
pub fn node_index(&self, id: &N) -> Option<usize> {
|
||||
self.node_indices.get(id).cloned()
|
||||
}
|
||||
|
||||
/// Returns the unique ID of the Honey Badger invocation.
|
||||
///
|
||||
/// FIXME: Using the public key as the invocation ID either requires agreeing on the keys on
|
||||
/// each invocation, or makes it unsafe to reuse keys for different invocations. A better
|
||||
/// invocation ID would be one that is distributed to all nodes on each invocation and would be
|
||||
/// independent from the public key, so that reusing keys would be safer.
|
||||
pub fn invocation_id(&self) -> Vec<u8> {
|
||||
self.public_key_set.public_key().to_bytes()
|
||||
}
|
||||
|
||||
/// Returns `true` if this node takes part in the consensus itself. If not, it is only an
|
||||
/// observer.
|
||||
pub fn is_validator(&self) -> bool {
|
||||
self.is_validator
|
||||
}
|
||||
|
||||
/// Returns `true` if the given node takes part in the consensus itself. If not, it is only an
|
||||
/// observer.
|
||||
pub fn is_node_validator(&self, id: &N) -> bool {
|
||||
self.public_keys.contains_key(id)
|
||||
}
|
||||
|
||||
/// Generates a map of matching `NetworkInfo`s for testing.
|
||||
pub fn generate_map<I, R>(
|
||||
ids: I,
|
||||
rng: &mut R,
|
||||
) -> Result<BTreeMap<N, NetworkInfo<N>>, crypto::error::Error>
|
||||
where
|
||||
I: IntoIterator<Item = N>,
|
||||
R: rand::Rng,
|
||||
{
|
||||
use crypto::SecretKeySet;
|
||||
|
||||
let all_ids: BTreeSet<N> = ids.into_iter().collect();
|
||||
let num_faulty = (all_ids.len() - 1) / 3;
|
||||
|
||||
// Generate the keys for threshold cryptography.
|
||||
let sk_set = SecretKeySet::random(num_faulty, rng)?;
|
||||
let pk_set = sk_set.public_keys();
|
||||
|
||||
// Generate keys for individually signing and encrypting messages.
|
||||
let sec_keys: BTreeMap<_, SecretKey> =
|
||||
all_ids.iter().map(|id| (id.clone(), rng.gen())).collect();
|
||||
let pub_keys: BTreeMap<_, PublicKey> = sec_keys
|
||||
.iter()
|
||||
.map(|(id, sk)| (id.clone(), sk.public_key()))
|
||||
.collect();
|
||||
|
||||
// Create the corresponding `NetworkInfo` for each node.
|
||||
let create_netinfo = |(i, id): (usize, N)| {
|
||||
let netinfo = NetworkInfo::new(
|
||||
id.clone(),
|
||||
sk_set.secret_key_share(i)?,
|
||||
pk_set.clone(),
|
||||
sec_keys[&id].clone(),
|
||||
pub_keys.clone(),
|
||||
);
|
||||
Ok((id, netinfo))
|
||||
};
|
||||
all_ids
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(create_netinfo)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use crypto::{self, PublicKey, PublicKeySet, PublicKeyShare, SecretKey, SecretKeyShare};
|
||||
use rand;
|
||||
|
||||
use NodeIdT;
|
||||
|
||||
/// Common data shared between algorithms: the nodes' IDs and key shares.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NetworkInfo<N> {
|
||||
our_id: N,
|
||||
num_nodes: usize,
|
||||
num_faulty: usize,
|
||||
is_validator: bool,
|
||||
// TODO: Should this be an option? It only makes sense for validators.
|
||||
secret_key_share: SecretKeyShare,
|
||||
secret_key: SecretKey,
|
||||
public_key_set: PublicKeySet,
|
||||
public_key_shares: BTreeMap<N, PublicKeyShare>,
|
||||
public_keys: BTreeMap<N, PublicKey>,
|
||||
node_indices: BTreeMap<N, usize>,
|
||||
}
|
||||
|
||||
impl<N: NodeIdT> NetworkInfo<N> {
|
||||
pub fn new(
|
||||
our_id: N,
|
||||
secret_key_share: SecretKeyShare,
|
||||
public_key_set: PublicKeySet,
|
||||
secret_key: SecretKey,
|
||||
public_keys: BTreeMap<N, PublicKey>,
|
||||
) -> Self {
|
||||
let num_nodes = public_keys.len();
|
||||
let is_validator = public_keys.contains_key(&our_id);
|
||||
let node_indices: BTreeMap<N, usize> = public_keys
|
||||
.keys()
|
||||
.enumerate()
|
||||
.map(|(n, id)| (id.clone(), n))
|
||||
.collect();
|
||||
let public_key_shares = node_indices
|
||||
.iter()
|
||||
.map(|(id, idx)| (id.clone(), public_key_set.public_key_share(*idx)))
|
||||
.collect();
|
||||
NetworkInfo {
|
||||
our_id,
|
||||
num_nodes,
|
||||
num_faulty: (num_nodes - 1) / 3,
|
||||
is_validator,
|
||||
secret_key_share,
|
||||
secret_key,
|
||||
public_key_set,
|
||||
public_key_shares,
|
||||
node_indices,
|
||||
public_keys,
|
||||
}
|
||||
}
|
||||
|
||||
/// The ID of the node the algorithm runs on.
|
||||
pub fn our_id(&self) -> &N {
|
||||
&self.our_id
|
||||
}
|
||||
|
||||
/// ID of all nodes in the network.
|
||||
pub fn all_ids(&self) -> impl Iterator<Item = &N> {
|
||||
self.public_keys.keys()
|
||||
}
|
||||
|
||||
/// The total number _N_ of nodes.
|
||||
pub fn num_nodes(&self) -> usize {
|
||||
self.num_nodes
|
||||
}
|
||||
|
||||
/// The maximum number _f_ of faulty, Byzantine nodes up to which Honey Badger is guaranteed to
|
||||
/// be correct.
|
||||
pub fn num_faulty(&self) -> usize {
|
||||
self.num_faulty
|
||||
}
|
||||
|
||||
/// The minimum number _N - f_ of correct nodes with which Honey Badger is guaranteed to be
|
||||
/// correct.
|
||||
pub fn num_correct(&self) -> usize {
|
||||
self.num_nodes - self.num_faulty
|
||||
}
|
||||
|
||||
/// Returns our secret key share for threshold cryptography.
|
||||
pub fn secret_key_share(&self) -> &SecretKeyShare {
|
||||
&self.secret_key_share
|
||||
}
|
||||
|
||||
/// Returns our secret key for encryption and signing.
|
||||
pub fn secret_key(&self) -> &SecretKey {
|
||||
&self.secret_key
|
||||
}
|
||||
|
||||
/// Returns the public key set for threshold cryptography.
|
||||
pub fn public_key_set(&self) -> &PublicKeySet {
|
||||
&self.public_key_set
|
||||
}
|
||||
|
||||
/// Returns the public key share if a node with that ID exists, otherwise `None`.
|
||||
pub fn public_key_share(&self, id: &N) -> Option<&PublicKeyShare> {
|
||||
self.public_key_shares.get(id)
|
||||
}
|
||||
|
||||
/// Returns a map of all node IDs to their public key shares.
|
||||
pub fn public_key_share_map(&self) -> &BTreeMap<N, PublicKeyShare> {
|
||||
&self.public_key_shares
|
||||
}
|
||||
|
||||
/// Returns a map of all node IDs to their public keys.
|
||||
pub fn public_key(&self, id: &N) -> Option<&PublicKey> {
|
||||
self.public_keys.get(id)
|
||||
}
|
||||
|
||||
/// Returns a map of all node IDs to their public keys.
|
||||
pub fn public_key_map(&self) -> &BTreeMap<N, PublicKey> {
|
||||
&self.public_keys
|
||||
}
|
||||
|
||||
/// The index of a node in a canonical numbering of all nodes.
|
||||
pub fn node_index(&self, id: &N) -> Option<usize> {
|
||||
self.node_indices.get(id).cloned()
|
||||
}
|
||||
|
||||
/// Returns the unique ID of the Honey Badger invocation.
|
||||
///
|
||||
/// FIXME: Using the public key as the invocation ID either requires agreeing on the keys on
|
||||
/// each invocation, or makes it unsafe to reuse keys for different invocations. A better
|
||||
/// invocation ID would be one that is distributed to all nodes on each invocation and would be
|
||||
/// independent from the public key, so that reusing keys would be safer.
|
||||
pub fn invocation_id(&self) -> Vec<u8> {
|
||||
self.public_key_set.public_key().to_bytes()
|
||||
}
|
||||
|
||||
/// Returns `true` if this node takes part in the consensus itself. If not, it is only an
|
||||
/// observer.
|
||||
pub fn is_validator(&self) -> bool {
|
||||
self.is_validator
|
||||
}
|
||||
|
||||
/// Returns `true` if the given node takes part in the consensus itself. If not, it is only an
|
||||
/// observer.
|
||||
pub fn is_node_validator(&self, id: &N) -> bool {
|
||||
self.public_keys.contains_key(id)
|
||||
}
|
||||
|
||||
/// Generates a map of matching `NetworkInfo`s for testing.
|
||||
pub fn generate_map<I, R>(
|
||||
ids: I,
|
||||
rng: &mut R,
|
||||
) -> Result<BTreeMap<N, NetworkInfo<N>>, crypto::error::Error>
|
||||
where
|
||||
I: IntoIterator<Item = N>,
|
||||
R: rand::Rng,
|
||||
{
|
||||
use crypto::SecretKeySet;
|
||||
|
||||
let all_ids: BTreeSet<N> = ids.into_iter().collect();
|
||||
let num_faulty = (all_ids.len() - 1) / 3;
|
||||
|
||||
// Generate the keys for threshold cryptography.
|
||||
let sk_set = SecretKeySet::random(num_faulty, rng)?;
|
||||
let pk_set = sk_set.public_keys();
|
||||
|
||||
// Generate keys for individually signing and encrypting messages.
|
||||
let sec_keys: BTreeMap<_, SecretKey> =
|
||||
all_ids.iter().map(|id| (id.clone(), rng.gen())).collect();
|
||||
let pub_keys: BTreeMap<_, PublicKey> = sec_keys
|
||||
.iter()
|
||||
.map(|(id, sk)| (id.clone(), sk.public_key()))
|
||||
.collect();
|
||||
|
||||
// Create the corresponding `NetworkInfo` for each node.
|
||||
let create_netinfo = |(i, id): (usize, N)| {
|
||||
let netinfo = NetworkInfo::new(
|
||||
id.clone(),
|
||||
sk_set.secret_key_share(i)?,
|
||||
pk_set.clone(),
|
||||
sec_keys[&id].clone(),
|
||||
pub_keys.clone(),
|
||||
);
|
||||
Ok((id, netinfo))
|
||||
};
|
||||
all_ids
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(create_netinfo)
|
||||
.collect()
|
||||
}
|
||||
}
|
|
@ -31,9 +31,8 @@ use rand::Rand;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use dynamic_honey_badger::{self, Batch as DhbBatch, DynamicHoneyBadger, Message};
|
||||
use messaging::{self, DistAlgorithm};
|
||||
use traits::{Contribution, NodeIdT};
|
||||
use transaction_queue::TransactionQueue;
|
||||
use {Contribution, DistAlgorithm, NodeIdT};
|
||||
|
||||
pub use dynamic_honey_badger::{Change, ChangeState, Input};
|
||||
|
||||
|
@ -172,7 +171,7 @@ where
|
|||
queue: TransactionQueue<T>,
|
||||
}
|
||||
|
||||
pub type Step<T, N> = messaging::Step<QueueingHoneyBadger<T, N>>;
|
||||
pub type Step<T, N> = ::Step<QueueingHoneyBadger<T, N>>;
|
||||
|
||||
impl<T, N> DistAlgorithm for QueueingHoneyBadger<T, N>
|
||||
where
|
||||
|
|
|
@ -30,9 +30,8 @@ use std::sync::Arc;
|
|||
use binary_agreement::{self, BinaryAgreement};
|
||||
use broadcast::{self, Broadcast};
|
||||
use fmt::HexBytes;
|
||||
use messaging::{self, DistAlgorithm, NetworkInfo};
|
||||
use rand::Rand;
|
||||
use traits::NodeIdT;
|
||||
use {DistAlgorithm, NetworkInfo, NodeIdT};
|
||||
|
||||
/// A subset error.
|
||||
#[derive(Clone, PartialEq, Debug, Fail)]
|
||||
|
@ -85,7 +84,7 @@ pub struct Subset<N: Rand> {
|
|||
decided: bool,
|
||||
}
|
||||
|
||||
pub type Step<N> = messaging::Step<Subset<N>>;
|
||||
pub type Step<N> = ::Step<Subset<N>>;
|
||||
|
||||
impl<N: NodeIdT + Rand> DistAlgorithm for Subset<N> {
|
||||
type NodeId = N;
|
||||
|
|
|
@ -175,8 +175,7 @@ use pairing::{CurveAffine, Field};
|
|||
use rand;
|
||||
|
||||
use fault_log::{AckMessageFault as Fault, FaultKind, FaultLog};
|
||||
use messaging::NetworkInfo;
|
||||
use traits::NodeIdT;
|
||||
use {NetworkInfo, NodeIdT};
|
||||
|
||||
// TODO: No need to send our own row and value to ourselves.
|
||||
|
||||
|
|
|
@ -13,11 +13,9 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crypto::error as cerror;
|
||||
use crypto::{Ciphertext, DecryptionShare};
|
||||
use crypto::{self, Ciphertext, DecryptionShare};
|
||||
use fault_log::{Fault, FaultKind, FaultLog};
|
||||
use messaging::{self, DistAlgorithm, NetworkInfo, Target};
|
||||
use traits::NodeIdT;
|
||||
use {DistAlgorithm, NetworkInfo, NodeIdT, Target};
|
||||
|
||||
/// A threshold decryption error.
|
||||
#[derive(Clone, Eq, PartialEq, Debug, Fail)]
|
||||
|
@ -29,7 +27,7 @@ pub enum Error {
|
|||
#[fail(display = "Unknown sender")]
|
||||
UnknownSender,
|
||||
#[fail(display = "Decryption failed: {:?}", _0)]
|
||||
Decryption(cerror::Error),
|
||||
Decryption(crypto::error::Error),
|
||||
}
|
||||
|
||||
/// A threshold decryption result.
|
||||
|
@ -52,7 +50,7 @@ pub struct ThresholdDecryption<N> {
|
|||
terminated: bool,
|
||||
}
|
||||
|
||||
pub type Step<N> = messaging::Step<ThresholdDecryption<N>>;
|
||||
pub type Step<N> = ::Step<ThresholdDecryption<N>>;
|
||||
|
||||
impl<N: NodeIdT> DistAlgorithm for ThresholdDecryption<N> {
|
||||
type NodeId = N;
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
//! Common supertraits for distributed algorithms.
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::iter::once;
|
||||
|
||||
use failure::Fail;
|
||||
|
||||
use fault_log::{Fault, FaultLog};
|
||||
use TargetedMessage;
|
||||
|
||||
/// A transaction, user message, etc.
|
||||
pub trait Contribution: Eq + Debug + Hash + Send + Sync {}
|
||||
impl<C> Contribution for C where C: Eq + Debug + Hash + Send + Sync {}
|
||||
|
||||
/// A peer node's unique identifier.
|
||||
pub trait NodeIdT: Eq + Ord + Clone + Debug + Hash + Send + Sync {}
|
||||
impl<N> NodeIdT for N where N: Eq + Ord + Clone + Debug + Hash + Send + Sync {}
|
||||
|
||||
/// Messages.
|
||||
pub trait Message: Debug + Send + Sync {}
|
||||
impl<M> Message for M where M: Debug + Send + Sync {}
|
||||
|
||||
/// Result of one step of the local state machine of a distributed algorithm. Such a result should
|
||||
/// be used and never discarded by the client of the algorithm.
|
||||
#[must_use = "The algorithm step result must be used."]
|
||||
#[derive(Debug)]
|
||||
pub struct Step<D>
|
||||
where
|
||||
D: DistAlgorithm,
|
||||
<D as DistAlgorithm>::NodeId: NodeIdT,
|
||||
{
|
||||
pub output: VecDeque<D::Output>,
|
||||
pub fault_log: FaultLog<D::NodeId>,
|
||||
pub messages: VecDeque<TargetedMessage<D::Message, D::NodeId>>,
|
||||
}
|
||||
|
||||
impl<D> Default for Step<D>
|
||||
where
|
||||
D: DistAlgorithm,
|
||||
<D as DistAlgorithm>::NodeId: NodeIdT,
|
||||
{
|
||||
fn default() -> Step<D> {
|
||||
Step {
|
||||
output: VecDeque::default(),
|
||||
fault_log: FaultLog::default(),
|
||||
messages: VecDeque::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DistAlgorithm> Step<D>
|
||||
where
|
||||
<D as DistAlgorithm>::NodeId: NodeIdT,
|
||||
{
|
||||
/// Creates a new `Step` from the given collections.
|
||||
pub fn new(
|
||||
output: VecDeque<D::Output>,
|
||||
fault_log: FaultLog<D::NodeId>,
|
||||
messages: VecDeque<TargetedMessage<D::Message, D::NodeId>>,
|
||||
) -> Self {
|
||||
Step {
|
||||
output,
|
||||
fault_log,
|
||||
messages,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the same step, with the given additional output.
|
||||
pub fn with_output(mut self, output: D::Output) -> Self {
|
||||
self.output.push_back(output);
|
||||
self
|
||||
}
|
||||
|
||||
/// Converts `self` into a step of another type, given conversion methods for output and
|
||||
/// messages.
|
||||
pub fn map<D2, FO, FM>(self, f_out: FO, f_msg: FM) -> Step<D2>
|
||||
where
|
||||
D2: DistAlgorithm<NodeId = D::NodeId>,
|
||||
FO: Fn(D::Output) -> D2::Output,
|
||||
FM: Fn(D::Message) -> D2::Message,
|
||||
{
|
||||
Step {
|
||||
output: self.output.into_iter().map(f_out).collect(),
|
||||
fault_log: self.fault_log,
|
||||
messages: self.messages.into_iter().map(|tm| tm.map(&f_msg)).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Extends `self` with `other`s messages and fault logs, and returns `other.output`.
|
||||
pub fn extend_with<D2, FM>(&mut self, other: Step<D2>, f_msg: FM) -> VecDeque<D2::Output>
|
||||
where
|
||||
D2: DistAlgorithm<NodeId = D::NodeId>,
|
||||
FM: Fn(D2::Message) -> D::Message,
|
||||
{
|
||||
self.fault_log.extend(other.fault_log);
|
||||
let msgs = other.messages.into_iter().map(|tm| tm.map(&f_msg));
|
||||
self.messages.extend(msgs);
|
||||
other.output
|
||||
}
|
||||
|
||||
/// Adds the outputs, fault logs and messages of `other` to `self`.
|
||||
pub fn extend(&mut self, other: Self) {
|
||||
self.output.extend(other.output);
|
||||
self.fault_log.extend(other.fault_log);
|
||||
self.messages.extend(other.messages);
|
||||
}
|
||||
|
||||
/// Converts this step into an equivalent step for a different `DistAlgorithm`.
|
||||
// This cannot be a `From` impl, because it would conflict with `impl From<T> for T`.
|
||||
pub fn convert<D2>(self) -> Step<D2>
|
||||
where
|
||||
D2: DistAlgorithm<NodeId = D::NodeId, Output = D::Output, Message = D::Message>,
|
||||
{
|
||||
Step {
|
||||
output: self.output,
|
||||
fault_log: self.fault_log,
|
||||
messages: self.messages,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if there are now messages, faults or outputs.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.output.is_empty() && self.fault_log.is_empty() && self.messages.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DistAlgorithm> From<FaultLog<D::NodeId>> for Step<D> {
|
||||
fn from(fault_log: FaultLog<D::NodeId>) -> Self {
|
||||
Step {
|
||||
fault_log,
|
||||
..Step::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DistAlgorithm> From<Fault<D::NodeId>> for Step<D> {
|
||||
fn from(fault: Fault<D::NodeId>) -> Self {
|
||||
Step {
|
||||
fault_log: fault.into(),
|
||||
..Step::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DistAlgorithm> From<TargetedMessage<D::Message, D::NodeId>> for Step<D> {
|
||||
fn from(msg: TargetedMessage<D::Message, D::NodeId>) -> Self {
|
||||
Step {
|
||||
messages: once(msg).collect(),
|
||||
..Step::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A distributed algorithm that defines a message flow.
|
||||
pub trait DistAlgorithm: Send + Sync {
|
||||
/// Unique node identifier.
|
||||
type NodeId: NodeIdT;
|
||||
/// The input provided by the user.
|
||||
type Input;
|
||||
/// The output type. Some algorithms return an output exactly once, others return multiple
|
||||
/// times.
|
||||
type Output;
|
||||
/// The messages that need to be exchanged between the instances in the participating nodes.
|
||||
type Message: Message;
|
||||
/// The errors that can occur during execution.
|
||||
type Error: Fail;
|
||||
|
||||
/// Handles an input provided by the user, and returns
|
||||
fn handle_input(&mut self, input: Self::Input) -> Result<Step<Self>, Self::Error>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Handles a message received from node `sender_id`.
|
||||
fn handle_message(
|
||||
&mut self,
|
||||
sender_id: &Self::NodeId,
|
||||
message: Self::Message,
|
||||
) -> Result<Step<Self>, Self::Error>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Returns `true` if execution has completed and this instance can be dropped.
|
||||
fn terminated(&self) -> bool;
|
||||
|
||||
/// Returns this node's own ID.
|
||||
fn our_id(&self) -> &Self::NodeId;
|
||||
}
|
|
@ -3,7 +3,7 @@ use std::collections::{HashSet, VecDeque};
|
|||
|
||||
use rand;
|
||||
|
||||
use traits::Contribution;
|
||||
use Contribution;
|
||||
|
||||
/// A wrapper providing a few convenience methods for a queue of pending transactions.
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -33,7 +33,7 @@ use std::sync::Arc;
|
|||
use rand::Rng;
|
||||
|
||||
use hbbft::binary_agreement::BinaryAgreement;
|
||||
use hbbft::messaging::NetworkInfo;
|
||||
use hbbft::NetworkInfo;
|
||||
|
||||
use network::{Adversary, MessageScheduler, NodeId, SilentAdversary, TestNetwork, TestNode};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use std::sync::Arc;
|
|||
use rand::Rng;
|
||||
|
||||
use hbbft::broadcast::{Broadcast, Message};
|
||||
use hbbft::messaging::{DistAlgorithm, NetworkInfo, Target, TargetedMessage};
|
||||
use hbbft::{DistAlgorithm, NetworkInfo, Target, TargetedMessage};
|
||||
use network::{
|
||||
Adversary, MessageScheduler, MessageWithSender, NodeId, RandomAdversary, SilentAdversary,
|
||||
TestNetwork, TestNode,
|
||||
|
|
|
@ -22,8 +22,8 @@ use itertools::Itertools;
|
|||
use rand::Rng;
|
||||
|
||||
use hbbft::dynamic_honey_badger::{Batch, Change, ChangeState, DynamicHoneyBadger, Input};
|
||||
use hbbft::messaging::NetworkInfo;
|
||||
use hbbft::transaction_queue::TransactionQueue;
|
||||
use hbbft::NetworkInfo;
|
||||
|
||||
use network::{Adversary, MessageScheduler, NodeId, SilentAdversary, TestNetwork, TestNode};
|
||||
|
||||
|
|
|
@ -23,9 +23,8 @@ use itertools::Itertools;
|
|||
use rand::Rng;
|
||||
|
||||
use hbbft::honey_badger::{self, Batch, HoneyBadger, MessageContent};
|
||||
use hbbft::messaging::{NetworkInfo, Target, TargetedMessage};
|
||||
use hbbft::threshold_decryption;
|
||||
use hbbft::transaction_queue::TransactionQueue;
|
||||
use hbbft::{threshold_decryption, NetworkInfo, Target, TargetedMessage};
|
||||
|
||||
use network::{
|
||||
Adversary, MessageScheduler, MessageWithSender, NodeId, RandomAdversary, SilentAdversary,
|
||||
|
|
|
@ -35,7 +35,8 @@
|
|||
|
||||
use std::cmp;
|
||||
|
||||
use hbbft::messaging::{DistAlgorithm, Step};
|
||||
use hbbft::{DistAlgorithm, Step};
|
||||
|
||||
use net::{CrankError, NetMessage, Node, VirtualNet};
|
||||
|
||||
/// Immutable network handle.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use std::{fmt, time};
|
||||
|
||||
use failure;
|
||||
use hbbft::messaging::DistAlgorithm;
|
||||
use hbbft::DistAlgorithm;
|
||||
|
||||
use super::NetMessage;
|
||||
|
||||
|
|
|
@ -26,9 +26,8 @@ use rand::{Rand, Rng};
|
|||
use threshold_crypto as crypto;
|
||||
|
||||
use hbbft::dynamic_honey_badger::Batch;
|
||||
use hbbft::messaging::{self, DistAlgorithm, NetworkInfo, Step};
|
||||
use hbbft::traits::{Contribution, NodeIdT};
|
||||
use hbbft::util::SubRng;
|
||||
use hbbft::{self, Contribution, DistAlgorithm, NetworkInfo, NodeIdT, Step};
|
||||
|
||||
pub use self::adversary::Adversary;
|
||||
pub use self::err::CrankError;
|
||||
|
@ -135,7 +134,7 @@ impl<D: DistAlgorithm> Node<D> {
|
|||
}
|
||||
|
||||
/// A network message on the virtual network.
|
||||
// Note: We do not use `messaging::TargetedMessage` and `messaging::SourceMessage` here, the nesting
|
||||
// Note: We do not use `hbbft::TargetedMessage` and `hbbft::SourceMessage` here, the nesting
|
||||
// is inconvenient and we do not want to support broadcasts at this level.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NetworkMessage<M, N> {
|
||||
|
@ -198,7 +197,7 @@ where
|
|||
for tmsg in &step.messages {
|
||||
match &tmsg.target {
|
||||
// Single target message.
|
||||
messaging::Target::Node(to) => {
|
||||
hbbft::Target::Node(to) => {
|
||||
if !faulty {
|
||||
message_count = message_count.saturating_add(1);
|
||||
}
|
||||
|
@ -210,7 +209,7 @@ where
|
|||
));
|
||||
}
|
||||
// Broadcast messages get expanded into multiple direct messages.
|
||||
messaging::Target::All => for to in nodes.keys().filter(|&to| to != &sender) {
|
||||
hbbft::Target::All => for to in nodes.keys().filter(|&to| to != &sender) {
|
||||
if !faulty {
|
||||
message_count = message_count.saturating_add(1);
|
||||
}
|
||||
|
@ -706,7 +705,7 @@ where
|
|||
R: rand::Rng,
|
||||
{
|
||||
// Generate a new set of cryptographic keys for threshold cryptography.
|
||||
let net_infos = messaging::NetworkInfo::generate_map(node_ids, &mut rng)?;
|
||||
let net_infos = NetworkInfo::generate_map(node_ids, &mut rng)?;
|
||||
|
||||
assert!(
|
||||
faulty * 3 < net_infos.len(),
|
||||
|
|
|
@ -11,7 +11,7 @@ pub mod net;
|
|||
use std::{collections, time};
|
||||
|
||||
use hbbft::dynamic_honey_badger::{Change, ChangeState, DynamicHoneyBadger, Input};
|
||||
use hbbft::messaging::DistAlgorithm;
|
||||
use hbbft::DistAlgorithm;
|
||||
use net::proptest::{gen_seed, NetworkDimension, TestRng, TestRngSeed};
|
||||
use net::NetBuilder;
|
||||
use proptest::prelude::ProptestConfig;
|
||||
|
|
|
@ -7,8 +7,7 @@ use crypto::SecretKeyShare;
|
|||
use rand::{self, Rng};
|
||||
|
||||
use hbbft::dynamic_honey_badger::Batch;
|
||||
use hbbft::messaging::{DistAlgorithm, NetworkInfo, Step, Target, TargetedMessage};
|
||||
use hbbft::traits::Contribution;
|
||||
use hbbft::{Contribution, DistAlgorithm, NetworkInfo, Step, Target, TargetedMessage};
|
||||
|
||||
/// A node identifier. In the tests, nodes are simply numbered.
|
||||
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, Serialize, Deserialize, Rand)]
|
||||
|
|
|
@ -19,8 +19,8 @@ use std::collections::BTreeMap;
|
|||
use std::sync::Arc;
|
||||
|
||||
use hbbft::dynamic_honey_badger::DynamicHoneyBadger;
|
||||
use hbbft::messaging::NetworkInfo;
|
||||
use hbbft::queueing_honey_badger::{Batch, Change, ChangeState, Input, QueueingHoneyBadger, Step};
|
||||
use hbbft::NetworkInfo;
|
||||
use itertools::Itertools;
|
||||
use rand::Rng;
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@ use std::collections::{BTreeMap, BTreeSet};
|
|||
use std::iter::once;
|
||||
use std::sync::Arc;
|
||||
|
||||
use hbbft::messaging::NetworkInfo;
|
||||
use hbbft::subset::{Subset, SubsetOutput};
|
||||
use hbbft::NetworkInfo;
|
||||
|
||||
use network::{Adversary, MessageScheduler, NodeId, SilentAdversary, TestNetwork, TestNode};
|
||||
|
||||
|
|
Loading…
Reference in New Issue