Skip to content

Commit a72d782

Browse files
committed
Make the acceptable time gaps configurable
1 parent 9dd53eb commit a72d782

File tree

12 files changed

+84
-14
lines changed

12 files changed

+84
-14
lines changed

codechain/codechain.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ version_short: "v"
33
author: CodeChain Team <[email protected]>
44
about: CodeChian client
55
args:
6+
- allowed-future-gap:
7+
long: allowed-future-gap
8+
value_name: MS
9+
help: Specify the allowed gap in future direction from the system time to the block generation time. MS is time measured in milliseconds.
10+
takes_value: true
11+
- allowed-past-gap:
12+
long: allowed-past-gap
13+
value_name: MS
14+
help: Specify the allowed gap in past direction from the system time to the block generation time. MS is time measured in milliseconds.
15+
takes_value: true
616
- config:
717
long: config
818
help: Specify the certain config file path that you want to use to configure CodeChain to your needs.

codechain/config/mod.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::fs;
2020
use std::str::{self, FromStr};
2121
use std::time::Duration;
2222

23-
use ccore::{MinerOptions, StratumConfig};
23+
use ccore::{MinerOptions, StratumConfig, TimeGapParams};
2424
use cidr::IpCidr;
2525
use ckey::PlatformAddress;
2626
use clap;
@@ -225,6 +225,8 @@ pub struct Mining {
225225
pub reseal_max_period: Option<u64>,
226226
pub no_reseal_timer: Option<bool>,
227227
pub work_queue_size: Option<usize>,
228+
pub allowed_past_gap: Option<u64>,
229+
pub allowed_future_gap: Option<u64>,
228230
}
229231

230232
#[derive(Deserialize)]
@@ -439,8 +441,24 @@ impl Mining {
439441
if let Some(work_queue_size) = matches.value_of("work-queue-size") {
440442
self.work_queue_size = Some(work_queue_size.parse().map_err(|_| "Invalid size")?);
441443
}
444+
if let Some(allowed_past_gap) = matches.value_of("allowed-past-gap") {
445+
self.allowed_past_gap = Some(allowed_past_gap.parse().map_err(|_| "Invalid time gap")?);
446+
}
447+
if let Some(allowed_future_gap) = matches.value_of("allowed-future-gap") {
448+
self.allowed_future_gap = Some(allowed_future_gap.parse().map_err(|_| "Invalid time gap")?);
449+
}
442450
Ok(())
443451
}
452+
453+
pub fn create_time_gaps(&self) -> TimeGapParams {
454+
let allowed_past_gap = Duration::from_millis(self.allowed_past_gap.unwrap_or(30000));
455+
let allowed_future_gap = Duration::from_millis(self.allowed_future_gap.unwrap_or(5000));
456+
457+
TimeGapParams {
458+
allowed_past_gap,
459+
allowed_future_gap,
460+
}
461+
}
444462
}
445463

446464
impl Network {

codechain/config/presets/config.dev.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ reseal_min_period = 0
1717
reseal_max_period = 120000
1818
no_reseal_timer = false
1919
work_queue_size = 20
20+
allowed_past_gap = 30000
21+
allowed_future_gap = 5000
2022

2123
[network]
2224
disable = false

codechain/config/presets/config.prod.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ reseal_min_period = 4000
1717
reseal_max_period = 120000
1818
no_reseal_timer = false
1919
work_queue_size = 20
20+
allowed_past_gap = 30000
21+
allowed_future_gap = 5000
2022

2123
[network]
2224
disable = false

codechain/run_node.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,13 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> {
239239
::std::thread::sleep(Duration::from_secs(wait_before_shutdown));
240240
});
241241

242+
let time_gap_params = config.mining.create_time_gaps();
243+
242244
let scheme = match &config.operating.chain {
243245
Some(chain) => chain.scheme()?,
244246
None => return Err("chain is not specified".to_string()),
245247
};
248+
scheme.engine.register_time_gap_config_to_worker(time_gap_params);
246249

