Test SELFDESTRUCT Gas¶
Documentation for tests/amsterdam/eip8038_state_access_gas_cost_increase/test_selfdestruct_gas.py@5fa5938b.
Generate fixtures for these test cases for Amsterdam with:
fill -v tests/amsterdam/eip8038_state_access_gas_cost_increase/test_selfdestruct_gas.py --fork Amsterdam
Tests for the EIP-8038 State Access Gas Cost Increase
SELFDESTRUCT regular-gas dimension.
Under EIP-8038 SELFDESTRUCT is charged, in its regular gas
dimension:
OPCODE_SELFDESTRUCT_BASE(5,000);- a
COLD_ACCOUNT_ACCESS(3,000) surcharge when the beneficiary is cold (a warm beneficiary adds nothing — SELFDESTRUCT has noWARM_ACCESSsurcharge); - a net-new
ACCOUNT_WRITE(8,000) when a positive balance is sent to an empty (or non-existent) beneficiary, replacing the legacy combined 25,000 regular account-creation cost.
So regular = 5,000 + (3,000 if cold) + (8,000 if creating): 13,000
warm / 16,000 cold when a new beneficiary is created, 5,000 warm / 8,000
cold otherwise.
The beneficiary account-creation charge GAS_NEW_ACCOUNT (183,600) is
the EIP-8037 state dimension (charge_state_gas in the spec), covered
in eip8037_state_creation_gas_cost_increase/test_state_gas_selfdestruct.py.
SELFDESTRUCT halts the frame, so it is driven via a wrapping CALL
and verified through block gas_used accounting and balances. Per
EIP-6780, a contract not created in the same transaction is not deleted,
but its balance is still transferred and the beneficiary creation charge
still applies.
The framework opcode-gas model splits the two dimensions for
SELFDESTRUCT exactly as the spec does: ACCOUNT_WRITE is charged
as regular gas and GAS_NEW_ACCOUNT as state gas, so
Op.SELFDESTRUCT(account_new=True).regular_cost(fork) is the regular
charge (16,000 cold / 13,000 warm) and .state_cost(fork) is
GAS_NEW_ACCOUNT. These tests assert the regular dimension and verify
account-creation via balances; the state dimension is owned by
eip8037_state_creation_gas_cost_increase/test_state_gas_selfdestruct.py.
Test Functions Overview¶
| Name | Type | Cases (Amsterdam) | Description |
|---|---|---|---|
test_same_tx_created_selfdestruct_self_burn |
state_test | 1 | EIP-6780: a same-tx-created contract SELFDESTRUCTs to itself, charged |
test_same_tx_created_selfdestruct_to_fresh_beneficiary |
state_test | 1 | EIP-6780: a same-tx-created contract sends value to a fresh |
test_selfdestruct_alive_beneficiary_no_account_write |
state_test | 2 | SELFDESTRUCT to an already-alive beneficiary charges no ACCOUNT_WRITE. |
test_selfdestruct_codebearing_zero_balance_beneficiary_no_account_write |
state_test | 2 | SELFDESTRUCT to a code-bearing zero-balance beneficiary: no |
test_selfdestruct_new_beneficiary_regular_gas |
state_test | 2 | SELFDESTRUCT to an empty beneficiary with balance charges |
test_selfdestruct_oog_boundary |
state_test | 2 | Drive a cold SELFDESTRUCT that funds a new account at its exact total |
test_selfdestruct_self_or_precompile_beneficiary |
state_test | 2 | SELFDESTRUCT to self or a precompile is warm and charges no |
test_selfdestruct_zero_balance_no_account_write |
state_test | 2 | SELFDESTRUCT with a zero-balance destructor charges no ACCOUNT_WRITE. |