Generalize engine trait (#6591)

* move common forks and parameters to common params

* port specs over to new format

* fix RPC tests

* parity-machine skeleton

* remove block type

* extract out ethereum-specific methods into EthereumMachine

* beginning to integrate Machine into engines. dealing with stale transitions in Ethash

* initial porting to machine

* move block reward back into engine

* abstract block reward logic

* move last hash and DAO HF logic into machine

* begin making engine function parameters generic

* abstract epoch verifier and ethash block reward logic

* instantiate special ethereummachine for ethash in spec

* optional full verification in verify_block_family

* re-instate tx_filter in a way that works for all engines

* fix warnings

* fix most tests, further generalize engine trait

* uncomment nullengine, get ethcore tests compiling

* fix warnings

* update a bunch of specs

* re-enable engine signer, validator set, and transition handler

* migrate basic_authority engine

* move last hashes into executedblock

* port tendermint

* make all ethcore tests pass

* json-tests compilation

* fix RPC tests: change in gas limit for new block changed PoW hash

* fix minor grumbles

* validate chainspecs

* fix broken import

* fix transaction verification for pre-homestead
This commit is contained in:
Robert Habermeier
2017-09-26 14:19:08 +02:00
committed by Gav Wood
parent d8af9f4e7b
commit bc167a211b
85 changed files with 2233 additions and 1923 deletions

View File

@@ -40,6 +40,9 @@ pub struct AuthorityRoundParams {
/// Whether transitions should be immediate.
#[serde(rename="immediateTransitions")]
pub immediate_transitions: Option<bool>,
/// Reward per block in wei.
#[serde(rename="blockReward")]
pub block_reward: Option<Uint>,
}
/// Authority engine deserialization.
@@ -67,7 +70,8 @@ mod tests {
"list" : ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"]
},
"startStep" : 24,
"validateStepTransition": 150
"validateStepTransition": 150,
"blockReward": 5000000
}
}"#;
@@ -76,5 +80,6 @@ mod tests {
assert_eq!(deserialized.params.validators, ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))]));
assert_eq!(deserialized.params.start_step, Some(Uint(U256::from(24))));
assert_eq!(deserialized.params.immediate_transitions, None);
}
}

View File