247250
let instance_id = config.operating.instance_id.unwrap_or(
248251
SystemTime::now()

core/src/consensus/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub use self::cuckoo::Cuckoo;
3131
pub use self::null_engine::NullEngine;
3232
pub use self::simple_poa::SimplePoA;
3333
pub use self::solo::Solo;
34-
pub use self::tendermint::{Tendermint, TendermintParams};
34+
pub use self::tendermint::{Tendermint, TendermintParams, TimeGapParams};
3535
pub use self::validator_set::validator_list::ValidatorList;
3636
pub use self::validator_set::ValidatorSet;
3737

@@ -282,6 +282,8 @@ pub trait ConsensusEngine<M: Machine>: Sync + Send {
282282

283283
fn register_network_extension_to_service(&self, _: &NetworkService) {}
284284

285+
fn register_time_gap_config_to_worker(&self, _time_gap_params: TimeGapParams) {}
286+
285287
fn score_to_target(&self, _score: &U256) -> U256 {
286288
U256::zero()
287289
}

core/src/consensus/tendermint/engine.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use crate::consensus::EngineType;
4343
use crate::error::Error;
4444
use crate::header::Header;
4545
use crate::views::HeaderView;
46+
use consensus::tendermint::params::TimeGapParams;
4647

4748
impl ConsensusEngine<CodeChainMachine> for Tendermint {
4849
fn name(&self) -> &str {
@@ -265,6 +266,10 @@ impl ConsensusEngine<CodeChainMachine> for Tendermint {
265266
receiver.recv().unwrap();
266267
}
267268

269+
fn register_time_gap_config_to_worker(&self, time_gap_params: TimeGapParams) {
270+
self.external_params_initializer.send(time_gap_params).unwrap();
271+
}
272+
268273
fn block_reward(&self, _block_number: u64) -> u64 {
269274
self.block_reward
270275
}

core/src/consensus/tendermint/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use parking_lot::RwLock;
3535
use primitives::H256;
3636

3737
use self::chain_notify::TendermintChainNotify;
38-
pub use self::params::{TendermintParams, TimeoutParams};
38+
pub use self::params::{TendermintParams, TimeGapParams, TimeoutParams};
3939
use self::types::{Height, Step, View};
4040
use super::stake;
4141
use super::validator_set::ValidatorSet;
@@ -58,6 +58,7 @@ pub type BlockHash = H256;
5858
/// ConsensusEngine using `Tendermint` consensus algorithm
5959
pub struct Tendermint {
6060
client: RwLock<Option<Weak<EngineClient>>>,
61+
external_params_initializer: crossbeam::Sender<TimeGapParams>,
6162
extension_initializer: crossbeam::Sender<(crossbeam::Sender<network::Event>, Weak<EngineClient>)>,
6263
timeouts: TimeoutParams,
6364
join: Option<JoinHandle<()>>,
@@ -94,12 +95,14 @@ impl Tendermint {
9495
let validators = Arc::clone(&our_params.validators);
9596
let machine = Arc::new(machine);
9697

97-
let (join, extension_initializer, inner, quit_tendermint) = worker::spawn(our_params.validators);
98+
let (join, external_params_initializer, extension_initializer, inner, quit_tendermint) =
99+
worker::spawn(our_params.validators);
98100
let action_handlers: Vec<Arc<ActionHandler>> = vec![Arc::new(stake)];
99101
let chain_notify = Arc::new(TendermintChainNotify::new(inner.clone()));
100102

101103
Arc::new(Tendermint {
102104
client: Default::default(),
105+
external_params_initializer,
103106
extension_initializer,
104107
timeouts,
105108
join: Some(join),

core/src/consensus/tendermint/params.rs

Lines changed: 6 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};
@@ -67,6 +68,11 @@ fn to_duration(ms: cjson::uint::Uint) -> Duration {
6768
Duration::milliseconds(ms as i64)
6869
}
6970

71+
pub struct TimeGapParams {
72+
pub allowed_past_gap: StdDuration,
73+
pub allowed_future_gap: StdDuration,
74+
}
75+
7076
/// Base timeout of each step in ms.
7177
#[derive(Debug, Copy, Clone)]
7278
pub struct TimeoutParams {

core/src/consensus/tendermint/worker.rs

Lines changed: 24 additions & 9 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,
@@ -52,6 +53,7 @@ use crate::BlockId;
5253

5354
type SpawnResult = (
5455
JoinHandle<()>,
56+
crossbeam::Sender<TimeGapParams>,
5557
crossbeam::Sender<(crossbeam::Sender<network::Event>, Weak<EngineClient>)>,
5658
crossbeam::Sender<Event>,
5759
crossbeam::Sender<()>,
@@ -87,7 +89,7 @@ struct Worker {
8789
validators: Arc<ValidatorSet>,
8890
/// Channel to the network extension, must be set later.
8991
extension: EventSender<network::Event>,
90-
92+
time_gap_params: TimeGapParams,
9193
timeout_token_nonce: usize,
9294
}
9395

@@ -167,7 +169,12 @@ pub enum Event {
167169
impl Worker {
168170
#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_ret_no_self))]
169171
/// Create a new instance of Tendermint engine
170-
fn new(validators: Arc<ValidatorSet>, extension: EventSender<network::Event>, client: Weak<EngineClient>) -> Self {
172+
fn new(
173+
validators: Arc<ValidatorSet>,
174+
extension: EventSender<network::Event>,
175+
client: Weak<EngineClient>,
176+
time_gap_params: TimeGapParams,
177+
) -> Self {
171178
Worker {
172179
client,
173180
height: 1,
@@ -182,18 +189,26 @@ impl Worker {
182189
extension,
183190
votes_received: BitSet::new(),
184191
votes_received_changed: false,
185-
192+
time_gap_params,
186193
timeout_token_nonce: ENGINE_TIMEOUT_TOKEN_NONCE_BASE,
187194
}
188195
}
189196

190197
fn spawn(validators: Arc<ValidatorSet>) -> SpawnResult {
191198
let (sender, receiver) = crossbeam::unbounded();
192199
let (quit, quit_receiver) = crossbeam::bounded(1);
200+
let (external_params_initializer, external_params_receiver) = crossbeam::bounded(1);
193201
let (extension_initializer, extension_receiver) = crossbeam::bounded(1);
194202
let join = Builder::new()
195203
.name("tendermint".to_string())
196204
.spawn(move || {
205+
let time_gap_params = match external_params_receiver.recv() {
206+
Ok(time_gap_params) => time_gap_params,
207+
Err(crossbeam::RecvError) => {
208+
cerror!(ENGINE, "The tendermint external parameters are not initialized");
209+
return
210+
}
211+
};
197212
let (extension, client) = crossbeam::select! {
198213
recv(extension_receiver) -> msg => {
199214
match msg {
@@ -215,7 +230,7 @@ impl Worker {
215230
}
216231
};
217232
validators.register_client(Weak::clone(&client));
218-
let mut inner = Self::new(validators, extension, client);
233+
let mut inner = Self::new(validators, extension, client, time_gap_params);
219234
loop {
220235
crossbeam::select! {
221236
recv(receiver) -> msg => {
@@ -342,7 +357,7 @@ impl Worker {
342357
}
343358
})
344359
.unwrap();
345-
(join, extension_initializer, sender, quit)
360+
(join, external_params_initializer, extension_initializer, sender, quit)
346361
}
347362

348363
/// The client is a thread-safe struct. Using it in multi-threads is safe.
@@ -693,11 +708,11 @@ impl Worker {
693708
}
694709

695710
fn is_generation_time_relevant(&self, block_header: &Header) -> bool {
696-
const ACCEPTABLE_FUTURE_GAP: Duration = Duration::from_secs(5);
697-
const ACCEPTABLE_PAST_GAP: Duration = Duration::from_secs(30);
711+
let acceptable_past_gap = self.time_gap_params.allowed_past_gap;
712+
let acceptable_future_gap = self.time_gap_params.allowed_future_gap;
698713
let now = SystemTime::now();
699-
let allowed_min = now - ACCEPTABLE_PAST_GAP;
700-
let allowed_max = now + ACCEPTABLE_FUTURE_GAP;
714+
let allowed_min = now - acceptable_past_gap;
715+
let allowed_max = now + acceptable_future_gap;
701716
let block_generation_time = UNIX_EPOCH.checked_add(Duration::from_secs(block_header.timestamp()));
702717

703718
match block_generation_time {

0 commit comments

Comments
 (0)