Skip to content

fix(rpc): null pending fields + zero-address coinbase in getTransactionByHash#702

Merged
github-actions[bot] merged 1 commit into
mainfrom
fix/rpc-tx-shape-pending-coinbase
May 20, 2026
Merged

fix(rpc): null pending fields + zero-address coinbase in getTransactionByHash#702
github-actions[bot] merged 1 commit into
mainfrom
fix/rpc-tx-shape-pending-coinbase

Conversation

@satyakwok
Copy link
Copy Markdown
Collaborator

@satyakwok satyakwok commented May 20, 2026

Summary

Two follow-ups on the EVM-shape conversion shipped in #692, both flagged by CodeRabbit after merge.

What changed

  1. Pending / not-yet-included txs return null for blockHash, blockNumber, and transactionIndex instead of genesis-looking defaults (block 0, empty string, "0x0"). EIP-1474 clients rely on null to distinguish a mined tx at genesis from one still in the mempool. Pre-fix, ethers.js would treat any pending tx as "mined at block 0" and poll genesis for confirmations.

  2. Coinbase / system-emitted txs (sentinel sender "COINBASE" or empty) now serialize from as the zero address. Receipts already do this; the tx-by-hash path was emitting "0xCOINBASE" or "0x" verbatim, which crashes the same address parsers fix(rpc): eth_getTransactionByHash returns EVM-standard JSON shape #692 tried to unblock.

What's skipped

Third CodeRabbit point — branching tx_type / maxFeePerGas / v on the original TxEnvelope variant — is skipped. Every EVM tx on Sentrix currently flows through the EIP-1559 base-fee pipeline (cast / forge / Hyperlane all submit type 0x2), so the hard-coded values match actual execution semantics. Worth revisiting if/when legacy or 2930 envelopes start landing.

Test plan

  • CI passes
  • Sentrix testnet RPC returns null on a not-yet-mined tx (pending state probe)
  • Existing receipt + tx-by-hash agree on from for coinbase / reward txs

Summary by CodeRabbit

Bug Fixes

  • Fixed pending transaction representation to consistently return null for block-related fields, providing clearer and more accurate transaction status information when transactions are not yet mined.

Review Change Stack

…onByHash

Two follow-ups on the EVM-shape conversion shipped in #692, both flagged
by review after merge:

1. Pending / not-yet-included txs now return null for blockHash,
   blockNumber, and transactionIndex instead of genesis-looking defaults
   (block 0, empty string, "0x0"). EIP-1474 clients rely on these three
   being null to distinguish a mined tx at genesis from one still in the
   mempool. Pre-fix, ethers.js would happily treat any pending tx as
   "mined at block 0" and start polling for confirmations against the
   genesis block.

2. Coinbase / system-emitted txs ("COINBASE" sentinel sender, or empty)
   now serialize from as the zero address. Receipts already do this; the
   tx-by-hash path was emitting "0xCOINBASE" or "0x" verbatim, which
   crashes the same address parsers the original fix tried to unblock.

Skipped the third review point — branching tx_type/maxFeePerGas/v on
the original TxEnvelope variant — because every EVM tx on Sentrix
currently flows through the EIP-1559 base-fee pipeline (cast/forge/
Hyperlane all send type 0x2), so the hard-coded "0x2" matches actual
execution semantics. Worth revisiting if/when legacy or 2930 envelopes
start landing.
@github-actions github-actions Bot enabled auto-merge (squash) May 20, 2026 07:35
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 23821944-0f34-4547-92ca-78686bd604f7

📥 Commits

Reviewing files that changed from the base of the PR and between 3debf85 and 04131a5.

📒 Files selected for processing (1)
  • crates/sentrix-rpc/src/jsonrpc/eth.rs

📝 Walkthrough

Walkthrough

