mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
core/vm: fix opExtStaticCall
This commit is contained in:
parent
a1b359f310
commit
aa8e431183
3 changed files with 103 additions and 55 deletions
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue