Skip to content

Commit 5b604da

Browse files
committed
fix(eth): present revert "data" as plain bytes
decode the cbor return value for reverts and present that, as is expected by Ethereum tooling
1 parent 3a34832 commit 5b604da

File tree

3 files changed

+29
-31
lines changed

3 files changed

+29
-31
lines changed

api/api_errors.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/filecoin-project/go-jsonrpc"
1111
"github.com/filecoin-project/go-state-types/abi"
12+
"github.com/filecoin-project/go-state-types/exitcode"
1213
)
1314

1415
var invalidExecutionRevertedMsg = xerrors.New("invalid execution reverted error")
@@ -160,10 +161,10 @@ func (e *ErrExecutionReverted) ToJSONRPCError() (jsonrpc.JSONRPCError, error) {
160161
}
161162

162163
// NewErrExecutionReverted creates a new ErrExecutionReverted with the given reason.
163-
func NewErrExecutionReverted(reason string) *ErrExecutionReverted {
164+
func NewErrExecutionReverted(exitCode exitcode.ExitCode, error, reason string, data []byte) *ErrExecutionReverted {
164165
return &ErrExecutionReverted{
165-
Message: "execution reverted",
166-
Data: reason,
166+
Message: fmt.Sprintf("message execution failed (exit=[%s], revert reason=[%s], vm error=[%s])", exitCode, reason, error),
167+
Data: fmt.Sprintf("0x%x", data),
167168
}
168169
}
169170

node/impl/full/eth.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,9 +1496,16 @@ func (a *EthModule) applyMessage(ctx context.Context, msg *types.Message, tsk ty
14961496
}
14971497

14981498
if res.MsgRct.ExitCode.IsError() {
1499-
return nil, api.NewErrExecutionReverted(
1500-
parseEthRevert(res.MsgRct.Return),
1501-
)
1499+
reason := "none"
1500+
var cbytes abi.CborBytes
1501+
if err := cbytes.UnmarshalCBOR(bytes.NewReader(res.MsgRct.Return)); err != nil {
1502+
log.Warnw("failed to unmarshal cbor bytes from message receipt return", "error", err)
1503+
reason = "ERROR: revert reason is not cbor encoded bytes"
1504+
} // else leave as empty bytes
1505+
if len(cbytes) > 0 {
1506+
reason = parseEthRevert(cbytes)
1507+
}
1508+
return nil, api.NewErrExecutionReverted(res.MsgRct.ExitCode, reason, res.Error, cbytes)
15021509
}
15031510

15041511
return res, nil

node/impl/full/eth_utils.go

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -331,62 +331,52 @@ var panicErrorCodes = map[uint64]string{
331331
//
332332
// See https://docs.soliditylang.org/en/latest/control-structures.html#panic-via-assert-and-error-via-require
333333
func parseEthRevert(ret []byte) string {
334-
if len(ret) == 0 {
335-
return "none"
336-
}
337-
var cbytes abi.CborBytes
338-
if err := cbytes.UnmarshalCBOR(bytes.NewReader(ret)); err != nil {
339-
return "ERROR: revert reason is not cbor encoded bytes"
340-
}
341-
if len(cbytes) == 0 {
342-
return "none"
343-
}
344334
// If it's not long enough to contain an ABI encoded response, return immediately.
345-
if len(cbytes) < 4+32 {
346-
return ethtypes.EthBytes(cbytes).String()
335+
if len(ret) < 4+32 {
336+
return ethtypes.EthBytes(ret).String()
347337
}
348-
switch string(cbytes[:4]) {
338+
switch string(ret[:4]) {
349339
case panicFunctionSelector:
350-
cbytes := cbytes[4 : 4+32]
340+
ret := ret[4 : 4+32]
351341
// Read the and check the code.
352-
code, err := ethtypes.EthUint64FromBytes(cbytes)
342+
code, err := ethtypes.EthUint64FromBytes(ret)
353343
if err != nil {
354344
// If it's too big, just return the raw value.
355-
codeInt := big.PositiveFromUnsignedBytes(cbytes)
345+
codeInt := big.PositiveFromUnsignedBytes(ret)
356346
return fmt.Sprintf("Panic(%s)", ethtypes.EthBigInt(codeInt).String())
357347
}
358348
if s, ok := panicErrorCodes[uint64(code)]; ok {
359349
return s
360350
}
361351
return fmt.Sprintf("Panic(0x%x)", code)
362352
case errorFunctionSelector:
363-
cbytes := cbytes[4:]
364-
cbytesLen := ethtypes.EthUint64(len(cbytes))
353+
ret := ret[4:]
354+
retLen := ethtypes.EthUint64(len(ret))
365355
// Read the and check the offset.
366-
offset, err := ethtypes.EthUint64FromBytes(cbytes[:32])
356+
offset, err := ethtypes.EthUint64FromBytes(ret[:32])
367357
if err != nil {
368358
break
369359
}
370-
if cbytesLen < offset {
360+
if retLen < offset {
371361
break
372362
}
373363

374364
// Read and check the length.
375-
if cbytesLen-offset < 32 {
365+
if retLen-offset < 32 {
376366
break
377367
}
378368
start := offset + 32
379-
length, err := ethtypes.EthUint64FromBytes(cbytes[offset : offset+32])
369+
length, err := ethtypes.EthUint64FromBytes(ret[offset : offset+32])
380370
if err != nil {
381371
break
382372
}
383-
if cbytesLen-start < length {
373+
if retLen-start < length {
384374
break
385375
}
386376
// Slice the error message.
387-
return fmt.Sprintf("Error(%s)", cbytes[start:start+length])
377+
return fmt.Sprintf("Error(%s)", ret[start:start+length])
388378
}
389-
return ethtypes.EthBytes(cbytes).String()
379+
return ethtypes.EthBytes(ret).String()
390380
}
391381

392382
// lookupEthAddress makes its best effort at finding the Ethereum address for a

0 commit comments

Comments
 (0)