Skip to content

fix(jsonrpc): correct TransactionResult.nonce per JSON-RPC spec#6709

Open
waynercheung wants to merge 1 commit intotronprotocol:developfrom
waynercheung:fix/jsonrpc-tx-info-quantity-format-6547
Open

fix(jsonrpc): correct TransactionResult.nonce per JSON-RPC spec#6709
waynercheung wants to merge 1 commit intotronprotocol:developfrom
waynercheung:fix/jsonrpc-tx-info-quantity-format-6547

Conversation

@waynercheung
Copy link
Copy Markdown
Collaborator

@waynercheung waynercheung commented Apr 27, 2026

What this PR does

Corrects the nonce field in TransactionResult, the response body shared by eth_getTransactionByHash, eth_getTransactionByBlockHashAndIndex, eth_getTransactionByBlockNumberAndIndex, and the full-tx mode of eth_getBlockByHash / eth_getBlockByNumber.

Closes #6547.

Why

Per ethereum/execution-apis:

  • TransactionInfo.nonce is uint (QUANTITY), pattern ^0x(0|[1-9a-f][0-9a-f]*)$ - no leading zeros; zero is 0x0.

java-tron's TransactionResult previously emitted ByteArray.toJsonHex(new byte[8]) -> "0x0000000000000000" (16 hex chars), which violates the pattern.

What changes

Field Path Before After
nonce both TransactionResult constructors 0x0000000000000000 0x0

Why Block.nonce is intentionally NOT changed

Block.nonce is bytes8 per the spec (pattern ^0x[0-9a-f]{16}$), so the existing 0x0000000000000000 is already compliant. Shortening it to 0x0 would break conformance with the bytes8 length requirement.

BlockResult.nonce is therefore left untouched and existing JsonrpcServiceTest assertions on it ("0x0000000000000000") remain valid.

Compatibility

This PR makes a minimal, surgical change: only the nonce literal value is modified. All other fields in TransactionResult retain their existing serialization, preserving byte-for-byte compatibility with current production responses.

The numeric semantics of nonce are unchanged (Long.parseLong of either value yields 0); only the string representation tightens to the spec-compliant form.

Tests

TransactionResultTest is updated to:

  • Assert nonce == "0x0" in both test methods (covering both TransactionResult constructors).
  • Validate nonce against the schema regex ^0x(0|[1-9a-f][0-9a-f]*)$ via a small assertQuantity helper, so any future regression that re-introduces a leading-zero form will fail the test.

Pre-submit checklist

  • Single module (jsonrpc), single issue (The nonce returned by eth_getTransactionByHash is non-compliant #6547), 2 files changed
  • Code style follows Google Java Style
  • No debug code / temporary comments / stray TODOs
  • No unsafe numeric ops introduced
  • No log-level changes
  • No DB schema / consensus / config changes
  • No dependency upgrades
  • Comments explain WHY (the spec rationale), not WHAT

@waynercheung waynercheung changed the title fix(jsonrpc): correct zero-value QUANTITY/null format violations in TransactionResult fix(jsonrpc): correct QUANTITY/null format in TransactionResult Apr 27, 2026
@halibobo1205 halibobo1205 added topic:api rpc/http related issue topic:json-rpc labels Apr 28, 2026
@halibobo1205 halibobo1205 added this to the GreatVoyage-v4.8.2 milestone Apr 28, 2026
Comment thread framework/src/test/java/org/tron/core/services/jsonrpc/TransactionResultTest.java Outdated
@waynercheung waynercheung requested a review from bladehan1 April 29, 2026 03:24
Per ethereum/execution-apis, TransactionInfo.nonce is `uint` (QUANTITY)
and must match `^0x(0|[1-9a-f][0-9a-f]*)$`. java-tron emitted the field
as `0x0000000000000000` via `ByteArray.toJsonHex(new byte[8])`, which
violates the pattern. Both `TransactionResult` constructors now emit
`"0x0"`.

Block.nonce is intentionally left at `0x0000000000000000` because the
Block schema defines it as `bytes8`, so that value is already compliant
and shortening it would break conformance.

Closes tronprotocol#6547
@waynercheung waynercheung force-pushed the fix/jsonrpc-tx-info-quantity-format-6547 branch from cc50549 to ef27b6d Compare April 30, 2026 09:39
@waynercheung waynercheung changed the title fix(jsonrpc): correct QUANTITY/null format in TransactionResult fix(jsonrpc): correct TransactionResult.nonce per JSON-RPC spec Apr 30, 2026
@waynercheung
Copy link
Copy Markdown
Collaborator Author

After review discussion, the scope of this PR has been narrowed to only the nonce field - the change directly addressing #6547. All other fields previously modified in earlier commits (v / r / s in the unsigned-signature branch, blockHash / blockNumber / transactionIndex / gasPrice in the fallback constructor) have been reverted to their original behavior to maintain strict byte-level compatibility with current production responses.

The branch has been force-pushed to a single minimal commit. Earlier inline comments on the now-removed changes are no longer applicable; please re-review the latest state.

Copy link
Copy Markdown
Collaborator

@halibobo1205 halibobo1205 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

byte[] txId = capsule.getTransactionId().getBytes();
hash = ByteArray.toJsonHex(txId);
nonce = ByteArray.toJsonHex(new byte[8]); // no value
nonce = QUANTITY_ZERO; // no value
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NIT] Drop or rewrite the stale // no value comment on nonce
The // no value comment on both nonce = QUANTITY_ZERO lines describes the old new byte[8] placeholder. After this PR the value is a real spec-compliant zero, not a placeholder, so the comment is misleading.
Suggestion: drop it, or replace with // TRON has no Ethereum nonce, always 0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic:api rpc/http related issue topic:json-rpc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The nonce returned by eth_getTransactionByHash is non-compliant

4 participants