core/vm: fix opExtStaticCall

This commit is contained in:
Marius van der Wijden 2024-06-26 09:34:01 +02:00
parent a1b359f310
commit aa8e431183
3 changed files with 103 additions and 55 deletions

View file

@ -724,27 +724,27 @@ func enableEOF(jt *JumpTable) {
} }
jt[EXTCALL] = &operation{ jt[EXTCALL] = &operation{
execute: opExtCall, execute: opExtCall,
constantGas: params.CallGasEIP150, constantGas: params.WarmStorageReadCostEIP2929,
dynamicGas: gasCallExt, dynamicGas: makeCallVariantGasCallEIP2929(gasExtCall),
minStack: minStack(4, 1), minStack: minStack(4, 1),
maxStack: maxStack(4, 1), maxStack: maxStack(4, 1),
memorySize: memoryExtCall, memorySize: memoryExtCall,
} }
jt[EXTDELEGATECALL] = &operation{ jt[EXTDELEGATECALL] = &operation{
execute: opExtDelegateCall, execute: opExtDelegateCall,
dynamicGas: gasDelegateCall, dynamicGas: makeCallVariantGasCallEIP2929(gasExtDelegateCall),
constantGas: params.CallGasEIP150, constantGas: params.WarmStorageReadCostEIP2929,
minStack: minStack(3, 1), minStack: minStack(3, 1),
maxStack: maxStack(3, 1), maxStack: maxStack(3, 1),
memorySize: memoryDelegateCall, memorySize: memoryExtDelegateCall,
} }
jt[EXTSTATICCALL] = &operation{ jt[EXTSTATICCALL] = &operation{
execute: opExtStaticCall, execute: opExtStaticCall,
constantGas: params.CallGasEIP150, constantGas: params.WarmStorageReadCostEIP2929,
dynamicGas: gasStaticCall, dynamicGas: makeCallVariantGasCallEIP2929(gasExtStaticCall),
minStack: minStack(3, 1), minStack: minStack(3, 1),
maxStack: maxStack(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) { func opExtDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
stack := scope.Stack stack := scope.Stack
// Use all available gas // Use all available gas
gas := (scope.Contract.Gas / 64) * 63 gas := interpreter.evm.callGasTemp
// Pop other call parameters. // Pop other call parameters.
addr, inOffset, inSize := stack.pop(), stack.pop(), stack.pop() addr, inOffset, inSize := stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20()) 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) { func opExtStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
stack := scope.Stack stack := scope.Stack
// Use all available gas // Use all available gas
gas := (scope.Contract.Gas / 64) * 63 gas := interpreter.evm.callGasTemp
// Pop other call parameters. // Pop other call parameters.
addr, inOffset, inSize := stack.pop(), stack.pop(), stack.pop() addr, inOffset, inSize := stack.pop(), stack.pop(), stack.pop()
toAddr := common.Address(addr.Bytes20()) toAddr := common.Address(addr.Bytes20())

View file

@ -414,51 +414,6 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize
return gas, nil 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) { func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
memoryGas, err := memoryGasCost(mem, memorySize) memoryGas, err := memoryGasCost(mem, memorySize)
if err != nil { if err != nil {
@ -526,6 +481,83 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo
return gas, nil 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) { func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
var gas uint64 var gas uint64
// EIP150 homestead gas reprice fork: // EIP150 homestead gas reprice fork:

View file

@ -125,6 +125,22 @@ func memoryExtCall(stack *Stack) (uint64, bool) {
return x, false 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) { func memoryReturn(stack *Stack) (uint64, bool) {
return calcMemSize64(stack.Back(0), stack.Back(1)) return calcMemSize64(stack.Back(0), stack.Back(1))
} }