diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b8dc72eb2c..f00527e9dad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ - docs: fix dead link in documentation ([#13437](https://github.com/filecoin-project/lotus/pull/13437)) - feat(cli): implement FRC-0102 signing envelope for wallet sign/verify ([filecoin-project/lotus#13471](https://github.com/filecoin-project/lotus/pull/13471)) - feat(cli): add --order-by-nonce flag to list messages sequentially when filtering by sender ([filecoin-project/lotus#13394](https://github.com/filecoin-project/lotus/pull/13394)) +- fix(eth): use error code 3 for EExecutionReverted for Ethereum RPC tooling compatibility ([filecoin-project/lotus#13467](https://github.com/filecoin-project/lotus/pull/13467)) + - BREAKING: RPC error codes changed - EActorNotFound (3→11), EExecutionReverted (11→3). Mismatched client/server versions will deserialize these errors as the wrong Go type, breaking errors.Is/As checks. # Node v1.34.3 / 2025-12-03 diff --git a/api/api_errors.go b/api/api_errors.go index 3d4854261fd..480518ff099 100644 --- a/api/api_errors.go +++ b/api/api_errors.go @@ -19,7 +19,7 @@ var invalidExecutionRevertedMsg = xerrors.New("invalid execution reverted error" const ( EOutOfGas = iota + jsonrpc.FirstUserCode - EActorNotFound + EExecutionReverted EF3Disabled EF3ParticipationTicketInvalid EF3ParticipationTicketExpired @@ -27,7 +27,7 @@ const ( EF3ParticipationTooManyInstances EF3ParticipationTicketStartBeforeExisting EF3NotReady - EExecutionReverted + EActorNotFound ENullRound EPaymentChannelDisabled ) diff --git a/itests/fevm_test.go b/itests/fevm_test.go index 53daa49c815..8611f245b10 100644 --- a/itests/fevm_test.go +++ b/itests/fevm_test.go @@ -1066,6 +1066,34 @@ func TestFEVMErrorParsing(t *testing.T) { }) }) } + + // Verify that the raw JSON-RPC error code is 3, per Ethereum standard for execution reverted. + // See: https://github.com/ethereum/go-ethereum/pull/21083 (geth v1.9.15) + t.Run("RawErrorCode3", func(t *testing.T) { + entryPoint := kit.CalcFuncSignature("failRevertReason()") + + request := fmt.Sprintf(`{ + "jsonrpc": "2.0", + "id": 1, + "method": "eth_call", + "params": [{"to": "%s", "data": "0x%x"}, "latest"] + }`, contractAddrEth.String(), entryPoint) + + statusCode, responseBody := client.DoRawRPCRequest(t, 1, request) + require.Equal(t, 200, statusCode) + + var rpcResponse struct { + Error struct { + Code int `json:"code"` + Message string `json:"message"` + Data string `json:"data"` + } `json:"error"` + } + require.NoError(t, json.Unmarshal(responseBody, &rpcResponse)) + require.Equal(t, 3, rpcResponse.Error.Code, + "execution reverted error code must be 3 for Ethereum RPC compatibility (EIP-1474 de facto standard)") + require.NotEmpty(t, rpcResponse.Error.Data, "error response should include revert data") + }) } // TestEthGetBlockReceipts tests retrieving block receipts after invoking a contract