forked from cerc-io/laconicd-deprecated
evm: update error format (#350)
* return geth error format * fix format in gasestimate * deal with other evm errors * fix import * fix lint * add test Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
co-authored by
Federico Kunze Küllmer
parent
695027cb2a
commit
63aa0de1e8
+30
-5
@@ -1,7 +1,11 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
@@ -75,12 +79,33 @@ var (
|
||||
|
||||
// NewExecErrorWithReason unpacks the revert return bytes and returns a wrapped error
|
||||
// with the return reason.
|
||||
func NewExecErrorWithReason(revertReason []byte) error {
|
||||
hexValue := hexutil.Encode(revertReason)
|
||||
reason, errUnpack := abi.UnpackRevert(revertReason)
|
||||
func NewExecErrorWithReason(revertReason []byte) *RevertError {
|
||||
var result = common.CopyBytes(revertReason)
|
||||
reason, errUnpack := abi.UnpackRevert(result)
|
||||
err := errors.New("execution reverted")
|
||||
if errUnpack == nil {
|
||||
return sdkerrors.Wrapf(ErrExecutionReverted, "%s: %s", reason, hexValue)
|
||||
err = fmt.Errorf("execution reverted: %v", reason)
|
||||
}
|
||||
return &RevertError{
|
||||
error: err,
|
||||
reason: hexutil.Encode(result),
|
||||
}
|
||||
}
|
||||
|
||||
return sdkerrors.Wrapf(ErrExecutionReverted, "%s", hexValue)
|
||||
// RevertError is an API error that encompass an EVM revert with JSON error
|
||||
// code and a binary data blob.
|
||||
type RevertError struct {
|
||||
error
|
||||
reason string // revert reason hex encoded
|
||||
}
|
||||
|
||||
// ErrorCode returns the JSON error code for a revert.
|
||||
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
|
||||
func (e *RevertError) ErrorCode() int {
|
||||
return 3
|
||||
}
|
||||
|
||||
// ErrorData returns the hex encoded revert reason.
|
||||
func (e *RevertError) ErrorData() interface{} {
|
||||
return e.reason
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/status-im/keycard-go/hexutils"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4]
|
||||
|
||||
func TestNewExecErrorWithReason(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
errorMessage string
|
||||
revertReason []byte
|
||||
data string
|
||||
}{
|
||||
{
|
||||
"Empty reason",
|
||||
"execution reverted",
|
||||
nil,
|
||||
"0x",
|
||||
},
|
||||
{
|
||||
"With unpackable reason",
|
||||
"execution reverted",
|
||||
[]byte("a"),
|
||||
"0x61",
|
||||
},
|
||||
{
|
||||
"With packable reason but empty reason",
|
||||
"execution reverted",
|
||||
revertSelector,
|
||||
"0x08c379a0",
|
||||
},
|
||||
{
|
||||
"With packable reason with reason",
|
||||
"execution reverted: COUNTER_TOO_LOW",
|
||||
hexutils.HexToBytes("08C379A00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000F434F554E5445525F544F4F5F4C4F570000000000000000000000000000000000"),
|
||||
"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000f434f554e5445525f544f4f5f4c4f570000000000000000000000000000000000",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
errWithReason := NewExecErrorWithReason(tc.revertReason)
|
||||
require.Equal(t, tc.errorMessage, errWithReason.Error())
|
||||
require.Equal(t, tc.data, errWithReason.ErrorData())
|
||||
require.Equal(t, 3, errWithReason.ErrorCode())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user