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 {
Gas::from(
if current == new {
// 1. If current value equals new value (this is a no-op), 200 gas is deducted.
schedule.sload_gas
// 1. If current value equals new value (this is a no-op), `SSTORE_DIRTY_GAS`
// (or if not set, `SLOAD_GAS`) is deducted.
schedule.sstore_dirty_gas.unwrap_or(schedule.sload_gas)
} else {
// 2. If current value does not equal new value
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() {
// 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
} else {
// 2.1.2. Otherwise, 5000 gas is deducted.
// 2.1.2. Otherwise, `SSTORE_RESET_GAS` gas is deducted.
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 {
// 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.
schedule.sload_gas
// 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.
schedule.sstore_dirty_gas.unwrap_or(schedule.sload_gas)
// 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.2. If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter.
// 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.
// 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.1. If original value is 0, add 19800 gas to refund counter.
// 2.2.2.2. Otherwise, add 4800 gas to refund counter.
// 2.2.2.1. If original value is 0, add `SSTORE_SET_GAS - SSTORE_DIRTY_GAS`
// 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;
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 {
// 2. If current value does not equal new value
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() {
// 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 {
// 2.1.2. Otherwise, 5000 gas is deducted.
// 2.1.2. Otherwise, `SSTORE_RESET_GAS` gas is deducted.
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);
}
}
} 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() {
// 2.2.1. If original value is not 0
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);
} 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);
}
}
@ -441,12 +455,16 @@ pub fn handle_eip1283_sstore_clears_refund(ext: &mut dyn vm::Ext, original: &U25
if original == new {
// 2.2.2. If original value equals new value (this storage slot is reset)
if original.is_zero() {
// 2.2.2.1. If original value is 0, add 19800 gas to refund counter.
let refund = ext.schedule().sstore_set_gas - ext.schedule().sload_gas;
// 2.2.2.1. If original value is 0, add `SSTORE_SET_GAS - SSTORE_DIRTY_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);
} else {
// 2.2.2.2. Otherwise, add 4800 gas to refund counter.
let refund = ext.schedule().sstore_reset_gas - ext.schedule().sload_gas;
// 2.2.2.2. Otherwise, add `SSTORE_RESET_GAS - SSTORE_DIRTY_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);
}
}

View File

@ -40,7 +40,12 @@
"eip658Transition": "0x85d9a0",
"eip145Transition": "0x921288",
"eip1014Transition": "0x921288",
"eip1052Transition": "0x921288"
"eip1052Transition": "0x921288",
"eip1283Transition": "0xa03ae7",
"eip1344Transition": "0xa03ae7",
"eip1706Transition": "0xa03ae7",
"eip2028Transition": "0xa03ae7",
"eip2200AdvanceTransition": "0xa03ae7"
},
"genesis": {
"seal": {
@ -4425,7 +4430,7 @@
"0x85d9a0": {
"price": { "alt_bn128_const_operations": { "price": 500 }}
},
"0x7fffffffffffff": {
"0xa03ae7": {
"price": { "alt_bn128_const_operations": { "price": 150 }}
}
}
@ -4438,7 +4443,7 @@
"0x85d9a0": {
"price": { "alt_bn128_const_operations": { "price": 40000 }}
},
"0x7fffffffffffff": {
"0xa03ae7": {
"price": { "alt_bn128_const_operations": { "price": 6000 }}
}
}
@ -4451,12 +4456,24 @@
"0x85d9a0": {
"price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }}
},
"0x7fffffffffffff": {
"0xa03ae7": {
"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": {
"balance": "1337000000000000000000"
},

View File

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

View File

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

View File

@ -100,6 +100,8 @@ pub struct CommonParams {
pub eip1884_transition: BlockNumber,
/// Number of first block where EIP-2028 rules begin.
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.
pub dust_protection_transition: BlockNumber,
/// 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 {
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 {
schedule.blockhash_gas = 800;
}
@ -322,6 +327,10 @@ impl From<ethjson::spec::Params> for CommonParams {
BlockNumber::max_value,
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(
BlockNumber::max_value,
Into::into,

View File

@ -53,6 +53,8 @@ pub struct Schedule {
pub sha3_word_gas: usize,
/// Gas price for loading from storage
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`)
pub sstore_set_gas: usize,
/// Gas price for altering value in storage
@ -240,6 +242,7 @@ impl Schedule {
sha3_gas: 30,
sha3_word_gas: 6,
sload_gas: 200,
sstore_dirty_gas: None,
sstore_set_gas: 20000,
sstore_reset_gas: 5000,
sstore_refund_gas: 15000,
@ -331,6 +334,7 @@ impl Schedule {
sha3_gas: 30,
sha3_word_gas: 6,
sload_gas: 50,
sstore_dirty_gas: None,
sstore_set_gas: 20000,
sstore_reset_gas: 5000,
sstore_refund_gas: 15000,

View File

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