Skip to content

Commit

Permalink
Merge pull request #63 from poanetwork/afck-hb-whose-batch
Browse files Browse the repository at this point in the history
Return proposer info from HoneyBadger.
  • Loading branch information
vkomenda authored Jun 19, 2018
2 parents 9faf1d8 + 66f396e commit 1436d85
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 102 deletions.
8 changes: 4 additions & 4 deletions examples/simulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ where
/// The timestamped batches for a particular epoch that have already been output.
#[derive(Clone, Default)]
struct EpochInfo {
nodes: BTreeMap<NodeUid, (Duration, Batch<Transaction>)>,
nodes: BTreeMap<NodeUid, (Duration, Batch<Transaction, NodeUid>)>,
}

impl EpochInfo {
Expand All @@ -338,7 +338,7 @@ impl EpochInfo {
&mut self,
id: NodeUid,
time: Duration,
batch: &Batch<Transaction>,
batch: &Batch<Transaction, NodeUid>,
network: &TestNetwork<HoneyBadger<Transaction, NodeUid>>,
) {
if self.nodes.contains_key(&id) {
Expand All @@ -355,7 +355,7 @@ impl EpochInfo {
.minmax()
.into_option()
.unwrap();
let txs = batch.transactions.len();
let txs = batch.len();
println!(
"{:>5} {:6} {:6} {:5} {:9} {:>9}B",
batch.epoch.to_string().cyan(),
Expand All @@ -379,7 +379,7 @@ fn simulate_honey_badger(
let node_busy = |node: &mut TestNode<HoneyBadger<Transaction, NodeUid>>| {
node.outputs
.iter()
.map(|&(_, ref batch)| batch.transactions.len())
.map(|&(_, ref batch)| batch.len())
.sum::<usize>() < num_txs
};

Expand Down
10 changes: 3 additions & 7 deletions src/agreement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pub mod bin_values;

use std::collections::{BTreeMap, BTreeSet, VecDeque};
use std::fmt::Debug;
use std::hash::Hash;
use std::mem::replace;
use std::rc::Rc;

Expand Down Expand Up @@ -68,10 +67,7 @@ pub struct AgreementMessage {
}

/// Binary Agreement instance
pub struct Agreement<NodeUid>
where
NodeUid: Clone + Debug + Eq + Hash,
{
pub struct Agreement<NodeUid> {
/// Shared network information.
netinfo: Rc<NetworkInfo<NodeUid>>,
/// Session ID, e.g, the Honey Badger algorithm epoch.
Expand Down Expand Up @@ -121,7 +117,7 @@ where
common_coin: CommonCoin<NodeUid, Nonce>,
}

impl<NodeUid: Clone + Debug + Eq + Hash + Ord> DistAlgorithm for Agreement<NodeUid> {
impl<NodeUid: Clone + Debug + Ord> DistAlgorithm for Agreement<NodeUid> {
type NodeUid = NodeUid;
type Input = bool;
type Output = bool;
Expand Down Expand Up @@ -177,7 +173,7 @@ impl<NodeUid: Clone + Debug + Eq + Hash + Ord> DistAlgorithm for Agreement<NodeU
}
}

impl<NodeUid: Clone + Debug + Eq + Hash + Ord> Agreement<NodeUid> {
impl<NodeUid: Clone + Debug + Ord> Agreement<NodeUid> {
pub fn new(
netinfo: Rc<NetworkInfo<NodeUid>>,
session_id: u64,
Expand Down
41 changes: 22 additions & 19 deletions src/broadcast.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::collections::{BTreeMap, VecDeque};
use std::fmt::{self, Debug};
use std::hash::Hash;
use std::iter::once;
use std::rc::Rc;

Expand Down Expand Up @@ -92,11 +91,11 @@ impl Debug for BroadcastMessage {
/// eventually be able to decode (i.e. receive at least `f + 1` `Echo` messages).
/// * So a node with `2 * f + 1` `Ready`s and `f + 1` `Echos` will decode and _output_ the value,
/// knowing that every other good node will eventually do the same.
pub struct Broadcast<N: Clone + Eq + Hash> {
pub struct Broadcast<NodeUid> {
/// Shared network data.
netinfo: Rc<NetworkInfo<N>>,
netinfo: Rc<NetworkInfo<NodeUid>>,
/// The UID of the sending node.
proposer_id: N,
proposer_id: NodeUid,
data_shard_num: usize,
coding: Coding,
/// Whether we have already multicast `Echo`.
Expand All @@ -106,17 +105,17 @@ pub struct Broadcast<N: Clone + Eq + Hash> {
/// Whether we have already output a value.
decided: bool,
/// The proofs we have received via `Echo` messages, by sender ID.
echos: BTreeMap<N, Proof<Vec<u8>>>,
echos: BTreeMap<NodeUid, Proof<Vec<u8>>>,
/// The root hashes we received via `Ready` messages, by sender ID.
readys: BTreeMap<N, Vec<u8>>,
readys: BTreeMap<NodeUid, Vec<u8>>,
/// The outgoing message queue.
messages: VecDeque<TargetedMessage<BroadcastMessage, N>>,
messages: VecDeque<TargetedMessage<BroadcastMessage, NodeUid>>,
/// The output, if any.
output: Option<Vec<u8>>,
}

impl<N: Eq + Debug + Clone + Hash + Ord> DistAlgorithm for Broadcast<N> {
type NodeUid = N;
impl<NodeUid: Debug + Clone + Ord> DistAlgorithm for Broadcast<NodeUid> {
type NodeUid = NodeUid;
// TODO: Allow anything serializable and deserializable, i.e. make this a type parameter
// T: Serialize + DeserializeOwned
type Input = Vec<u8>;
Expand All @@ -136,7 +135,11 @@ impl<N: Eq + Debug + Clone + Hash + Ord> DistAlgorithm for Broadcast<N> {
self.handle_value(our_uid, proof)
}

fn handle_message(&mut self, sender_id: &N, message: Self::Message) -> BroadcastResult<()> {
fn handle_message(
&mut self,
sender_id: &NodeUid,
message: Self::Message,
) -> BroadcastResult<()> {
if !self.netinfo.all_uids().contains(sender_id) {
return Err(ErrorKind::UnknownSender.into());
}
Expand All @@ -147,7 +150,7 @@ impl<N: Eq + Debug + Clone + Hash + Ord> DistAlgorithm for Broadcast<N> {
}
}

fn next_message(&mut self) -> Option<TargetedMessage<Self::Message, N>> {
fn next_message(&mut self) -> Option<TargetedMessage<Self::Message, NodeUid>> {
self.messages.pop_front()
}

Expand All @@ -159,15 +162,15 @@ impl<N: Eq + Debug + Clone + Hash + Ord> DistAlgorithm for Broadcast<N> {
self.decided
}

fn our_id(&self) -> &N {
fn our_id(&self) -> &NodeUid {
self.netinfo.our_uid()
}
}

impl<N: Eq + Debug + Clone + Hash + Ord> Broadcast<N> {
impl<NodeUid: Debug + Clone + Ord> Broadcast<NodeUid> {
/// Creates a new broadcast instance to be used by node `our_id` which expects a value proposal
/// from node `proposer_id`.
pub fn new(netinfo: Rc<NetworkInfo<N>>, proposer_id: N) -> BroadcastResult<Self> {
pub fn new(netinfo: Rc<NetworkInfo<NodeUid>>, proposer_id: NodeUid) -> BroadcastResult<Self> {
let parity_shard_num = 2 * netinfo.num_faulty();
let data_shard_num = netinfo.num_nodes() - parity_shard_num;
let coding = Coding::new(data_shard_num, parity_shard_num)?;
Expand Down Expand Up @@ -266,7 +269,7 @@ impl<N: Eq + Debug + Clone + Hash + Ord> Broadcast<N> {
}

/// Handles a received echo and verifies the proof it contains.
fn handle_value(&mut self, sender_id: &N, p: Proof<Vec<u8>>) -> BroadcastResult<()> {
fn handle_value(&mut self, sender_id: &NodeUid, p: Proof<Vec<u8>>) -> BroadcastResult<()> {
// If the sender is not the proposer, this is not the first `Value` or the proof is invalid,
// ignore.
if *sender_id != self.proposer_id {
Expand Down Expand Up @@ -299,7 +302,7 @@ impl<N: Eq + Debug + Clone + Hash + Ord> Broadcast<N> {
}

/// Handles a received `Echo` message.
fn handle_echo(&mut self, sender_id: &N, p: Proof<Vec<u8>>) -> BroadcastResult<()> {
fn handle_echo(&mut self, sender_id: &NodeUid, p: Proof<Vec<u8>>) -> BroadcastResult<()> {
// If the proof is invalid or the sender has already sent `Echo`, ignore.
if self.echos.contains_key(sender_id) {
info!(
Expand Down Expand Up @@ -333,7 +336,7 @@ impl<N: Eq + Debug + Clone + Hash + Ord> Broadcast<N> {
}

/// Handles a received `Ready` message.
fn handle_ready(&mut self, sender_id: &N, hash: &[u8]) -> BroadcastResult<()> {
fn handle_ready(&mut self, sender_id: &NodeUid, hash: &[u8]) -> BroadcastResult<()> {
// If the sender has already sent a `Ready` before, ignore.
if self.readys.contains_key(sender_id) {
info!(
Expand Down Expand Up @@ -389,13 +392,13 @@ impl<N: Eq + Debug + Clone + Hash + Ord> Broadcast<N> {
}

/// Returns `i` if `node_id` is the `i`-th ID among all participating nodes.
fn index_of_node(&self, node_id: &N) -> Option<usize> {
fn index_of_node(&self, node_id: &NodeUid) -> Option<usize> {
self.netinfo.all_uids().iter().position(|id| id == node_id)
}

/// Returns `true` if the proof is valid and has the same index as the node ID. Otherwise
/// logs an info message.
fn validate_proof(&self, p: &Proof<Vec<u8>>, id: &N) -> bool {
fn validate_proof(&self, p: &Proof<Vec<u8>>, id: &NodeUid) -> bool {
if !p.validate(&p.root_hash) {
info!(
"Node {:?} received invalid proof: {:?}",
Expand Down
29 changes: 13 additions & 16 deletions src/common_coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
use std::collections::{BTreeMap, VecDeque};
use std::fmt::Debug;
use std::hash::Hash;
use std::rc::Rc;

use pairing::bls12_381::Bls12;
Expand Down Expand Up @@ -44,31 +43,28 @@ impl CommonCoinMessage {
/// receiving at least `num_faulty + 1` shares, attempts to combine them into a signature. If that
/// signature is valid, the instance outputs it and terminates; otherwise the instance aborts.
#[derive(Debug)]
pub struct CommonCoin<N, T>
where
N: Clone + Debug + Eq + Hash,
{
netinfo: Rc<NetworkInfo<N>>,
pub struct CommonCoin<NodeUid, T> {
netinfo: Rc<NetworkInfo<NodeUid>>,
/// The name of this common coin. It is required to be unique for each common coin round.
nonce: T,
/// The result of combination of at least `num_faulty + 1` threshold signature shares.
output: Option<bool>,
/// Outgoing message queue.
messages: VecDeque<CommonCoinMessage>,
/// All received threshold signature shares.
received_shares: BTreeMap<N, Signature<Bls12>>,
received_shares: BTreeMap<NodeUid, Signature<Bls12>>,
/// Whether we provided input to the common coin.
had_input: bool,
/// Termination flag.
terminated: bool,
}

impl<N, T> DistAlgorithm for CommonCoin<N, T>
impl<NodeUid, T> DistAlgorithm for CommonCoin<NodeUid, T>
where
N: Clone + Debug + Hash + Ord,
NodeUid: Clone + Debug + Ord,
T: Clone + AsRef<[u8]>,
{
type NodeUid = N;
type NodeUid = NodeUid;
type Input = ();
type Output = bool;
type Message = CommonCoinMessage;
Expand Down Expand Up @@ -115,12 +111,12 @@ where
}
}

impl<N, T> CommonCoin<N, T>
impl<NodeUid, T> CommonCoin<NodeUid, T>
where
N: Clone + Debug + Hash + Ord,
NodeUid: Clone + Debug + Ord,
T: Clone + AsRef<[u8]>,
{
pub fn new(netinfo: Rc<NetworkInfo<N>>, nonce: T) -> Self {
pub fn new(netinfo: Rc<NetworkInfo<NodeUid>>, nonce: T) -> Self {
CommonCoin {
netinfo,
nonce,
Expand All @@ -139,7 +135,7 @@ where
self.handle_share(&id, share)
}

fn handle_share(&mut self, sender_id: &N, share: Signature<Bls12>) -> Result<()> {
fn handle_share(&mut self, sender_id: &NodeUid, share: Signature<Bls12>) -> Result<()> {
if let Some(i) = self.netinfo.node_index(sender_id) {
let pk_i = self.netinfo.public_key_set().public_key_share(*i as u64);
if !pk_i.verify(&share, &self.nonce) {
Expand All @@ -163,8 +159,9 @@ where

fn combine_and_verify_sig(&self) -> Result<Signature<Bls12>> {
// Pass the indices of sender nodes to `combine_signatures`.
let ids_shares: BTreeMap<&N, &Signature<Bls12>> = self.received_shares.iter().collect();
let ids_u64: BTreeMap<&N, u64> = ids_shares
let ids_shares: BTreeMap<&NodeUid, &Signature<Bls12>> =
self.received_shares.iter().collect();
let ids_u64: BTreeMap<&NodeUid, u64> = ids_shares
.keys()
.map(|&id| (id, *self.netinfo.node_index(id).unwrap() as u64))
.collect();
Expand Down
9 changes: 4 additions & 5 deletions src/common_subset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
use std::collections::{BTreeMap, BTreeSet, VecDeque};
use std::fmt::Debug;
use std::hash::Hash;
use std::rc::Rc;

use agreement;
Expand Down Expand Up @@ -47,7 +46,7 @@ pub enum Message<NodeUid> {
#[derive(Deref, DerefMut)]
struct MessageQueue<NodeUid>(VecDeque<TargetedMessage<Message<NodeUid>, NodeUid>>);

impl<NodeUid: Clone + Debug + Eq + Hash + Ord> MessageQueue<NodeUid> {
impl<NodeUid: Clone + Debug + Ord> MessageQueue<NodeUid> {
/// Appends to the queue the messages from `agr`, wrapped with `proposer_id`.
fn extend_agreement(&mut self, proposer_id: &NodeUid, agr: &mut Agreement<NodeUid>) {
let convert = |msg: TargetedMessage<AgreementMessage, NodeUid>| {
Expand Down Expand Up @@ -88,7 +87,7 @@ impl<NodeUid: Clone + Debug + Eq + Hash + Ord> MessageQueue<NodeUid> {
/// remaining ones, where we haven't provided input yet.
/// * Once all `Agreement` instances have decided, `CommonSubset` returns the set of all proposed
/// values for which the decision was "yes".
pub struct CommonSubset<NodeUid: Clone + Debug + Eq + Hash + Ord> {
pub struct CommonSubset<NodeUid> {
/// Shared network information.
netinfo: Rc<NetworkInfo<NodeUid>>,
broadcast_instances: BTreeMap<NodeUid, Broadcast<NodeUid>>,
Expand All @@ -103,7 +102,7 @@ pub struct CommonSubset<NodeUid: Clone + Debug + Eq + Hash + Ord> {
decided: bool,
}

impl<NodeUid: Clone + Debug + Eq + Hash + Ord> DistAlgorithm for CommonSubset<NodeUid> {
impl<NodeUid: Clone + Debug + Ord> DistAlgorithm for CommonSubset<NodeUid> {
type NodeUid = NodeUid;
type Input = ProposedValue;
type Output = BTreeMap<NodeUid, ProposedValue>;
Expand Down Expand Up @@ -147,7 +146,7 @@ impl<NodeUid: Clone + Debug + Eq + Hash + Ord> DistAlgorithm for CommonSubset<No
}
}

impl<NodeUid: Clone + Debug + Eq + Hash + Ord> CommonSubset<NodeUid> {
impl<NodeUid: Clone + Debug + Ord> CommonSubset<NodeUid> {
pub fn new(netinfo: Rc<NetworkInfo<NodeUid>>, session_id: u64) -> CommonSubsetResult<Self> {
// Create all broadcast instances.
let mut broadcast_instances: BTreeMap<NodeUid, Broadcast<NodeUid>> = BTreeMap::new();
Expand Down
Loading

0 comments on commit 1436d85

Please sign in to comment.