Skip to content

Commit

Permalink
BFT delay adjustments (paritytech#593)
Browse files Browse the repository at this point in the history
* force delay only on votes

* set proposal timestamp forward

* Adjusted timeout formula
  • Loading branch information
arkpar authored and rphmeier committed Aug 31, 2018
1 parent e7d3bf7 commit 292ed2c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 24 deletions.
19 changes: 13 additions & 6 deletions consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ extern crate substrate_keyring;

use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use std::time::{Duration, Instant};
use std::time::{self, Duration, Instant};

use codec::{Decode, Encode};
use extrinsic_store::Store as ExtrinsicStore;
Expand Down Expand Up @@ -274,6 +274,9 @@ impl<C, N, P> bft::Environment<Block> for ProposerFactory<C, N, P>
) -> Result<(Self::Proposer, Self::Input, Self::Output), Error> {
use runtime_primitives::traits::{Hash as HashT, BlakeTwo256};

// force delay in evaluation this long.
const FORCE_DELAY: Timestamp = 5;

let parent_hash = parent_header.hash().into();

let id = BlockId::hash(parent_hash);
Expand Down Expand Up @@ -343,6 +346,7 @@ impl<C, N, P> bft::Environment<Block> for ProposerFactory<C, N, P>
transaction_pool: self.transaction_pool.clone(),
offline: self.offline.clone(),
validators,
minimum_timestamp: current_timestamp() + FORCE_DELAY,
_drop_signal: drop_signal,
};

Expand Down Expand Up @@ -422,6 +426,7 @@ pub struct Proposer<C: PolkadotApi + Send + Sync> {
transaction_pool: Arc<TransactionPool<C>>,
offline: SharedOfflineTracker,
validators: Vec<AccountId>,
minimum_timestamp: u64,
_drop_signal: exit_future::Signal,
}

Expand Down Expand Up @@ -473,6 +478,7 @@ impl<C> bft::Proposer<Block> for Proposer<C>
table: self.table.clone(),
offline: self.offline.clone(),
validators: self.validators.clone(),
minimum_timestamp: self.minimum_timestamp,
timing,
})
}
Expand Down Expand Up @@ -525,9 +531,11 @@ impl<C> bft::Proposer<Block> for Proposer<C>
);

// the duration until the given timestamp is current
let proposed_timestamp = proposal.timestamp();
let proposed_timestamp = ::std::cmp::max(self.minimum_timestamp, proposal.timestamp());
let timestamp_delay = if proposed_timestamp > current_timestamp {
Some(now + Duration::from_secs(proposed_timestamp - current_timestamp))
let delay_s = proposed_timestamp - current_timestamp;
debug!(target: "bft", "Delaying evaluation of proposal for {} seconds", delay_s);
Some(now + Duration::from_secs(delay_s))
} else {
None
};
Expand Down Expand Up @@ -677,8 +685,6 @@ impl<C> bft::Proposer<Block> for Proposer<C>
}

fn current_timestamp() -> Timestamp {
use std::time;

time::SystemTime::now().duration_since(time::UNIX_EPOCH)
.expect("now always later than unix epoch; qed")
.as_secs()
Expand Down Expand Up @@ -732,6 +738,7 @@ pub struct CreateProposal<C: PolkadotApi + Send + Sync> {
timing: ProposalTiming,
validators: Vec<AccountId>,
offline: SharedOfflineTracker,
minimum_timestamp: Timestamp,
}

impl<C> CreateProposal<C> where C: PolkadotApi + Send + Sync {
Expand All @@ -743,7 +750,7 @@ impl<C> CreateProposal<C> where C: PolkadotApi + Send + Sync {
const MAX_VOTE_OFFLINE_SECONDS: Duration = Duration::from_secs(60);

// TODO: handle case when current timestamp behind that in state.
let timestamp = current_timestamp();
let timestamp = ::std::cmp::max(self.minimum_timestamp, current_timestamp());

let elapsed_since_start = self.timing.dynamic_inclusion.started_at().elapsed();
let offline_indices = if elapsed_since_start > MAX_VOTE_OFFLINE_SECONDS {
Expand Down
21 changes: 3 additions & 18 deletions consensus/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use extrinsic_store::Store as ExtrinsicStore;
use tokio::executor::current_thread::TaskExecutor as LocalThreadHandle;
use tokio::runtime::TaskExecutor as ThreadPoolHandle;
use tokio::runtime::current_thread::Runtime as LocalRuntime;
use tokio::timer::{Delay, Interval};
use tokio::timer::Interval;

use super::{Network, Collators, ProposerFactory};
use error;
Expand All @@ -59,25 +59,10 @@ fn start_bft<F, C>(
<F::Proposer as bft::Proposer<Block>>::Error: ::std::fmt::Display + Into<error::Error>,
<F as bft::Environment<Block>>::Error: ::std::fmt::Display
{
const DELAY_UNTIL: Duration = Duration::from_millis(5000);

let mut handle = LocalThreadHandle::current();
match bft_service.build_upon(&header) {
Ok(Some(bft_work)) => {
// do not poll work for some amount of time.
let work = Delay::new(Instant::now() + DELAY_UNTIL).then(move |res| {
if let Err(e) = res {
warn!(target: "bft", "Failed to force delay of consensus: {:?}", e);
}

debug!(target: "bft", "Starting agreement. After forced delay for {:?}",
DELAY_UNTIL);

bft_work
});
if let Err(e) = handle.spawn_local(Box::new(work)) {
warn!(target: "bft", "Couldn't initialize BFT agreement: {:?}", e);
}
Ok(Some(bft_work)) => if let Err(e) = handle.spawn_local(Box::new(bft_work)) {
warn!(target: "bft", "Couldn't initialize BFT agreement: {:?}", e);
}
Ok(None) => trace!(target: "bft", "Could not start agreement on top of {}", header.hash()),
Err(e) => warn!(target: "bft", "BFT agreement error: {}", e),
Expand Down

0 comments on commit 292ed2c

Please sign in to comment.