Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Ethereum Classic Monetary Policy #5741

Merged
merged 5 commits into from
Jun 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ethcore/res/ethereum/classic.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"eip160Transition": 3000000,
"ecip1010PauseTransition": 3000000,
"ecip1010ContinueTransition": 5000000,
"ecip1017EraRounds": 5000000,

"eip161abcTransition": "0x7fffffffffffffff",
"eip161dTransition": "0x7fffffffffffffff"
Expand Down
73 changes: 67 additions & 6 deletions ethcore/src/ethereum/ethash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ pub struct EthashParams {
pub ecip1010_pause_transition: u64,
/// Number of first block where ECIP-1010 ends.
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.
pub max_code_size: u64,
/// Number of first block where the max gas limit becomes effective.
Expand Down Expand Up @@ -124,6 +126,7 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
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_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_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),
Expand Down Expand Up @@ -272,6 +275,8 @@ impl Engine for Arc<Ethash> {
fn on_close_block(&self, block: &mut ExecutedBlock) -> Result<(), Error> {
let reward = self.ethash_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());

// Bestow block reward
fields.state.add_balance(
Expand All @@ -283,11 +288,19 @@ impl Engine for Arc<Ethash> {
// Bestow uncle rewards
let current_number = fields.header.number();
for u in fields.uncles.iter() {
fields.state.add_balance(
u.author(),
&(reward * U256::from(8 + u.number() - current_number) / U256::from(8)),
CleanupMode::NoEmpty
)?;
if eras == 0 {
fields.state.add_balance(
u.author(),
&(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
)
}?;
}

// Commit state so that we can actually figure out the state root.
Expand Down Expand Up @@ -413,6 +426,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))]
impl Ethash {
fn calculate_difficulty(&self, header: &Header, parent: &Header) -> U256 {
Expand Down Expand Up @@ -524,7 +549,7 @@ mod tests {
use error::{BlockError, Error};
use header::Header;
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;

#[test]
Expand Down Expand Up @@ -760,6 +785,42 @@ mod tests {
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]
fn difficulty_classic_bomb_delay() {
let spec = new_homestead_test();
Expand Down
1 change: 1 addition & 0 deletions ethcore/src/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ pub fn get_default_ethash_params() -> EthashParams{
eip161d_transition: u64::max_value(),
ecip1010_pause_transition: u64::max_value(),
ecip1010_continue_transition: u64::max_value(),
ecip1017_era_rounds: u64::max_value(),
max_code_size: u64::max_value(),
max_gas_limit_transition: u64::max_value(),
max_gas_limit: U256::max_value(),
Expand Down
4 changes: 4 additions & 0 deletions json/src/spec/ethash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ pub struct EthashParams {
#[serde(rename="ecip1010ContinueTransition")]
pub ecip1010_continue_transition: Option<Uint>,

/// 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>,
Expand Down