|
98 | 98 | from .vm.gas import ( |
99 | 99 | BLOB_SCHEDULE_MAX, |
100 | 100 | GAS_PER_BLOB, |
| 101 | + STATE_BYTES_PER_NEW_ACCOUNT, |
| 102 | + STATE_BYTES_PER_STORAGE_SET, |
101 | 103 | calculate_blob_gas_price, |
102 | 104 | calculate_data_fee, |
103 | 105 | calculate_excess_blob_gas, |
104 | 106 | calculate_total_blob_gas, |
| 107 | + state_gas_per_byte, |
105 | 108 | ) |
106 | 109 | from .vm.interpreter import MessageCallOutput, process_message_call |
107 | 110 |
|
@@ -1053,6 +1056,34 @@ def process_transaction( |
1053 | 1056 | if tx_output.error is not None: |
1054 | 1057 | tx_output.state_gas_left += tx_output.state_gas_used |
1055 | 1058 | tx_output.state_gas_used = Uint(0) |
| 1059 | + else: |
| 1060 | + # Refund state gas for accounts created and destroyed in the |
| 1061 | + # same tx (EIP-6780). Covers account, storage, and code. |
| 1062 | + cost_per_state_byte = state_gas_per_byte(block_env.block_gas_limit) |
| 1063 | + for address in tx_output.accounts_to_delete: |
| 1064 | + if address in tx_state.created_accounts: |
| 1065 | + selfdestruct_refund = ( |
| 1066 | + STATE_BYTES_PER_NEW_ACCOUNT * cost_per_state_byte |
| 1067 | + ) |
| 1068 | + storage = tx_state.storage_writes.get(address, {}) |
| 1069 | + created_slots = sum(1 for v in storage.values() if v != 0) |
| 1070 | + selfdestruct_refund += ( |
| 1071 | + Uint(created_slots) |
| 1072 | + * STATE_BYTES_PER_STORAGE_SET |
| 1073 | + * cost_per_state_byte |
| 1074 | + ) |
| 1075 | + # EIP-6780 defers account/storage/code removal to |
| 1076 | + # tx-end, so `account.code_hash` still points at the |
| 1077 | + # deployed code here and `get_code` returns it |
| 1078 | + # pre-deletion. |
| 1079 | + account = get_account(tx_state, address) |
| 1080 | + code = get_code(tx_state, account.code_hash) |
| 1081 | + selfdestruct_refund += Uint(len(code)) * cost_per_state_byte |
| 1082 | + selfdestruct_refund = min( |
| 1083 | + selfdestruct_refund, tx_output.state_gas_used |
| 1084 | + ) |
| 1085 | + tx_output.state_gas_left += selfdestruct_refund |
| 1086 | + tx_output.state_gas_used -= selfdestruct_refund |
1056 | 1087 |
|
1057 | 1088 | tx_gas_used_before_refund = ( |
1058 | 1089 | tx.gas - tx_output.gas_left - tx_output.state_gas_left |
|
0 commit comments