Skip to content

Commit 899444d

Browse files
committed
[WIP] Make the acceptable time gaps configurable
1 parent 33201e2 commit 899444d

File tree

4 files changed

+52
-12
lines changed

4 files changed

+52
-12
lines changed

core/src/consensus/tendermint/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ impl Tendermint {
9494
let validators = Arc::clone(&our_params.validators);
9595
let machine = Arc::new(machine);
9696

97-
let (join, extension_initializer, inner, quit_tendermint) = worker::spawn(our_params.validators);
97+
let (join, extension_initializer, inner, quit_tendermint) =
98+
worker::spawn(our_params.validators, our_params.allowed_timegaps);
9899
let action_handlers: Vec<Arc<ActionHandler>> = vec![Arc::new(stake)];
99100
let chain_notify = Arc::new(TendermintChainNotify::new(inner.clone()));
100101

core/src/consensus/tendermint/params.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
use std::collections::HashMap;
1818
use std::sync::Arc;
19+
use std::time::Duration as StdDuration;
1920

2021
use cjson;
2122
use ckey::{Address, PlatformAddress};
@@ -33,13 +34,16 @@ pub struct TendermintParams {
3334
pub timeouts: TimeoutParams,
3435
/// Reward per block in base units.
3536
pub block_reward: u64,
37+
/// Allowed time gap from the system time and the block generation time.
38+
pub allowed_timegaps: TimegapParams,
3639
/// Tokens distributed at genesis.
3740
pub genesis_stakes: HashMap<Address, u64>,
3841
}
3942

4043
impl From<cjson::scheme::TendermintParams> for TendermintParams {
4144
fn from(p: cjson::scheme::TendermintParams) -> Self {
4245
let dt = TimeoutParams::default();
46+
let dtg = TimegapParams::default();
4347
TendermintParams {
4448
validators: new_validator_set(p.validators),
4549
timeouts: TimeoutParams {
@@ -51,6 +55,16 @@ impl From<cjson::scheme::TendermintParams> for TendermintParams {
5155
precommit_delta: p.timeout_precommit_delta.map_or(dt.precommit_delta, to_duration),
5256
commit: p.timeout_commit.map_or(dt.commit, to_duration),
5357
},
58+
allowed_timegaps: TimegapParams {
59+
allowed_past_gap: p.allowed_past_timegap.map_or(dtg.allowed_past_gap, |x| {
60+
let mx: u64 = x.into();
61+
StdDuration::from_millis(mx)
62+
}),
63+
allowed_future_gap: p.allowed_future_timegap.map_or(dtg.allowed_future_gap, |x| {
64+
let mx: u64 = x.into();
65+
StdDuration::from_millis(mx)
66+
}),
67+
},
5468
block_reward: p.block_reward.map_or(0, Into::into),
5569
genesis_stakes: p
5670
.genesis_stakes
@@ -67,6 +81,20 @@ fn to_duration(ms: cjson::uint::Uint) -> Duration {
6781
Duration::milliseconds(ms as i64)
6882
}
6983

84+
pub struct TimegapParams {
85+
pub allowed_past_gap: StdDuration,
86+
pub allowed_future_gap: StdDuration,
87+
}
88+
89+
impl Default for TimegapParams {
90+
fn default() -> Self {
91+
TimegapParams {
92+
allowed_past_gap: StdDuration::from_millis(30000),
93+
allowed_future_gap: StdDuration::from_millis(5000),
94+
}
95+
}
96+
}
97+
7098
/// Base timeout of each step in ms.
7199
#[derive(Debug, Copy, Clone)]
72100
pub struct TimeoutParams {

core/src/consensus/tendermint/worker.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use rlp::{Encodable, UntrustedRlp};
3232
use super::backup::{backup, restore, BackupView};
3333
use super::message::*;
3434
use super::network;
35+
use super::params::TimegapParams;
3536
use super::types::{BitSet, Height, Proposal, Step, TendermintSealView, TendermintState, TwoThirdsMajority, View};
3637
use super::{
3738
BlockHash, ENGINE_TIMEOUT_BROADCAST_STEP_STATE, ENGINE_TIMEOUT_EMPTY_PROPOSAL, ENGINE_TIMEOUT_TOKEN_NONCE_BASE,
@@ -57,8 +58,8 @@ type SpawnResult = (
5758
crossbeam::Sender<()>,
5859
);
5960

60-
pub fn spawn(validators: Arc<ValidatorSet>) -> SpawnResult {
61-
Worker::spawn(validators)
61+
pub fn spawn(validators: Arc<ValidatorSet>, allowed_time_gaps: TimegapParams) -> SpawnResult {
62+
Worker::spawn(validators, allowed_time_gaps)
6263
}
6364

6465
struct Worker {
@@ -87,7 +88,7 @@ struct Worker {
8788
validators: Arc<ValidatorSet>,
8889
/// Channel to the network extension, must be set later.
8990
extension: EventSender<network::Event>,
90-
91+
allowed_time_gaps: TimegapParams,
9192
timeout_token_nonce: usize,
9293
}
9394

@@ -167,7 +168,12 @@ pub enum Event {
167168
impl Worker {
168169
#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_ret_no_self))]
169170
/// Create a new instance of Tendermint engine
170-
fn new(validators: Arc<ValidatorSet>, extension: EventSender<network::Event>, client: Weak<EngineClient>) -> Self {
171+
fn new(
172+
validators: Arc<ValidatorSet>,
173+
extension: EventSender<network::Event>,
174+
client: Weak<EngineClient>,
175+
allowed_time_gaps: TimegapParams,
176+
) -> Self {
171177
Worker {
172178
client,
173179
height: 1,
@@ -182,12 +188,12 @@ impl Worker {
182188
extension,
183189
votes_received: BitSet::new(),
184190
votes_received_changed: false,
185-
191+
allowed_time_gaps,
186192
timeout_token_nonce: ENGINE_TIMEOUT_TOKEN_NONCE_BASE,
187193
}
188194
}
189195

190-
fn spawn(validators: Arc<ValidatorSet>) -> SpawnResult {
196+
fn spawn(validators: Arc<ValidatorSet>, allowed_timegaps: TimegapParams) -> SpawnResult {
191197
let (sender, receiver) = crossbeam::unbounded();
192198
let (quit, quit_receiver) = crossbeam::bounded(1);
193199
let (extension_initializer, extension_receiver) = crossbeam::bounded(1);
@@ -215,7 +221,7 @@ impl Worker {
215221
}
216222
};
217223
validators.register_client(Weak::clone(&client));
218-
let mut inner = Self::new(validators, extension, client);
224+
let mut inner = Self::new(validators, extension, client, allowed_timegaps);
219225
loop {
220226
crossbeam::select! {
221227
recv(receiver) -> msg => {
@@ -690,11 +696,12 @@ impl Worker {
690696
}
691697

692698
fn is_generation_time_relevant(&self, proposal: &Header) -> bool {
693-
const ACCEPTABLE_FUTURE_GAP: Duration = Duration::from_secs(5);
694-
const ACCEPTABLE_PAST_GAP: Duration = Duration::from_secs(30);
699+
let acceptable_past_gap: Duration = self.allowed_time_gaps.allowed_past_gap;
700+
let acceptable_future_gap: Duration = self.allowed_time_gaps.allowed_future_gap;
701+
695702
let now = SystemTime::now();
696-
let allowed_min = now - ACCEPTABLE_PAST_GAP;
697-
let allowed_max = now + ACCEPTABLE_FUTURE_GAP;
703+
let allowed_min = now - acceptable_past_gap;
704+
let allowed_max = now + acceptable_future_gap;
698705
let block_generation_time = UNIX_EPOCH.checked_add(Duration::from_secs(proposal.timestamp()));
699706

700707
match block_generation_time {

json/src/scheme/tendermint.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ pub struct TendermintParams {
4444
pub block_reward: Option<Uint>,
4545
/// How much tokens are distributed at Genesis?
4646
pub genesis_stakes: Option<HashMap<PlatformAddress, u64>>,
47+
/// allowed past time gap in milliseconds.
48+
pub allowed_past_timegap: Option<Uint>,
49+
/// allowed future time gap in milliseconds.
50+
pub allowed_future_timegap: Option<Uint>,
4751
}
4852

4953
/// Tendermint engine deserialization.

0 commit comments

Comments
 (0)