Merge pull request #137 from poanetwork/afck-dhb-votes

Fix DHB test with 1 validator; purge key gen msgs.
This commit is contained in:
Vladimir Komendantskiy 2018-07-16 12:31:54 +01:00 committed by GitHub
commit 5f858396aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 42 deletions

View File

@ -258,10 +258,16 @@ where
let mut batch = Batch::new(hb_batch.epoch + self.start_epoch);
// Add the user transactions to `batch` and handle votes and DKG messages.
for (id, int_contrib) in hb_batch.contributions {
let votes = int_contrib.votes;
let InternalContrib {
votes,
key_gen_messages,
contrib,
} = int_contrib;
fault_log.extend(self.vote_counter.add_committed_votes(&id, votes)?);
batch.contributions.insert(id, int_contrib.contrib);
for SignedKeyGenMsg(epoch, s_id, kg_msg, sig) in int_contrib.key_gen_messages {
batch.contributions.insert(id, contrib);
self.key_gen_msg_buffer
.retain(|skgm| !key_gen_messages.contains(skgm));
for SignedKeyGenMsg(epoch, s_id, kg_msg, sig) in key_gen_messages {
if epoch < self.start_epoch {
info!("Obsolete key generation message: {:?}.", kg_msg);
continue;

View File

@ -1,6 +1,7 @@
//! Network tests for Dynamic Honey Badger.
extern crate hbbft;
extern crate itertools;
#[macro_use]
extern crate log;
extern crate env_logger;
@ -17,6 +18,7 @@ use std::cmp;
use std::collections::BTreeMap;
use std::sync::Arc;
use itertools::Itertools;
use rand::Rng;
use hbbft::dynamic_honey_badger::{Batch, Change, ChangeState, DynamicHoneyBadger, Input};
@ -54,38 +56,35 @@ where
}
// Returns `true` if the node has not output all transactions yet.
// If it has, and has advanced another epoch, it clears all messages for later epochs.
let node_busy = |node: &mut TestNode<UsizeDhb>| {
let node_busy = |node: &TestNode<UsizeDhb>| {
if !has_remove(node) || !has_add(node) {
return true;
}
let mut min_missing = 0;
for tx in node.outputs().iter().flat_map(Batch::iter) {
if *tx >= min_missing {
min_missing = tx + 1;
}
}
if min_missing < num_txs {
return true;
}
if node.outputs().last().unwrap().is_empty() {
let last = node.outputs().last().unwrap().epoch;
node.queue.retain(|(_, ref msg)| msg.epoch() < last);
}
false
node.outputs().iter().flat_map(Batch::iter).unique().count() < num_txs
};
let mut rng = rand::thread_rng();
let mut input_add = false; // Whether the vote to add node 0 has already been input.
let mut input_add = false;
// Handle messages in random order until all nodes have output all transactions.
while network.nodes.values_mut().any(node_busy) {
while network.nodes.values().any(node_busy) {
// Remove all messages belonging to epochs after all expected outputs.
for node in network.nodes.values_mut().filter(|node| !node_busy(node)) {
if let Some(last) = node.outputs().last().map(|out| out.epoch) {
node.queue.retain(|(_, ref msg)| msg.epoch() < last);
}
}
// If a node is expecting input, take it from the queue. Otherwise handle a message.
let input_ids: Vec<_> = network
.nodes
.iter()
.filter(|(_, node)| {
!node.instance().has_input() && node.instance().netinfo().is_validator()
node_busy(*node)
&& !node.instance().has_input()
&& node.instance().netinfo().is_validator()
// If there's only one node, it will immediately output on input. Make sure we
// first process all incoming messages before providing input again.
&& (network.nodes.len() > 2 || node.queue.is_empty())
})
.map(|(id, _)| *id)
.collect();
@ -93,14 +92,12 @@ where
let queue = queues.get_mut(id).unwrap();
queue.remove_all(network.nodes[id].outputs().iter().flat_map(Batch::iter));
network.input(*id, Input::User(queue.choose(3, 10)));
} else {
network.step();
}
network.step();
// Once all nodes have processed the removal of node 0, add it again.
if !input_add && network.nodes.values().all(has_remove) {
let pk = network.pk_set.public_key_share(0);
network.input_all(Input::Change(Change::Add(NodeUid(0), pk)));
info!("Input!");
input_add = true;
}
}
@ -137,8 +134,7 @@ where
let _ = env_logger::try_init();
let mut rng = rand::thread_rng();
// TODO: This should also work with two nodes.
let sizes = vec![3, 5, rng.gen_range(6, 10)];
let sizes = vec![2, 3, 5, rng.gen_range(6, 10)];
for size in sizes {
// The test is removing one correct node, so we allow fewer faulty ones.
let num_adv_nodes = (size - 2) / 3;

View File

@ -2,6 +2,7 @@
extern crate bincode;
extern crate hbbft;
extern crate itertools;
#[macro_use]
extern crate log;
extern crate env_logger;
@ -17,6 +18,7 @@ mod network;
use std::collections::BTreeMap;
use std::sync::Arc;
use itertools::Itertools;
use rand::Rng;
use hbbft::honey_badger::{self, Batch, HoneyBadger, MessageContent};
@ -130,13 +132,7 @@ where
// Returns `true` if the node has not output all transactions yet.
// If it has, and has advanced another epoch, it clears all messages for later epochs.
let node_busy = |node: &mut TestNode<UsizeHoneyBadger>| {
let mut min_missing = 0;
for tx in node.outputs().iter().flat_map(Batch::iter) {
if *tx >= min_missing {
min_missing = tx + 1;
}
}
if min_missing < num_txs {
if node.outputs().iter().flat_map(Batch::iter).unique().count() < num_txs {
return true;
}
if node.outputs().last().unwrap().is_empty() {

View File

@ -2,6 +2,7 @@
extern crate env_logger;
extern crate hbbft;
extern crate itertools;
#[macro_use]
extern crate log;
extern crate pairing;
@ -19,6 +20,7 @@ use std::sync::Arc;
use hbbft::messaging::NetworkInfo;
use hbbft::queueing_honey_badger::{Batch, Change, ChangeState, Input, QueueingHoneyBadger};
use itertools::Itertools;
use rand::Rng;
use network::{Adversary, MessageScheduler, NodeUid, SilentAdversary, TestNetwork, TestNode};
@ -55,13 +57,7 @@ fn test_queueing_honey_badger<A>(
if !has_remove(node) || !has_add(node) {
return true;
}
let mut min_missing = 0;
for tx in node.outputs().iter().flat_map(Batch::iter) {
if *tx >= min_missing {
min_missing = tx + 1;
}
}
if min_missing < num_txs {
if node.outputs().iter().flat_map(Batch::iter).unique().count() < num_txs {
return true;
}
if node.outputs().last().unwrap().is_empty() {
@ -81,7 +77,6 @@ fn test_queueing_honey_badger<A>(
}
let pk = network.pk_set.public_key_share(0);
network.input_all(Input::Change(Change::Add(NodeUid(0), pk)));
info!("Input!");
input_add = true;
}
}