Skip to content
Merged
74 changes: 42 additions & 32 deletions core/vm/gas_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func memoryGasCost(mem *Memory, newMemSize uint64) (*multigas.MultiGas, uint64,
fee := newTotalFee - mem.lastGasCost
mem.lastGasCost = newTotalFee

return multigas.ZeroGas(), fee, nil
return multigas.ComputationGas(fee), fee, nil
}
return multigas.ZeroGas(), 0, nil
}
Expand Down Expand Up @@ -404,82 +404,92 @@ func gasExpEIP158(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memor

func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (*multigas.MultiGas, uint64, error) {
var (
gas uint64
multiGas = multigas.ZeroGas()
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
multiGas.SafeIncrement(multigas.ResourceKindStorageGrowth, params.CallNewAccountGas)
}
} else if !evm.StateDB.Exist(address) {
gas += params.CallNewAccountGas
multiGas.SafeIncrement(multigas.ResourceKindStorageGrowth, params.CallNewAccountGas)
}

if transfersValue && !evm.chainRules.IsEIP4762 {
gas += params.CallValueTransferGas
multiGas.SafeIncrement(multigas.ResourceKindComputation, params.CallValueTransferGas)
}
multiGas, memoryGas, err := memoryGasCost(mem, memorySize)

memoryMultiGas, _, err := memoryGasCost(mem, memorySize)
if err != nil {
return multigas.ZeroGas(), 0, err
}
// TODO(NIT-3484): Update multi dimensional gas here
var overflow bool
if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
multiGas, overflow := multiGas.SafeAdd(multiGas, memoryMultiGas)
if overflow {
return multigas.ZeroGas(), 0, ErrGasUintOverflow
}

if evm.chainRules.IsEIP4762 && !contract.IsSystemCall {
if transfersValue {
gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address(), address))
if overflow {
valueTransferGas := evm.AccessEvents.ValueTransferGas(contract.Address(), address)
if overflow := multiGas.SafeIncrement(multigas.ResourceKindStorageAccess, valueTransferGas); overflow {
return multigas.ZeroGas(), 0, ErrGasUintOverflow
}
}
}
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))

singleGas, _ := multiGas.SingleGas()
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, singleGas, stack.Back(0))
if err != nil {
return multigas.ZeroGas(), 0, err
}
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
if overflow = multiGas.SafeIncrement(multigas.ResourceKindComputation, evm.callGasTemp); overflow {
return multigas.ZeroGas(), 0, ErrGasUintOverflow
}

return multiGas, gas, nil
singleGas, _ = multiGas.SingleGas()
return multiGas, singleGas, nil
}

func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (*multigas.MultiGas, uint64, error) {
multiGas, memoryGas, err := memoryGasCost(mem, memorySize)
memoryMultiGas, _, err := memoryGasCost(mem, memorySize)
if err != nil {
return multigas.ZeroGas(), 0, err
}
var (
gas uint64
multiGas = multigas.ZeroGas()
overflow bool
)
if stack.Back(2).Sign() != 0 && !evm.chainRules.IsEIP4762 {
gas += params.CallValueTransferGas
multiGas.SafeIncrement(multigas.ResourceKindComputation, params.CallValueTransferGas)
}
// TODO(NIT-3484): Update multi dimensional gas here
if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
multiGas, overflow = multiGas.SafeAdd(multiGas, memoryMultiGas)
if overflow {
return multigas.ZeroGas(), 0, ErrGasUintOverflow
}
if evm.chainRules.IsEIP4762 && !contract.IsSystemCall {
address := common.Address(stack.Back(1).Bytes20())
transfersValue := !stack.Back(2).IsZero()
if transfersValue {
gas, overflow = math.SafeAdd(gas, evm.AccessEvents.ValueTransferGas(contract.Address(), address))
if overflow {
valueTransferGas := evm.AccessEvents.ValueTransferGas(contract.Address(), address)
if overflow = multiGas.SafeIncrement(multigas.ResourceKindStorageAccess, valueTransferGas); overflow {
return multigas.ZeroGas(), 0, ErrGasUintOverflow
}
}
}
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))

