Skip to content

Commit

Permalink
feat(core/vm): better oog error with backport ethereum/go-ethereum#29354
Browse files Browse the repository at this point in the history
 (#12066)

align with go-ethereum of detailed oog reason, ref:
https://github.com/ethereum/go-ethereum/blob/b018da9d02513ab13de50d63688c465798bd0e14/core/vm/interpreter.go#L273-L275

```go
dynamicCost, err = operation.dynamicGas(in.evm, contract, stack, mem, memorySize)
cost += dynamicCost // for tracing
if err != nil {
    return nil, fmt.Errorf("%w: %v", ErrOutOfGas, err)
}
if !contract.UseGas(dynamicCost, in.evm.Config.Tracer, tracing.GasChangeIgnored) {
    return nil, ErrOutOfGas
}
```

---------

Signed-off-by: jsvisa <[email protected]>
  • Loading branch information
jsvisa authored Sep 25, 2024
1 parent 134d0b1 commit 68b0c3e
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
1 change: 1 addition & 0 deletions core/vm/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var (
ErrContractAddressCollision = errors.New("contract address collision")
ErrExecutionReverted = errors.New("execution reverted")
ErrMaxCodeSizeExceeded = errors.New("max code size exceeded")
ErrMaxInitCodeSizeExceeded = errors.New("max initcode size exceeded")
ErrInvalidJump = errors.New("invalid jump destination")
ErrWriteProtection = errors.New("write protection")
ErrReturnDataOutOfBounds = errors.New("return data out of bounds")
Expand Down
23 changes: 15 additions & 8 deletions core/vm/gas_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package vm

import (
"errors"
"fmt"

"github.com/holiman/uint256"

Expand Down Expand Up @@ -297,11 +298,11 @@ func gasCreate2(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memory, mem
if err != nil {
return 0, err
}
len, overflow := stack.Back(2).Uint64WithOverflow()
size, overflow := stack.Back(2).Uint64WithOverflow()
if overflow {
return 0, ErrGasUintOverflow
}
numWords := ToWordSize(len)
numWords := ToWordSize(size)
wordGas, overflow := math.SafeMul(numWords, params.Keccak256WordGas)
if overflow {
return 0, ErrGasUintOverflow
Expand All @@ -318,11 +319,14 @@ func gasCreateEip3860(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memor
if err != nil {
return 0, err
}
len, overflow := stack.Back(2).Uint64WithOverflow()
if overflow || len > params.MaxInitCodeSize {
size, overflow := stack.Back(2).Uint64WithOverflow()
if overflow {
return 0, ErrGasUintOverflow
}
numWords := ToWordSize(len)
if size > params.MaxInitCodeSize {
return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size)
}
numWords := ToWordSize(size)
// Since size <= params.MaxInitCodeSize, this multiplication cannot overflow
wordGas := params.InitCodeWordGas * numWords
gas, overflow = math.SafeAdd(gas, wordGas)
Expand All @@ -337,11 +341,14 @@ func gasCreate2Eip3860(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memo
if err != nil {
return 0, err
}
len, overflow := stack.Back(2).Uint64WithOverflow()
if overflow || len > params.MaxInitCodeSize {
size, overflow := stack.Back(2).Uint64WithOverflow()
if overflow {
return 0, ErrGasUintOverflow
}
numWords := ToWordSize(len)
if size > params.MaxInitCodeSize {
return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size)
}
numWords := ToWordSize(size)
// Since size <= params.MaxInitCodeSize, this multiplication cannot overflow
wordGas := (params.InitCodeWordGas + params.Keccak256WordGas) * numWords
gas, overflow = math.SafeAdd(gas, wordGas)
Expand Down
6 changes: 5 additions & 1 deletion core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package vm

import (
"fmt"
"hash"
"sync"

Expand Down Expand Up @@ -298,7 +299,10 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
var dynamicCost uint64
dynamicCost, err = operation.dynamicGas(in.evm, contract, locStack, mem, memorySize)
cost += dynamicCost // for tracing
if err != nil || !contract.UseGas(dynamicCost, tracing.GasChangeIgnored) {
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrOutOfGas, err)
}
if !contract.UseGas(dynamicCost, tracing.GasChangeIgnored) {
return nil, ErrOutOfGas
}
// Do tracing before memory expansion
Expand Down

0 comments on commit 68b0c3e

Please sign in to comment.