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

View File

@ -1,6 +1,7 @@
//! Network tests for Dynamic Honey Badger. //! Network tests for Dynamic Honey Badger.
extern crate hbbft; extern crate hbbft;
extern crate itertools;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate env_logger; extern crate env_logger;
@ -17,6 +18,7 @@ use std::cmp;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::sync::Arc; use std::sync::Arc;
use itertools::Itertools;
use rand::Rng; use rand::Rng;
use hbbft::dynamic_honey_badger::{Batch, Change, ChangeState, DynamicHoneyBadger, Input}; 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. // 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: &TestNode<UsizeDhb>| {
let node_busy = |node: &mut TestNode<UsizeDhb>| {
if !has_remove(node) || !has_add(node) { if !has_remove(node) || !has_add(node) {
return true; return true;
} }
let mut min_missing = 0; node.outputs().iter().flat_map(Batch::iter).unique().count() < num_txs
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
}; };
let mut rng = rand::thread_rng(); 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. // 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. // If a node is expecting input, take it from the queue. Otherwise handle a message.
let input_ids: Vec<_> = network let input_ids: Vec<_> = network
.nodes .nodes
.iter() .iter()
.filter(|(_, node)| { .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) .map(|(id, _)| *id)
.collect(); .collect();
@ -93,14 +92,12 @@ where
let queue = queues.get_mut(id).unwrap(); let queue = queues.get_mut(id).unwrap();
queue.remove_all(network.nodes[id].outputs().iter().flat_map(Batch::iter)); queue.remove_all(network.nodes[id].outputs().iter().flat_map(Batch::iter));
network.input(*id, Input::User(queue.choose(3, 10))); 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. // Once all nodes have processed the removal of node 0, add it again.
if !input_add && network.nodes.values().all(has_remove) { if !input_add && network.nodes.values().all(has_remove) {
let pk = network.pk_set.public_key_share(0); let pk = network.pk_set.public_key_share(0);
network.input_all(Input::Change(Change::Add(NodeUid(0), pk))); network.input_all(Input::Change(Change::Add(NodeUid(0), pk)));
info!("Input!");
input_add = true; input_add = true;
} }
} }
@ -137,8 +134,7 @@ where
let _ = env_logger::try_init(); let _ = env_logger::try_init();
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
// TODO: This should also work with two nodes. let sizes = vec![2, 3, 5, rng.gen_range(6, 10)];
let sizes = vec![3, 5, rng.gen_range(6, 10)];
for size in sizes { for size in sizes {
// The test is removing one correct node, so we allow fewer faulty ones. // The test is removing one correct node, so we allow fewer faulty ones.
let num_adv_nodes = (size - 2) / 3; let num_adv_nodes = (size - 2) / 3;

View File

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

View File

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