singleGas, _ := multiGas.SingleGas()
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, singleGas, stack.Back(0))
if err != nil {
return multigas.ZeroGas(), 0, err
}
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
if overflow = multiGas.SafeIncrement(multigas.ResourceKindComputation, evm.callGasTemp); overflow {
return multigas.ZeroGas(), 0, ErrGasUintOverflow
}
return multiGas, gas, nil

singleGas, _ = multiGas.SingleGas()
return multiGas, singleGas, nil
}

func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (*multigas.MultiGas, uint64, error) {
Expand All @@ -491,12 +501,12 @@ func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me
if err != nil {
return multigas.ZeroGas(), 0, err
}
var overflow bool
// TODO(NIT-3484): Update multi dimensional gas here
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
if overflow := multiGas.SafeIncrement(multigas.ResourceKindComputation, evm.callGasTemp); overflow {
return multigas.ZeroGas(), 0, ErrGasUintOverflow
}
return multiGas, gas, nil

singleGas, _ := multiGas.SingleGas()
return multiGas, singleGas, nil
}

func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (*multigas.MultiGas, uint64, error) {
Expand All @@ -508,12 +518,12 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo
if err != nil {
return multigas.ZeroGas(), 0, err
}
var overflow bool
// TODO(NIT-3484): Update multi dimensional gas here
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
if overflow := multiGas.SafeIncrement(multigas.ResourceKindComputation, evm.callGasTemp); overflow {
return multigas.ZeroGas(), 0, ErrGasUintOverflow
}
return multiGas, gas, nil

singleGas, _ := multiGas.SingleGas()
return multiGas, singleGas, nil
}

func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (*multigas.MultiGas, uint64, error) {
Expand Down
24 changes: 13 additions & 11 deletions core/vm/operations_acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,12 @@ func makeCallVariantGasCallEIP2929(oldCalculator gasFunc, addressPosition int) g
// also become correctly reported to tracers.
contract.Gas += coldCost

// TODO(NIT-3484): Update multi dimensional gas here
var overflow bool
if gas, overflow = math.SafeAdd(gas, coldCost); overflow {
if overflow := multiGas.SafeIncrement(multigas.ResourceKindStorageAccess, coldCost); overflow {
return multigas.ZeroGas(), 0, ErrGasUintOverflow
}
return multigas.ZeroGas(), gas, nil

singleGas, _ := multiGas.SingleGas()
return multiGas, singleGas, nil
}
}

Expand Down Expand Up @@ -265,8 +265,8 @@ var (
func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (*multigas.MultiGas, uint64, error) {
var (
total uint64 // total dynamic gas used
addr = common.Address(stack.Back(1).Bytes20())
multiGas = multigas.ZeroGas() // total dynamic gas used
addr = common.Address(stack.Back(1).Bytes20())
)

// Check slot presence in the access list
Expand All @@ -280,7 +280,7 @@ func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
if !contract.UseGas(coldCost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) {
return multigas.ZeroGas(), 0, ErrOutOfGas
}
total += coldCost
multiGas.SafeIncrement(multigas.ResourceKindStorageAccess, coldCost)
}

// Check if code is a delegation and if so, charge for resolution.
Expand All @@ -295,7 +295,7 @@ func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
if !contract.UseGas(cost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) {
return multigas.ZeroGas(), 0, ErrOutOfGas
}
total += cost
multiGas.SafeIncrement(multigas.ResourceKindStorageAccess, cost)
}

// Now call the old calculator, which takes into account
Expand All @@ -312,12 +312,14 @@ func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc {
// adding it to the return, it will be charged outside of this function, as
// part of the dynamic gas. This will ensure it is correctly reported to
// tracers.
contract.Gas += total
contract.Gas += multiGas.Get(multigas.ResourceKindStorageAccess)

var overflow bool
if total, overflow = math.SafeAdd(old, total); overflow {
if multiGas, overflow = multiGas.SafeAdd(multiGas, multiOld); overflow {
return multigas.ZeroGas(), 0, ErrGasUintOverflow
}
return multigas.ZeroGas(), total, nil

singleGas, _ := multiGas.SingleGas()
return multiGas, singleGas, nil
}
}
Loading
Loading