More backports into stable (#6061)

* Ethereum Classic Monetary Policy (#5741)

* Ethereum Classic Monetary Policy

Create a new parameter `ecip1017EraRounds`. When the block number
passes one era rounds, the reward is reduced by 20%.

See https://github.com/ethereumproject/ECIPs/blob/master/ECIPs/ECIP-1017.md

* Update rewards for uncle miners for ECIP1017

In the monetary policy, the rewards are changed from "up to 7/8 of the
reward" to "1/32 of the reward".

* Fix an off-by-one error in ECIP1017 era calculation

According to
https://github.com/ethereumproject/ECIPs/blob/master/ECIPs/ECIP-1017.md,
when in block number 5,000,000, it should still be in Era 1 (which in
our code `era == 0`). So we need to check whether the `rem` equals to
zero and act accordingly when calculating the era.

* `ecip1017_era_rounds` missing from EthashParams when run in build bot

* strip out ecip1017_eras_block_reward function and add unit test

* JS precompiled set to stable
This commit is contained in:
Arkadiy Paronyan 2017-07-14 20:39:38 +02:00 committed by GitHub
parent 1f176c7798
commit aa7dfdf0f5
5 changed files with 74 additions and 8 deletions

View File

@ -11,7 +11,7 @@ rustc_version = "0.1"
[dependencies] [dependencies]
parity-ui-dev = { path = "../../js", optional = true } parity-ui-dev = { path = "../../js", optional = true }
parity-ui-precompiled = { git = "https://github.com/paritytech/js-precompiled.git", branch = "beta", optional = true } parity-ui-precompiled = { git = "https://github.com/paritytech/js-precompiled.git", branch = "stable", optional = true }
[features] [features]
no-precompiled-js = ["parity-ui-dev"] no-precompiled-js = ["parity-ui-dev"]

View File

@ -16,6 +16,7 @@
"eip160Transition": 3000000, "eip160Transition": 3000000,
"ecip1010PauseTransition": 3000000, "ecip1010PauseTransition": 3000000,
"ecip1010ContinueTransition": 5000000, "ecip1010ContinueTransition": 5000000,
"ecip1017EraRounds": 5000000,
"eip161abcTransition": "0x7fffffffffffffff", "eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff" "eip161dTransition": "0x7fffffffffffffff"

View File

@ -77,6 +77,8 @@ pub struct EthashParams {
pub ecip1010_pause_transition: u64, pub ecip1010_pause_transition: u64,
/// Number of first block where ECIP-1010 ends. /// Number of first block where ECIP-1010 ends.
pub ecip1010_continue_transition: u64, pub ecip1010_continue_transition: u64,
/// Total block number for one ECIP-1017 era.
pub ecip1017_era_rounds: u64,
/// Maximum amount of code that can be deploying into a contract. /// Maximum amount of code that can be deploying into a contract.
pub max_code_size: u64, pub max_code_size: u64,
/// Number of first block where the max gas limit becomes effective. /// Number of first block where the max gas limit becomes effective.
@ -113,6 +115,7 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
eip161d_transition: p.eip161d_transition.map_or(u64::max_value(), Into::into), eip161d_transition: p.eip161d_transition.map_or(u64::max_value(), Into::into),
ecip1010_pause_transition: p.ecip1010_pause_transition.map_or(u64::max_value(), Into::into), ecip1010_pause_transition: p.ecip1010_pause_transition.map_or(u64::max_value(), Into::into),
ecip1010_continue_transition: p.ecip1010_continue_transition.map_or(u64::max_value(), Into::into), ecip1010_continue_transition: p.ecip1010_continue_transition.map_or(u64::max_value(), Into::into),
ecip1017_era_rounds: p.ecip1017_era_rounds.map_or(u64::max_value(), Into::into),
max_code_size: p.max_code_size.map_or(u64::max_value(), Into::into), max_code_size: p.max_code_size.map_or(u64::max_value(), Into::into),
max_gas_limit_transition: p.max_gas_limit_transition.map_or(u64::max_value(), Into::into), max_gas_limit_transition: p.max_gas_limit_transition.map_or(u64::max_value(), Into::into),
max_gas_limit: p.max_gas_limit.map_or(U256::max_value(), Into::into), max_gas_limit: p.max_gas_limit.map_or(U256::max_value(), Into::into),
@ -249,6 +252,8 @@ impl Engine for Ethash {
fn on_close_block(&self, block: &mut ExecutedBlock) { fn on_close_block(&self, block: &mut ExecutedBlock) {
let reward = self.ethash_params.block_reward; let reward = self.ethash_params.block_reward;
let fields = block.fields_mut(); 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());
// Bestow block reward // Bestow block reward
let res = fields.state.add_balance( let res = fields.state.add_balance(
@ -264,12 +269,19 @@ impl Engine for Ethash {
// Bestow uncle rewards // Bestow uncle rewards
let current_number = fields.header.number(); let current_number = fields.header.number();
for u in fields.uncles.iter() { for u in fields.uncles.iter() {
let res = fields.state.add_balance( let res = if eras == 0 {
u.author(), fields.state.add_balance(
&(reward * U256::from(8 + u.number() - current_number) / U256::from(8)), u.author(),
CleanupMode::NoEmpty &(reward * U256::from(8 + u.number() - current_number) / U256::from(8)),
); CleanupMode::NoEmpty
)
} else {
fields.state.add_balance(
u.author(),
&(reward / U256::from(32)),
CleanupMode::NoEmpty
)
};
if let Err(e) = res { if let Err(e) = res {
warn!("Failed to give uncle reward: {}", e); warn!("Failed to give uncle reward: {}", e);
} }
@ -398,6 +410,18 @@ fn round_block_gas_limit(gas_limit: U256, lower_limit: U256, upper_limit: U256)
} }
} }
fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u64) -> (u64, U256){
let eras = if block_number != 0 && block_number % era_rounds == 0 {
block_number / era_rounds - 1
} else {
block_number / era_rounds
};
for _ in 0..eras {
reward = reward / U256::from(5) * U256::from(4);
}
(eras, reward)
}
#[cfg_attr(feature="dev", allow(wrong_self_convention))] #[cfg_attr(feature="dev", allow(wrong_self_convention))]
impl Ethash { impl Ethash {
fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 { fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 {
@ -500,7 +524,7 @@ mod tests {
use error::{BlockError, Error}; use error::{BlockError, Error};
use header::Header; use header::Header;
use super::super::{new_morden, new_homestead_test}; use super::super::{new_morden, new_homestead_test};
use super::{Ethash, EthashParams, PARITY_GAS_LIMIT_DETERMINANT}; use super::{Ethash, EthashParams, PARITY_GAS_LIMIT_DETERMINANT, ecip1017_eras_block_reward};
use rlp; use rlp;
#[test] #[test]
@ -756,6 +780,42 @@ mod tests {
assert_eq!(U256::from_str("1fc50f118efe").unwrap(), difficulty); assert_eq!(U256::from_str("1fc50f118efe").unwrap(), difficulty);
} }
#[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 block_number = 0;
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, 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);
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);
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);
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);
assert_eq!(15, eras);
assert_eq!(U256::from_str("271000000000000").unwrap(), reward);
}
#[test] #[test]
fn difficulty_classic_bomb_delay() { fn difficulty_classic_bomb_delay() {
let spec = new_homestead_test(); let spec = new_homestead_test();

View File

@ -455,6 +455,7 @@ pub fn get_default_ethash_params() -> EthashParams{
eip161d_transition: u64::max_value(), eip161d_transition: u64::max_value(),
ecip1010_pause_transition: u64::max_value(), ecip1010_pause_transition: u64::max_value(),
ecip1010_continue_transition: u64::max_value(), ecip1010_continue_transition: u64::max_value(),
ecip1017_era_rounds: u64::max_value(),
max_code_size: u64::max_value(), max_code_size: u64::max_value(),
max_gas_limit_transition: u64::max_value(), max_gas_limit_transition: u64::max_value(),
max_gas_limit: U256::max_value(), max_gas_limit: U256::max_value(),

View File

@ -93,6 +93,10 @@ pub struct EthashParams {
#[serde(rename="ecip1010ContinueTransition")] #[serde(rename="ecip1010ContinueTransition")]
pub ecip1010_continue_transition: Option<Uint>, pub ecip1010_continue_transition: Option<Uint>,
/// See main EthashParams docs.
#[serde(rename="ecip1017EraRounds")]
pub ecip1017_era_rounds: Option<Uint>,
/// See main EthashParams docs. /// See main EthashParams docs.
#[serde(rename="maxCodeSize")] #[serde(rename="maxCodeSize")]
pub max_code_size: Option<Uint>, pub max_code_size: Option<Uint>,