mirror of https://github.com/poanetwork/hbbft.git
Add Honey Badger builder.
This commit is contained in:
parent
0f92010fe4
commit
1a3016d94d
|
@ -25,7 +25,7 @@ use serde::Serialize;
|
|||
use signifix::{metric, TryFrom};
|
||||
|
||||
use hbbft::crypto::SecretKeySet;
|
||||
use hbbft::honey_badger::{Batch, HoneyBadger};
|
||||
use hbbft::honey_badger::{Batch, HoneyBadger, HoneyBadgerBuilder};
|
||||
use hbbft::messaging::{DistAlgorithm, NetworkInfo, Target};
|
||||
|
||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
@ -436,7 +436,10 @@ fn main() {
|
|||
sk_set.secret_key_share(id.0 as u64),
|
||||
pk_set.clone(),
|
||||
));
|
||||
HoneyBadger::new(netinfo, args.flag_b, 0, txs.clone()).expect("Instantiate honey_badger")
|
||||
HoneyBadgerBuilder::new(netinfo)
|
||||
.batch_size(args.flag_b)
|
||||
.build_with_transactions(txs.clone())
|
||||
.expect("Instantiate honey_badger")
|
||||
};
|
||||
let hw_quality = HwQuality {
|
||||
latency: Duration::from_millis(args.flag_lag),
|
||||
|
|
|
@ -57,7 +57,7 @@ use clear_on_drop::ClearOnDrop;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crypto::{PublicKey, PublicKeySet, SecretKey, Signature};
|
||||
use honey_badger::{self, Batch as HbBatch, HoneyBadger, Message as HbMessage};
|
||||
use honey_badger::{self, Batch as HbBatch, HoneyBadger, HoneyBadgerBuilder, Message as HbMessage};
|
||||
use messaging::{DistAlgorithm, NetworkInfo, Target, TargetedMessage};
|
||||
use sync_key_gen::{Accept, Propose, SyncKeyGen};
|
||||
|
||||
|
@ -165,8 +165,9 @@ where
|
|||
where
|
||||
Tx: Serialize + for<'r> Deserialize<'r> + Debug + Hash + Eq,
|
||||
{
|
||||
let honey_badger =
|
||||
HoneyBadger::new(Rc::new(self.netinfo.clone()), self.batch_size, 0, None)?;
|
||||
let honey_badger = HoneyBadgerBuilder::new(Rc::new(self.netinfo.clone()))
|
||||
.batch_size(self.batch_size)
|
||||
.build()?;
|
||||
let dyn_hb = DynamicHoneyBadger {
|
||||
netinfo: self.netinfo.clone(),
|
||||
batch_size: self.batch_size,
|
||||
|
@ -445,7 +446,9 @@ where
|
|||
let old_buf = self.honey_badger.drain_buffer();
|
||||
let outputs = (self.honey_badger.output_iter()).flat_map(HbBatch::into_tx_iter);
|
||||
let buffer = outputs.chain(old_buf).filter(Transaction::is_user);
|
||||
HoneyBadger::new(netinfo, self.batch_size, 0, buffer)?
|
||||
HoneyBadgerBuilder::new(netinfo)
|
||||
.batch_size(self.batch_size)
|
||||
.build_with_transactions(buffer)?
|
||||
};
|
||||
self.honey_badger = honey_badger;
|
||||
Ok(())
|
||||
|
|
|
@ -32,6 +32,76 @@ error_chain!{
|
|||
}
|
||||
}
|
||||
|
||||
/// A Honey Badger builder, to configure the parameters and create new instances of `HoneyBadger`.
|
||||
pub struct HoneyBadgerBuilder<NodeUid> {
|
||||
/// Shared network data.
|
||||
netinfo: Rc<NetworkInfo<NodeUid>>,
|
||||
/// The target number of transactions to be included in each batch.
|
||||
// TODO: Do experiments and pick a suitable default.
|
||||
batch_size: usize,
|
||||
/// The maximum number of future epochs for which we handle messages simultaneously.
|
||||
max_future_epochs: usize,
|
||||
}
|
||||
|
||||
impl<NodeUid: Ord + Clone + Debug> HoneyBadgerBuilder<NodeUid> {
|
||||
/// Creates a new builder for Honey Badger.
|
||||
pub fn new(netinfo: Rc<NetworkInfo<NodeUid>>) -> Self {
|
||||
HoneyBadgerBuilder {
|
||||
netinfo,
|
||||
batch_size: 100,
|
||||
max_future_epochs: 3,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the target number of transactions per batch.
|
||||
pub fn batch_size(&mut self, batch_size: usize) -> &mut Self {
|
||||
self.batch_size = batch_size;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the maximum number of future epochs for which we handle messages simultaneously.
|
||||
pub fn max_future_epochs(&mut self, max_future_epochs: usize) -> &mut Self {
|
||||
self.max_future_epochs = max_future_epochs;
|
||||
self
|
||||
}
|
||||
|
||||
/// Creates a new Honey Badger instance with an empty buffer.
|
||||
pub fn build<Tx>(&self) -> HoneyBadgerResult<HoneyBadger<Tx, NodeUid>>
|
||||
where
|
||||
Tx: Serialize + for<'r> Deserialize<'r> + Debug + Hash + Eq,
|
||||
{
|
||||
self.build_with_transactions(None)
|
||||
}
|
||||
|
||||
/// Returns a new Honey Badger instance that starts with the given transactions in its buffer.
|
||||
pub fn build_with_transactions<Tx, TI>(
|
||||
&self,
|
||||
txs: TI,
|
||||
) -> HoneyBadgerResult<HoneyBadger<Tx, NodeUid>>
|
||||
where
|
||||
TI: IntoIterator<Item = Tx>,
|
||||
Tx: Serialize + for<'r> Deserialize<'r> + Debug + Hash + Eq,
|
||||
{
|
||||
let mut honey_badger = HoneyBadger {
|
||||
netinfo: self.netinfo.clone(),
|
||||
buffer: Vec::new(),
|
||||
epoch: 0,
|
||||
common_subsets: BTreeMap::new(),
|
||||
batch_size: self.batch_size,
|
||||
max_future_epochs: self.max_future_epochs as u64,
|
||||
messages: MessageQueue(VecDeque::new()),
|
||||
output: VecDeque::new(),
|
||||
incoming_queue: BTreeMap::new(),
|
||||
received_shares: BTreeMap::new(),
|
||||
decrypted_selections: BTreeMap::new(),
|
||||
ciphertexts: BTreeMap::new(),
|
||||
};
|
||||
honey_badger.buffer.extend(txs);
|
||||
honey_badger.propose()?;
|
||||
Ok(honey_badger)
|
||||
}
|
||||
}
|
||||
|
||||
/// An instance of the Honey Badger Byzantine fault tolerant consensus algorithm.
|
||||
pub struct HoneyBadger<Tx, NodeUid> {
|
||||
/// Shared network data.
|
||||
|
@ -127,40 +197,6 @@ where
|
|||
Tx: Serialize + for<'r> Deserialize<'r> + Debug + Hash + Eq,
|
||||
NodeUid: Ord + Clone + Debug,
|
||||
{
|
||||
/// Returns a new Honey Badger instance with the given parameters, starting at epoch `0`.
|
||||
///
|
||||
/// The `batch_size` is the target number of transactions that get committed in every epoch.
|
||||
///
|
||||
/// No messages belonging to `epoch + max_future_epochs + 1` or later will be sent before the
|
||||
/// batch for `epoch` has been output. If that guarantee is not needed, setting it to a higher
|
||||
/// value can improve speed.
|
||||
pub fn new<TI>(
|
||||
netinfo: Rc<NetworkInfo<NodeUid>>,
|
||||
batch_size: usize,
|
||||
max_future_epochs: usize,
|
||||
txs: TI,
|
||||
) -> HoneyBadgerResult<Self>
|
||||
where
|
||||
TI: IntoIterator<Item = Tx>,
|
||||
{
|
||||
let mut honey_badger = HoneyBadger {
|
||||
netinfo,
|
||||
buffer: txs.into_iter().collect(),
|
||||
epoch: 0,
|
||||
common_subsets: BTreeMap::new(),
|
||||
batch_size,
|
||||
max_future_epochs: max_future_epochs as u64,
|
||||
messages: MessageQueue(VecDeque::new()),
|
||||
output: VecDeque::new(),
|
||||
incoming_queue: BTreeMap::new(),
|
||||
received_shares: BTreeMap::new(),
|
||||
decrypted_selections: BTreeMap::new(),
|
||||
ciphertexts: BTreeMap::new(),
|
||||
};
|
||||
honey_badger.propose()?;
|
||||
Ok(honey_badger)
|
||||
}
|
||||
|
||||
/// Adds transactions into the buffer.
|
||||
pub fn add_transactions<I: IntoIterator<Item = Tx>>(&mut self, txs: I) {
|
||||
self.buffer.extend(txs);
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::rc::Rc;
|
|||
|
||||
use rand::Rng;
|
||||
|
||||
use hbbft::honey_badger::{self, Batch, HoneyBadger, MessageContent};
|
||||
use hbbft::honey_badger::{self, Batch, HoneyBadger, HoneyBadgerBuilder, MessageContent};
|
||||
use hbbft::messaging::{NetworkInfo, Target, TargetedMessage};
|
||||
|
||||
use network::{
|
||||
|
@ -181,7 +181,10 @@ where
|
|||
}
|
||||
|
||||
fn new_honey_badger(netinfo: Rc<NetworkInfo<NodeUid>>) -> HoneyBadger<usize, NodeUid> {
|
||||
HoneyBadger::new(netinfo, 12, 0, 0..5).expect("Instantiate honey_badger")
|
||||
HoneyBadgerBuilder::new(netinfo)
|
||||
.batch_size(12)
|
||||
.build_with_transactions(0..5)
|
||||
.expect("Instantiate honey_badger")
|
||||
}
|
||||
|
||||
fn test_honey_badger_different_sizes<A, F>(new_adversary: F, num_txs: usize)
|
||||
|
|
Loading…
Reference in New Issue