rpc/jsonrpc: return InvalidParams for malformed sendRawTransaction RLP - #21701
rpc/jsonrpc: return InvalidParams for malformed sendRawTransaction RLP#21701manusw7 wants to merge 9 commits into
Conversation
SendRawTransaction currently returns the bare DecodeWrappedTransaction error to the JSON-RPC layer. Because the underlying decode errors don't implement rpc.Error.ErrorCode(), the dispatcher falls back to errcodeDefault = -32000. Per JSON-RPC 2.0, malformed method parameters should use -32602 (InvalidParams), which is what Reth and Besu emit for the same input. Erigon already exports rpc.InvalidParamsError with ErrorCode() = -32602. Wire it into the decode path and add a parameterised test covering 5 distinct RLP-decode failure shapes. SendRawTransactionSync delegates to SendRawTransaction (rpc/jsonrpc/send_transaction.go:97) so the fix propagates transitively.
There was a problem hiding this comment.
Pull request overview
Aligns eth_sendRawTransaction JSON-RPC error codes with JSON-RPC 2.0 by returning -32602 (InvalidParams) when the submitted raw transaction cannot be RLP-decoded, instead of falling back to the default -32000.
Changes:
- Wrap
types.DecodeWrappedTransactiondecode failures inrpc.InvalidParamsErrorinSendRawTransaction. - Add a regression test covering multiple malformed-RLP inputs and asserting the returned RPC error code is
-32602.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| rpc/jsonrpc/send_transaction.go | Wraps raw-tx decode failures with rpc.InvalidParamsError so the dispatcher emits -32602. |
| rpc/jsonrpc/send_transaction_test.go | Adds a test suite validating malformed RLP inputs map to InvalidParams error code. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
yperbasis
left a comment
There was a problem hiding this comment.
The mainnet-rpc-integ-tests failure on this PR is structural, not flaky: the erigontech/rpc-tests fixtures integration/mainnet/eth_sendRawTransaction/test_01..03.json (and integration/arb-sepolia/eth_sendRawTransaction/test_01.json) hardcode "code": -32000 — test_02/test_03 use the same 0xd4 vector as the new unit test. Hence the 9 "diff mismatch" failures (3 fixtures × http/http_comp/websocket).
Required to land:
- A companion rpc-tests PR updating the expected codes to -32602 (messages unchanged), then a new rpc-tests tag and an
RPC_VERSIONbump in.github/workflows/scripts/rpc_version.env(currently v2.13.0) in this PR, so both land together. - A decision on the daily geth/nethermind comparison runs (
qa-rpc-integration-tests-clients.yml), which use the same fixtures: geth still returns -32000 on the wire (ethereum/go-ethereum#35129 is unmerged), so updating the shared fixtures turns those runs red until upstream catches up.
Nits:
send_transaction_test.go: thegithub.com/erigontech/erigon/rpcimport is inserted out of alphabetical order (betweenexecution/tests/blockgenandexecution/types).require := require.New(t)is bound to the parent test but used insidet.Runsubtests, so a failing assertion callsFailNowon the parent'stfrom the subtest goroutine. Bind assertions to the subtest'stinstead.
yperbasis
left a comment
There was a problem hiding this comment.
mainnet-rpc-integ-tests is red
Summary
SendRawTransactionreturns the bareDecodeWrappedTransactionerror (rpc/jsonrpc/send_transaction.go:25). Since decode errors don't implementErrorCode(), the dispatcher (forked from go-ethereum) falls back toerrcodeDefault = -32000. Per JSON-RPC 2.0, malformed params should be-32602.This wires the existing
rpc.InvalidParamsErrorwrapper into the decode path.SendRawTransactionSyncdelegates toSendRawTransaction(send_transaction.go:97), so the fix applies transitively.Changes
rpcis already imported; message passes through unchanged.Why -32602
The
-32000today is a fallback accident, not a deliberate choice. This matches where the spec is heading: execution-apis#817 (fjl: input-validation conditions on submit methods are just "invalid parameters") and #818 (drops the-32000 "Invalid input"group frometh_sendRawTransaction). Reth and Besu already return-32602for RLP-decode failures; Erigon and geth default to-32000.Test plan
Added
TestSendRawTransaction_InvalidParams_OnMalformedRLP(rpc/jsonrpc/send_transaction_test.go): 5 decode-failure shapes (0xc0,0xd4,0x09c0,0x03c0,0x04c0), assertingErrorCode() == -32602viaerrors.As.SendRawTransactionSynccovered transitively. All pass;make lintclean.Out of scope
checkTxFee,AllowUnprotectedTxs,chainConfig, txpoolAdd): not param validation —-32000stays.Related