Skip to content

[Feature]Standardize JSON-RPC error handling(revert codes, LiteNode pruned-history responses, request fields validation) #6676

@0xbigapple

Description

@0xbigapple

Summary

Align java-tron's JSON-RPC behavior with the Ethereum Execution API standard in three areas: contract revert error codes, LiteNode pruned-history responses, and JSON-RPC 2.0 request validation. This improves compatibility with Ethereum tooling, makes LiteNode failure modes explicit, and adds an opt-in strict protocol validation mode.

Problem

Motivation

java-tron's JSON-RPC behavior currently diverges from the Ethereum Execution API standard in ways that can break compatibility with wallets, DApps, SDKs, and debugging tools that assume Ethereum-compatible semantics.

Current State

  1. eth_call and eth_estimateGas currently return -32000 for all execution failures, without distinguishing TVM revert from other failures such as OUT_OF_ENERGY.
  2. On LiteNode which historical blocks have been pruned, clients cannot distinguish between "data was pruned" and "data does not exist". The earliest tag is also treated as the genesis block rather than the lowest available block on the node.
  3. java-tron relies on jsonrpc4j's default behavior, which does not strictly validate the jsonrpc: "2.0" field. In addition, certain id values are handled in a way that is not suitable for blockchain node scenarios, for example treating "id": null as a notification and returning no response.

Limitations or Risks

  • DApps and tooling cannot reliably distinguish contract revert from internal execution failures, which affects error handling and UX.
  • LiteNode clients cannot make informed fallback decisions, such as retrying against an archive node, because pruned-history cases are not explicitly signaled.
  • Protocol-level request handling is less consistent with mainstream Ethereum clients such as geth, which increases cross-client compatibility risk.

Proposed Solution

Proposed Design

Introduce the following behavior changes:

  1. eth_call and eth_estimateGas return error code 3 for contract revert, and include the revert payload in the data field as hex. Non-revert execution failures continue to return -32000.
  2. On LiteNode, return error code 4444 with message Pruned history unavailable when the requested block range is deterministically below the node's lowest available block. This applies to:
    • eth_getBlockByNumber
    • eth_getBlockTransactionCountByNumber
    • eth_getTransactionByBlockNumberAndIndex
    • eth_getBlockReceipts when block number/tag is used
    • eth_getLogs
    • eth_newFilter
  3. Resolve earliest to the node's lowest available block number instead of always mapping it to the genesis block. For single-block queries, explicit 0x0 keeps its genesis-block meaning.
  4. Add a new config item node.jsonrpc.strictComplianceMode, disabled by default. When enabled:
    • requests missing jsonrpc: "2.0" or carrying an invalid version return -32600 Invalid Request
    • invalid id types return responses with id: null
  5. Limit pruned-history handling to selectors that can be deterministically evaluated by block number or tag. Hash-only methods such as eth_getBlockByHash and eth_getTransactionByHash remain out of scope.

Key Changes

  • Modules
    • JSON-RPC execution error mapping
    • LiteNode block selector / history availability handling
    • JSON-RPC Servlet request validation
  • Configuration
    • add node.jsonrpc.strictComplianceMode = false
  • API / Behavior Surface
    • eth_call
    • eth_estimateGas
    • eth_getBlockByNumber
    • eth_getBlockTransactionCountByNumber
    • eth_getTransactionByBlockNumberAndIndex
    • eth_getBlockReceipts
    • eth_getLogs
    • eth_newFilter
  • Testing
    • add regression coverage for error mapping, pruned-history handling, earliest resolution, and strict mode validation

Impact

This change primarily affects API compatibility and developer experience, with positive impact on interoperability with Ethereum tooling. Performance impact should be negligible: protocol validation is an O(1) field check, and pruned-history validation happens before deeper business logic, which can reduce unnecessary I/O on LiteNode.

Compatibility

  • Breaking Change: Yes
  • Default Behavior Change: Partial. eth_call / eth_estimateGas revert responses and LiteNode pruned-history responses change behavior immediately; strictComplianceMode is added but remains disabled by default.
  • Migration Required: Possibly. Clients that currently rely on -32000 for all execution failures or expect null for pruned LiteNode data may need to adjust. Clients that omit the jsonrpc field are unaffected unless strictComplianceMode is explicitly enabled.

References

Additional Notes

  • Do you have ideas regarding implementation? Yes
  • Are you willing to implement this feature? Yes

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions