Fix Aztlan hard fork issues (#11347)

* Fix Aztlan hard fork issues

* Fix mordor block number

* Fix classic block number

* Add missing precompiles

* Make EIP-1283's comments reflact the current spec

Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
This commit is contained in:
Wei Tang 2020-01-13 22:54:00 +01:00 committed by Andronik Ordian
parent ea8e7fcf73
commit d8a0d38229
7 changed files with 81 additions and 29 deletions

View File

@ -375,32 +375,40 @@ fn to_word_size<Gas: evm::CostType>(value: Gas) -> (Gas, bool) {
fn calculate_eip1283_sstore_gas<Gas: evm::CostType>(schedule: &Schedule, original: &U256, current: &U256, new: &U256) -> Gas { fn calculate_eip1283_sstore_gas<Gas: evm::CostType>(schedule: &Schedule, original: &U256, current: &U256, new: &U256) -> Gas {
Gas::from( Gas::from(
if current == new { if current == new {
// 1. If current value equals new value (this is a no-op), 200 gas is deducted. // 1. If current value equals new value (this is a no-op), `SSTORE_DIRTY_GAS`
schedule.sload_gas // (or if not set, `SLOAD_GAS`) is deducted.
schedule.sstore_dirty_gas.unwrap_or(schedule.sload_gas)
} else { } else {
// 2. If current value does not equal new value // 2. If current value does not equal new value
if original == current { if original == current {
// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context) // 2.1. If original value equals current value (this storage slot has not
// been changed by the current execution context)
if original.is_zero() { if original.is_zero() {
// 2.1.1. If original value is 0, 20000 gas is deducted. // 2.1.1. If original value is 0, `SSTORE_SET_GAS` is deducted.
schedule.sstore_set_gas schedule.sstore_set_gas
} else { } else {
// 2.1.2. Otherwise, 5000 gas is deducted. // 2.1.2. Otherwise, `SSTORE_RESET_GAS` gas is deducted.
schedule.sstore_reset_gas schedule.sstore_reset_gas
// 2.1.2.1. If new value is 0, add 15000 gas to refund counter. // 2.1.2.1. If new value is 0, add `SSTORE_CLEARS_SCHEDULE` to refund counter.
} }
} else { } else {
// 2.2. If original value does not equal current value (this storage slot is dirty), 200 gas is deducted. Apply both of the following clauses. // 2.2. If original value does not equal current value (this storage slot is
schedule.sload_gas // dirty), `SSTORE_DIRTY_GAS` (or if not set, `SLOAD_GAS`) is deducted.
// Apply both of the following clauses.
schedule.sstore_dirty_gas.unwrap_or(schedule.sload_gas)
// 2.2.1. If original value is not 0 // 2.2.1. If original value is not 0
// 2.2.1.1. If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0. // 2.2.1.1. If current value is 0 (also means that new value is not 0), remove
// 2.2.1.2. If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter. // `SSTORE_SET_GAS - SSTORE_DIRTY_GAS` from refund counter.
// 2.2.1.2. If new value is 0 (also means that current value is not 0), add
// `SSTORE_CLEARS_SCHEDULE` to refund counter.
// 2.2.2. If original value equals new value (this storage slot is reset) // 2.2.2. If original value equals new value (this storage slot is reset)
// 2.2.2.1. If original value is 0, add 19800 gas to refund counter. // 2.2.2.1. If original value is 0, add `SSTORE_SET_GAS - SSTORE_DIRTY_GAS`
// 2.2.2.2. Otherwise, add 4800 gas to refund counter. // to refund counter.
// 2.2.2.2. Otherwise, add `SSTORE_RESET_GAS - SSTORE_DIRTY_GAS`
// to refund counter.
} }
} }
) )
@ -410,30 +418,36 @@ pub fn handle_eip1283_sstore_clears_refund(ext: &mut dyn vm::Ext, original: &U25
let sstore_clears_schedule = ext.schedule().sstore_refund_gas; let sstore_clears_schedule = ext.schedule().sstore_refund_gas;
if current == new { if current == new {
// 1. If current value equals new value (this is a no-op), 200 gas is deducted. // 1. If current value equals new value (this is a no-op), `SSTORE_DIRTY_GAS`
// (or if not set, `SLOAD_GAS`) is deducted.
} else { } else {
// 2. If current value does not equal new value // 2. If current value does not equal new value
if original == current { if original == current {
// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context) // 2.1. If original value equals current value (this storage slot has not
// been changed by the current execution context)
if original.is_zero() { if original.is_zero() {
// 2.1.1. If original value is 0, 20000 gas is deducted. // 2.1.1. If original value is 0, `SSTORE_SET_GAS` is deducted.
} else { } else {
// 2.1.2. Otherwise, 5000 gas is deducted. // 2.1.2. Otherwise, `SSTORE_RESET_GAS` gas is deducted.
if new.is_zero() { if new.is_zero() {
// 2.1.2.1. If new value is 0, add 15000 gas to refund counter. // 2.1.2.1. If new value is 0, add `SSTORE_CLEARS_SCHEDULE` to refund counter.
ext.add_sstore_refund(sstore_clears_schedule); ext.add_sstore_refund(sstore_clears_schedule);
} }
} }
} else { } else {
// 2.2. If original value does not equal current value (this storage slot is dirty), 200 gas is deducted. Apply both of the following clauses. // 2.2. If original value does not equal current value (this storage slot is
// dirty), `SSTORE_DIRTY_GAS` (or if not set, `SLOAD_GAS`) is deducted.
// Apply both of the following clauses.
if !original.is_zero() { if !original.is_zero() {
// 2.2.1. If original value is not 0 // 2.2.1. If original value is not 0
if current.is_zero() { if current.is_zero() {
// 2.2.1.1. If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0. // 2.2.1.1. If current value is 0 (also means that new value is not 0), remove
// `SSTORE_SET_GAS - SSTORE_DIRTY_GAS` from refund counter.
ext.sub_sstore_refund(sstore_clears_schedule); ext.sub_sstore_refund(sstore_clears_schedule);
} else if new.is_zero() { } else if new.is_zero() {
// 2.2.1.2. If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter. // 2.2.1.2. If new value is 0 (also means that current value is not 0), add
// `SSTORE_CLEARS_SCHEDULE` to refund counter.
ext.add_sstore_refund(sstore_clears_schedule); ext.add_sstore_refund(sstore_clears_schedule);
} }
} }
@ -441,12 +455,16 @@ pub fn handle_eip1283_sstore_clears_refund(ext: &mut dyn vm::Ext, original: &U25
if original == new { if original == new {
// 2.2.2. If original value equals new value (this storage slot is reset) // 2.2.2. If original value equals new value (this storage slot is reset)
if original.is_zero() { if original.is_zero() {
// 2.2.2.1. If original value is 0, add 19800 gas to refund counter. // 2.2.2.1. If original value is 0, add `SSTORE_SET_GAS - SSTORE_DIRTY_GAS`
let refund = ext.schedule().sstore_set_gas - ext.schedule().sload_gas; // to refund counter.
let refund = ext.schedule().sstore_set_gas
- ext.schedule().sstore_dirty_gas.unwrap_or(ext.schedule().sload_gas);
ext.add_sstore_refund(refund); ext.add_sstore_refund(refund);
} else { } else {
// 2.2.2.2. Otherwise, add 4800 gas to refund counter. // 2.2.2.2. Otherwise, add `SSTORE_RESET_GAS - SSTORE_DIRTY_GAS`
let refund = ext.schedule().sstore_reset_gas - ext.schedule().sload_gas; // to refund counter.
let refund = ext.schedule().sstore_reset_gas
- ext.schedule().sstore_dirty_gas.unwrap_or(ext.schedule().sload_gas);
ext.add_sstore_refund(refund); ext.add_sstore_refund(refund);
} }
} }

View File

@ -40,7 +40,12 @@
"eip658Transition": "0x85d9a0", "eip658Transition": "0x85d9a0",
"eip145Transition": "0x921288", "eip145Transition": "0x921288",
"eip1014Transition": "0x921288", "eip1014Transition": "0x921288",
"eip1052Transition": "0x921288" "eip1052Transition": "0x921288",
"eip1283Transition": "0xa03ae7",
"eip1344Transition": "0xa03ae7",
"eip1706Transition": "0xa03ae7",
"eip2028Transition": "0xa03ae7",
"eip2200AdvanceTransition": "0xa03ae7"
}, },
"genesis": { "genesis": {
"seal": { "seal": {
@ -4425,7 +4430,7 @@
"0x85d9a0": { "0x85d9a0": {
"price": { "alt_bn128_const_operations": { "price": 500 }} "price": { "alt_bn128_const_operations": { "price": 500 }}
}, },
"0x7fffffffffffff": { "0xa03ae7": {
"price": { "alt_bn128_const_operations": { "price": 150 }} "price": { "alt_bn128_const_operations": { "price": 150 }}
} }
} }
@ -4438,7 +4443,7 @@
"0x85d9a0": { "0x85d9a0": {
"price": { "alt_bn128_const_operations": { "price": 40000 }} "price": { "alt_bn128_const_operations": { "price": 40000 }}
}, },
"0x7fffffffffffff": { "0xa03ae7": {
"price": { "alt_bn128_const_operations": { "price": 6000 }} "price": { "alt_bn128_const_operations": { "price": 6000 }}
} }
} }
@ -4451,12 +4456,24 @@
"0x85d9a0": { "0x85d9a0": {
"price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }}
}, },
"0x7fffffffffffff": { "0xa03ae7": {
"price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }}
} }
} }
} }
}, },
"0x0000000000000000000000000000000000000009": {
"balance": "0x1",
"builtin": {
"name": "blake2_f",
"activate_at": "0x1f67cf",
"pricing": {
"blake2_f": {
"gas_per_round": 1
}
}
}
},
"3282791d6fd713f1e94f4bfd565eaa78b3a0599d": { "3282791d6fd713f1e94f4bfd565eaa78b3a0599d": {
"balance": "1337000000000000000000" "balance": "1337000000000000000000"
}, },

View File

@ -28,6 +28,7 @@
"eip1344Transition": "0x1f67cf", "eip1344Transition": "0x1f67cf",
"eip1706Transition": "0x1f67cf", "eip1706Transition": "0x1f67cf",
"eip2028Transition": "0x1f67cf", "eip2028Transition": "0x1f67cf",
"eip2200AdvanceTransition": "0x1f67cf",
"gasLimitBoundDivisor": "0x400", "gasLimitBoundDivisor": "0x400",
"maxCodeSize": "0x6000", "maxCodeSize": "0x6000",
"maxCodeSizeTransition": "0xaef49", "maxCodeSizeTransition": "0xaef49",

View File

@ -41,7 +41,8 @@
"eip1283Transition":"0xbe10b", "eip1283Transition":"0xbe10b",
"eip1344Transition":"0xbe10b", "eip1344Transition":"0xbe10b",
"eip1706Transition":"0xbe10b", "eip1706Transition":"0xbe10b",
"eip2028Transition":"0xbe10b" "eip2028Transition":"0xbe10b",
"eip2200AdvanceTransition": "0xbe10b"
}, },
"genesis":{ "genesis":{
"seal":{ "seal":{

View File

@ -100,6 +100,8 @@ pub struct CommonParams {
pub eip1884_transition: BlockNumber, pub eip1884_transition: BlockNumber,
/// Number of first block where EIP-2028 rules begin. /// Number of first block where EIP-2028 rules begin.
pub eip2028_transition: BlockNumber, pub eip2028_transition: BlockNumber,
/// Number of first block where EIP-2200 advance transition begin.
pub eip2200_advance_transition: BlockNumber,
/// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin. /// Number of first block where dust cleanup rules (EIP-168 and EIP169) begin.
pub dust_protection_transition: BlockNumber, pub dust_protection_transition: BlockNumber,
/// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled. /// Nonce cap increase per block. Nonce cap is only checked if dust protection is enabled.
@ -185,6 +187,9 @@ impl CommonParams {
if block_number >= self.eip2028_transition { if block_number >= self.eip2028_transition {
schedule.tx_data_non_zero_gas = 16; schedule.tx_data_non_zero_gas = 16;
} }
if block_number >= self.eip2200_advance_transition {
schedule.sstore_dirty_gas = Some(800);
}
if block_number >= self.eip210_transition { if block_number >= self.eip210_transition {
schedule.blockhash_gas = 800; schedule.blockhash_gas = 800;
} }
@ -322,6 +327,10 @@ impl From<ethjson::spec::Params> for CommonParams {
BlockNumber::max_value, BlockNumber::max_value,
Into::into, Into::into,
), ),
eip2200_advance_transition: p.eip2200_advance_transition.map_or_else(
BlockNumber::max_value,
Into::into,
),
dust_protection_transition: p.dust_protection_transition.map_or_else( dust_protection_transition: p.dust_protection_transition.map_or_else(
BlockNumber::max_value, BlockNumber::max_value,
Into::into, Into::into,

View File

@ -53,6 +53,8 @@ pub struct Schedule {
pub sha3_word_gas: usize, pub sha3_word_gas: usize,
/// Gas price for loading from storage /// Gas price for loading from storage
pub sload_gas: usize, pub sload_gas: usize,
/// Special gas price for dirty gas of SSTORE, after net gas metering.
pub sstore_dirty_gas: Option<usize>,
/// Gas price for setting new value to storage (`storage==0`, `new!=0`) /// Gas price for setting new value to storage (`storage==0`, `new!=0`)
pub sstore_set_gas: usize, pub sstore_set_gas: usize,
/// Gas price for altering value in storage /// Gas price for altering value in storage
@ -240,6 +242,7 @@ impl Schedule {
sha3_gas: 30, sha3_gas: 30,
sha3_word_gas: 6, sha3_word_gas: 6,
sload_gas: 200, sload_gas: 200,
sstore_dirty_gas: None,
sstore_set_gas: 20000, sstore_set_gas: 20000,
sstore_reset_gas: 5000, sstore_reset_gas: 5000,
sstore_refund_gas: 15000, sstore_refund_gas: 15000,
@ -331,6 +334,7 @@ impl Schedule {
sha3_gas: 30, sha3_gas: 30,
sha3_word_gas: 6, sha3_word_gas: 6,
sload_gas: 50, sload_gas: 50,
sstore_dirty_gas: None,
sstore_set_gas: 20000, sstore_set_gas: 20000,
sstore_reset_gas: 5000, sstore_reset_gas: 5000,
sstore_refund_gas: 15000, sstore_refund_gas: 15000,

View File

@ -107,6 +107,8 @@ pub struct Params {
/// See `CommonParams` docs. /// See `CommonParams` docs.
pub eip2028_transition: Option<Uint>, pub eip2028_transition: Option<Uint>,
/// See `CommonParams` docs. /// See `CommonParams` docs.
pub eip2200_advance_transition: Option<Uint>,
/// See `CommonParams` docs.
pub dust_protection_transition: Option<Uint>, pub dust_protection_transition: Option<Uint>,
/// See `CommonParams` docs. /// See `CommonParams` docs.
pub nonce_cap_increment: Option<Uint>, pub nonce_cap_increment: Option<Uint>,