Improve JSON-RPC error handling in Consensus/Execution communication#4629
Improve JSON-RPC error handling in Consensus/Execution communication#4629pmikolajczyk41 wants to merge 9 commits intomasterfrom
Conversation
…tation to the execution package
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #4629 +/- ##
==========================================
+ Coverage 33.90% 33.97% +0.07%
==========================================
Files 498 499 +1
Lines 59879 59870 -9
==========================================
+ Hits 20303 20342 +39
+ Misses 36022 35989 -33
+ Partials 3554 3539 -15 |
❌ 6 Tests Failed:
View the top 3 failed tests by shortest run time
📣 Thoughts on this report? Let Codecov know! | Powered by Codecov |
There was a problem hiding this comment.
Pull request overview
This PR hardens Consensus ↔ Execution JSON-RPC error handling by replacing fragile string-based sentinel detection with stable, code-based JSON-RPC errors that work both in-process and over the wire.
Changes:
- Introduce
execution.RPCErrorcarrying a JSON-RPC error code and define code-based sentinel errors (ErrRetrySequencer,ErrSequencerInsertLockTaken,ErrResultNotFound). - Remove
convertErrorstring-matching logic from both execution and consensus RPC clients; errors now propagate unchanged and are matched viaerrors.Is. - Move the “result not found” sentinel from
execution/gethexecintoexecutionand update call sites/tests accordingly.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| execution_consensus/init.go | Minor formatting tweak (blank line after header). |
| execution/rpcerror.go | Adds RPCError, custom JSON-RPC codes, and exported sentinel errors for cross-boundary matching. |
| execution/rpcclient/client.go | Removes string-based convertError; returns raw RPC errors to enable code-based errors.Is. |
| execution/rpcclient/client_test.go | Updates/extends tests to validate sentinel matching (including wrapped errors) and prevent false positives. |
| execution/interface.go | Removes old errors.New(...) sentinel declarations now replaced by RPCError sentinels. |
| execution/gethexec/executionengine.go | Switches to execution.ErrResultNotFound and removes the old gethexec.ResultNotFound. |
| consensus/consensusrpcclient/client.go | Removes string-based convertError; returns raw RPC errors. |
| consensus/consensusrpcclient/client_test.go | Adds wire-path tests ensuring code-based sentinel matching and no false positives. |
| arbnode/consensus_execution_syncer.go | Updates ResultNotFound handling to use execution.ErrResultNotFound. |
| changelog/pmikolajczyk-nit-4738.md | Adds an internal changelog entry for the RPC error handling change. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
We should test this with execution and consensus communicating over rpc too.
If I remember correctly, CI tests regarding execution and consensus communicating over rpc can be reintroduced after #4661 is merged.
I am OK on waiting for this other PR to be merged before testing this one through the CI, or just relying on local testing with them communicating over rpc.
| // | ||
| // On the client side the Is method enables code-based comparison via | ||
| // errors.Is, so callers do not need to inspect error message strings. | ||
| type RPCError struct { |
There was a problem hiding this comment.
This is not specific for execution, so we can move to /util
The consensus <-> execution RPC boundary previously relied on
convertErrorfunctions that matched sentinel errors by scanning error message strings withstrings.Contains. This approach was fragile (breaks on message rewording or multi-layer wrapping), incomplete (ErrSequencerInsertLockTakenwas missing from the execution client;ErrRetrySequencerwas missing from the consensus client), and required duplicated conversion logic in two separate clients.What changed:
execution.RPCError— a struct that carries a JSON-RPC error code and implements bothrpc.Error(server side, so go-ethereum embeds the code in the wire response) and a code-based Is method (in-process path). CorrespondingjsonError.Isin the go-ethereum fork handles the wire path by comparingErrorCode()values.ErrRetrySequencer,ErrSequencerInsertLockTaken,ErrResultNotFound) and numeric constants for their codes, chosen below -32768 to avoid collision with the JSON-RPC 2.0 reserved range.convertErrorfrom bothexecution/rpcclientandconsensus/consensusrpcclient; errors now propagate as-is anderrors.Ismatches by code.ResultNotFoundfromexecution/gethexecto the execution package (renamedErrResultNotFound), removing an unnecessary import of gethexec from arbnode.closes NIT-4738
pulls in OffchainLabs/go-ethereum#649