fix(jsonrpc): handle null parameters consistently - #5
Open
waynercheung wants to merge 1 commit into
Open
Conversation
Validate nullable JSON-RPC arguments before they are dereferenced. Return stable protocol errors instead of jsonrpc4j's unhandled -32001 fallback, which exposes Java exception types. Validate eth_call's required transaction argument before its block selector. The double-null case now returns -32602 instead of -32600. Give null filter IDs a geth-compatible lookup-miss result: eth_uninstallFilter returns false, while eth_getFilterChanges and eth_getFilterLogs report "filter not found". Requests to eth_uninstallFilter with unknown non-null IDs keep the existing -32000 path, locked by service- and wire-level tests. Treat null block-detail flags as false and retain DTO defaults for explicitly null optional fields. Preserve filter wildcard semantics and request-source precedence. Add binding, service, wire, and VM execution regression tests for error codes, messages, DTO defaults, and unaffected behavior.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Handles 10 identified top-level parameter positions that can trigger unchecked dereferences, and normalizes seven optional DTO fields whose explicit JSON
nullcurrently behaves differently from omission. The per-parameter decision basis is recorded in #PHASE1.disableInPBFT/ FullNode-only) stays first. Object and filter-ID arguments are validated before business processing, whilefullTransactionObjectsis normalized at its existing use site after the block lookup, preserving the non-existent-block behavior:eth_getLogs/eth_newFilterwith a null filter object ->-32602 "invalid filter request"eth_call/eth_estimateGas/buildTransactionwith a null argument object ->-32602 "invalid params"eth_uninstallFilter(null)->false;eth_getFilterChanges(null)/eth_getFilterLogs(null)->-32000 "filter not found"(go-ethereum's results for a null filter ID)eth_getBlockByHash/eth_getBlockByNumberwith a nullfullTransactionObjects-> treated asfalse(Boolean.TRUE.equals(...)instead of auto-unboxing)eth_callvalidates its required transaction argument before the block selector, so[null, null]returns-32602instead of-32600.@JsonSetter(nulls = Nulls.SKIP)on the six optionalBuildArgumentsfields (tokenId,tokenValue,consumeUserResourcePercent,originEnergyLimit,permissionId,extraData) and onCallArguments.from, so an explicit JSONnullkeeps the field default exactly as omitting the field does.LogFilter(FilterRequest)constructor, plus a sharedINVALID_FILTER_REQUESTmessage constant.All error responses keep the existing
@JsonRpcErrorsmapping:datastays"{}"and the requestidis echoed.Why are these changes required?
Before this PR the ten positions dereferenced the argument without a null check. The resulting
NullPointerExceptionis not covered by@JsonRpcErrors, so jsonrpc4j's fallback returned:{"jsonrpc":"2.0","id":1,"error":{"code":-32001,"message":null,"data":"java.lang.NullPointerException"}}message: nullviolates JSON-RPC 2.0 (on Java 17 it becomes a helpful-NPE string that echoes internal class and method names),dataexposes the Java exception type, and a required-parameter error such as this example is reported under the code java-tron documents for internal errors. The seven DTO fields were inconsistent among themselves: an explicitnullfailed with-32001or-32000depending on the path, whileCallArguments.fromreturned-32602where omitting the field continues with the zero address.The per-parameter decisions follow the basis recorded in #PHASE1: the Execution API
required/ schema first, then whether a zero value can be inferred fromnull, then go-ethereum / Besu behavior as a reference. Details and reproduction steps are in #PHASE1.This PR has been tested by:
Unit Tests
Manual Testing
JsonRpcArgumentNullBindingTest- Jackson binding throughObjectMapper: an explicitnulland an omitted field produce the sameBuildArguments/CallArguments.JsonRpcCallAndEstimateGasTest/JsonRpcTest- service-level results for null argument objects and null filter requests, and theeth_callargument-before-block ordering.JsonrpcServiceTest- wire-level contract through a realJsonRpcServer:code/message/datafor every case above, filter-object null wildcard semantics unchanged (address: null,topics: null, positional[A, null]), optional DTO null fields, and an assertion that no response containsjava.or an exception class name. Includes wire regressions for the four hash-parameter methods fixed by fix(jsonrpc): harden RPC/HTTP parameter validation tronprotocol/java-tron#6828.WalletCursorTest- the null checks keep request-source precedence: SolidityNode and PBFT behavior is unchanged../gradlew :framework:checkstyleMain :framework:checkstyleTest :framework:test --tests 'org.tron.core.jsonrpc.*' --tests 'org.tron.core.services.jsonrpc.*'passes on JDK 17 (arm64).Compatibility
Not a breaking change: no request that succeeds today starts failing. Default behavior changes only for the null inputs above:
-32001fallback to-32602, while the two get-filter methods change from-32001to-32000;eth_uninstallFilter(null)andeth_getBlockBy*(..., null)go from an error to a normal response;eth_call([null, null])goes from-32600to-32602;eth_call([null, "earliest"])and similar shapes where parameter 0 and the block selector are both invalid keep-32602, but the message changes from the block error to"invalid params"because the required argument is now validated first.Clients matching on the old codes or messages for these paths need to adjust.
Unchanged: results of valid non-null requests, HTTP status, request-source precedence,
dataon mapped errors,result: nullfor a non-existent block, filter-object null wildcards,eth_uninstallFilterwith an unknown non-null ID (still-32000; aligning it tofalseis follow-up work), gRPC and non-JSON-RPC HTTP APIs.Follow up
eth_uninstallFilterwith an unknown non-null ID ->false,web3_sha3(null), unconditional transaction index validation.paramsmissing /null/[]are rejected by jsonrpc4j's arity check before the method body and are not touched here. Request-envelope validation is tracked by [Feature]Standardize JSON-RPC error handling(revert codes, LiteNode pruned-history responses, request fields validation) tronprotocol/java-tron#6676, which overlaps this PR inJsonRpcApiUtilandTronJsonRpcImpl; there is no dependency between them (see Extra details).Extra details
This PR overlaps the request-envelope validation planned in tronprotocol#6676 in
JsonRpcApiUtilandTronJsonRpcImpl, and sharesTronJsonRpcImplwith the error-mapping PR (no conflicting hunks, verified withgit merge-tree). There is no dependency on either: this PR can land in any order, and whichever change lands second rebases.Pre-submit checklist:
@JsonSetterprotects Jackson input only, and positional vs. OR-list null topics inLogFilterRefs tronprotocol#6676