From 3c662404454d77ec3ac81e47687fa218ec5c46d7 Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 25 Aug 2021 09:40:31 -0400 Subject: [PATCH 1/4] Add MAX_REFUND_QUOTIENT parameter --- runtime/src/lib.rs | 6 ++++++ src/executor/stack/mod.rs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 5838a14b..e018e951 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. @@ -265,6 +267,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, @@ -314,6 +317,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, @@ -363,6 +367,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: 0, @@ -412,6 +417,7 @@ impl Config { gas_sstore_set: 20000, gas_sstore_reset: 5000, refund_sstore_clears: 15000, + max_refund_quotient: 5, gas_suicide: 5000, gas_suicide_new_account: 25000, gas_call: 0, 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, ) } From 33737b647c4b1589d3ee7ac5a1dba013e4d8a4a1 Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 25 Aug 2021 10:16:53 -0400 Subject: [PATCH 2/4] Reduce SSTORE_CLEARS_SCHEDULE value --- gasometer/src/costs.rs | 14 ++++++++++---- runtime/src/lib.rs | 6 ++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/gasometer/src/costs.rs b/gasometer/src/costs.rs index 9ac1702a..40b626e5 100644 --- a/gasometer/src/costs.rs +++ b/gasometer/src/costs.rs @@ -21,20 +21,26 @@ pub fn suicide_refund(already_removed: bool) -> i64 { #[allow(clippy::collapsible_else_if)] pub fn sstore_refund(original: H256, current: H256, new: H256, config: &Config) -> i64 { + let refund_sstore_clears = if config.decrease_clears_refund { + (config.gas_sstore_reset - config.gas_sload_cold + config.gas_access_list_storage_key) + as i64 + } else { + config.refund_sstore_clears + }; if config.sstore_gas_metering { if current == new { 0 } else { if original == current && new == H256::default() { - config.refund_sstore_clears + refund_sstore_clears } else { let mut refund = 0; if original != H256::default() { if current == H256::default() { - refund -= config.refund_sstore_clears; + refund -= refund_sstore_clears; } else if new == H256::default() { - refund += config.refund_sstore_clears; + refund += refund_sstore_clears; } } @@ -59,7 +65,7 @@ pub fn sstore_refund(original: H256, current: H256, new: H256, config: &Config) } } else { if current != H256::default() && new == H256::default() { - config.refund_sstore_clears + refund_sstore_clears } else { 0 } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index e018e951..0455aebd 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -211,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 @@ -283,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, @@ -333,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, @@ -383,6 +387,7 @@ impl Config { sstore_gas_metering: true, sstore_revert_under_stipend: true, increase_state_access_gas: true, + decrease_clears_refund: false, disallow_executable_format: false, err_on_call_with_more_gas: false, empty_considered_exists: false, @@ -433,6 +438,7 @@ impl Config { sstore_gas_metering: true, sstore_revert_under_stipend: true, increase_state_access_gas: true, + decrease_clears_refund: true, disallow_executable_format: true, err_on_call_with_more_gas: false, empty_considered_exists: false, From 6d2be2c5720004b94ecb39917af5491bbfe77ffd Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 25 Aug 2021 10:20:30 -0400 Subject: [PATCH 3/4] Remove the SELFDESTRUCT refund. --- gasometer/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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, } } From 5251f48ac32a5da7dc172430a4e3dd9d53eeb981 Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Wed, 25 Aug 2021 11:05:50 -0400 Subject: [PATCH 4/4] Avoid some runtime arithmetic --- gasometer/src/costs.rs | 42 +++++--------------- runtime/src/lib.rs | 90 ++++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 89 deletions(-) diff --git a/gasometer/src/costs.rs b/gasometer/src/costs.rs index 40b626e5..c16c5d42 100644 --- a/gasometer/src/costs.rs +++ b/gasometer/src/costs.rs @@ -21,42 +21,28 @@ pub fn suicide_refund(already_removed: bool) -> i64 { #[allow(clippy::collapsible_else_if)] pub fn sstore_refund(original: H256, current: H256, new: H256, config: &Config) -> i64 { - let refund_sstore_clears = if config.decrease_clears_refund { - (config.gas_sstore_reset - config.gas_sload_cold + config.gas_access_list_storage_key) - as i64 - } else { - config.refund_sstore_clears - }; if config.sstore_gas_metering { if current == new { 0 } else { if original == current && new == H256::default() { - refund_sstore_clears + config.refund_sstore_clears } else { let mut refund = 0; if original != H256::default() { if current == H256::default() { - refund -= refund_sstore_clears; + refund -= config.refund_sstore_clears; } else if new == H256::default() { - refund += refund_sstore_clears; + refund += config.refund_sstore_clears; } } 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; } } @@ -65,7 +51,7 @@ pub fn sstore_refund(original: H256, current: H256, new: H256, config: &Config) } } else { if current != H256::default() && new == H256::default() { - refund_sstore_clears + config.refund_sstore_clears } else { 0 } @@ -220,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/runtime/src/lib.rs b/runtime/src/lib.rs index 0455aebd..7c3be417 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -362,67 +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, - max_refund_quotient: 2, - 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, - decrease_clears_refund: false, - 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, - max_refund_quotient: 5, + gas_sstore_reset, + refund_sstore_clears, + max_refund_quotient, gas_suicide: 5000, gas_suicide_new_account: 25000, gas_call: 0, @@ -432,14 +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, - decrease_clears_refund: 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, @@ -457,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, } }