From 00136d1735b9f2538b88b2ffdd4ee1cde8763072 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Tue, 16 Dec 2025 11:21:31 -0800 Subject: [PATCH] only perform state reads in selfdestruct if we have sufficient gas to cover the state access costs --- core/state/bal_reader.go | 6 +++--- core/vm/gas_table.go | 8 ++++++++ core/vm/operations_acl.go | 4 +++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/core/state/bal_reader.go b/core/state/bal_reader.go index 93310b2d07..1cd0491db6 100644 --- a/core/state/bal_reader.go +++ b/core/state/bal_reader.go @@ -143,10 +143,10 @@ func (r *BALReader) ModifiedAccounts() (res []common.Address) { return res } -func (r *BALReader) ValidateStateReads(allReads bal.StateAccesses) error { +func (r *BALReader) ValidateStateReads(computedReads bal.StateAccesses) error { // 1. remove any slots from 'allReads' which were written // 2. validate that the read set in the BAL matches 'allReads' exactly - for addr, reads := range allReads { + for addr, reads := range computedReads { balAcctDiff := r.readAccountDiff(addr, len(r.block.Transactions())+2) if balAcctDiff != nil { for writeSlot := range balAcctDiff.StorageWrites { @@ -154,7 +154,7 @@ func (r *BALReader) ValidateStateReads(allReads bal.StateAccesses) error { } } if _, ok := r.accesses[addr]; !ok { - return fmt.Errorf("%x wasn't in BAL", addr) + return fmt.Errorf("account %x was accessed during execution but is not present in the access list", addr) } expectedReads := r.accesses[addr].StorageReads diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index ccd50afbd6..ff0cc6f5f0 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -538,11 +538,19 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var gas uint64 + fmt.Println("gasSelfdestruct") + // EIP150 homestead gas reprice fork: if evm.chainRules.IsEIP150 { gas = params.SelfdestructGasEIP150 var address = common.Address(stack.Back(0).Bytes20()) + fmt.Println("okay we're") + if gas > contract.Gas { + fmt.Println("here") + return gas, nil + } + if evm.chainRules.IsEIP158 { // if empty and transfers value if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index 26d7570be0..11354d1421 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -18,7 +18,6 @@ package vm import ( "errors" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/tracing" @@ -269,6 +268,9 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { evm.StateDB.AddAddressToAccessList(address) gas = params.ColdAccountAccessCostEIP2929 } + if contract.Gas < gas { + return gas, nil + } // if empty and transfers value if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { gas += params.CreateBySelfdestructGas