Move more params to the common section. (#6134)
* move common forks and parameters to common params * port specs over to new format * fix RPC tests
This commit is contained in:
committed by
Gav Wood
parent
9c5ef1f776
commit
003eef982b
@@ -47,22 +47,14 @@ mod finality;
|
||||
|
||||
/// `AuthorityRound` params.
|
||||
pub struct AuthorityRoundParams {
|
||||
/// Gas limit divisor.
|
||||
pub gas_limit_bound_divisor: U256,
|
||||
/// Time to wait before next block or authority switching.
|
||||
pub step_duration: Duration,
|
||||
/// Block reward.
|
||||
pub block_reward: U256,
|
||||
/// Namereg contract address.
|
||||
pub registrar: Address,
|
||||
/// Starting step,
|
||||
pub start_step: Option<u64>,
|
||||
/// Valid validators.
|
||||
pub validators: Box<ValidatorSet>,
|
||||
/// Chain score validation transition block.
|
||||
pub validate_score_transition: u64,
|
||||
/// Number of first block where EIP-155 rules are validated.
|
||||
pub eip155_transition: u64,
|
||||
/// Monotonic step validation transition block.
|
||||
pub validate_step_transition: u64,
|
||||
/// Immediate transitions.
|
||||
@@ -72,14 +64,10 @@ pub struct AuthorityRoundParams {
|
||||
impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
fn from(p: ethjson::spec::AuthorityRoundParams) -> Self {
|
||||
AuthorityRoundParams {
|
||||
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
|
||||
step_duration: Duration::from_secs(p.step_duration.into()),
|
||||
validators: new_validator_set(p.validators),
|
||||
block_reward: p.block_reward.map_or_else(U256::zero, Into::into),
|
||||
registrar: p.registrar.map_or_else(Address::new, Into::into),
|
||||
start_step: p.start_step.map(Into::into),
|
||||
validate_score_transition: p.validate_score_transition.map_or(0, Into::into),
|
||||
eip155_transition: p.eip155_transition.map_or(0, Into::into),
|
||||
validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
|
||||
immediate_transitions: p.immediate_transitions.unwrap_or(false),
|
||||
}
|
||||
@@ -214,9 +202,6 @@ impl EpochManager {
|
||||
/// Engine using `AuthorityRound` proof-of-authority BFT consensus.
|
||||
pub struct AuthorityRound {
|
||||
params: CommonParams,
|
||||
gas_limit_bound_divisor: U256,
|
||||
block_reward: U256,
|
||||
registrar: Address,
|
||||
builtins: BTreeMap<Address, Builtin>,
|
||||
transition_service: IoService<()>,
|
||||
step: Arc<Step>,
|
||||
@@ -225,7 +210,6 @@ pub struct AuthorityRound {
|
||||
signer: RwLock<EngineSigner>,
|
||||
validators: Box<ValidatorSet>,
|
||||
validate_score_transition: u64,
|
||||
eip155_transition: u64,
|
||||
validate_step_transition: u64,
|
||||
epoch_manager: Mutex<EpochManager>,
|
||||
immediate_transitions: bool,
|
||||
@@ -362,9 +346,6 @@ impl AuthorityRound {
|
||||
let engine = Arc::new(
|
||||
AuthorityRound {
|
||||
params: params,
|
||||
gas_limit_bound_divisor: our_params.gas_limit_bound_divisor,
|
||||
block_reward: our_params.block_reward,
|
||||
registrar: our_params.registrar,
|
||||
builtins: builtins,
|
||||
transition_service: IoService::<()>::start()?,
|
||||
step: Arc::new(Step {
|
||||
@@ -377,7 +358,6 @@ impl AuthorityRound {
|
||||
signer: Default::default(),
|
||||
validators: our_params.validators,
|
||||
validate_score_transition: our_params.validate_score_transition,
|
||||
eip155_transition: our_params.eip155_transition,
|
||||
validate_step_transition: our_params.validate_step_transition,
|
||||
epoch_manager: Mutex::new(EpochManager::blank()),
|
||||
immediate_transitions: our_params.immediate_transitions,
|
||||
@@ -433,7 +413,9 @@ impl Engine for AuthorityRound {
|
||||
|
||||
fn params(&self) -> &CommonParams { &self.params }
|
||||
|
||||
fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.registrar.hex()] }
|
||||
fn additional_params(&self) -> HashMap<String, String> {
|
||||
hash_map!["registrar".to_owned() => self.params().registrar.hex()]
|
||||
}
|
||||
|
||||
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
|
||||
|
||||
@@ -461,7 +443,7 @@ impl Engine for AuthorityRound {
|
||||
header.set_difficulty(new_difficulty);
|
||||
header.set_gas_limit({
|
||||
let gas_limit = parent.gas_limit().clone();
|
||||
let bound_divisor = self.gas_limit_bound_divisor;
|
||||
let bound_divisor = self.params().gas_limit_bound_divisor;
|
||||
if gas_limit < gas_floor_target {
|
||||
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
|
||||
} else {
|
||||
@@ -564,7 +546,8 @@ impl Engine for AuthorityRound {
|
||||
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
|
||||
let fields = block.fields_mut();
|
||||
// Bestow block reward
|
||||
let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty)
|
||||
let reward = self.params().block_reward;
|
||||
let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty)
|
||||
.map_err(::error::Error::from)
|
||||
.and_then(|_| fields.state.commit());
|
||||
// Commit state so that we can actually figure out the state root.
|
||||
@@ -629,7 +612,7 @@ impl Engine for AuthorityRound {
|
||||
}
|
||||
}
|
||||
|
||||
let gas_limit_divisor = self.gas_limit_bound_divisor;
|
||||
let gas_limit_divisor = self.params().gas_limit_bound_divisor;
|
||||
let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor;
|
||||
let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor;
|
||||
if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas {
|
||||
@@ -819,7 +802,7 @@ impl Engine for AuthorityRound {
|
||||
t.check_low_s()?;
|
||||
|
||||
if let Some(n) = t.network_id() {
|
||||
if header.number() >= self.eip155_transition && n != self.params().chain_id {
|
||||
if header.number() >= self.params().eip155_transition && n != self.params().chain_id {
|
||||
return Err(TransactionError::InvalidNetworkId.into());
|
||||
}
|
||||
}
|
||||
@@ -1014,18 +997,19 @@ mod tests {
|
||||
fn reports_skipped() {
|
||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||
let params = AuthorityRoundParams {
|
||||
gas_limit_bound_divisor: U256::from_str("400").unwrap(),
|
||||
step_duration: Default::default(),
|
||||
block_reward: Default::default(),
|
||||
registrar: Default::default(),
|
||||
start_step: Some(1),
|
||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||
validate_score_transition: 0,
|
||||
validate_step_transition: 0,
|
||||
eip155_transition: 0,
|
||||
immediate_transitions: true,
|
||||
};
|
||||
let aura = AuthorityRound::new(Default::default(), params, Default::default()).unwrap();
|
||||
|
||||
let aura = {
|
||||
let mut c_params = ::spec::CommonParams::default();
|
||||
c_params.gas_limit_bound_divisor = 5.into();
|
||||
AuthorityRound::new(c_params, params, Default::default()).unwrap()
|
||||
};
|
||||
|
||||
let mut parent_header: Header = Header::default();
|
||||
parent_header.set_seal(vec![encode(&1usize).into_vec()]);
|
||||
|
||||
@@ -35,8 +35,6 @@ use super::validator_set::{ValidatorSet, SimpleList, new_validator_set};
|
||||
/// `BasicAuthority` params.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct BasicAuthorityParams {
|
||||
/// Gas limit divisor.
|
||||
pub gas_limit_bound_divisor: U256,
|
||||
/// Valid signatories.
|
||||
pub validators: ethjson::spec::ValidatorSet,
|
||||
}
|
||||
@@ -44,7 +42,6 @@ pub struct BasicAuthorityParams {
|
||||
impl From<ethjson::spec::BasicAuthorityParams> for BasicAuthorityParams {
|
||||
fn from(p: ethjson::spec::BasicAuthorityParams) -> Self {
|
||||
BasicAuthorityParams {
|
||||
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
|
||||
validators: p.validators,
|
||||
}
|
||||
}
|
||||
@@ -80,7 +77,6 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err
|
||||
/// Engine using `BasicAuthority`, trivial proof-of-authority consensus.
|
||||
pub struct BasicAuthority {
|
||||
params: CommonParams,
|
||||
gas_limit_bound_divisor: U256,
|
||||
builtins: BTreeMap<Address, Builtin>,
|
||||
signer: RwLock<EngineSigner>,
|
||||
validators: Box<ValidatorSet>,
|
||||
@@ -91,7 +87,6 @@ impl BasicAuthority {
|
||||
pub fn new(params: CommonParams, our_params: BasicAuthorityParams, builtins: BTreeMap<Address, Builtin>) -> Self {
|
||||
BasicAuthority {
|
||||
params: params,
|
||||
gas_limit_bound_divisor: our_params.gas_limit_bound_divisor,
|
||||
builtins: builtins,
|
||||
validators: new_validator_set(our_params.validators),
|
||||
signer: Default::default(),
|
||||
@@ -119,7 +114,7 @@ impl Engine for BasicAuthority {
|
||||
header.set_difficulty(parent.difficulty().clone());
|
||||
header.set_gas_limit({
|
||||
let gas_limit = parent.gas_limit().clone();
|
||||
let bound_divisor = self.gas_limit_bound_divisor;
|
||||
let bound_divisor = self.params().gas_limit_bound_divisor;
|
||||
if gas_limit < gas_floor_target {
|
||||
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
|
||||
} else {
|
||||
@@ -172,7 +167,7 @@ impl Engine for BasicAuthority {
|
||||
if header.difficulty() != parent.difficulty() {
|
||||
return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: *parent.difficulty(), found: *header.difficulty() })))
|
||||
}
|
||||
let gas_limit_divisor = self.gas_limit_bound_divisor;
|
||||
let gas_limit_divisor = self.params().gas_limit_bound_divisor;
|
||||
let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor;
|
||||
let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor;
|
||||
if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas {
|
||||
|
||||
@@ -24,16 +24,14 @@ use block::ExecutedBlock;
|
||||
/// An engine which does not provide any consensus mechanism, just seals blocks internally.
|
||||
pub struct InstantSeal {
|
||||
params: CommonParams,
|
||||
registrar: Address,
|
||||
builtins: BTreeMap<Address, Builtin>,
|
||||
}
|
||||
|
||||
impl InstantSeal {
|
||||
/// Returns new instance of InstantSeal with default VM Factory
|
||||
pub fn new(params: CommonParams, registrar: Address, builtins: BTreeMap<Address, Builtin>) -> Self {
|
||||
pub fn new(params: CommonParams, builtins: BTreeMap<Address, Builtin>) -> Self {
|
||||
InstantSeal {
|
||||
params: params,
|
||||
registrar: registrar,
|
||||
builtins: builtins,
|
||||
}
|
||||
}
|
||||
@@ -49,7 +47,7 @@ impl Engine for InstantSeal {
|
||||
}
|
||||
|
||||
fn additional_params(&self) -> HashMap<String, String> {
|
||||
hash_map!["registrar".to_owned() => self.registrar.hex()]
|
||||
hash_map!["registrar".to_owned() => self.params().registrar.hex()]
|
||||
}
|
||||
|
||||
fn builtins(&self) -> &BTreeMap<Address, Builtin> {
|
||||
|
||||
@@ -71,12 +71,9 @@ pub type BlockHash = H256;
|
||||
/// Engine using `Tendermint` consensus algorithm, suitable for EVM chain.
|
||||
pub struct Tendermint {
|
||||
params: CommonParams,
|
||||
gas_limit_bound_divisor: U256,
|
||||
builtins: BTreeMap<Address, Builtin>,
|
||||
step_service: IoService<Step>,
|
||||
client: RwLock<Option<Weak<EngineClient>>>,
|
||||
block_reward: U256,
|
||||
registrar: Address,
|
||||
/// Blockchain height.
|
||||
height: AtomicUsize,
|
||||
/// Consensus view.
|
||||
@@ -166,12 +163,9 @@ impl Tendermint {
|
||||
let engine = Arc::new(
|
||||
Tendermint {
|
||||
params: params,
|
||||
gas_limit_bound_divisor: our_params.gas_limit_bound_divisor,
|
||||
builtins: builtins,
|
||||
client: RwLock::new(None),
|
||||
step_service: IoService::<Step>::start()?,
|
||||
block_reward: our_params.block_reward,
|
||||
registrar: our_params.registrar,
|
||||
height: AtomicUsize::new(1),
|
||||
view: AtomicUsize::new(0),
|
||||
step: RwLock::new(Step::Propose),
|
||||
@@ -446,7 +440,9 @@ impl Engine for Tendermint {
|
||||
|
||||
fn params(&self) -> &CommonParams { &self.params }
|
||||
|
||||
fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.registrar.hex()] }
|
||||
fn additional_params(&self) -> HashMap<String, String> {
|
||||
hash_map!["registrar".to_owned() => self.params().registrar.hex()]
|
||||
}
|
||||
|
||||
fn builtins(&self) -> &BTreeMap<Address, Builtin> { &self.builtins }
|
||||
|
||||
@@ -471,7 +467,7 @@ impl Engine for Tendermint {
|
||||
header.set_difficulty(new_difficulty);
|
||||
header.set_gas_limit({
|
||||
let gas_limit = parent.gas_limit().clone();
|
||||
let bound_divisor = self.gas_limit_bound_divisor;
|
||||
let bound_divisor = self.params().gas_limit_bound_divisor;
|
||||
if gas_limit < gas_floor_target {
|
||||
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
|
||||
} else {
|
||||
@@ -545,7 +541,8 @@ impl Engine for Tendermint {
|
||||
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error>{
|
||||
let fields = block.fields_mut();
|
||||
// Bestow block reward
|
||||
let res = fields.state.add_balance(fields.header.author(), &self.block_reward, CleanupMode::NoEmpty)
|
||||
let reward = self.params().block_reward;
|
||||
let res = fields.state.add_balance(fields.header.author(), &reward, CleanupMode::NoEmpty)
|
||||
.map_err(::error::Error::from)
|
||||
.and_then(|_| fields.state.commit());
|
||||
// Commit state so that we can actually figure out the state root.
|
||||
@@ -617,7 +614,7 @@ impl Engine for Tendermint {
|
||||
self.check_above_threshold(origins.len())?
|
||||
}
|
||||
|
||||
let gas_limit_divisor = self.gas_limit_bound_divisor;
|
||||
let gas_limit_divisor = self.params().gas_limit_bound_divisor;
|
||||
let min_gas = parent.gas_limit().clone() - parent.gas_limit().clone() / gas_limit_divisor;
|
||||
let max_gas = parent.gas_limit().clone() + parent.gas_limit().clone() / gas_limit_divisor;
|
||||
if header.gas_limit() <= &min_gas || header.gas_limit() >= &max_gas {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
//! Tendermint specific parameters.
|
||||
|
||||
use ethjson;
|
||||
use util::{U256, Address};
|
||||
use time::Duration;
|
||||
use super::super::validator_set::{ValidatorSet, new_validator_set};
|
||||
use super::super::transition::Timeouts;
|
||||
@@ -25,16 +24,10 @@ use super::Step;
|
||||
|
||||
/// `Tendermint` params.
|
||||
pub struct TendermintParams {
|
||||
/// Gas limit divisor.
|
||||
pub gas_limit_bound_divisor: U256,
|
||||
/// List of validators.
|
||||
pub validators: Box<ValidatorSet>,
|
||||
/// Timeout durations for different steps.
|
||||
pub timeouts: TendermintTimeouts,
|
||||
/// Block reward.
|
||||
pub block_reward: U256,
|
||||
/// Namereg contract address.
|
||||
pub registrar: Address,
|
||||
}
|
||||
|
||||
/// Base timeout of each step in ms.
|
||||
@@ -81,7 +74,6 @@ impl From<ethjson::spec::TendermintParams> for TendermintParams {
|
||||
fn from(p: ethjson::spec::TendermintParams) -> Self {
|
||||
let dt = TendermintTimeouts::default();
|
||||
TendermintParams {
|
||||
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
|
||||
validators: new_validator_set(p.validators),
|
||||
timeouts: TendermintTimeouts {
|
||||
propose: p.timeout_propose.map_or(dt.propose, to_duration),
|
||||
@@ -89,8 +81,6 @@ impl From<ethjson::spec::TendermintParams> for TendermintParams {
|
||||
precommit: p.timeout_precommit.map_or(dt.precommit, to_duration),
|
||||
commit: p.timeout_commit.map_or(dt.commit, to_duration),
|
||||
},
|
||||
block_reward: p.block_reward.map_or_else(U256::zero, Into::into),
|
||||
registrar: p.registrar.map_or_else(Address::new, Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,6 @@ const SNAPSHOT_BLOCKS: u64 = 30000;
|
||||
/// Ethash params.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct EthashParams {
|
||||
/// Gas limit divisor.
|
||||
pub gas_limit_bound_divisor: U256,
|
||||
/// Minimum difficulty.
|
||||
pub minimum_difficulty: U256,
|
||||
/// Difficulty bound divisor.
|
||||
@@ -53,10 +51,6 @@ pub struct EthashParams {
|
||||
pub metropolis_difficulty_increment_divisor: u64,
|
||||
/// Block duration.
|
||||
pub duration_limit: u64,
|
||||
/// Block reward.
|
||||
pub block_reward: U256,
|
||||
/// Namereg contract address.
|
||||
pub registrar: Address,
|
||||
/// Homestead transition block number.
|
||||
pub homestead_transition: u64,
|
||||
/// DAO hard-fork transition block (X).
|
||||
@@ -75,8 +69,6 @@ pub struct EthashParams {
|
||||
pub eip100b_transition: u64,
|
||||
/// Number of first block where EIP-150 rules begin.
|
||||
pub eip150_transition: u64,
|
||||
/// Number of first block where EIP-155 rules begin.
|
||||
pub eip155_transition: u64,
|
||||
/// Number of first block where EIP-160 rules begin.
|
||||
pub eip160_transition: u64,
|
||||
/// Number of first block where EIP-161.abc begin.
|
||||
@@ -104,14 +96,11 @@ pub struct EthashParams {
|
||||
impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||
fn from(p: ethjson::spec::EthashParams) -> Self {
|
||||
EthashParams {
|
||||
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
|
||||
minimum_difficulty: p.minimum_difficulty.into(),
|
||||
difficulty_bound_divisor: p.difficulty_bound_divisor.into(),
|
||||
difficulty_increment_divisor: p.difficulty_increment_divisor.map_or(10, Into::into),
|
||||
metropolis_difficulty_increment_divisor: p.metropolis_difficulty_increment_divisor.map_or(9, Into::into),
|
||||
duration_limit: p.duration_limit.map_or(0, Into::into),
|
||||
block_reward: p.block_reward.into(),
|
||||
registrar: p.registrar.map_or_else(Address::new, Into::into),
|
||||
homestead_transition: p.homestead_transition.map_or(0, Into::into),
|
||||
dao_hardfork_transition: p.dao_hardfork_transition.map_or(u64::max_value(), Into::into),
|
||||
dao_hardfork_beneficiary: p.dao_hardfork_beneficiary.map_or_else(Address::new, Into::into),
|
||||
@@ -121,7 +110,6 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||
bomb_defuse_transition: p.bomb_defuse_transition.map_or(u64::max_value(), Into::into),
|
||||
eip100b_transition: p.eip100b_transition.map_or(u64::max_value(), Into::into),
|
||||
eip150_transition: p.eip150_transition.map_or(0, Into::into),
|
||||
eip155_transition: p.eip155_transition.map_or(0, Into::into),
|
||||
eip160_transition: p.eip160_transition.map_or(0, Into::into),
|
||||
eip161abc_transition: p.eip161abc_transition.map_or(0, Into::into),
|
||||
eip161d_transition: p.eip161d_transition.map_or(u64::max_value(), Into::into),
|
||||
@@ -185,7 +173,7 @@ impl Engine for Arc<Ethash> {
|
||||
fn seal_fields(&self) -> usize { 2 }
|
||||
|
||||
fn params(&self) -> &CommonParams { &self.params }
|
||||
fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.ethash_params.registrar.hex()] }
|
||||
fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.params().registrar.hex()] }
|
||||
|
||||
fn builtins(&self) -> &BTreeMap<Address, Builtin> {
|
||||
&self.builtins
|
||||
@@ -216,7 +204,7 @@ impl Engine for Arc<Ethash> {
|
||||
}
|
||||
|
||||
fn signing_network_id(&self, env_info: &EnvInfo) -> Option<u64> {
|
||||
if env_info.number >= self.ethash_params.eip155_transition {
|
||||
if env_info.number >= self.params().eip155_transition {
|
||||
Some(self.params().chain_id)
|
||||
} else {
|
||||
None
|
||||
@@ -231,7 +219,7 @@ impl Engine for Arc<Ethash> {
|
||||
}
|
||||
let gas_limit = {
|
||||
let gas_limit = parent.gas_limit().clone();
|
||||
let bound_divisor = self.ethash_params.gas_limit_bound_divisor;
|
||||
let bound_divisor = self.params().gas_limit_bound_divisor;
|
||||
let lower_limit = gas_limit - gas_limit / bound_divisor + 1.into();
|
||||
let upper_limit = gas_limit + gas_limit / bound_divisor - 1.into();
|
||||
let gas_limit = if gas_limit < gas_floor_target {
|
||||
@@ -284,7 +272,7 @@ impl Engine for Arc<Ethash> {
|
||||
/// Apply the block reward on finalisation of the block.
|
||||
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
|
||||
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
|
||||
let reward = self.ethash_params.block_reward;
|
||||
let reward = self.params().block_reward;
|
||||
let fields = block.fields_mut();
|
||||
let eras_rounds = self.ethash_params.ecip1017_era_rounds;
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, fields.header.number());
|
||||
@@ -387,7 +375,7 @@ impl Engine for Arc<Ethash> {
|
||||
if header.difficulty() != &expected_difficulty {
|
||||
return Err(From::from(BlockError::InvalidDifficulty(Mismatch { expected: expected_difficulty, found: header.difficulty().clone() })))
|
||||
}
|
||||
let gas_limit_divisor = self.ethash_params.gas_limit_bound_divisor;
|
||||
let gas_limit_divisor = self.params().gas_limit_bound_divisor;
|
||||
let parent_gas_limit = *parent.gas_limit();
|
||||
let min_gas = parent_gas_limit - parent_gas_limit / gas_limit_divisor;
|
||||
let max_gas = parent_gas_limit + parent_gas_limit / gas_limit_divisor;
|
||||
@@ -406,7 +394,7 @@ impl Engine for Arc<Ethash> {
|
||||
}
|
||||
|
||||
let check_low_s = header.number() >= self.ethash_params.homestead_transition;
|
||||
let network_id = if header.number() >= self.ethash_params.eip155_transition { Some(self.params().chain_id) } else { None };
|
||||
let network_id = if header.number() >= self.params().eip155_transition { Some(self.params().chain_id) } else { None };
|
||||
t.verify_basic(check_low_s, network_id, false)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -809,36 +797,32 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn has_valid_ecip1017_eras_block_reward() {
|
||||
let ethparams = EthashParams {
|
||||
// see ethcore/res/ethereum/classic.json
|
||||
ecip1017_era_rounds: 5000000,
|
||||
block_reward: U256::from_str("4563918244F40000").unwrap(),
|
||||
..get_default_ethash_params()
|
||||
};
|
||||
let eras_rounds = ethparams.ecip1017_era_rounds;
|
||||
let reward = ethparams.block_reward;
|
||||
let eras_rounds = 5000000;
|
||||
|
||||
let start_reward: U256 = "4563918244F40000".parse().unwrap();
|
||||
|
||||
let block_number = 0;
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number);
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
|
||||
assert_eq!(0, eras);
|
||||
assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward);
|
||||
let reward = ethparams.block_reward;
|
||||
|
||||
let block_number = 5000000;
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number);
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
|
||||
assert_eq!(0, eras);
|
||||
assert_eq!(U256::from_str("4563918244F40000").unwrap(), reward);
|
||||
let reward = ethparams.block_reward;
|
||||
|
||||
let block_number = 10000000;
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number);
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
|
||||
assert_eq!(1, eras);
|
||||
assert_eq!(U256::from_str("3782DACE9D900000").unwrap(), reward);
|
||||
let reward = ethparams.block_reward;
|
||||
|
||||
let block_number = 20000000;
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number);
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
|
||||
assert_eq!(3, eras);
|
||||
assert_eq!(U256::from_str("2386F26FC1000000").unwrap(), reward);
|
||||
let reward = ethparams.block_reward;
|
||||
|
||||
let block_number = 80000000;
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, reward, block_number);
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
|
||||
assert_eq!(15, eras);
|
||||
assert_eq!(U256::from_str("271000000000000").unwrap(), reward);
|
||||
}
|
||||
|
||||
@@ -1112,6 +1112,8 @@ impl MinerService for Miner {
|
||||
/// Prepare the block and work if the Engine does not seal internally.
|
||||
fn update_sealing(&self, chain: &MiningBlockChainClient) {
|
||||
trace!(target: "miner", "update_sealing");
|
||||
const NO_NEW_CHAIN_WITH_FORKS: &str = "Your chain specification contains one or more hard forks which are required to be \
|
||||
on by default. Please remove these forks and start your chain again.";
|
||||
|
||||
if self.requires_reseal(chain.chain_info().best_block_number) {
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -1120,6 +1122,14 @@ impl MinerService for Miner {
|
||||
// --------------------------------------------------------------------------
|
||||
trace!(target: "miner", "update_sealing: preparing a block");
|
||||
let (block, original_work_hash) = self.prepare_block(chain);
|
||||
|
||||
// refuse to seal the first block of the chain if it contains hard forks
|
||||
// which should be on by default.
|
||||
if block.block().fields().header.number() == 1 && self.engine.params().contains_bugfix_hard_fork() {
|
||||
warn!("{}", NO_NEW_CHAIN_WITH_FORKS);
|
||||
return;
|
||||
}
|
||||
|
||||
match self.engine.seals_internally() {
|
||||
Some(true) => {
|
||||
trace!(target: "miner", "update_sealing: engine indicates internal sealing");
|
||||
@@ -1127,11 +1137,11 @@ impl MinerService for Miner {
|
||||
trace!(target: "miner", "update_sealing: imported internally sealed block");
|
||||
}
|
||||
},
|
||||
Some(false) => trace!(target: "miner", "update_sealing: engine is not keen to seal internally right now"),
|
||||
None => {
|
||||
trace!(target: "miner", "update_sealing: engine does not seal internally, preparing work");
|
||||
self.prepare_work(block, original_work_hash)
|
||||
},
|
||||
_ => trace!(target: "miner", "update_sealing: engine is not keen to seal internally right now")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"engine": {
|
||||
"authorityRound": {
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"stepDuration": 1,
|
||||
"startStep": 0,
|
||||
"validators": {
|
||||
@@ -17,6 +16,7 @@
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"accountStartNonce": "0x0",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
|
||||
@@ -39,7 +39,12 @@ use trace::{NoopTracer, NoopVMTracer};
|
||||
use evm::CallType;
|
||||
use util::*;
|
||||
|
||||
/// Parameters common to all engines.
|
||||
/// Parameters common to ethereum-like blockchains.
|
||||
/// NOTE: when adding bugfix hard-fork parameters,
|
||||
/// add to `contains_bugfix_hard_fork`
|
||||
///
|
||||
/// we define a "bugfix" hard fork as any hard fork which
|
||||
/// you would put on-by-default in a new chain.
|
||||
#[derive(Debug, PartialEq, Default)]
|
||||
#[cfg_attr(test, derive(Clone))]
|
||||
pub struct CommonParams {
|
||||
@@ -59,8 +64,10 @@ pub struct CommonParams {
|
||||
pub fork_block: Option<(BlockNumber, H256)>,
|
||||
/// Number of first block where EIP-98 rules begin.
|
||||
pub eip98_transition: BlockNumber,
|
||||
/// Number of first block where EIP-155 rules begin.
|
||||
pub eip155_transition: BlockNumber,
|
||||
/// Validate block receipts root.
|
||||
pub validate_receipts_transition: u64,
|
||||
pub validate_receipts_transition: BlockNumber,
|
||||
/// Number of first block where EIP-86 (Metropolis) rules begin.
|
||||
pub eip86_transition: BlockNumber,
|
||||
/// Number of first block where EIP-140 (Metropolis: REVERT opcode) rules begin.
|
||||
@@ -85,6 +92,12 @@ pub struct CommonParams {
|
||||
pub remove_dust_contracts: bool,
|
||||
/// Wasm support
|
||||
pub wasm: bool,
|
||||
/// Gas limit bound divisor (how much gas limit can change per block)
|
||||
pub gas_limit_bound_divisor: U256,
|
||||
/// Block reward in wei.
|
||||
pub block_reward: U256,
|
||||
/// Registrar contract address.
|
||||
pub registrar: Address,
|
||||
}
|
||||
|
||||
impl CommonParams {
|
||||
@@ -111,6 +124,19 @@ impl CommonParams {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether these params contain any bug-fix hard forks.
|
||||
pub fn contains_bugfix_hard_fork(&self) -> bool {
|
||||
self.eip98_transition != 0 &&
|
||||
self.eip155_transition != 0 &&
|
||||
self.validate_receipts_transition != 0 &&
|
||||
self.eip86_transition != 0 &&
|
||||
self.eip140_transition != 0 &&
|
||||
self.eip210_transition != 0 &&
|
||||
self.eip211_transition != 0 &&
|
||||
self.eip214_transition != 0 &&
|
||||
self.dust_protection_transition != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ethjson::spec::Params> for CommonParams {
|
||||
@@ -124,6 +150,7 @@ impl From<ethjson::spec::Params> for CommonParams {
|
||||
min_gas_limit: p.min_gas_limit.into(),
|
||||
fork_block: if let (Some(n), Some(h)) = (p.fork_block, p.fork_hash) { Some((n.into(), h.into())) } else { None },
|
||||
eip98_transition: p.eip98_transition.map_or(0, Into::into),
|
||||
eip155_transition: p.eip155_transition.map_or(0, Into::into),
|
||||
validate_receipts_transition: p.validate_receipts_transition.map_or(0, Into::into),
|
||||
eip86_transition: p.eip86_transition.map_or(BlockNumber::max_value(), Into::into),
|
||||
eip140_transition: p.eip140_transition.map_or(BlockNumber::max_value(), Into::into),
|
||||
@@ -139,6 +166,9 @@ impl From<ethjson::spec::Params> for CommonParams {
|
||||
nonce_cap_increment: p.nonce_cap_increment.map_or(64, Into::into),
|
||||
remove_dust_contracts: p.remove_dust_contracts.unwrap_or(false),
|
||||
wasm: p.wasm.unwrap_or(false),
|
||||
gas_limit_bound_divisor: p.gas_limit_bound_divisor.into(),
|
||||
block_reward: p.block_reward.map_or_else(U256::zero, Into::into),
|
||||
registrar: p.registrar.map_or_else(Address::new, Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -242,7 +272,7 @@ impl Spec {
|
||||
) -> Arc<Engine> {
|
||||
match engine_spec {
|
||||
ethjson::spec::Engine::Null => Arc::new(NullEngine::new(params, builtins)),
|
||||
ethjson::spec::Engine::InstantSeal(instant) => Arc::new(InstantSeal::new(params, instant.params.registrar.map_or_else(Address::new, Into::into), builtins)),
|
||||
ethjson::spec::Engine::InstantSeal => Arc::new(InstantSeal::new(params, builtins)),
|
||||
ethjson::spec::Engine::Ethash(ethash) => Arc::new(ethereum::Ethash::new(cache_dir, params, From::from(ethash.params), builtins)),
|
||||
ethjson::spec::Engine::BasicAuthority(basic_authority) => Arc::new(BasicAuthority::new(params, From::from(basic_authority.params), builtins)),
|
||||
ethjson::spec::Engine::AuthorityRound(authority_round) => AuthorityRound::new(params, From::from(authority_round.params), builtins).expect("Failed to start AuthorityRound consensus engine."),
|
||||
|
||||
@@ -394,16 +394,13 @@ pub fn get_bad_state_dummy_block() -> Bytes {
|
||||
create_test_block(&block_header)
|
||||
}
|
||||
|
||||
pub fn get_default_ethash_params() -> EthashParams{
|
||||
pub fn get_default_ethash_params() -> EthashParams {
|
||||
EthashParams {
|
||||
gas_limit_bound_divisor: U256::from(1024),
|
||||
minimum_difficulty: U256::from(131072),
|
||||
difficulty_bound_divisor: U256::from(2048),
|
||||
difficulty_increment_divisor: 10,
|
||||
metropolis_difficulty_increment_divisor: 9,
|
||||
duration_limit: 13,
|
||||
block_reward: U256::from(0),
|
||||
registrar: "0000000000000000000000000000000000000001".into(),
|
||||
homestead_transition: 1150000,
|
||||
dao_hardfork_transition: u64::max_value(),
|
||||
dao_hardfork_beneficiary: "0000000000000000000000000000000000000001".into(),
|
||||
@@ -413,7 +410,6 @@ pub fn get_default_ethash_params() -> EthashParams{
|
||||
bomb_defuse_transition: u64::max_value(),
|
||||
eip100b_transition: u64::max_value(),
|
||||
eip150_transition: u64::max_value(),
|
||||
eip155_transition: u64::max_value(),
|
||||
eip160_transition: u64::max_value(),
|
||||
eip161abc_transition: u64::max_value(),
|
||||
eip161d_transition: u64::max_value(),
|
||||
|
||||
Reference in New Issue
Block a user