Rename CommonCoin to Coin.

This commit is contained in:
Andreas Fackler 2018-08-14 14:56:32 +02:00 committed by Nick Sanders
parent f7d4860a94
commit 6bcf365cf8
7 changed files with 64 additions and 65 deletions

View File

@ -37,7 +37,7 @@ In addition to **validators**, the algorithms support **observers**: These don't
- [x] **[Binary Agreement](https://github.com/poanetwork/hbbft/blob/master/src/agreement/mod.rs):** Each node inputs a binary value. The nodes agree on a value that was input by at least one correct node.
- [x] **[Coin](https://github.com/poanetwork/hbbft/blob/master/src/common_coin.rs):** A pseudorandom binary value used by the Binary Agreement protocol.
- [x] **[Coin](https://github.com/poanetwork/hbbft/blob/master/src/coin.rs):** A pseudorandom binary value used by the Binary Agreement protocol.
- [x] **[Synchronous Key Generation](https://github.com/poanetwork/hbbft/blob/master/src/sync_key_gen.rs)** A dealerless algorithm that generates keys for threshold encryption and signing. Unlike the other algorithms, this one is _completely synchronous_ and should run on top of Honey Badger (or another consensus algorithm)

View File

@ -7,18 +7,18 @@ use super::bool_multimap::BoolMultimap;
use super::sbv_broadcast::{self, SbvBroadcast};
use super::{AgreementContent, Error, Message, Nonce, Result, Step};
use agreement::bool_set::BoolSet;
use common_coin::{self, CommonCoin, CommonCoinMessage};
use coin::{self, Coin, CoinMessage};
use messaging::{DistAlgorithm, NetworkInfo, Target};
use traits::NodeUidT;
/// The state of the current epoch's common coin. In some epochs this is fixed, in others it starts
/// The state of the current epoch's coin. In some epochs this is fixed, in others it starts
/// with in `InProgress`.
#[derive(Debug)]
enum CoinState<N> {
/// The value was fixed in the current epoch, or the coin has already terminated.
Decided(bool),
/// The coin value is not known yet.
InProgress(CommonCoin<N, Nonce>),
InProgress(Coin<N, Nonce>),
}
impl<N> CoinState<N> {
@ -68,7 +68,7 @@ pub struct Agreement<N> {
incoming_queue: BTreeMap<u32, Vec<(N, AgreementContent)>>,
/// The values we found in the first _N - f_ `Aux` messages that were in `bin_values`.
conf_values: Option<BoolSet>,
/// The state of this epoch's common coin.
/// The state of this epoch's coin.
coin_state: CoinState<N>,
}
@ -182,7 +182,7 @@ impl<N: NodeUidT> Agreement<N> {
return Ok(step); // The `Conf` round has already started.
}
if let Some(aux_vals) = output.into_iter().next() {
// Execute the Common Coin schedule `false, true, get_coin(), false, true, get_coin(), ...`
// Execute the Coin schedule `false, true, get_coin(), false, true, get_coin(), ...`
match self.coin_state {
CoinState::Decided(_) => {
self.conf_values = Some(aux_vals);
@ -224,14 +224,14 @@ impl<N: NodeUidT> Agreement<N> {
}
}
/// Handles a Common Coin message. If there is output from Common Coin, starts the next
/// Handles a Coin message. If there is output from Coin, starts the next
/// epoch. The function may output a decision value.
fn handle_coin(&mut self, sender_id: &N, msg: CommonCoinMessage) -> Result<Step<N>> {
fn handle_coin(&mut self, sender_id: &N, msg: CoinMessage) -> Result<Step<N>> {
let coin_step = match self.coin_state {
CoinState::Decided(_) => return Ok(Step::default()), // Coin value is already decided.
CoinState::InProgress(ref mut common_coin) => common_coin
CoinState::InProgress(ref mut coin) => coin
.handle_message(sender_id, msg)
.map_err(Error::HandleCoinCommonCoin)?,
.map_err(Error::HandleCoin)?,
};
self.on_coin_step(coin_step)
}
@ -266,8 +266,8 @@ impl<N: NodeUidT> Agreement<N> {
Ok(step)
}
/// Handles a step returned from the `CommonCoin`.
fn on_coin_step(&mut self, coin_step: common_coin::Step<N, Nonce>) -> Result<Step<N>> {
/// Handles a step returned from the `Coin`.
fn on_coin_step(&mut self, coin_step: coin::Step<N, Nonce>) -> Result<Step<N>> {
let mut step = Step::default();
let epoch = self.epoch;
let to_msg = |c_msg| AgreementContent::Coin(Box::new(c_msg)).with_epoch(epoch);
@ -307,7 +307,7 @@ impl<N: NodeUidT> Agreement<N> {
}
/// Creates the initial coin state for the current epoch, i.e. sets it to the predetermined
/// value, or initializes a `CommonCoin` instance.
/// value, or initializes a `Coin` instance.
fn coin_state(&self) -> CoinState<N> {
match self.epoch % 3 {
0 => CoinState::Decided(true),
@ -319,7 +319,7 @@ impl<N: NodeUidT> Agreement<N> {
self.netinfo.node_index(&self.proposer_id).unwrap(),
self.epoch,
);
CoinState::InProgress(CommonCoin::new(self.netinfo.clone(), nonce))
CoinState::InProgress(Coin::new(self.netinfo.clone(), nonce))
}
}
}
@ -354,12 +354,12 @@ impl<N: NodeUidT> Agreement<N> {
return Ok(Step::default());
}
// Invoke the common coin.
// Invoke the coin.
let coin_step = match self.coin_state {
CoinState::Decided(_) => return Ok(Step::default()), // Coin has already decided.
CoinState::InProgress(ref mut common_coin) => common_coin
.input(())
.map_err(Error::TryFinishConfRoundCommonCoin)?,
CoinState::InProgress(ref mut coin) => {
coin.input(()).map_err(Error::TryFinishConfRoundCoin)?
}
};
let mut step = self.on_coin_step(coin_step)?;
step.extend(self.try_update_epoch()?);

View File

@ -45,7 +45,7 @@
//! * If both values are candidates, we set `e = s` and proceed to the next epoch.
//!
//! In epochs that are 0 modulo 3, the value `s` is `true`. In 1 modulo 3, it is `false`. In the
//! case 2 modulo 3, we flip a common coin to determine a pseudorandom `s`.
//! case 2 modulo 3, we flip a coin to determine a pseudorandom `s`.
//!
//! An adversary that knows each coin value, controls a few validators and controls network
//! scheduling can delay the delivery of `Aux` and `BVal` messages to influence which candidate
@ -58,7 +58,7 @@
//!
//! * Since every good node believes in all values it puts into its `Conf` message, we will
//! eventually receive _N - f_ `Conf` messages containing only values we believe in. Then we
//! trigger the common coin.
//! trigger the coin.
//!
//! * After _f + 1_ nodes have sent us their coin shares, we receive the coin output and assign it
//! to `s`.
@ -71,7 +71,7 @@ mod sbv_broadcast;
use rand;
use self::bool_set::BoolSet;
use common_coin::{self, CommonCoinMessage};
use coin::{self, CoinMessage};
use messaging;
pub use self::agreement::Agreement;
@ -79,10 +79,10 @@ pub use self::agreement::Agreement;
/// An agreement error.
#[derive(Clone, Eq, PartialEq, Debug, Fail)]
pub enum Error {
#[fail(display = "HandleCoinCommonCoin error: {}", _0)]
HandleCoinCommonCoin(common_coin::Error),
#[fail(display = "TryFinishConfRoundCommonCoin error: {}", _0)]
TryFinishConfRoundCommonCoin(common_coin::Error),
#[fail(display = "HandleCoin error: {}", _0)]
HandleCoin(coin::Error),
#[fail(display = "TryFinishConfRoundCoin error: {}", _0)]
TryFinishConfRoundCoin(coin::Error),
#[fail(display = "Unknown proposer")]
UnknownProposer,
#[fail(display = "Input not accepted")]
@ -102,8 +102,8 @@ pub enum AgreementContent {
Conf(BoolSet),
/// `Term` message.
Term(bool),
/// Common Coin message,
Coin(Box<CommonCoinMessage>),
/// Coin message,
Coin(Box<CoinMessage>),
}
impl AgreementContent {

View File

@ -1,9 +1,9 @@
//! # A Cryptographic Common Coin
//! # A Cryptographic Coin
//!
//! The Common Coin produces a pseudorandom binary value that the correct nodes agree on, and that
//! The Coin produces a pseudorandom binary value that the correct nodes agree on, and that
//! cannot be known beforehand.
//!
//! Every Common Coin instance has a _nonce_ that determines the value, without giving it away: It
//! Every Coin instance has a _nonce_ that determines the value, without giving it away: It
//! is not feasible to compute the output from the nonce alone, and the output is uniformly
//! distributed.
//!
@ -30,7 +30,7 @@ use fault_log::{Fault, FaultKind};
use messaging::{self, DistAlgorithm, NetworkInfo, Target};
use traits::NodeUidT;
/// A common coin error.
/// A coin error.
#[derive(Clone, Eq, PartialEq, Debug, Fail)]
pub enum Error {
#[fail(display = "CombineAndVerifySigCrypto error: {}", _0)]
@ -41,15 +41,15 @@ pub enum Error {
VerificationFailed,
}
/// A common coin result.
/// A coin result.
pub type Result<T> = ::std::result::Result<T, Error>;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Rand)]
pub struct CommonCoinMessage(SignatureShare);
pub struct CoinMessage(SignatureShare);
impl CommonCoinMessage {
impl CoinMessage {
pub fn new(sig: SignatureShare) -> Self {
CommonCoinMessage(sig)
CoinMessage(sig)
}
pub fn to_sig(&self) -> &SignatureShare {
@ -57,25 +57,25 @@ impl CommonCoinMessage {
}
}
/// A common coin algorithm instance. On input, broadcasts our threshold signature share. Upon
/// A coin algorithm instance. On input, broadcasts our threshold signature share. Upon
/// receiving at least `num_faulty + 1` shares, attempts to combine them into a signature. If that
/// signature is valid, the instance outputs it and terminates; otherwise the instance aborts.
#[derive(Debug)]
pub struct CommonCoin<N, T> {
pub struct Coin<N, T> {
netinfo: Arc<NetworkInfo<N>>,
/// The name of this common coin. It is required to be unique for each common coin round.
/// The name of this coin. It is required to be unique for each coin round.
nonce: T,
/// All received threshold signature shares.
received_shares: BTreeMap<N, SignatureShare>,
/// Whether we provided input to the common coin.
/// Whether we provided input to the coin.
had_input: bool,
/// Termination flag.
terminated: bool,
}
pub type Step<N, T> = messaging::Step<CommonCoin<N, T>>;
pub type Step<N, T> = messaging::Step<Coin<N, T>>;
impl<N, T> DistAlgorithm for CommonCoin<N, T>
impl<N, T> DistAlgorithm for Coin<N, T>
where
N: NodeUidT,
T: Clone + AsRef<[u8]>,
@ -83,7 +83,7 @@ where
type NodeUid = N;
type Input = ();
type Output = bool;
type Message = CommonCoinMessage;
type Message = CoinMessage;
type Error = Error;
/// Sends our threshold signature share if not yet sent.
@ -103,7 +103,7 @@ where
message: Self::Message,
) -> Result<Step<N, T>> {
if !self.terminated {
let CommonCoinMessage(share) = message;
let CoinMessage(share) = message;
self.handle_share(sender_id, share)
} else {
Ok(Step::default())
@ -120,13 +120,13 @@ where
}
}
impl<N, T> CommonCoin<N, T>
impl<N, T> Coin<N, T>
where
N: NodeUidT,
T: Clone + AsRef<[u8]>,
{
pub fn new(netinfo: Arc<NetworkInfo<N>>, nonce: T) -> Self {
CommonCoin {
Coin {
netinfo,
nonce,
received_shares: BTreeMap::new(),
@ -140,7 +140,7 @@ where
return self.try_output();
}
let share = self.netinfo.secret_key_share().sign(&self.nonce);
let mut step: Step<_, _> = Target::All.message(CommonCoinMessage(share.clone())).into();
let mut step: Step<_, _> = Target::All.message(CoinMessage(share.clone())).into();
let id = self.netinfo.our_uid().clone();
step.extend(self.handle_share(&id, share)?);
Ok(step)

View File

@ -25,7 +25,7 @@ pub enum AckMessageFault {
/// Represents each reason why a node could be considered faulty.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum FaultKind {
/// `CommonCoin` received a signature share from an unverified sender.
/// `Coin` received a signature share from an unverified sender.
UnverifiedSignatureShareSender,
/// `HoneyBadger` received a decryption share from an unverified sender.
UnverifiedDecryptionShareSender,

View File

@ -85,7 +85,7 @@
//! This is used in Subset to decide whether each node's proposal should be included in the subset
//! or not.
//!
//! [**Common Coin**](common_coin/index.html)
//! [**Coin**](coin/index.html)
//!
//! Each node inputs `()` to initiate a coin flip. Once _f + 1_ nodes have input, either all nodes
//! receive `true` or all nodes receive `false`. The outcome cannot be known by the adversary
@ -124,7 +124,7 @@ extern crate tiny_keccak;
pub mod agreement;
pub mod broadcast;
pub mod common_coin;
pub mod coin;
pub mod common_subset;
pub mod dynamic_honey_badger;
pub mod fault_log;

View File

@ -1,5 +1,5 @@
#![deny(unused_must_use)]
//! Common Coin tests
//! Coin tests
extern crate env_logger;
extern crate hbbft;
@ -19,15 +19,15 @@ use std::iter::once;
use rand::Rng;
use hbbft::common_coin::CommonCoin;
use hbbft::coin::Coin;
use network::{Adversary, MessageScheduler, NodeUid, SilentAdversary, TestNetwork, TestNode};
/// Tests a network of Common Coin instances with an optional expected value. Outputs the computed
/// common coin value if the test is successful.
fn test_common_coin<A>(mut network: TestNetwork<A, CommonCoin<NodeUid, String>>) -> bool
/// Tests a network of Coin instances with an optional expected value. Outputs the computed
/// coin value if the test is successful.
fn test_coin<A>(mut network: TestNetwork<A, Coin<NodeUid, String>>) -> bool
where
A: Adversary<CommonCoin<NodeUid, String>>,
A: Adversary<Coin<NodeUid, String>>,
{
network.input_all(());
network.observer.input(()); // Observer will only return after `input` was called.
@ -72,9 +72,9 @@ fn check_coin_distribution(num_samples: usize, count_true: usize, count_false: u
assert!(count_false > min_throws);
}
fn test_common_coin_different_sizes<A, F>(new_adversary: F, num_samples: usize)
fn test_coin_different_sizes<A, F>(new_adversary: F, num_samples: usize)
where
A: Adversary<CommonCoin<NodeUid, String>>,
A: Adversary<Coin<NodeUid, String>>,
F: Fn(usize, usize) -> A,
{
assert!(num_samples > 0);
@ -106,10 +106,9 @@ where
let adversary = |_| new_adversary(num_good_nodes, num_faulty_nodes);
let nonce = format!("My very unique nonce {:x}:{}", unique_id, i);
info!("Nonce: {}", nonce);
let new_common_coin = |netinfo: _| CommonCoin::new(netinfo, nonce.clone());
let network =
TestNetwork::new(num_good_nodes, num_faulty_nodes, adversary, new_common_coin);
let coin = test_common_coin(network);
let new_coin = |netinfo: _| Coin::new(netinfo, nonce.clone());
let network = TestNetwork::new(num_good_nodes, num_faulty_nodes, adversary, new_coin);
let coin = test_coin(network);
if coin {
count_true += 1;
} else {
@ -121,13 +120,13 @@ where
}
#[test]
fn test_common_coin_random_silent_200_samples() {
fn test_coin_random_silent_200_samples() {
let new_adversary = |_: usize, _: usize| SilentAdversary::new(MessageScheduler::Random);
test_common_coin_different_sizes(new_adversary, 200);
test_coin_different_sizes(new_adversary, 200);
}
#[test]
fn test_common_coin_first_silent_50_samples() {
fn test_coin_first_silent_50_samples() {
let new_adversary = |_: usize, _: usize| SilentAdversary::new(MessageScheduler::First);
test_common_coin_different_sizes(new_adversary, 50);
test_coin_different_sizes(new_adversary, 50);
}