From 57528698244c9e55bfe0cd6a67daaa1b2bf07c2b Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 6 Sep 2018 17:38:00 +0800 Subject: [PATCH] Support millisecond timestamp for instant seal engine (#9469) * Support millisecond timestamp for instant seal engine * Forgot to checkin instant_seal mod * Fix instant seal config * Fix json crate compile * Fix private_spec.json * Option -> bool --- ethcore/res/instant_seal.json | 4 +++- ethcore/src/engines/instant_seal.rs | 28 ++++++++++++++++++---- ethcore/src/spec/spec.rs | 2 +- ethcore/sync/src/res/private_spec.json | 6 +++-- json/src/spec/engine.rs | 8 +++---- json/src/spec/instant_seal.rs | 33 ++++++++++++++++++++++++++ json/src/spec/mod.rs | 2 ++ 7 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 json/src/spec/instant_seal.rs diff --git a/ethcore/res/instant_seal.json b/ethcore/res/instant_seal.json index 005342437..3ec998f0e 100644 --- a/ethcore/res/instant_seal.json +++ b/ethcore/res/instant_seal.json @@ -1,7 +1,9 @@ { "name": "DevelopmentChain", "engine": { - "instantSeal": null + "instantSeal": { + "params": {} + } }, "params": { "gasLimitBoundDivisor": "0x0400", diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 5719e11b1..80e9ea451 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -17,17 +17,33 @@ use engines::{Engine, Seal}; use parity_machine::{Machine, Transactions, TotalScoredHeader}; +/// `InstantSeal` params. +#[derive(Debug, PartialEq)] +pub struct InstantSealParams { + /// Whether to use millisecond timestamp + pub millisecond_timestamp: bool, +} + +impl From<::ethjson::spec::InstantSealParams> for InstantSealParams { + fn from(p: ::ethjson::spec::InstantSealParams) -> Self { + InstantSealParams { + millisecond_timestamp: p.millisecond_timestamp, + } + } +} + /// An engine which does not provide any consensus mechanism, just seals blocks internally. /// Only seals blocks which have transactions. pub struct InstantSeal { + params: InstantSealParams, machine: M, } impl InstantSeal { /// Returns new instance of InstantSeal over the given state machine. - pub fn new(machine: M) -> Self { + pub fn new(params: InstantSealParams, machine: M) -> Self { InstantSeal { - machine: machine, + params, machine, } } } @@ -56,8 +72,12 @@ impl Engine for InstantSeal fn open_block_header_timestamp(&self, parent_timestamp: u64) -> u64 { use std::{time, cmp}; - let now = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap_or_default(); - cmp::max(now.as_secs(), parent_timestamp) + let dur = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap_or_default(); + let mut now = dur.as_secs(); + if self.params.millisecond_timestamp { + now = now * 1000 + dur.subsec_millis() as u64; + } + cmp::max(now, parent_timestamp) } fn is_timestamp_valid(&self, header_timestamp: u64, parent_timestamp: u64) -> bool { diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 5131adaf7..9ba3d5d30 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -589,7 +589,7 @@ impl Spec { match engine_spec { ethjson::spec::Engine::Null(null) => Arc::new(NullEngine::new(null.params.into(), machine)), ethjson::spec::Engine::Ethash(ethash) => Arc::new(::ethereum::Ethash::new(spec_params.cache_dir, ethash.params.into(), machine, spec_params.optimization_setting)), - ethjson::spec::Engine::InstantSeal => Arc::new(InstantSeal::new(machine)), + ethjson::spec::Engine::InstantSeal(instant_seal) => Arc::new(InstantSeal::new(instant_seal.params.into(), machine)), ethjson::spec::Engine::BasicAuthority(basic_authority) => Arc::new(BasicAuthority::new(basic_authority.params.into(), machine)), ethjson::spec::Engine::AuthorityRound(authority_round) => AuthorityRound::new(authority_round.params.into(), machine) .expect("Failed to start AuthorityRound consensus engine."), diff --git a/ethcore/sync/src/res/private_spec.json b/ethcore/sync/src/res/private_spec.json index f93d754a6..1fb191c85 100644 --- a/ethcore/sync/src/res/private_spec.json +++ b/ethcore/sync/src/res/private_spec.json @@ -1,7 +1,9 @@ { "name": "PrivateTransactions", "engine": { - "instantSeal": null + "instantSeal": { + "params": {} + } }, "params": { "gasLimitBoundDivisor": "0x0400", @@ -27,4 +29,4 @@ "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } } } -} \ No newline at end of file +} diff --git a/json/src/spec/engine.rs b/json/src/spec/engine.rs index 55b9c1b2a..f8476757c 100644 --- a/json/src/spec/engine.rs +++ b/json/src/spec/engine.rs @@ -16,7 +16,7 @@ //! Engine deserialization. -use super::{Ethash, BasicAuthority, AuthorityRound, Tendermint, NullEngine}; +use super::{Ethash, BasicAuthority, AuthorityRound, Tendermint, NullEngine, InstantSeal}; /// Engine deserialization. #[derive(Debug, PartialEq, Deserialize)] @@ -26,7 +26,7 @@ pub enum Engine { Null(NullEngine), /// Instantly sealing engine. #[serde(rename="instantSeal")] - InstantSeal, + InstantSeal(InstantSeal), /// Ethash engine. Ethash(Ethash), /// BasicAuthority engine. @@ -62,12 +62,12 @@ mod tests { } let s = r#"{ - "instantSeal": null + "instantSeal": {"params": {}} }"#; let deserialized: Engine = serde_json::from_str(s).unwrap(); match deserialized { - Engine::InstantSeal => {}, // instant seal is unit tested in its own file. + Engine::InstantSeal(_) => {}, // instant seal is unit tested in its own file. _ => panic!(), }; diff --git a/json/src/spec/instant_seal.rs b/json/src/spec/instant_seal.rs new file mode 100644 index 000000000..4621a19dd --- /dev/null +++ b/json/src/spec/instant_seal.rs @@ -0,0 +1,33 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Instant seal engine params deserialization. + +/// Instant seal engine params deserialization. +#[derive(Debug, PartialEq, Deserialize)] +pub struct InstantSealParams { + /// Whether to enable millisecond timestamp. + #[serde(rename="millisecondTimestamp")] + #[serde(default)] + pub millisecond_timestamp: bool, +} + +/// Instant seal engine descriptor. +#[derive(Debug, PartialEq, Deserialize)] +pub struct InstantSeal { + /// Instant seal parameters. + pub params: InstantSealParams, +} diff --git a/json/src/spec/mod.rs b/json/src/spec/mod.rs index 26965c887..c4b10afbd 100644 --- a/json/src/spec/mod.rs +++ b/json/src/spec/mod.rs @@ -30,6 +30,7 @@ pub mod basic_authority; pub mod authority_round; pub mod tendermint; pub mod null_engine; +pub mod instant_seal; pub mod hardcoded_sync; pub use self::account::Account; @@ -46,4 +47,5 @@ pub use self::basic_authority::{BasicAuthority, BasicAuthorityParams}; pub use self::authority_round::{AuthorityRound, AuthorityRoundParams}; pub use self::tendermint::{Tendermint, TendermintParams}; pub use self::null_engine::{NullEngine, NullEngineParams}; +pub use self::instant_seal::{InstantSeal, InstantSealParams}; pub use self::hardcoded_sync::HardcodedSync;