Generalized blockReward and difficultyBombDelays config (#9480)
* Implement multi blockReward * Implement difficultyBombDelays * Fix json crate compile * json keys can only be string
This commit is contained in:
parent
4040d73c60
commit
e1f333021f
@ -6,11 +6,12 @@
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"blockReward": "0x29A2241AF62C0000",
|
||||
"homesteadTransition": "0x0",
|
||||
"eip649Reward": "0x29A2241AF62C0000",
|
||||
"eip100bTransition": "0x0",
|
||||
"eip649Transition": "0x0"
|
||||
"difficultyBombDelays": {
|
||||
"0": 3000000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -6,11 +6,12 @@
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"blockReward": "0x29A2241AF62C0000",
|
||||
"homesteadTransition": "0x0",
|
||||
"eip649Reward": "0x29A2241AF62C0000",
|
||||
"eip100bTransition": "0x0",
|
||||
"eip649Transition": "0x0"
|
||||
"difficultyBombDelays": {
|
||||
"0": 3000000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -8,15 +8,19 @@
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"difficultyIncrementDivisor": "0x3C",
|
||||
"durationLimit": "0x3C",
|
||||
"blockReward": "0x6f05b59d3b200000",
|
||||
"blockReward": {
|
||||
"0x0": "0x6f05b59d3b200000",
|
||||
"0xC3500": "0x3782DACE9D900000"
|
||||
},
|
||||
"homesteadTransition": "0x30d40",
|
||||
"difficultyHardforkTransition": "0x59d9",
|
||||
"difficultyHardforkBoundDivisor": "0x0200",
|
||||
"bombDefuseTransition": "0x30d40",
|
||||
"eip100bTransition": "0xC3500",
|
||||
"metropolisDifficultyIncrementDivisor": "0x1E",
|
||||
"eip649Transition": "0xC3500",
|
||||
"eip649Reward": "0x3782DACE9D900000",
|
||||
"difficultyBombDelays": {
|
||||
"0xC3500": 3000000
|
||||
},
|
||||
"expip2Transition": "0xC3500",
|
||||
"expip2DurationLimit": "0x1E"
|
||||
}
|
||||
|
@ -7,7 +7,10 @@
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"blockReward": {
|
||||
"0": "0x4563918244F40000",
|
||||
"4370000": "0x29A2241AF62C0000"
|
||||
},
|
||||
"homesteadTransition": "0x118c30",
|
||||
"daoHardforkTransition": "0x1d4c00",
|
||||
"daoHardforkBeneficiary": "0xbf4ed7b27f1d666546e30d74d50d173d20bca754",
|
||||
@ -129,9 +132,10 @@
|
||||
"0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
|
||||
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a"
|
||||
],
|
||||
"eip649Reward": "0x29A2241AF62C0000",
|
||||
"eip100bTransition": 4370000,
|
||||
"eip649Transition": 4370000
|
||||
"difficultyBombDelays": {
|
||||
"4370000": 3000000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -9,7 +9,6 @@
|
||||
"durationLimit":"0x0d",
|
||||
"homesteadTransition":"0x118c30",
|
||||
"eip100bTransition":"0x7fffffffffffff",
|
||||
"eip649Transition":"0x7fffffffffffff",
|
||||
"blockReward":"0x1105a0185b50a80000",
|
||||
"mcip3Transition":"0x00",
|
||||
"mcip3MinerReward":"0xd8d726b7177a80000",
|
||||
|
@ -9,14 +9,16 @@
|
||||
"durationLimit": "0x0d",
|
||||
"homesteadTransition": "0x17",
|
||||
"eip100bTransition": "0x2a",
|
||||
"eip649Transition":"0x2a",
|
||||
"blockReward": "0x1105a0185b50a80000",
|
||||
"mcip3Transition": "0x17",
|
||||
"mcip3MinerReward": "0xd8d726b7177a80000",
|
||||
"mcip3UbiReward": "0x2b5e3af16b1880000",
|
||||
"mcip3UbiContract": "0x00efdd5883ec628983e9063c7d969fe268bbf310",
|
||||
"mcip3DevReward": "0xc249fdd327780000",
|
||||
"mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536"
|
||||
"mcip3DevContract": "0x00756cf8159095948496617f5fb17ed95059f536",
|
||||
"difficultyBombDelays": {
|
||||
"0x2a": 3000000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -9,14 +9,16 @@
|
||||
"durationLimit":"0x0d",
|
||||
"homesteadTransition":"0x118c30",
|
||||
"eip100bTransition":"0x21e88e",
|
||||
"eip649Transition":"0x21e88e",
|
||||
"blockReward":"0x1105a0185b50a80000",
|
||||
"mcip3Transition":"0x124f81",
|
||||
"mcip3MinerReward":"0xd8d726b7177a80000",
|
||||
"mcip3UbiReward":"0x2b5e3af16b1880000",
|
||||
"mcip3UbiContract":"0x00efdd5883ec628983e9063c7d969fe268bbf310",
|
||||
"mcip3DevReward":"0xc249fdd327780000",
|
||||
"mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536"
|
||||
"mcip3DevContract":"0x00756cf8159095948496617f5fb17ed95059f536",
|
||||
"difficultyBombDelays": {
|
||||
"0x21e88e": 3000000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -7,11 +7,15 @@
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"blockReward": {
|
||||
"0": "0x4563918244F40000",
|
||||
"1700000": "0x29A2241AF62C0000"
|
||||
},
|
||||
"homesteadTransition": 0,
|
||||
"eip649Reward": "0x29A2241AF62C0000",
|
||||
"eip100bTransition": 1700000,
|
||||
"eip649Transition": 1700000
|
||||
"difficultyBombDelays": {
|
||||
"1700000": 3000000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -6,11 +6,15 @@
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"blockReward": {
|
||||
"0x0": "0x4563918244F40000",
|
||||
"0x5": "0x29A2241AF62C0000"
|
||||
},
|
||||
"homesteadTransition": "0",
|
||||
"eip649Reward": "0x29A2241AF62C0000",
|
||||
"eip100bTransition": "5",
|
||||
"eip649Transition": "5"
|
||||
"difficultyBombDelays": {
|
||||
"5": 3000000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -37,8 +37,6 @@ const SNAPSHOT_BLOCKS: u64 = 5000;
|
||||
/// Maximum number of blocks allowed in an ethash snapshot.
|
||||
const MAX_SNAPSHOT_BLOCKS: u64 = 30000;
|
||||
|
||||
const DEFAULT_EIP649_DELAY: u64 = 3_000_000;
|
||||
|
||||
/// Ethash specific seal
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Seal {
|
||||
@ -113,13 +111,7 @@ pub struct EthashParams {
|
||||
/// MCIP-3 contract address for the developer funds.
|
||||
pub mcip3_dev_contract: Address,
|
||||
/// Block reward in base units.
|
||||
pub block_reward: U256,
|
||||
/// EIP-649 transition block.
|
||||
pub eip649_transition: u64,
|
||||
/// EIP-649 bomb delay.
|
||||
pub eip649_delay: u64,
|
||||
/// EIP-649 base reward.
|
||||
pub eip649_reward: Option<U256>,
|
||||
pub block_reward: BTreeMap<BlockNumber, U256>,
|
||||
/// EXPIP-2 block height
|
||||
pub expip2_transition: u64,
|
||||
/// EXPIP-2 duration limit
|
||||
@ -128,6 +120,8 @@ pub struct EthashParams {
|
||||
pub block_reward_contract_transition: u64,
|
||||
/// Block reward contract.
|
||||
pub block_reward_contract: Option<BlockRewardContract>,
|
||||
/// Difficulty bomb delays.
|
||||
pub difficulty_bomb_delays: BTreeMap<BlockNumber, BlockNumber>,
|
||||
}
|
||||
|
||||
impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||
@ -152,10 +146,26 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||
mcip3_ubi_contract: p.mcip3_ubi_contract.map_or_else(Address::new, Into::into),
|
||||
mcip3_dev_reward: p.mcip3_dev_reward.map_or(U256::from(0), Into::into),
|
||||
mcip3_dev_contract: p.mcip3_dev_contract.map_or_else(Address::new, Into::into),
|
||||
block_reward: p.block_reward.map_or_else(Default::default, Into::into),
|
||||
eip649_transition: p.eip649_transition.map_or(u64::max_value(), Into::into),
|
||||
eip649_delay: p.eip649_delay.map_or(DEFAULT_EIP649_DELAY, Into::into),
|
||||
eip649_reward: p.eip649_reward.map(Into::into),
|
||||
block_reward: p.block_reward.map_or_else(
|
||||
|| {
|
||||
let mut ret = BTreeMap::new();
|
||||
ret.insert(0, U256::zero());
|
||||
ret
|
||||
},
|
||||
|reward| {
|
||||
match reward {
|
||||
ethjson::spec::BlockReward::Single(reward) => {
|
||||
let mut ret = BTreeMap::new();
|
||||
ret.insert(0, reward.into());
|
||||
ret
|
||||
},
|
||||
ethjson::spec::BlockReward::Multi(multi) => {
|
||||
multi.into_iter()
|
||||
.map(|(block, reward)| (block.into(), reward.into()))
|
||||
.collect()
|
||||
},
|
||||
}
|
||||
}),
|
||||
expip2_transition: p.expip2_transition.map_or(u64::max_value(), Into::into),
|
||||
expip2_duration_limit: p.expip2_duration_limit.map_or(30, Into::into),
|
||||
block_reward_contract_transition: p.block_reward_contract_transition.map_or(0, Into::into),
|
||||
@ -164,6 +174,9 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||
(_, Some(address)) => Some(BlockRewardContract::new_from_address(address.into())),
|
||||
(None, None) => None,
|
||||
},
|
||||
difficulty_bomb_delays: p.difficulty_bomb_delays.unwrap_or_default().into_iter()
|
||||
.map(|(block, delay)| (block.into(), delay.into()))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,12 +272,11 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
_ => {
|
||||
let mut rewards = Vec::new();
|
||||
|
||||
// Applies EIP-649 reward.
|
||||
let reward = if number >= self.ethash_params.eip649_transition {
|
||||
self.ethash_params.eip649_reward.unwrap_or(self.ethash_params.block_reward)
|
||||
} else {
|
||||
self.ethash_params.block_reward
|
||||
};
|
||||
let (_, reward) = self.ethash_params.block_reward.iter()
|
||||
.rev()
|
||||
.find(|&(block, _)| *block <= number)
|
||||
.expect("Current block's reward is not found; this indicates a chain config error; qed");
|
||||
let reward = *reward;
|
||||
|
||||
// Applies ECIP-1017 eras.
|
||||
let eras_rounds = self.ethash_params.ecip1017_era_rounds;
|
||||
@ -457,19 +469,20 @@ impl Ethash {
|
||||
if header.number() < self.ethash_params.bomb_defuse_transition {
|
||||
if header.number() < self.ethash_params.ecip1010_pause_transition {
|
||||
let mut number = header.number();
|
||||
if number >= self.ethash_params.eip649_transition {
|
||||
number = number.saturating_sub(self.ethash_params.eip649_delay);
|
||||
let original_number = number;
|
||||
for (block, delay) in &self.ethash_params.difficulty_bomb_delays {
|
||||
if original_number >= *block {
|
||||
number = number.saturating_sub(*delay);
|
||||
}
|
||||
}
|
||||
let period = (number / EXP_DIFF_PERIOD) as usize;
|
||||
if period > 1 {
|
||||
target = cmp::max(min_difficulty, target + (U256::from(1) << (period - 2)));
|
||||
}
|
||||
}
|
||||
else if header.number() < self.ethash_params.ecip1010_continue_transition {
|
||||
} else if header.number() < self.ethash_params.ecip1010_continue_transition {
|
||||
let fixed_difficulty = ((self.ethash_params.ecip1010_pause_transition / EXP_DIFF_PERIOD) - 2) as usize;
|
||||
target = cmp::max(min_difficulty, target + (U256::from(1) << fixed_difficulty));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let period = ((parent.number() + 1) / EXP_DIFF_PERIOD) as usize;
|
||||
let delay = ((self.ethash_params.ecip1010_continue_transition - self.ethash_params.ecip1010_pause_transition) / EXP_DIFF_PERIOD) as usize;
|
||||
target = cmp::max(min_difficulty, target + (U256::from(1) << (period - delay - 2)));
|
||||
@ -498,6 +511,7 @@ fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u6
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::collections::BTreeMap;
|
||||
use ethereum_types::{H64, H256, U256, Address};
|
||||
use block::*;
|
||||
use test_helpers::get_temp_state_db;
|
||||
@ -523,7 +537,11 @@ mod tests {
|
||||
metropolis_difficulty_increment_divisor: 9,
|
||||
homestead_transition: 1150000,
|
||||
duration_limit: 13,
|
||||
block_reward: 0.into(),
|
||||
block_reward: {
|
||||
let mut ret = BTreeMap::new();
|
||||
ret.insert(0, 0.into());
|
||||
ret
|
||||
},
|
||||
difficulty_hardfork_transition: u64::max_value(),
|
||||
difficulty_hardfork_bound_divisor: U256::from(0),
|
||||
bomb_defuse_transition: u64::max_value(),
|
||||
@ -537,13 +555,11 @@ mod tests {
|
||||
mcip3_ubi_contract: "0000000000000000000000000000000000000001".into(),
|
||||
mcip3_dev_reward: 0.into(),
|
||||
mcip3_dev_contract: "0000000000000000000000000000000000000001".into(),
|
||||
eip649_transition: u64::max_value(),
|
||||
eip649_delay: 3_000_000,
|
||||
eip649_reward: None,
|
||||
expip2_transition: u64::max_value(),
|
||||
expip2_duration_limit: 30,
|
||||
block_reward_contract: None,
|
||||
block_reward_contract_transition: 0,
|
||||
difficulty_bomb_delays: BTreeMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,19 @@
|
||||
|
||||
//! Ethash params deserialization.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use uint::{self, Uint};
|
||||
use bytes::Bytes;
|
||||
use hash::Address;
|
||||
|
||||
/// Deserializable doppelganger of block rewards for EthashParams
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum BlockReward {
|
||||
Single(Uint),
|
||||
Multi(BTreeMap<Uint, Uint>),
|
||||
}
|
||||
|
||||
/// Deserializable doppelganger of EthashParams.
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize)]
|
||||
pub struct EthashParams {
|
||||
@ -48,7 +57,7 @@ pub struct EthashParams {
|
||||
pub homestead_transition: Option<Uint>,
|
||||
/// Reward per block in wei.
|
||||
#[serde(rename="blockReward")]
|
||||
pub block_reward: Option<Uint>,
|
||||
pub block_reward: Option<BlockReward>,
|
||||
/// Block at which the block reward contract should start being used.
|
||||
#[serde(rename="blockRewardContractTransition")]
|
||||
pub block_reward_contract_transition: Option<Uint>,
|
||||
@ -115,22 +124,13 @@ pub struct EthashParams {
|
||||
#[serde(rename="mcip3DevContract")]
|
||||
pub mcip3_dev_contract: Option<Address>,
|
||||
|
||||
/// EIP-649 transition block.
|
||||
#[serde(rename="eip649Transition")]
|
||||
pub eip649_transition: Option<Uint>,
|
||||
|
||||
/// EIP-649 bomb delay.
|
||||
#[serde(rename="eip649Delay")]
|
||||
pub eip649_delay: Option<Uint>,
|
||||
|
||||
/// EIP-649 base reward.
|
||||
#[serde(rename="eip649Reward")]
|
||||
pub eip649_reward: Option<Uint>,
|
||||
/// Delays of difficulty bombs.
|
||||
#[serde(rename="difficultyBombDelays")]
|
||||
pub difficulty_bomb_delays: Option<BTreeMap<Uint, Uint>>,
|
||||
|
||||
/// EXPIP-2 block height
|
||||
#[serde(rename="expip2Transition")]
|
||||
pub expip2_transition: Option<Uint>,
|
||||
|
||||
/// EXPIP-2 duration limit
|
||||
#[serde(rename="expip2DurationLimit")]
|
||||
pub expip2_duration_limit: Option<Uint>,
|
||||
@ -149,7 +149,7 @@ mod tests {
|
||||
use uint::Uint;
|
||||
use ethereum_types::{H160, U256};
|
||||
use hash::Address;
|
||||
use spec::ethash::{Ethash, EthashParams};
|
||||
use spec::ethash::{Ethash, EthashParams, BlockReward};
|
||||
|
||||
#[test]
|
||||
fn ethash_deserialization() {
|
||||
@ -201,7 +201,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))),
|
||||
block_reward: Some(BlockReward::Single(Uint(U256::from(0x100)))),
|
||||
block_reward_contract_address: None,
|
||||
block_reward_contract_code: None,
|
||||
block_reward_contract_transition: None,
|
||||
@ -242,11 +242,9 @@ mod tests {
|
||||
mcip3_ubi_contract: None,
|
||||
mcip3_dev_reward: None,
|
||||
mcip3_dev_contract: None,
|
||||
eip649_transition: None,
|
||||
eip649_delay: None,
|
||||
eip649_reward: None,
|
||||
expip2_transition: None,
|
||||
expip2_duration_limit: None,
|
||||
difficulty_bomb_delays: None,
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -289,11 +287,9 @@ mod tests {
|
||||
mcip3_ubi_contract: None,
|
||||
mcip3_dev_reward: None,
|
||||
mcip3_dev_contract: None,
|
||||
eip649_transition: None,
|
||||
eip649_delay: None,
|
||||
eip649_reward: None,
|
||||
expip2_transition: None,
|
||||
expip2_duration_limit: None,
|
||||
difficulty_bomb_delays: None,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ pub use self::spec::Spec;
|
||||
pub use self::seal::{Seal, Ethereum, AuthorityRoundSeal, TendermintSeal};
|
||||
pub use self::engine::Engine;
|
||||
pub use self::state::State;
|
||||
pub use self::ethash::{Ethash, EthashParams};
|
||||
pub use self::ethash::{Ethash, EthashParams, BlockReward};
|
||||
pub use self::validator_set::ValidatorSet;
|
||||
pub use self::basic_authority::{BasicAuthority, BasicAuthorityParams};
|
||||
pub use self::authority_round::{AuthorityRound, AuthorityRoundParams};
|
||||
|
Loading…
Reference in New Issue
Block a user