mirror of https://github.com/poanetwork/hbbft.git
Rename CommonCoin to Coin.
This commit is contained in:
parent
f7d4860a94
commit
6bcf365cf8
|
@ -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)
|
||||
|
||||
|
|
|
@ -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()?);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue