From 466104bce6e9a7fd6cfeb4fc12183ff90be6a62a Mon Sep 17 00:00:00 2001 From: Andreas Fackler Date: Wed, 18 Jul 2018 16:46:46 +0200 Subject: [PATCH] Extend *honey_badger module docs. --- src/dynamic_honey_badger/mod.rs | 33 +++++++++++++++++---------------- src/honey_badger.rs | 24 ++++++++++++++++++++++++ src/lib.rs | 12 +++++++++--- src/queueing_honey_badger.rs | 20 +++++++++++++++++++- 4 files changed, 69 insertions(+), 20 deletions(-) diff --git a/src/dynamic_honey_badger/mod.rs b/src/dynamic_honey_badger/mod.rs index fe8cf06..76bebc2 100644 --- a/src/dynamic_honey_badger/mod.rs +++ b/src/dynamic_honey_badger/mod.rs @@ -5,26 +5,29 @@ //! _batches_ of contributions. The protocol proceeds in _epochs_, starting at number 0, and outputs //! one batch in each epoch. It never terminates: It handles a continuous stream of incoming //! contributions and keeps producing new batches from them. All correct nodes will output the same -//! batch for each epoch. +//! batch for each epoch. Each validator proposes one contribution per epoch, and every batch will +//! contain the contributions of at least _N - f_ validators. //! //! Unlike Honey Badger, this algorithm allows dynamically adding new validators from the pool of //! observer nodes, and turning validators back into observers. As a signal to initiate that //! process, it defines a special `Change` input variant, which contains either a vote //! `Add(node_id, public_key)`, to add a new validator, or `Remove(node_id)` to remove it. Each //! validator can have at most one active vote, and casting another vote revokes the previous one. -//! Once a simple majority of validators has the same active vote, a reconfiguration process begins -//! (they need to create new cryptographic key shares for the new composition). +//! Once a simple majority of validators has the same active vote, a reconfiguration process +//! begins: They create new cryptographic key shares for the new group of validators. //! //! The state of that process after each epoch is communicated via the `Batch::change` field. When //! this contains an `InProgress(Add(..))` value, all nodes need to send every future `Target::All` -//! message to the new node, too. Once the value is `Complete`, the votes will be reset, and the -//! next epoch will run using the new set of validators. +//! message to the new node, too. Once the value is `Complete`, the next epoch will run using the +//! new set of validators. //! -//! New observers can also be added by starting them with an appropriate `start_epoch` parameter -//! and ensuring that they receive all `Target::All` messages from that epoch on. Together with the -//! above mechanism, this allows the network to change dynamically. You can introduce a new node to -//! the network and make it a validator, you can demote validators to observers, and you can remove -//! observers at any time. +//! New observers can also be added to the network. However, the can only join after an epoch where +//! `change` was not `None`. These epochs' batches contain a `JoinPlan`, which can be sent as an +//! invitation to the new node: The `DynamicHoneyBadger` created from a `JoinPlan` will start as an +//! observer in the following epoch. All `Target::All` messages from that and later epochs must be +//! be sent to the new node. Together with the above mechanism, this allows the network to change +//! dynamically. You can introduce a new node to the network and make it a validator, you can +//! demote validators to observers, and you can remove observers at any time. //! //! ## How it works //! @@ -37,12 +40,10 @@ //! contributions in its own batch. The other transactions are processed: votes are counted and key //! generation messages are passed into a `SyncKeyGen` instance. //! -//! If after an epoch key generation has completed, the Honey Badger instance (including all -//! pending batches) is dropped, and replaced by a new one with the new set of participants. -//! -//! Otherwise we check if the majority of votes has changed. If a new change has a majority, the -//! `SyncKeyGen` instance is dropped, and a new one is started to create keys according to the new -//! pending change. +//! Whenever a change has a majority of votes, the votes are reset and key generation for that +//! change begins. If key generation completes successfully, the Honey Badger instance is dropped, +//! and replaced by a new one with the new set of participants. If a different change gains a +//! majority before that happens, key generation resets again, and is attempted for the new change. use rand::Rand; use std::collections::{BTreeSet, VecDeque}; diff --git a/src/honey_badger.rs b/src/honey_badger.rs index 73c62c7..8f5ad1e 100644 --- a/src/honey_badger.rs +++ b/src/honey_badger.rs @@ -1,3 +1,27 @@ +//! # Honey Badger +//! +//! Honey Badger allows a network of _N_ nodes with at most _f_ faulty ones, +//! where _3 f < N_, to input "contributions" - any kind of data -, and to agree on a sequence of +//! _batches_ of contributions. The protocol proceeds in _epochs_, starting at number 0, and outputs +//! one batch in each epoch. It never terminates: It handles a continuous stream of incoming +//! contributions and keeps producing new batches from them. All correct nodes will output the same +//! batch for each epoch. Each validator proposes one contribution per epoch, and every batch will +//! contain the contributions of at least _N - f_ validators. +//! +//! ## How it works +//! +//! In every epoch, every validator encrypts their contribution and proposes it to the others. +//! A `CommonSubset` instance determines which proposals are accepted and will be part of the new +//! batch. Using threshold encryption, the nodes collaboratively decrypt all accepted +//! contributions. Invalid contributions (that e.g. cannot be deserialized) are discarded - their +//! proposers must be faulty -, and the remaining ones are output as the new batch. The next epoch +//! begins as soon as the validators propose new contributions again. +//! +//! So it is essentially an endlessly repeating `CommonSubset`, but with the proposed values +//! encrypted. The encryption makes it harder for an attacker to try and censor a particular value +//! by influencing the set of proposals that make it into the common subset, because they don't +//! know the decrypted values before the subset is determined. + use rand::Rand; use std::collections::btree_map::Entry; use std::collections::{BTreeMap, BTreeSet, VecDeque}; diff --git a/src/lib.rs b/src/lib.rs index d323ece..bfd4cd7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,9 +42,9 @@ //! //! [**Honey Badger**](honey_badger/index.html) //! -//! The nodes input any number of _transactions_ (any user-defined type) and output a sequence of -//! _batches_. The batches have sequential numbers (_epochs_) and contain a set of transactions -//! that were input by the nodes. The sequence and contents of the batches will be the same in all +//! The nodes repeatedly input _contributions_ (any user-defined type) and output a sequence of +//! _batches_. The batches have sequential numbers (_epochs_) and contain one contribution +//! from at least _N - f_ nodes. The sequence and contents of the batches will be the same in all //! nodes. //! //! [**Dynamic Honey Badger**](dynamic_honey_badger/index.html) @@ -53,6 +53,12 @@ //! network. In addition to the transactions, they can input `Add` and `Remove` requests. The //! output batches contain information about validator changes. //! +//! [**Queueing Honey Badger**](queueing_honey_badger/index.html) +//! +//! A modified Dynamic Honey Badger that has a built-in transaction queue. The nodes input any +//! number of _transactions_, and output a sequence of batches. Each batch contains a set of +//! transactions that were input by the nodes, and usually multiple transactions from each node. +//! //! [**Common Subset**](common_subset/index.html) //! //! Each node inputs one item. The output is a set of at least _N - f_ nodes' IDs, together with diff --git a/src/queueing_honey_badger.rs b/src/queueing_honey_badger.rs index 9532eca..590c4b3 100644 --- a/src/queueing_honey_badger.rs +++ b/src/queueing_honey_badger.rs @@ -1,6 +1,24 @@ //! # Queueing Honey Badger //! -//! This works exactly like Dynamic Honey Badger, but it has a transaction queue built in. +//! This works exactly like Dynamic Honey Badger, but it has a transaction queue built in. Whenever +//! an epoch is output, it will automatically select a list of pending transactions and propose it +//! for the next one. The user can continuously add more pending transactions to the queue. +//! +//! **Note**: `QueueingHoneyBadger` currently requires at least two validators. +//! +//! ## How it works +//! +//! Queueing Honey Badger runs a Dynamic Honey Badger internally, and automatically inputs a list +//! of pending transactions as its contribution at the beginning of each epoch. These are selected +//! by making a random choice of _B / N_ out of the first _B_ entries in the queue, where _B_ is the +//! configurable `batch_size` parameter, and _N_ is the current number of validators. +//! +//! After each output, the transactions that made it into the new batch are removed from the queue. +//! +//! The random choice of transactions is made to reduce redundancy even if all validators have +//! roughly the same entries in their queues. By selecting a random fraction of the first _B_ +//! entries, any two of them will likely make almost disjoint contributions instead of proposing +//! the same transaction multiple times. use std::cmp; use std::collections::VecDeque;