This PR refines how pending (mempool) transactions are represented in JSON-RPC responses. The tx_to_evm_json function now consistently uses null for three fields when a transaction is not yet mined: blockHash, blockNumber, and transactionIndex. Additionally, the sender address normalization logic now maps empty or sentinel system addresses (such as COINBASE or treasury) to the zero address, while ensuring non-sentinel addresses include the 0x prefix. These changes improve consistency in signaling the unmined state of transactions.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • sentrix-labs/sentrix#695: Modifies the same tx_to_evm_json function to emit null for pending transactions' mined fields and normalize sender addresses.
  • sentrix-labs/sentrix#692: Updates tx_to_evm_json logic in the same file for eth_getTransactionByHash, including pending vs. mined field representation.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning Description provides clear summary and scope, but is missing required checklist items for build, test, fmt, and deploy impact sections from the template. Complete the Checks and Deploy impact sections by verifying build status, test results, formatting, and specifying deploy impact (likely 'No on-chain change' since this is RPC-only).
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly identifies the main changes: fixing null pending fields and zero-address coinbase handling in getTransactionByHash RPC method.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/rpc-tx-shape-pending-coinbase

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot merged commit 03d3a9f into main May 20, 2026
25 checks passed
satyakwok added a commit that referenced this pull request May 21, 2026
2.2.14 went live on mainnet 2026-05-21 17:02 UTC carrying PRs
#692/#696/#702/#703/#704. Document the five fixes + flag that
the eth_call + logsBloom fixes on this branch are scheduled
for 2.2.15.
github-actions Bot pushed a commit that referenced this pull request May 21, 2026
* fix(rpc): eth_getTransactionCount + eth_call + logsBloom length

Three discrete chain-RPC fixes bundled because they share one cause
(strict-but-non-spec behavior breaking off-the-shelf EVM agents). All
discovered together standing up the Hyperlane relayer for the Base
Sepolia ↔ Sentrix Testnet bridge (audit fix H-4).

1) eth_getTransactionCount accepts any block tag.
   Relayer + ethers + viem all pin nonce queries to a recent past
   block. A stale nonce is self-correcting (chain rejects wrong-nonce
   tx, caller retries) so this method serves current nonce regardless
   of block tag.

2) eth_call accepts any block tag.
   Same pattern: Hyperlane queries Mailbox.delivered(msgId) and
   recipientIsm(addr) at past blocks. Returns current-state. The strict
   gate stays on eth_getBalance / eth_getCode / eth_getStorageAt where
   wrong = wrong protocol decision.

3) Empty logsBloom is now actually 256 bytes (Ethereum spec).
   The EMPTY_LOGS_BLOOM const was 304 bytes (608 hex chars) because of
   an off-by-one in the original hand-typed string. The doc comment
   said 256 but the literal was 304. ethers' fee-oracle middleware
   strict-parses Block.logsBloom — Hyperlane gas estimation
   SerdeJson'd on this with "invalid length 608, expected 256 bytes"
   before any process() tx could be submitted.

Bumps workspace 2.2.13 -> 2.2.14.

* docs(changelog): add 2.2.14 entry — five RPC compat fixes

2.2.14 went live on mainnet 2026-05-21 17:02 UTC carrying PRs
#692/#696/#702/#703/#704. Document the five fixes + flag that
the eth_call + logsBloom fixes on this branch are scheduled
for 2.2.15.
github-actions Bot pushed a commit that referenced this pull request May 22, 2026
…bytes (#707)

* fix(rpc): eth_getTransactionCount + eth_call + logsBloom length

Three discrete chain-RPC fixes bundled because they share one cause
(strict-but-non-spec behavior breaking off-the-shelf EVM agents). All
discovered together standing up the Hyperlane relayer for the Base
Sepolia ↔ Sentrix Testnet bridge (audit fix H-4).

1) eth_getTransactionCount accepts any block tag.
   Relayer + ethers + viem all pin nonce queries to a recent past
   block. A stale nonce is self-correcting (chain rejects wrong-nonce
   tx, caller retries) so this method serves current nonce regardless
   of block tag.

2) eth_call accepts any block tag.
   Same pattern: Hyperlane queries Mailbox.delivered(msgId) and
   recipientIsm(addr) at past blocks. Returns current-state. The strict
   gate stays on eth_getBalance / eth_getCode / eth_getStorageAt where
   wrong = wrong protocol decision.

3) Empty logsBloom is now actually 256 bytes (Ethereum spec).
   The EMPTY_LOGS_BLOOM const was 304 bytes (608 hex chars) because of
   an off-by-one in the original hand-typed string. The doc comment
   said 256 but the literal was 304. ethers' fee-oracle middleware
   strict-parses Block.logsBloom — Hyperlane gas estimation
   SerdeJson'd on this with "invalid length 608, expected 256 bytes"
   before any process() tx could be submitted.

Bumps workspace 2.2.13 -> 2.2.14.

* docs(changelog): add 2.2.14 entry — five RPC compat fixes

2.2.14 went live on mainnet 2026-05-21 17:02 UTC carrying PRs
#692/#696/#702/#703/#704. Document the five fixes + flag that
the eth_call + logsBloom fixes on this branch are scheduled
for 2.2.15.
@satyakwok satyakwok deleted the fix/rpc-tx-shape-pending-coinbase branch May 23, 2026 17:37
@satyakwok satyakwok self-assigned this May 23, 2026
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