Skip to content

Commit

Permalink
feat: match runtime errors with geth
Browse files Browse the repository at this point in the history
  • Loading branch information
lolchocotaco committed Jun 13, 2023
1 parent cbbcc10 commit 407e4b4
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 17 deletions.
4 changes: 2 additions & 2 deletions state/runtime/evm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func TestRun(t *testing.T) {
ReturnValue: nil,
GasLeft: 0,
GasUsed: 5000,
Err: errStackUnderflow,
Err: &runtime.ErrStackUnderflow{StackLen: 0, Required: 2},
},
},
{
Expand Down Expand Up @@ -339,7 +339,7 @@ func TestRunWithTracer(t *testing.T) {
"cost": uint64(2),
"lastReturnData": []byte{},
"depth": 1,
"err": errStackUnderflow,
"err": &runtime.ErrStackUnderflow{StackLen: 0, Required: 1},
},
},
},
Expand Down
7 changes: 3 additions & 4 deletions state/runtime/evm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ func opPush(n int) instruction {
func opDup(n int) instruction {
return func(c *state) {
if !c.stackAtLeast(n) {
c.exit(errStackUnderflow)
c.exit(&runtime.ErrStackUnderflow{StackLen: c.sp, Required: n})
} else {
val := c.peekAt(n)
c.push1().Set(val)
Expand All @@ -1005,7 +1005,7 @@ func opDup(n int) instruction {
func opSwap(n int) instruction {
return func(c *state) {
if !c.stackAtLeast(n + 1) {
c.exit(errStackUnderflow)
c.exit(&runtime.ErrStackUnderflow{StackLen: c.sp, Required: n + 1})
} else {
c.swap(n)
}
Expand All @@ -1023,8 +1023,7 @@ func opLog(size int) instruction {
}

if !c.stackAtLeast(2 + size) {
c.exit(errStackUnderflow)

c.exit(&runtime.ErrStackUnderflow{StackLen: c.sp, Required: 2 + size})
return
}

Expand Down
7 changes: 2 additions & 5 deletions state/runtime/evm/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ const stackSize = 1024

var (
errOutOfGas = runtime.ErrOutOfGas
errStackUnderflow = runtime.ErrStackUnderflow
errStackOverflow = runtime.ErrStackOverflow
errRevert = runtime.ErrExecutionReverted
errGasUintOverflow = errors.New("gas uint64 overflow")
errWriteProtection = errors.New("write protection")
Expand Down Expand Up @@ -245,7 +243,7 @@ func (c *state) Run() ([]byte, error) {

// check if the depth of the stack is enough for the instruction
if c.sp < inst.stack {
c.exit(errStackUnderflow)
c.exit(&runtime.ErrStackUnderflow{StackLen: c.sp, Required: inst.stack})
c.captureExecutionError(op.String(), c.ip, gasCopy, inst.gas)

break
Expand All @@ -266,8 +264,7 @@ func (c *state) Run() ([]byte, error) {

// check if stack size exceeds the max size
if c.sp > stackSize {
c.exit(errStackOverflow)

c.exit(&runtime.ErrStackOverflow{StackLen: c.sp, Limit: stackSize})
break
}

Expand Down
7 changes: 5 additions & 2 deletions state/runtime/evm/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package evm
import (
"testing"

"github.com/0xPolygon/polygon-edge/state/runtime"

"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -68,7 +70,7 @@ func TestStackOverflow(t *testing.T) {
s.host = &mockHost{}

_, err = s.Run()
assert.Equal(t, errStackOverflow, err)
assert.Equal(t, &runtime.ErrStackOverflow{StackLen: stackSize + 1, Limit: stackSize}, err)
}

func TestStackUnderflow(t *testing.T) {
Expand Down Expand Up @@ -99,7 +101,8 @@ func TestStackUnderflow(t *testing.T) {
s.host = &mockHost{}

_, err = s.Run()
assert.Equal(t, errStackUnderflow, err)
// need at least one operation on the stack
assert.Equal(t, &runtime.ErrStackUnderflow{StackLen: 0, Required: 1}, err)
}

func TestOpcodeNotFound(t *testing.T) {
Expand Down
29 changes: 25 additions & 4 deletions state/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package runtime

import (
"errors"
"fmt"
"math/big"

"github.com/0xPolygon/polygon-edge/chain"
Expand Down Expand Up @@ -130,20 +131,40 @@ func (r *ExecutionResult) UpdateGasUsed(gasLimit uint64, refund uint64) {

var (
ErrOutOfGas = errors.New("out of gas")
ErrStackOverflow = errors.New("stack overflow")
ErrStackUnderflow = errors.New("stack underflow")
ErrNotEnoughFunds = errors.New("not enough funds")
ErrInsufficientBalance = errors.New("insufficient balance for transfer")
ErrMaxCodeSizeExceeded = errors.New("evm: max code size exceeded")
ErrMaxCodeSizeExceeded = errors.New("max code size exceeded")
ErrContractAddressCollision = errors.New("contract address collision")
ErrDepth = errors.New("max call depth exceeded")
ErrExecutionReverted = errors.New("execution was reverted")
ErrExecutionReverted = errors.New("execution reverted")
ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas")
ErrUnauthorizedCaller = errors.New("unauthorized caller")
ErrInvalidInputData = errors.New("invalid input data")
ErrNotAuth = errors.New("not in allow list")
)

// ErrStackUnderflow wraps an evm error when the items on the stack less
// than the minimal requirement.
type ErrStackUnderflow struct {
StackLen int
Required int
}

func (e *ErrStackUnderflow) Error() string {
return fmt.Sprintf("stack underflow (%d <=> %d)", e.StackLen, e.Required)
}

// ErrStackOverflow wraps an evm error when the items on the stack exceeds
// the maximum allowance.
type ErrStackOverflow struct {
StackLen int
Limit int
}

func (e *ErrStackOverflow) Error() string {
return fmt.Sprintf("stack limit reached %d (%d)", e.StackLen, e.Limit)
}

type CallType int

const (
Expand Down

0 comments on commit 407e4b4

Please sign in to comment.