@@ -16,14 +16,14 @@
//! Engine deserialization.
use super::{Ethash, BasicAuthority, AuthorityRound, Tendermint};
use super::{Ethash, BasicAuthority, AuthorityRound, Tendermint, NullEngine};
/// Engine deserialization.
#[derive(Debug, PartialEq, Deserialize)]
pub enum Engine {
/// Null engine.
#[serde(rename="null")]
Null,
Null(NullEngine),
/// Instantly sealing engine.
#[serde(rename="instantSeal")]
InstantSeal,
@@ -48,11 +48,18 @@ mod tests {
#[test]
fn engine_deserialization() {
let s = r#"{
"null": null
"null": {
"params": {
"blockReward": "0x0d"
}
}
}"#;
let deserialized: Engine = serde_json::from_str(s).unwrap();
assert_eq!(Engine::Null, deserialized);
match deserialized {
Engine::Null(_) => {}, // unit test in its own file.
_ => panic!(),
}
let s = r#"{
"instantSeal": null
@@ -61,7 +68,7 @@ mod tests {
let deserialized: Engine = serde_json::from_str(s).unwrap();
match deserialized {
Engine::InstantSeal => {}, // instant seal is unit tested in its own file.
_ => assert!(false),
_ => panic!(),
};
let s = r#"{
@@ -82,7 +89,7 @@ mod tests {
let deserialized: Engine = serde_json::from_str(s).unwrap();
match deserialized {
Engine::Ethash(_) => {}, // ethash is unit tested in its own file.
_ => assert!(false),
_ => panic!(),
};
let s = r#"{
@@ -98,7 +105,7 @@ mod tests {
let deserialized: Engine = serde_json::from_str(s).unwrap();
match deserialized {
Engine::BasicAuthority(_) => {}, // basicAuthority is unit tested in its own file.
_ => assert!(false),
_ => panic!(),
};
let s = r#"{
@@ -116,7 +123,7 @@ mod tests {
let deserialized: Engine = serde_json::from_str(s).unwrap();
match deserialized {
Engine::AuthorityRound(_) => {}, // AuthorityRound is unit tested in its own file.
_ => assert!(false),
_ => panic!(),
};
let s = r#"{
@@ -131,7 +138,7 @@ mod tests {
let deserialized: Engine = serde_json::from_str(s).unwrap();
match deserialized {
Engine::Tendermint(_) => {}, // Tendermint is unit tested in its own file.
_ => assert!(false),
_ => panic!(),
};
}
}

View File

@@ -20,7 +20,7 @@ use uint::Uint;
use hash::Address;
/// Deserializable doppelganger of EthashParams.
#[derive(Debug, PartialEq, Deserialize)]
#[derive(Clone, Debug, PartialEq, Deserialize)]
pub struct EthashParams {
/// See main EthashParams docs.
#[serde(rename="minimumDifficulty")]
@@ -41,6 +41,9 @@ pub struct EthashParams {
/// See main EthashParams docs.
#[serde(rename="homesteadTransition")]
pub homestead_transition: Option<Uint>,
/// Reward per block in wei.
#[serde(rename="blockReward")]
pub block_reward: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="daoHardforkTransition")]
@@ -91,27 +94,6 @@ pub struct EthashParams {
/// See main EthashParams docs.
#[serde(rename="ecip1017EraRounds")]
pub ecip1017_era_rounds: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="maxCodeSize")]
pub max_code_size: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="maxGasLimitTransition")]
pub max_gas_limit_transition: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="maxGasLimit")]
pub max_gas_limit: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="minGasPriceTransition")]
pub min_gas_price_transition: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="minGasPrice")]
pub min_gas_price: Option<Uint>,
/// EIP-649 transition block.
#[serde(rename="eip649Transition")]
pub eip649_transition: Option<Uint>,
@@ -148,6 +130,7 @@ mod tests {
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"homesteadTransition": "0x42",
"blockReward": "0x100",
"daoHardforkTransition": "0x08",
"daoHardforkBeneficiary": "0xabcabcabcabcabcabcabcabcabcabcabcabcabca",
"daoHardforkAccounts": [
@@ -193,6 +176,7 @@ mod tests {
metropolis_difficulty_increment_divisor: None,
duration_limit: Some(Uint(U256::from(0x0d))),
homestead_transition: Some(Uint(U256::from(0x42))),
block_reward: Some(Uint(U256::from(0x100))),
dao_hardfork_transition: Some(Uint(U256::from(0x08))),
dao_hardfork_beneficiary: Some(Address(H160::from("0xabcabcabcabcabcabcabcabcabcabcabcabcabca"))),
dao_hardfork_accounts: Some(vec![
@@ -228,11 +212,6 @@ mod tests {
ecip1010_pause_transition: None,
ecip1010_continue_transition: None,
ecip1017_era_rounds: None,
max_code_size: None,
max_gas_limit_transition: None,
max_gas_limit: None,
min_gas_price_transition: None,
min_gas_price: None,
eip649_transition: None,
eip649_delay: None,
eip649_reward: None,
@@ -258,6 +237,7 @@ mod tests {
metropolis_difficulty_increment_divisor: None,
duration_limit: None,
homestead_transition: None,
block_reward: None,
dao_hardfork_transition: None,
dao_hardfork_beneficiary: None,
dao_hardfork_accounts: None,
@@ -272,11 +252,6 @@ mod tests {
ecip1010_pause_transition: None,
ecip1010_continue_transition: None,
ecip1017_era_rounds: None,
max_code_size: None,
max_gas_limit_transition: None,
max_gas_limit: None,
min_gas_price_transition: None,
min_gas_price: None,
eip649_transition: None,
eip649_delay: None,
eip649_reward: None,

View File

@@ -29,6 +29,7 @@ pub mod validator_set;
pub mod basic_authority;
pub mod authority_round;
pub mod tendermint;
pub mod null_engine;
pub use self::account::Account;
pub use self::builtin::{Builtin, Pricing, Linear};
@@ -43,3 +44,4 @@ pub use self::validator_set::ValidatorSet;
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};

View File

@@ -0,0 +1,54 @@
// Copyright 2015-2017 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/>.
//! Null engine params deserialization.
use uint::Uint;
/// Authority params deserialization.
#[derive(Debug, PartialEq, Deserialize)]
pub struct NullEngineParams {
/// Block reward.
#[serde(rename="blockReward")]
pub block_reward: Option<Uint>,
}
/// Null engine descriptor
#[derive(Debug, PartialEq, Deserialize)]
pub struct NullEngine {
/// Ethash params.
pub params: NullEngineParams,
}
#[cfg(test)]
mod tests {
use serde_json;
use uint::Uint;
use bigint::prelude::U256;
use super::*;
#[test]
fn null_engine_deserialization() {
let s = r#"{
"params": {
"blockReward": "0x0d"
}
}"#;
let deserialized: NullEngine = serde_json::from_str(s).unwrap();
assert_eq!(deserialized.params.block_reward, Some(Uint(U256::from(0x0d))));
}
}

View File

@@ -101,9 +101,6 @@ pub struct Params {
#[serde(rename="gasLimitBoundDivisor")]
pub gas_limit_bound_divisor: Uint,
/// See `CommonParams` docs.
#[serde(rename="blockReward")]
pub block_reward: Option<Uint>,
/// See `CommonParams` docs.
pub registrar: Option<Address>,
/// Apply reward flag
#[serde(rename="applyReward")]
@@ -111,6 +108,9 @@ pub struct Params {
/// Node permission contract address.
#[serde(rename="nodePermissionContract")]
pub node_permission_contract: Option<Address>,
/// See main EthashParams docs.
#[serde(rename="maxCodeSize")]
pub max_code_size: Option<Uint>,
/// Transaction permission contract address.
#[serde(rename="transactionPermissionContract")]
pub transaction_permission_contract: Option<Address>,
@@ -132,7 +132,8 @@ mod tests {
"subprotocolName" : "exp",
"minGasLimit": "0x1388",
"accountStartNonce": "0x01",
"gasLimitBoundDivisor": "0x20"
"gasLimitBoundDivisor": "0x20",
"maxCodeSize": "0x1000"
}"#;
let deserialized: Params = serde_json::from_str(s).unwrap();
@@ -143,5 +144,6 @@ mod tests {
assert_eq!(deserialized.min_gas_limit, Uint(U256::from(0x1388)));
assert_eq!(deserialized.account_start_nonce, Some(Uint(U256::from(0x01))));
assert_eq!(deserialized.gas_limit_bound_divisor, Uint(U256::from(0x20)));
assert_eq!(deserialized.max_code_size, Some(Uint(U256::from(0x1000))));
}
}

View File

@@ -36,6 +36,9 @@ pub struct TendermintParams {
/// Commit step timeout in milliseconds.
#[serde(rename="timeoutCommit")]
pub timeout_commit: Option<Uint>,
/// Reward per block.
#[serde(rename="blockReward")]
pub block_reward: Option<Uint>,
}
/// Tendermint engine deserialization.