fix(rpc): eth_getTransactionCount + eth_call + logsBloom length#705
Conversation
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.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
📝 WalkthroughWalkthroughThis PR performs two updates to the Ethereum RPC JSON-RPC implementation. First, it corrects the Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/sentrix-rpc/src/jsonrpc/eth.rs (1)
65-66:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winInconsistent comment: eth_call is no longer "kept strict".
The comment states "eth_call (kept strict)" but this PR removes the historical state gate from
eth_call(documented at lines 966-987). This method should be removed from the list of strict methods.📝 Proposed fix
- // Unlike eth_getBalance / eth_getCode / eth_getStorageAt / - // eth_call (kept strict), a "wrong" nonce is self-correcting: + // Unlike eth_getBalance / eth_getCode / eth_getStorageAt + // (kept strict), a "wrong" nonce is self-correcting:🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/sentrix-rpc/src/jsonrpc/eth.rs` around lines 65 - 66, The comment listing strict methods is now inaccurate because eth_call is no longer kept strict; update the comment in crates/sentrix-rpc/src/jsonrpc/eth.rs to remove "eth_call (kept strict)" from the list (the surrounding comment mentioning eth_getBalance, eth_getCode, eth_getStorageAt should remain), and ensure any nearby explanatory text that references the historical state gate for eth_call (previously around the removed gate at lines ~966-987) is also corrected to reflect that eth_call is no longer treated as strict.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@crates/sentrix-rpc/src/jsonrpc/eth.rs`:
- Around line 65-66: The comment listing strict methods is now inaccurate
because eth_call is no longer kept strict; update the comment in
crates/sentrix-rpc/src/jsonrpc/eth.rs to remove "eth_call (kept strict)" from
the list (the surrounding comment mentioning eth_getBalance, eth_getCode,
eth_getStorageAt should remain), and ensure any nearby explanatory text that
references the historical state gate for eth_call (previously around the removed
gate at lines ~966-987) is also corrected to reflect that eth_call is no longer
treated as strict.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 7bee925f-08ac-4e2a-9a64-c09dfbc21c05
📒 Files selected for processing (2)
crates/sentrix-rpc/src/jsonrpc/eth.rscrates/sentrix-rpc/src/jsonrpc/helpers.rs
PRs #705 + #707 (eth_call historical tags + logsBloom 256-byte fix) landed on main without a version bump, so post-merge main carried more RPC changes than the 2.2.14 binary already deployed to mainnet — two distinct binaries sharing one version string. Bump to 2.2.15 so the RPC-complete binary is distinguishable. This is the version to deploy on the next mainnet upgrade.
2.2.15 shipped to mainnet 2026-05-22 (34s halt window, zero cascade-jail). Documents PRs #705/#707/#708. Also scrubs all host identifiers from the file — the 2.2.14/2.2.15 entries plus six historical v2.0.0/v2.1.x entries. Topology now reads 'mainnet' / 'testnet' / 'host' generically, consistent with the file header's host-mapping-not-published note.
…counts 2.2.15 shipped to mainnet 2026-05-22 (34s halt window, zero cascade-jail). Documents PRs #705/#707/#708. Also scrubs infra detail from the file: host identifiers from the 2.2.14/2.2.15 entries + six historical v2.0.0/v2.1.x entries, and the explicit validator/host counts from the v1.0.0 entry. Topology now reads generically.
…counts (#709) 2.2.15 shipped to mainnet 2026-05-22 (34s halt window, zero cascade-jail). Documents PRs #705/#707/#708. Also scrubs infra detail from the file: host identifiers from the 2.2.14/2.2.15 entries + six historical v2.0.0/v2.1.x entries, and the explicit validator/host counts from the v1.0.0 entry. Topology now reads generically.
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).
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.
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.
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.
Summary
Risk tier
Check ONE:
sentrix-core,sentrix-trie,sentrix-staking,sentrix-bft),block_executor,apply_block_*,state_rootpathRequired by tier
🟢 Low — minimum bar
🟡 Medium — adds
#[test]in same PR🟠 High — adds
🔴 Critical — adds
Test plan
Rollback plan
Related
Summary by CodeRabbit
Release Notes
Bug Fixes
Changes
eth_callmethod to return results based on current state for non-tip block tags, improving compatibility while maintaining strict gating for other state-pinning RPC methods.