mirror of https://github.com/poanetwork/hbbft.git
Merge pull request #137 from poanetwork/afck-dhb-votes
Fix DHB test with 1 validator; purge key gen msgs.
This commit is contained in:
commit
5f858396aa
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue