diff --git a/gasometer/src/costs.rs b/gasometer/src/costs.rs index 9ac1702a..c16c5d42 100644 --- a/gasometer/src/costs.rs +++ b/gasometer/src/costs.rs @@ -39,18 +39,10 @@ pub fn sstore_refund(original: H256, current: H256, new: H256, config: &Config) } if original == new { - let (gas_sstore_reset, gas_sload) = if config.increase_state_access_gas { - ( - config.gas_sstore_reset - config.gas_sload_cold, - config.gas_storage_read_warm, - ) - } else { - (config.gas_sstore_reset, config.gas_sload) - }; if original == H256::default() { - refund += (config.gas_sstore_set - gas_sload) as i64; + refund += (config.gas_sstore_set - config.gas_sload) as i64; } else { - refund += (gas_sstore_reset - gas_sload) as i64; + refund += (config.gas_sstore_reset - config.gas_sload) as i64; } } @@ -214,37 +206,29 @@ pub fn sstore_cost( is_cold: bool, config: &Config, ) -> Result { - let (gas_sload, gas_sstore_reset) = if config.increase_state_access_gas { - ( - config.gas_storage_read_warm, - config.gas_sstore_reset - config.gas_sload_cold, - ) - } else { - (config.gas_sload, config.gas_sstore_reset) - }; let gas_cost = if config.sstore_gas_metering { if config.sstore_revert_under_stipend && gas <= config.call_stipend { return Err(ExitError::OutOfGas); } if new == current { - gas_sload + config.gas_sload } else { if original == current { if original == H256::zero() { config.gas_sstore_set } else { - gas_sstore_reset + config.gas_sstore_reset } } else { - gas_sload + config.gas_sload } } } else { if current == H256::zero() && new != H256::zero() { config.gas_sstore_set } else { - gas_sstore_reset + config.gas_sstore_reset } }; Ok( diff --git a/gasometer/src/lib.rs b/gasometer/src/lib.rs index 1676eb86..85c87f14 100644 --- a/gasometer/src/lib.rs +++ b/gasometer/src/lib.rs @@ -832,7 +832,7 @@ impl<'config> Inner<'config> { } => costs::sstore_refund(original, current, new, self.config), GasCost::Suicide { already_removed, .. - } => costs::suicide_refund(already_removed), + } if !self.config.decrease_clears_refund => costs::suicide_refund(already_removed), _ => 0, } } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 5838a14b..7c3be417 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -173,6 +173,8 @@ pub struct Config { pub gas_sstore_reset: u64, /// Gas paid for sstore refund. pub refund_sstore_clears: i64, + /// EIP-3529 + pub max_refund_quotient: u64, /// Gas paid for BALANCE opcode. pub gas_balance: u64, /// Gas paid for SLOAD opcode. @@ -209,6 +211,8 @@ pub struct Config { pub sstore_revert_under_stipend: bool, /// EIP-2929 pub increase_state_access_gas: bool, + /// EIP-3529 + pub decrease_clears_refund: bool, /// EIP-3541 pub disallow_executable_format: bool, /// Whether to throw out of gas error when @@ -265,6 +269,7 @@ impl Config { gas_sstore_set: 20000, gas_sstore_reset: 5000, refund_sstore_clears: 15000, + max_refund_quotient: 2, gas_suicide: 0, gas_suicide_new_account: 0, gas_call: 40, @@ -280,6 +285,7 @@ impl Config { sstore_gas_metering: false, sstore_revert_under_stipend: false, increase_state_access_gas: false, + decrease_clears_refund: false, disallow_executable_format: false, err_on_call_with_more_gas: true, empty_considered_exists: true, @@ -314,6 +320,7 @@ impl Config { gas_sstore_set: 20000, gas_sstore_reset: 5000, refund_sstore_clears: 15000, + max_refund_quotient: 2, gas_suicide: 5000, gas_suicide_new_account: 25000, gas_call: 700, @@ -329,6 +336,7 @@ impl Config { sstore_gas_metering: true, sstore_revert_under_stipend: true, increase_state_access_gas: false, + decrease_clears_refund: false, disallow_executable_format: false, err_on_call_with_more_gas: false, empty_considered_exists: false, @@ -354,64 +362,43 @@ impl Config { /// Berlin hard fork configuration. pub const fn berlin() -> Config { - Config { - gas_ext_code: 0, - gas_ext_code_hash: 0, - gas_balance: 0, - gas_sload: 0, - gas_sload_cold: 2100, - gas_sstore_set: 20000, - gas_sstore_reset: 5000, - refund_sstore_clears: 15000, - gas_suicide: 5000, - gas_suicide_new_account: 25000, - gas_call: 0, - gas_expbyte: 50, - gas_transaction_create: 53000, - gas_transaction_call: 21000, - gas_transaction_zero_data: 4, - gas_transaction_non_zero_data: 16, - gas_access_list_address: 2400, - gas_access_list_storage_key: 1900, - gas_account_access_cold: 2600, - gas_storage_read_warm: 100, - sstore_gas_metering: true, - sstore_revert_under_stipend: true, - increase_state_access_gas: true, - disallow_executable_format: false, - err_on_call_with_more_gas: false, - empty_considered_exists: false, - create_increase_nonce: true, - call_l64_after_gas: true, - stack_limit: 1024, - memory_limit: usize::MAX, - call_stack_limit: 1024, - create_contract_limit: Some(0x6000), - call_stipend: 2300, - has_delegate_call: true, - has_create2: true, - has_revert: true, - has_return_data: true, - has_bitwise_shifting: true, - has_chain_id: true, - has_self_balance: true, - has_ext_code_hash: true, - has_base_fee: false, - estimate: false, - } + Self::config_with_derived_values(100, 2100, 1900, false, false) } /// london hard fork configuration. pub const fn london() -> Config { + Self::config_with_derived_values(100, 2100, 1900, true, true) + } + + const fn config_with_derived_values( + gas_storage_read_warm: u64, + gas_sload_cold: u64, + gas_access_list_storage_key: u64, + decrease_clears_refund: bool, + has_base_fee: bool, + ) -> Config { + // See https://eips.ethereum.org/EIPS/eip-2929 + let gas_sload = gas_storage_read_warm; + let gas_sstore_reset = 5000 - gas_sload_cold; + + // See https://eips.ethereum.org/EIPS/eip-3529 + let refund_sstore_clears = if decrease_clears_refund { + (gas_sstore_reset + gas_access_list_storage_key) as i64 + } else { + 15000 + }; + let max_refund_quotient = if decrease_clears_refund { 5 } else { 2 }; + Config { gas_ext_code: 0, gas_ext_code_hash: 0, gas_balance: 0, - gas_sload: 0, - gas_sload_cold: 2100, + gas_sload, + gas_sload_cold, gas_sstore_set: 20000, - gas_sstore_reset: 5000, - refund_sstore_clears: 15000, + gas_sstore_reset, + refund_sstore_clears, + max_refund_quotient, gas_suicide: 5000, gas_suicide_new_account: 25000, gas_call: 0, @@ -421,13 +408,14 @@ impl Config { gas_transaction_zero_data: 4, gas_transaction_non_zero_data: 16, gas_access_list_address: 2400, - gas_access_list_storage_key: 1900, + gas_access_list_storage_key, gas_account_access_cold: 2600, - gas_storage_read_warm: 100, + gas_storage_read_warm, sstore_gas_metering: true, sstore_revert_under_stipend: true, increase_state_access_gas: true, - disallow_executable_format: true, + decrease_clears_refund, + disallow_executable_format: false, err_on_call_with_more_gas: false, empty_considered_exists: false, create_increase_nonce: true, @@ -445,7 +433,7 @@ impl Config { has_chain_id: true, has_self_balance: true, has_ext_code_hash: true, - has_base_fee: true, + has_base_fee, estimate: false, } } diff --git a/src/executor/stack/mod.rs b/src/executor/stack/mod.rs index 562b2381..a1d4f791 100644 --- a/src/executor/stack/mod.rs +++ b/src/executor/stack/mod.rs @@ -392,7 +392,7 @@ impl<'config, S: StackState<'config>> StackExecutor<'config, S> { pub fn used_gas(&self) -> u64 { self.state.metadata().gasometer.total_used_gas() - min( - self.state.metadata().gasometer.total_used_gas() / 2, + self.state.metadata().gasometer.total_used_gas() / self.config.max_refund_quotient, self.state.metadata().gasometer.refunded_gas() as u64, ) }