From aa8e43118345858da99515e183b1c62734995ee4 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Wed, 26 Jun 2024 09:34:01 +0200 Subject: [PATCH] core/vm: fix opExtStaticCall --- core/vm/eips.go | 20 +++---- core/vm/gas_table.go | 122 +++++++++++++++++++++++++--------------- core/vm/memory_table.go | 16 ++++++ 3 files changed, 103 insertions(+), 55 deletions(-) diff --git a/core/vm/eips.go b/core/vm/eips.go index 335186174a..8adc615043 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -724,27 +724,27 @@ func enableEOF(jt *JumpTable) { } jt[EXTCALL] = &operation{ execute: opExtCall, - constantGas: params.CallGasEIP150, - dynamicGas: gasCallExt, + constantGas: params.WarmStorageReadCostEIP2929, + dynamicGas: makeCallVariantGasCallEIP2929(gasExtCall), minStack: minStack(4, 1), maxStack: maxStack(4, 1), memorySize: memoryExtCall, } jt[EXTDELEGATECALL] = &operation{ execute: opExtDelegateCall, - dynamicGas: gasDelegateCall, - constantGas: params.CallGasEIP150, + dynamicGas: makeCallVariantGasCallEIP2929(gasExtDelegateCall), + constantGas: params.WarmStorageReadCostEIP2929, minStack: minStack(3, 1), maxStack: maxStack(3, 1), - memorySize: memoryDelegateCall, + memorySize: memoryExtDelegateCall, } jt[EXTSTATICCALL] = &operation{ execute: opExtStaticCall, - constantGas: params.CallGasEIP150, - dynamicGas: gasStaticCall, + constantGas: params.WarmStorageReadCostEIP2929, + dynamicGas: makeCallVariantGasCallEIP2929(gasExtStaticCall), minStack: minStack(3, 1), maxStack: maxStack(3, 1), - memorySize: memoryStaticCall, + memorySize: memoryExtStaticCall, } } @@ -1117,7 +1117,7 @@ func opExtCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] func opExtDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { stack := scope.Stack // Use all available gas - gas := (scope.Contract.Gas / 64) * 63 + gas := interpreter.evm.callGasTemp // Pop other call parameters. addr, inOffset, inSize := stack.pop(), stack.pop(), stack.pop() toAddr := common.Address(addr.Bytes20()) @@ -1143,7 +1143,7 @@ func opExtDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeCont func opExtStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { stack := scope.Stack // Use all available gas - gas := (scope.Contract.Gas / 64) * 63 + gas := interpreter.evm.callGasTemp // Pop other call parameters. addr, inOffset, inSize := stack.pop(), stack.pop(), stack.pop() toAddr := common.Address(addr.Bytes20()) diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index bf6401f9fc..931e09a384 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -414,51 +414,6 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize return gas, nil } -func gasCallExt(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var ( - gas uint64 - transfersValue = !stack.Back(2).IsZero() - address = common.Address(stack.Back(1).Bytes20()) - ) - if evm.chainRules.IsEIP158 { - if transfersValue && evm.StateDB.Empty(address) { - gas += params.CallNewAccountGas - } - } else if !evm.StateDB.Exist(address) { - gas += params.CallNewAccountGas - } - if transfersValue && !evm.chainRules.IsEIP4762 { - gas += params.CallValueTransferGas - } - memoryGas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - var overflow bool - if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { - return 0, ErrGasUintOverflow - } - if evm.chainRules.IsEIP4762 { - if transfersValue { - gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address(), address)) - if overflow { - return 0, ErrGasUintOverflow - } - } - } - - evm.callGasTemp, err = callGas(true, contract.Gas, gas, new(uint256.Int).SetUint64(contract.Gas)) - if err != nil { - return 0, err - } - - if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { - return 0, ErrGasUintOverflow - } - - return gas, nil -} - func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { memoryGas, err := memoryGasCost(mem, memorySize) if err != nil { @@ -526,6 +481,83 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo return gas, nil } +func gasExtCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var ( + gas uint64 + transfersValue = !stack.Back(2).IsZero() + address = common.Address(stack.Back(1).Bytes20()) + ) + if evm.chainRules.IsEIP158 { + if transfersValue && evm.StateDB.Empty(address) { + gas += params.CallNewAccountGas + } + } else if !evm.StateDB.Exist(address) { + gas += params.CallNewAccountGas + } + if transfersValue && !evm.chainRules.IsEIP4762 { + gas += params.CallValueTransferGas + } + memoryGas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + var overflow bool + if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { + return 0, ErrGasUintOverflow + } + if evm.chainRules.IsEIP4762 { + if transfersValue { + gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address(), address)) + if overflow { + return 0, ErrGasUintOverflow + } + } + } + + evm.callGasTemp, err = callGas(true, contract.Gas, gas, new(uint256.Int).SetUint64(contract.Gas)) + if err != nil { + return 0, err + } + + if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { + return 0, ErrGasUintOverflow + } + + return gas, nil +} + +func gasExtDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + evm.callGasTemp, err = callGas(true, contract.Gas, gas, new(uint256.Int).SetUint64(contract.Gas)) + if err != nil { + return 0, err + } + var overflow bool + if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { + return 0, ErrGasUintOverflow + } + return gas, nil +} + +func gasExtStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + evm.callGasTemp, err = callGas(true, contract.Gas, gas, new(uint256.Int).SetUint64(contract.Gas)) + if err != nil { + return 0, err + } + var overflow bool + if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { + return 0, ErrGasUintOverflow + } + return gas, nil +} + func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var gas uint64 // EIP150 homestead gas reprice fork: diff --git a/core/vm/memory_table.go b/core/vm/memory_table.go index d23c0033ab..206ef6145c 100644 --- a/core/vm/memory_table.go +++ b/core/vm/memory_table.go @@ -125,6 +125,22 @@ func memoryExtCall(stack *Stack) (uint64, bool) { return x, false } +func memoryExtDelegateCall(stack *Stack) (uint64, bool) { + x, overflow := calcMemSize64(stack.Back(1), stack.Back(2)) + if overflow { + return 0, true + } + return x, false +} + +func memoryExtStaticCall(stack *Stack) (uint64, bool) { + x, overflow := calcMemSize64(stack.Back(1), stack.Back(2)) + if overflow { + return 0, true + } + return x, false +} + func memoryReturn(stack *Stack) (uint64, bool) { return calcMemSize64(stack.Back(0), stack.Back(1)) }