diff --git a/core/vm/instructions.go b/core/vm/instructions.go index b88a4ef5877f..4a9595283940 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -20,7 +20,6 @@ import ( "encoding/binary" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -459,11 +458,11 @@ func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([ return nil, nil } -func getBlockHashFromContract(number uint64, statedb StateDB, witness *state.AccessWitness) (common.Hash, uint64) { +func getBlockHashFromContract(number uint64, statedb StateDB, witness *state.AccessWitness, availableGas uint64) (common.Hash, uint64) { ringIndex := number % params.Eip2935BlockHashHistorySize var pnum common.Hash binary.BigEndian.PutUint64(pnum[24:], ringIndex) - statelessGas := witness.TouchSlotAndChargeGas(params.HistoryStorageAddress[:], pnum, false, math.MaxUint64, false) + statelessGas := witness.TouchSlotAndChargeGas(params.HistoryStorageAddress[:], pnum, false, availableGas, false) return statedb.GetState(params.HistoryStorageAddress, pnum), statelessGas } @@ -487,7 +486,7 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( if num64 >= lower && num64 < upper { // if Verkle is active, read it from the history contract (EIP 2935). if evm.chainRules.IsVerkle { - blockHash, statelessGas := getBlockHashFromContract(num64, evm.StateDB, evm.Accesses) + blockHash, statelessGas := getBlockHashFromContract(num64, evm.StateDB, evm.Accesses, scope.Contract.Gas) if interpreter.evm.chainRules.IsEIP4762 { if !scope.Contract.UseGas(statelessGas) { return nil, ErrOutOfGas diff --git a/core/vm/operations_verkle.go b/core/vm/operations_verkle.go index a8c673bc5e28..1d96c9578f5d 100644 --- a/core/vm/operations_verkle.go +++ b/core/vm/operations_verkle.go @@ -111,7 +111,12 @@ func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Mem beneficiaryAddr := common.Address(stack.peek().Bytes20()) contractAddr := contract.Address() - statelessGas := evm.Accesses.TouchBasicData(contractAddr[:], false, contract.Gas, false) + wanted := evm.Accesses.TouchBasicData(contractAddr[:], false, contract.Gas, false) + if wanted > contract.Gas { + return wanted, nil + } + statelessGas := wanted + balanceIsZero := evm.StateDB.GetBalance(contractAddr).Sign() == 0 _, isPrecompile := evm.precompile(beneficiaryAddr) isSystemContract := evm.isSystemContract(beneficiaryAddr) @@ -121,21 +126,30 @@ func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Mem } if contractAddr != beneficiaryAddr { - statelessGas += evm.Accesses.TouchBasicData(beneficiaryAddr[:], false, contract.Gas-statelessGas, false) + wanted := evm.Accesses.TouchBasicData(beneficiaryAddr[:], false, contract.Gas-statelessGas, false) + if wanted > contract.Gas-statelessGas { + return statelessGas + wanted, nil + } + statelessGas += wanted } // Charge write costs if it transfers value if !balanceIsZero { - statelessGas += evm.Accesses.TouchBasicData(contractAddr[:], true, contract.Gas-statelessGas, false) + wanted := evm.Accesses.TouchBasicData(contractAddr[:], true, contract.Gas-statelessGas, false) + if wanted > contract.Gas-statelessGas { + return statelessGas + wanted, nil + } + statelessGas += wanted + if contractAddr != beneficiaryAddr { if evm.StateDB.Exist(beneficiaryAddr) { - statelessGas += evm.Accesses.TouchBasicData(beneficiaryAddr[:], true, contract.Gas-statelessGas, false) + wanted = evm.Accesses.TouchBasicData(beneficiaryAddr[:], true, contract.Gas-statelessGas, false) } else { - wanted := evm.Accesses.TouchFullAccount(beneficiaryAddr[:], true, contract.Gas-statelessGas) - if wanted > contract.Gas-statelessGas { - return statelessGas + wanted, nil - } - statelessGas += wanted + wanted = evm.Accesses.TouchFullAccount(beneficiaryAddr[:], true, contract.Gas-statelessGas) + } + if wanted > contract.Gas-statelessGas { + return statelessGas + wanted, nil } + statelessGas += wanted } } return statelessGas, nil @@ -158,7 +172,7 @@ func gasExtCodeCopyEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memo } return gas, nil } - wgas := evm.Accesses.TouchBasicData(addr[:], false, contract.Gas, true) + wgas := evm.Accesses.TouchBasicData(addr[:], false, contract.Gas-gas, true) var overflow bool if gas, overflow = math.SafeAdd(gas, wgas); overflow { return 0, ErrGasUintOverflow