message reordering net adversary and drop_and_readd change

This commit is contained in:
Vladimir Komendantskiy 2018-10-26 12:37:50 +01:00 committed by Andreas Fackler
parent 52d48675f0
commit 4560070fec
3 changed files with 54 additions and 1 deletions

View File

@ -33,7 +33,9 @@
//! some cases be upgraded to actual references, if the underlying node is faulty (see
//! `NodeHandle::node()` and `NodeHandle::node_mut()`).
use std::cmp;
use std::{cmp, fmt};
use rand::Rng;
use hbbft::{DistAlgorithm, Step};
@ -383,3 +385,46 @@ where
net.sort_messages_by(|a, b| a.to.cmp(&b.to))
}
}
/// Message reordering adversary.
///
/// An adversary that swaps the message at the front of the message queue for a random message
/// within the queue before every `crank`. Thus the order in which messages are received by nodes is
/// random, which allows to test randomized message delivery.
pub struct ReorderingAdversary {
/// Random number generator to reorder messages.
rng: Box<dyn Rng>,
}
impl fmt::Debug for ReorderingAdversary {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ReorderingAdversary")
.field("rng", &"<RNG>")
.finish()
}
}
impl ReorderingAdversary {
#[inline]
pub fn new<R>(rng: R) -> Self
where
R: 'static + Rng,
{
ReorderingAdversary { rng: Box::new(rng) }
}
}
impl<D> Adversary<D> for ReorderingAdversary
where
D: DistAlgorithm,
D::Message: Clone,
D::Output: Clone,
{
#[inline]
fn pre_crank(&mut self, mut net: NetMutHandle<D>) {
let l = net.0.messages_len();
if l > 0 {
net.swap_messages(0, self.rng.gen_range(0, l));
}
}
}

View File

@ -646,6 +646,12 @@ where
self.messages.iter_mut()
}
/// Length of the message queue.
#[inline]
pub fn messages_len(&self) -> usize {
self.messages.len()
}
/// Swap two queued messages at indices `i` and `j`.
#[inline]
pub fn swap_messages(&mut self, i: usize, j: usize) {

View File

@ -12,6 +12,7 @@ use std::{collections, time};
use hbbft::dynamic_honey_badger::{Change, ChangeState, DynamicHoneyBadger, Input};
use hbbft::DistAlgorithm;
use net::adversary::ReorderingAdversary;
use net::proptest::{gen_seed, NetworkDimension, TestRng, TestRngSeed};
use net::NetBuilder;
use proptest::prelude::ProptestConfig;
@ -101,6 +102,7 @@ fn do_drop_and_readd(cfg: TestConfig) {
.time_limit(time::Duration::from_secs(30 * cfg.dimension.size() as u64))
// Ensure runs are reproducible.
.rng(rng.gen::<TestRng>())
.adversary(ReorderingAdversary::new(rng.gen::<TestRng>()))
.using(move |node| {
println!("Constructing new dynamic honey badger node #{}", node.id);
DynamicHoneyBadger::builder()