Skip to content

fix(rpc): eth_getTransactionCount + eth_call + logsBloom length#705

Merged
github-actions[bot] merged 2 commits into
mainfrom
fix/rpc-eth-call-and-logsbloom
May 21, 2026
Merged

fix(rpc): eth_getTransactionCount + eth_call + logsBloom length#705
github-actions[bot] merged 2 commits into
mainfrom
fix/rpc-eth-call-and-logsbloom

Conversation

@satyakwok
Copy link
Copy Markdown
Collaborator

@satyakwok satyakwok commented May 21, 2026

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.

Summary

Risk tier

Check ONE:

  • 🟢 Low — docs, tools/, tests/, CI configs, dependency patch bumps in dev-only crates, comments
  • 🟡 Medium — non-consensus production code (RPC handlers, network plumbing, observability, ops scripts)
  • 🟠 High — consensus-critical crates (sentrix-core, sentrix-trie, sentrix-staking, sentrix-bft), block_executor, apply_block_*, state_root path
  • 🔴 Critical — Voyager activation, fork-height changes, hard-fork rollouts, anything that flips env vars on mainnet

Required by tier

🟢 Low — minimum bar

  • CI green (tests + clippy + audit + gitleaks)

🟡 Medium — adds

  • New public function or behavioural change has at least one corresponding #[test] in same PR
  • Brief description of how this was tested (manual run, integration test, etc.)

🟠 High — adds

  • Regression test that fails on main and passes with this change — paste test name in PR body
  • Designed against documented invariant (link the audit/runbook/design doc)
  • Fresh-brain review by someone other than the author (per the consensus-change review checklist)
  • Single conceptual unit per PR (no bundling — bundling consensus changes burned us on v2.1.12 → 2026-04-25 livelock)

🔴 Critical — adds

  • Testnet rehearsal completed with success criteria + log evidence linked here
  • Bake window observed: minimum 2h on testnet at the same configuration before mainnet
  • Coordinated rollback plan documented in PR body — exact commands operator runs if it fails
  • Operator sign-off at activation moment (not just PR approval — separate moment for the actual flip)

Test plan

Rollback plan

Related

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Corrected Ethereum logs bloom constant to the proper 256-byte value.
  • Changes

    • Modified eth_call method to return results based on current state for non-tip block tags, improving compatibility while maintaining strict gating for other state-pinning RPC methods.

Review Change Stack

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.
@github-actions github-actions Bot enabled auto-merge (squash) May 21, 2026 17:14
@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

📝 Walkthrough

Walkthrough

This PR performs two updates to the Ethereum RPC JSON-RPC implementation. First, it corrects the EMPTY_LOGS_BLOOM constant to use the proper 256-byte zero value. Second, it removes the strict historical-state read gate from eth_call to allow execution against current state regardless of the supplied block tag, with documentation updated to reflect that eth_call is no longer subject to the historical state read gating that remains applied to other state-pinning RPC methods.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • sentrix-labs/sentrix#704: Removes historical-state-read gating from eth_getTransactionCount using the same require_latest_state_read helper, with overlapping documentation updates in helpers.rs.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is missing critical sections required by the template: Summary section, Risk tier checkbox, Required checks (CI green, test coverage), Test plan, and Rollback plan are incomplete or absent. Complete the description by selecting a Risk tier, checking required boxes for that tier, providing a concrete test plan with at least one test name, and describing how the changes were validated.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes all three main fixes: eth_getTransactionCount, eth_call, and logsBloom length correction.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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-eth-call-and-logsbloom

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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 win

Inconsistent 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

📥 Commits

Reviewing files that changed from the base of the PR and between 7491759 and caf4f39.

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

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 github-actions Bot merged commit ab3d349 into main May 21, 2026
13 checks passed
github-actions Bot pushed a commit that referenced this pull request May 22, 2026
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.
satyakwok added a commit that referenced this pull request May 22, 2026
2.2.15 shipped to mainnet 2026-05-22 (34s halt window, zero
cascade-jail). Documents PRs #705/#707/#708.

Also scrubs host identifiers from the 2.2.14 + 2.2.15 entries —
topology now reads 'mainnet' / 'testnet' generically.
satyakwok added a commit that referenced this pull request May 22, 2026
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.
satyakwok added a commit that referenced this pull request May 22, 2026
…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.
github-actions Bot pushed a commit that referenced this pull request May 22, 2026
…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.
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