Skip to content

fix(jsonrpc): make the JSON-RPC output more compliant with specification#6763

Open
317787106 wants to merge 1 commit into
tronprotocol:release_v4.8.2from
317787106:hotfix/unify-jsonrpc_contenttype
Open

fix(jsonrpc): make the JSON-RPC output more compliant with specification#6763
317787106 wants to merge 1 commit into
tronprotocol:release_v4.8.2from
317787106:hotfix/unify-jsonrpc_contenttype

Conversation

@317787106
Copy link
Copy Markdown
Collaborator

@317787106 317787106 commented May 14, 2026

What does this PR do?

Fixes three JSON-RPC spec-compliance issues and one parser-hardening gap in JsonRpcServlet:

1. Content-Type response header — remove spurious ; charset=utf-8

The JSON-RPC 1.0/2.0 spec and Ethereum JSON-RPC both use application/json or application/json-rpc without a charset suffix. The extra ; charset=utf-8 suffix was non-standard and has been removed.

2. Non-object/non-array root node → Invalid Request

Sending a JSON primitive as the request body (e.g. null, true, 123) was silently forwarded to jsonrpc4j, which produced a malformed response with "id":"null" (string) instead of "id":null (JSON null). Now these cases are caught before dispatch and return a proper -32600 Invalid Request response with "id":null.

Before:

POST /jsonrpc  body: null
→ {"jsonrpc":"2.0","id":"null","error":{"code":-32600,"message":"invalid request"}}

After:

POST /jsonrpc  body: null
→ {"jsonrpc":"2.0",,"id":null,"error":{"code":-32600,"message":"Invalid Request"}}

3. Non-object element inside a batch → Invalid Request

A batch containing a non-object element (e.g. [[]]) was forwarded per-element to jsonrpc4j, which echoed the inner array back unchanged, producing [[]] instead of an error. Non-object sub-requests are now rejected with -32600 Invalid Request before dispatch.

Before:

POST /jsonrpc  body: [[]]
→ [[]]

After (Ethereum-compatible):

POST /jsonrpc  body: [[]]
→ [{"jsonrpc":"2.0","error":{"code":-32600,"message":"Invalid Request"},"id":null}]

4. Apply StreamReadConstraints to the JSON-RPC parser

JsonRpcServlet used a bare new ObjectMapper(), so the node.http.maxNestingDepth and node.http.maxTokenCount settings introduced in #6701 had no effect on JSON-RPC requests. The mapper is now built with a JsonFactory that reads those two limits from CommonParameter, consistent with how JSON.java constructs its mapper.

Without this fix, a ~4 MB request body such as [0,0,...,0] (~2 M tokens) could bypass the configured maxTokenCount (default 100,000) and force Jackson to allocate ~2 M JsonNode objects, causing GC pressure (Eden/Survivor saturation → premature promotion → Full GC). With the fix, the parser throws after the configured token limit is reached, well before the 4 MB body-size cap.

Why are these changes required?

  • Issues 1–3: bring responses in line with the JSON-RPC 2.0 specification and Ethereum JSON-RPC behaviour.
  • Issue 4: make the node.http.maxNestingDepth / node.http.maxTokenCount config knobs actually effective for the JSON-RPC endpoint, closing a token-density amplification vector.

This PR has been tested by

  • Unit Tests
  • Manual Testing

Extra details

Issue 4 shares the same root cause identified in the review comment on this PR: the MAPPER in JsonRpcServlet was not wired to the StreamReadConstraints configured via node.http.*.

@github-actions github-actions Bot requested review from 0xbigapple and bladehan1 May 14, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant