mirror of https://github.com/poanetwork/hbbft.git
Add SenderQueue convenience methods for voting.
This commit is contained in:
parent
2456db2d9e
commit
b71f9142f6
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||
use std::{fmt, result};
|
||||
|
||||
use bincode;
|
||||
use crypto::Signature;
|
||||
use crypto::{PublicKey, Signature};
|
||||
use derivative::Derivative;
|
||||
use log::{debug, warn};
|
||||
use rand::{self, Rand};
|
||||
|
@ -118,7 +118,7 @@ where
|
|||
self.process_output(step)
|
||||
}
|
||||
|
||||
/// Casts a vote to change the set of validators.
|
||||
/// Casts a vote to change the set of validators or parameters.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
|
@ -131,6 +131,22 @@ where
|
|||
Ok(Target::All.message(msg).into())
|
||||
}
|
||||
|
||||
/// Casts a vote to add a node as a validator.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
pub fn vote_to_add(&mut self, node_id: N, pub_key: PublicKey) -> Result<Step<C, N>> {
|
||||
self.vote_for(Change::NodeChange(NodeChange::Add(node_id, pub_key)))
|
||||
}
|
||||
|
||||
/// Casts a vote to demote a validator to observer.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
pub fn vote_to_remove(&mut self, node_id: N) -> Result<Step<C, N>> {
|
||||
self.vote_for(Change::NodeChange(NodeChange::Remove(node_id)))
|
||||
}
|
||||
|
||||
/// Handles a message received from `sender_id`.
|
||||
///
|
||||
/// This must be called with every message we receive from another node.
|
||||
|
|
|
@ -28,6 +28,7 @@ use std::fmt::{self, Display};
|
|||
use std::marker::PhantomData;
|
||||
use std::{cmp, iter};
|
||||
|
||||
use crypto::PublicKey;
|
||||
use derivative::Derivative;
|
||||
use failure::{Backtrace, Context, Fail};
|
||||
use rand::{Rand, Rng};
|
||||
|
@ -262,6 +263,22 @@ where
|
|||
.join(self.propose()?))
|
||||
}
|
||||
|
||||
/// Casts a vote to add a node as a validator.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
pub fn vote_to_add(&mut self, node_id: N, pub_key: PublicKey) -> Result<Step<T, N, Q>> {
|
||||
self.vote_for(Change::NodeChange(NodeChange::Add(node_id, pub_key)))
|
||||
}
|
||||
|
||||
/// Casts a vote to demote a validator to observer.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
pub fn vote_to_remove(&mut self, node_id: N) -> Result<Step<T, N, Q>> {
|
||||
self.vote_for(Change::NodeChange(NodeChange::Remove(node_id)))
|
||||
}
|
||||
|
||||
/// Handles a message received from `sender_id`.
|
||||
///
|
||||
/// This must be called with every message we receive from another node.
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
//! Convenience methods for a `SenderQueue` wrapping a `DynamicHoneyBadger`.
|
||||
|
||||
use crypto::PublicKey;
|
||||
use rand::Rand;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
use super::{SenderQueue, Step};
|
||||
use dynamic_honey_badger::{Change, DynamicHoneyBadger};
|
||||
use {Contribution, NodeIdT};
|
||||
|
||||
type Result<C, N> = super::Result<Step<DynamicHoneyBadger<C, N>>, DynamicHoneyBadger<C, N>>;
|
||||
|
||||
impl<C, N> SenderQueue<DynamicHoneyBadger<C, N>>
|
||||
where
|
||||
C: Contribution + Serialize + DeserializeOwned,
|
||||
N: NodeIdT + Serialize + DeserializeOwned + Rand,
|
||||
{
|
||||
/// Proposes a contribution in the current epoch.
|
||||
///
|
||||
/// Returns an error if we already made a proposal in this epoch.
|
||||
///
|
||||
/// If we are the only validator, this will immediately output a batch, containing our
|
||||
/// proposal.
|
||||
pub fn propose(&mut self, contrib: C) -> Result<C, N> {
|
||||
self.apply(|algo| algo.propose(contrib))
|
||||
}
|
||||
|
||||
/// Casts a vote to change the set of validators or parameters.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
pub fn vote_for(&mut self, change: Change<N>) -> Result<C, N> {
|
||||
self.apply(|algo| algo.vote_for(change))
|
||||
}
|
||||
|
||||
/// Casts a vote to add a node as a validator.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
pub fn vote_to_add(&mut self, node_id: N, pub_key: PublicKey) -> Result<C, N> {
|
||||
self.apply(|algo| algo.vote_to_add(node_id, pub_key))
|
||||
}
|
||||
|
||||
/// Casts a vote to demote a validator to observer.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
pub fn vote_to_remove(&mut self, node_id: N) -> Result<C, N> {
|
||||
self.apply(|algo| algo.vote_to_remove(node_id))
|
||||
}
|
||||
}
|
|
@ -5,7 +5,9 @@
|
|||
//! epoch matches the epoch of the message. Thus no queueing is required for incoming messages since
|
||||
//! any incoming messages with non-matching epochs can be safely discarded.
|
||||
|
||||
mod dynamic_honey_badger;
|
||||
mod message;
|
||||
mod queueing_honey_badger;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt::Debug;
|
||||
|
@ -155,11 +157,7 @@ where
|
|||
}
|
||||
|
||||
pub fn handle_input(&mut self, input: D::Input) -> Result<Step<D>, D> {
|
||||
let mut step = self.algo.handle_input(input)?;
|
||||
let mut sender_queue_step = self.update_lin_epoch(&step);
|
||||
self.defer_messages(&mut step);
|
||||
sender_queue_step.extend(step.map(|output| output, Message::from));
|
||||
Ok(sender_queue_step)
|
||||
self.apply(|algo| algo.handle_input(input))
|
||||
}
|
||||
|
||||
pub fn handle_message(
|
||||
|
@ -173,6 +171,19 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Applies `f` to the wrapped algorithm and converts the step in the result to a sender queue
|
||||
/// step, deferring or dropping messages, where necessary.
|
||||
pub fn apply<F>(&mut self, f: F) -> Result<Step<D>, D>
|
||||
where
|
||||
F: FnOnce(&mut D) -> Result<::Step<D>, D>,
|
||||
{
|
||||
let mut step = f(&mut self.algo)?;
|
||||
let mut sender_queue_step = self.update_lin_epoch(&step);
|
||||
self.defer_messages(&mut step);
|
||||
sender_queue_step.extend(step.map(|output| output, Message::from));
|
||||
Ok(sender_queue_step)
|
||||
}
|
||||
|
||||
/// Handles an epoch start announcement.
|
||||
fn handle_epoch_started(
|
||||
&mut self,
|
||||
|
@ -239,11 +250,7 @@ where
|
|||
sender_id: &D::NodeId,
|
||||
content: D::Message,
|
||||
) -> Result<Step<D>, D> {
|
||||
let mut step = self.algo.handle_message(sender_id, content)?;
|
||||
let mut sender_queue_step = self.update_lin_epoch(&step);
|
||||
self.defer_messages(&mut step);
|
||||
sender_queue_step.extend(step.map(|output| output, Message::from));
|
||||
Ok(sender_queue_step)
|
||||
self.apply(|algo| algo.handle_message(sender_id, content))
|
||||
}
|
||||
|
||||
/// Updates the current Honey Badger epoch.
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
//! Convenience methods for a `SenderQueue` wrapping a `QueueingHoneyBadger`.
|
||||
|
||||
use crypto::PublicKey;
|
||||
use rand::Rand;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
use super::{SenderQueue, Step};
|
||||
use queueing_honey_badger::{Change, QueueingHoneyBadger};
|
||||
use transaction_queue::TransactionQueue;
|
||||
use {Contribution, NodeIdT};
|
||||
|
||||
type Result<T, N, Q> =
|
||||
super::Result<Step<QueueingHoneyBadger<T, N, Q>>, QueueingHoneyBadger<T, N, Q>>;
|
||||
|
||||
impl<T, N, Q> SenderQueue<QueueingHoneyBadger<T, N, Q>>
|
||||
where
|
||||
T: Contribution + Serialize + DeserializeOwned + Clone,
|
||||
N: NodeIdT + Serialize + DeserializeOwned + Rand,
|
||||
Q: TransactionQueue<T>,
|
||||
{
|
||||
/// Adds a transaction to the queue.
|
||||
///
|
||||
/// This can be called at any time to append to the transaction queue. The new transaction will
|
||||
/// be proposed in some future epoch.
|
||||
///
|
||||
/// If no proposal has yet been made for the current epoch, this may trigger one. In this case,
|
||||
/// a nonempty step will returned, with the corresponding messages. (Or, if we are the only
|
||||
/// validator, even with the completed batch as an output.)
|
||||
pub fn push_transaction(&mut self, tx: T) -> Result<T, N, Q> {
|
||||
self.apply(|algo| algo.push_transaction(tx))
|
||||
}
|
||||
|
||||
/// Casts a vote to change the set of validators or parameters.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
pub fn vote_for(&mut self, change: Change<N>) -> Result<T, N, Q> {
|
||||
self.apply(|algo| algo.vote_for(change))
|
||||
}
|
||||
|
||||
/// Casts a vote to add a node as a validator.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
pub fn vote_to_add(&mut self, node_id: N, pub_key: PublicKey) -> Result<T, N, Q> {
|
||||
self.apply(|algo| algo.vote_to_add(node_id, pub_key))
|
||||
}
|
||||
|
||||
/// Casts a vote to demote a validator to observer.
|
||||
///
|
||||
/// This stores a pending vote for the change. It will be included in some future batch, and
|
||||
/// once enough validators have been voted for the same change, it will take effect.
|
||||
pub fn vote_to_remove(&mut self, node_id: N) -> Result<T, N, Q> {
|
||||
self.apply(|algo| algo.vote_to_remove(node_id))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue