delay before voting on proposals (#123)

This commit is contained in:
Robert Habermeier
2018-04-12 16:35:48 +02:00
committed by GitHub
parent 1c5d6d59a7
commit 002cacd26c
4 changed files with 31 additions and 6 deletions
+1 -1
View File
@@ -100,7 +100,7 @@ pub trait BlockBuilder: Sized {
}
/// A checked block identifier.
pub trait CheckedBlockId: Clone {
pub trait CheckedBlockId: Clone + 'static {
/// Yield the underlying block ID.
fn block_id(&self) -> &BlockId;
}
+5
View File
@@ -23,6 +23,11 @@ error_chain! {
Bft(::bft::Error, ::bft::ErrorKind);
}
foreign_links {
Io(::std::io::Error);
SharedIo(::futures::future::SharedError<::std::io::Error>);
}
errors {
InvalidDutyRosterLength(expected: usize, got: usize) {
description("Duty Roster had invalid length"),
+24 -5
View File
@@ -70,7 +70,9 @@ use transaction_pool::{Ready, TransactionPool, PolkadotBlock};
use futures::prelude::*;
use futures::future;
use future::Shared;
use parking_lot::Mutex;
use tokio_core::reactor::{Handle, Timeout};
pub use self::error::{ErrorKind, Error};
pub use service::Service;
@@ -475,6 +477,8 @@ pub struct ProposerFactory<C, N> {
pub transaction_pool: Arc<Mutex<TransactionPool>>,
/// The backing network handle.
pub network: N,
/// Handle to the underlying tokio-core.
pub handle: Handle,
}
impl<C: PolkadotApi, N: Network> bft::ProposerFactory for ProposerFactory<C, N> {
@@ -482,6 +486,10 @@ impl<C: PolkadotApi, N: Network> bft::ProposerFactory for ProposerFactory<C, N>
type Error = Error;
fn init(&self, parent_header: &SubstrateHeader, authorities: &[AuthorityId], sign_with: Arc<ed25519::Pair>) -> Result<Self::Proposer, Error> {
use std::time::Duration;
const DELAY_UNTIL: Duration = Duration::from_millis(5000);
let parent_hash = parent_header.blake2_256().into();
let checked_id = self.client.check_id(BlockId::Hash(parent_hash))?;
@@ -491,6 +499,11 @@ impl<C: PolkadotApi, N: Network> bft::ProposerFactory for ProposerFactory<C, N>
let table = Arc::new(SharedTable::new(group_info, sign_with.clone(), parent_hash));
let router = self.network.table_router(table.clone());
let timeout = Timeout::new(DELAY_UNTIL, &self.handle)?;
debug!(target: "bft", "Initialising consensus proposer. Refusing to evaluate for {:?} from now.",
DELAY_UNTIL);
// TODO [PoC-2]: kick off collation process.
Ok(Proposer {
parent_hash,
@@ -499,6 +512,7 @@ impl<C: PolkadotApi, N: Network> bft::ProposerFactory for ProposerFactory<C, N>
local_key: sign_with,
client: self.client.clone(),
transaction_pool: self.transaction_pool.clone(),
delay: timeout.shared(),
_table: table,
_router: router,
})
@@ -521,6 +535,7 @@ pub struct Proposer<C: PolkadotApi, R> {
client: Arc<C>,
local_key: Arc<ed25519::Pair>,
transaction_pool: Arc<Mutex<TransactionPool>>,
delay: Shared<Timeout>,
_table: Arc<SharedTable>,
_router: R,
}
@@ -528,9 +543,9 @@ pub struct Proposer<C: PolkadotApi, R> {
impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
type Error = Error;
type Create = Result<SubstrateBlock, Error>;
type Evaluate = Result<bool, Error>;
type Evaluate = Box<Future<Item=bool, Error=Error>>;
fn propose(&self) -> Result<SubstrateBlock, Error> {
fn propose(&self) -> Self::Create {
debug!(target: "bft", "proposing block on top of parent ({}, {:?})", self.parent_number, self.parent_hash);
// TODO: handle case when current timestamp behind that in state.
@@ -581,9 +596,10 @@ impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
}
// TODO: certain kinds of errors here should lead to a misbehavior report.
fn evaluate(&self, proposal: &SubstrateBlock) -> Result<bool, Error> {
fn evaluate(&self, proposal: &SubstrateBlock) -> Self::Evaluate {
debug!(target: "bft", "evaluating block on top of parent ({}, {:?})", self.parent_number, self.parent_hash);
match evaluate_proposal(proposal, &*self.client, current_timestamp(), &self.parent_hash, self.parent_number, &self.parent_id) {
let evaluated = match evaluate_proposal(proposal, &*self.client, current_timestamp(), &self.parent_hash, self.parent_number, &self.parent_id) {
Ok(x) => Ok(x),
Err(e) => match *e.kind() {
ErrorKind::PolkadotApi(polkadot_api::ErrorKind::Executor(_)) => Ok(false),
@@ -593,7 +609,10 @@ impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
ErrorKind::ProposalTooLarge(_) => Ok(false),
_ => Err(e),
}
}
};
// delay casting vote until able.
Box::new(self.delay.clone().map_err(Error::from).and_then(move |_| evaluated))
}
fn import_misbehavior(&self, misbehavior: Vec<(AuthorityId, bft::Misbehavior)>) {
+1
View File
@@ -276,6 +276,7 @@ impl Service {
client: client.clone(),
transaction_pool: transaction_pool.clone(),
network: Network(network.clone()),
handle: core.handle(),
};
let messages = SharedMessageCollection::new();
let bft_service = Arc::new(BftService::new(client.clone(), key, factory));