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> -> bool
This commit is contained in:
Wei Tang 2018-09-06 17:38:00 +08:00 committed by Andronik Ordian
parent 39a12622ae
commit 5752869824
7 changed files with 71 additions and 12 deletions

View File

@ -1,7 +1,9 @@
{
"name": "DevelopmentChain",
"engine": {
"instantSeal": null
"instantSeal": {
"params": {}
}
},
"params": {
"gasLimitBoundDivisor": "0x0400",

View File

@ -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<M> {
params: InstantSealParams,
machine: M,
}
impl<M> InstantSeal<M> {
/// 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<M: Machine> Engine<M> for InstantSeal<M>
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 {

View File

@ -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."),

View File

@ -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 } } } }
}
}
}

View File

@ -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!(),
};

View File

@ -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 <http://www.gnu.org/licenses/>.
//! 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,
}

View File

@ -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;