fix(jsonrpc): correct QUANTITY/null format in TransactionResult#6709
Open
waynercheung wants to merge 1 commit intotronprotocol:developfrom
Open
fix(jsonrpc): correct QUANTITY/null format in TransactionResult#6709waynercheung wants to merge 1 commit intotronprotocol:developfrom
waynercheung wants to merge 1 commit intotronprotocol:developfrom
Conversation
Per ethereum/execution-apis, uint (QUANTITY) fields must match the pattern `^0x(0|[1-9a-f][0-9a-f]*)$` (no leading zeros), and contextual fields are nullable when block context is absent. TransactionResult violated this in several places. What changes: * nonce in both constructors emitted `0x0000000000000000` (8 zero bytes); per the TransactionInfo schema this field is uint, so it now emits `0x0`. * In the unsigned-signature branch of parseSignature, v/r/s were built from `new byte[1]` / `new byte[32]`, producing `0x00` and 64 zero hex chars; per the legacy signature schema these are uint, so they now emit `0x0`. * In the fallback constructor (used when the containing block cannot be resolved), blockHash / blockNumber / transactionIndex were emitted as the literal `0x`, which is neither a valid hash32, nor a valid uint, nor null. Per spec they must be null when block context is unknown; gasPrice in the same path is corrected from `0x` to `0x0`. Notes: * Block.nonce is intentionally not changed -- the Block schema defines it as bytes8 (DATA), so `0x0000000000000000` is already compliant. Changing it would break conformance with the spec. * The 32-byte r/s outputs in the signed path are not altered here; a conformance-correct rewrite has wider implications and will be tracked separately. Strict Ethereum-compatible clients (geth ethclient, ethers.js, web3.js, Web3j) reject malformed QUANTITY values, so this also unblocks correct parsing on those clients. Tests pin the spec-compliant values and validate each QUANTITY field against the schema regex to prevent regressions. Closes tronprotocol#6547
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 this PR does
Fixes 9 spec-violation outputs in
TransactionResult, the response body shared byeth_getTransactionByHash,eth_getTransactionByBlockHashAndIndex,eth_getTransactionByBlockNumberAndIndex, and the full-tx mode ofeth_getBlockByHash/eth_getBlockByNumber.All fixed cases share a single root cause:
byte[N]zero-fill values were serialised viaByteArray.toJsonHex(byte[]), which preserves leading zero bytes, producing strings that violate theuint(QUANTITY) pattern. The fallback constructor additionally used a literal"0x"placeholder where the spec requiresnullor a validuint.Closes #6547.
Why
Per the Ethereum JSON-RPC schema in
ethereum/execution-apis:uint(QUANTITY) MUST match^0x(0|[1-9a-f][0-9a-f]*)$— no leading zeros; zero is0x0.TransactionInfo.blockHash/blockNumber/transactionIndexare nullable when block context is absent."0x"matches none of these forms.Strict Ethereum-compatible clients (geth
ethclient, ethers.js, web3.js, Web3j) reject the malformed values produced today, so this PR also unblocks correct parsing on those clients.What changes
nonce0x00000000000000000x0vparseSignatureunsigned branch0x000x0rparseSignatureunsigned branch0x000…000(64 zeros)0x0sparseSignatureunsigned branch0x000…000(64 zeros)0x0blockHash"0x"nullblockNumber"0x"nulltransactionIndex"0x"nullgasPrice"0x"0x0About the fallback constructor
TransactionResult(Transaction, Wallet)is invoked only on the data-pruning / inconsistency path insideTronJsonRpcImpl#getTransactionByHash: the transaction exists inTransactionStore(so it has been on-chain) butTransactionInfoStore/TransactionHistoryStoreandBlockStorecannot serve the correspondingTransactionInfoorBlock.This is not the pending-pool path. java-tron's jsonrpc module does not consult the mempool (
Manager#pendingTransactions); a transaction that lives only in the mempool already responds withnullfrometh_getTransactionByHash. Changing the fallback's malformed"0x"to spec-compliantnull/0x0therefore does not affect mempool query behaviour — those queries continue to returnnullexactly as before.Why
Block.nonceis intentionally NOT changedThe original issue says
nonceshould be0x0, but the spec types differ:TransactionInfo.nonceisuint→0x0000000000000000violates it, must become0x0. Fixed in this PR.Block.nonceisbytes8, pattern^0x[0-9a-f]{16}$→ the existing0x0000000000000000is already compliant. Changing it to0x0would shorten the value to 3 hex chars and break conformance.BlockResult.nonceis therefore left untouched and the existingJsonrpcServiceTestassertions on it ("0x0000000000000000") remain valid.Compatibility
parseSignature, which this PR does not touch. Production responses are byte-identical."0x"outputs were rejected by strict Ethereum clients (hexutil.UnmarshalJSON("0x")reportshex string "0x" is invalid); strict clients can now parse the response —nullfor unknown block context (matchingRPCTransactionpointer-field semantics in geth),0x0forgasPrice. Lenient clients see no behavioural change.eth_getTransactionByHashfor a mempool-only transaction continues to returnnull(java-tron's RPC does not query the mempool).Tests
TransactionResultTestis updated to:0x0for nonce / v / r / s / gasPrice) and the newnullvalues for the fallback path's block-context fields.^0x(0|[1-9a-f][0-9a-f]*)$via a smallassertQuantityhelper, so any future regression that re-introduces a leading-zero or"0x"value will fail the test.Pre-submit checklist
noncereturned byeth_getTransactionByHashis non-compliant #6547), 2 files changed