Skip to content

refactor(reference-index): replace ExEx with canonical cursor runtime#141

Open
panos-xyz wants to merge 9 commits into
mainfrom
codex/reth-main-reference-index
Open

refactor(reference-index): replace ExEx with canonical cursor runtime#141
panos-xyz wants to merge 9 commits into
mainfrom
codex/reth-main-reference-index

Conversation

@panos-xyz

@panos-xyz panos-xyz commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Important

This is a stacked PR on top of #140. PR #140 owns the Reth main upgrade and
engine-tree-ext removal; this PR should be reviewed only for the
reference-index changes. After #140 merges, this PR can be retargeted to
main.

Summary

  • replace the reference-index ExEx with a non-critical canonical-cursor runtime backed by its own MDBX database
  • remove the temporary reference-index disable flag and ExEx WAL dependency

Reference-index behavior

  • canonical provider data and the durable (block number, block hash) cursor are the source of truth; notifications are wake-up/rate signals only
  • rapid historical sync defers index I/O after more than 64 changed blocks in a rolling 2-second window, then resumes after 5 seconds without canonical activity
  • catch-up uses atomic batches of at most 512 blocks and drains notifications between batches
  • pre-Jade queries return the complete empty result without per-block index writes
  • post-Jade RPC results are served only when the durable cursor exactly matches the canonical head number and hash
  • normal suffix reorgs roll back and replay automatically; a reorg with no post-Jade common ancestor leaves the index unavailable for manual rebuild
  • reference-index failures do not terminate block execution; bodies-history pruning is rejected at startup because historical canonical bodies are required
  • the derived DB remains under <datadir>/morph/reference_index; there is no automatic migration or deletion of the unreleased ExEx schema

Validation

  • cargo fmt --all -- --check
  • cargo check --workspace --all-features
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --all-features --no-fail-fast
  • clean-branch targeted tests: reference index 36/36, node 32/32, RPC 83/83
  • clean-branch node/RPC reference-index E2E: 4/4
  • before the final scheduler-only review fixes, the morph Hive compatibility suite passed 103/103 RPC fixtures and 6/6 Morph Engine methods, with 0 unexpected or missing known divergences
  • the same validation pass completed 116 Emerald/Jade statetest rounds with 0 mismatch
  • the pre-review local post-Jade benchmark completed 45/45 blocks with 0 errors; throughput was effectively flat versus ExEx (+0.16% realized), while the ExEx baseline created about 60 MiB of WAL and the new runtime created none

Scope

This PR intentionally excludes the local benchmark harness, contracts, benchmark report, and snapshot scripts that are being developed separately.

panos-xyz and others added 3 commits July 13, 2026 21:48
validate_payload already registered an expectation in convert_payload_to_block;
clearing it on the early L1-index reject path matches the inner-failure cleanup
and avoids a stale cache entry until LRU eviction.
Format the L1-index cleanup path, upgrade crossbeam-epoch to 0.9.20, and
drop advisory ignores that no longer match after the reth main bump.
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@panos-xyz, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e84b4e5e-496c-4e69-9a1c-355875b082bc

📥 Commits

Reviewing files that changed from the base of the PR and between fc7af55 and b5dde70.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (25)
  • Cargo.toml
  • bin/morph-reth/Cargo.toml
  • bin/morph-reth/src/main.rs
  • crates/node/Cargo.toml
  • crates/node/src/add_ons.rs
  • crates/node/src/args.rs
  • crates/node/src/exex/mod.rs
  • crates/node/src/exex/reference_index.rs
  • crates/node/src/lib.rs
  • crates/node/tests/it/reference_index.rs
  • crates/reference-index/Cargo.toml
  • crates/reference-index/src/backfill.rs
  • crates/reference-index/src/db.rs
  • crates/reference-index/src/lib.rs
  • crates/reference-index/src/metrics.rs
  • crates/reference-index/src/reader.rs
  • crates/reference-index/src/reconcile.rs
  • crates/reference-index/src/runtime.rs
  • crates/reference-index/src/source.rs
  • crates/reference-index/src/tables.rs
  • crates/reference-index/src/types.rs
  • crates/reference-index/src/writer.rs
  • crates/rpc/Cargo.toml
  • crates/rpc/src/morph/handler.rs
  • crates/rpc/src/morph/rpc.rs
📝 Walkthrough

Walkthrough

The PR migrates Morph’s reference index from ExEx startup wiring to a background runtime, adds phase-aware canonical-chain synchronization and RPC reads, replaces the removed engine-tree extension with Morph-specific validation, and updates REth, payload, EVM, and workspace APIs.

Changes

Reference index runtime and RPC

Layer / File(s) Summary
Canonical index storage and synchronization
crates/reference-index/src/*
Adds canonical-chain abstractions, bounded backfill and rollback, phase-aware queries, runtime metrics, metadata validation, and asynchronous synchronization.
Node startup and RPC integration
crates/node/src/add_ons.rs, crates/rpc/src/morph/*, bin/morph-reth/src/main.rs
Starts the reference-index runtime from node add-ons, registers the RPC namespace unconditionally, and validates queries against canonical tip snapshots.
Reference-index integration tests
crates/node/tests/it/reference_index.rs
Moves coverage from direct database access to end-to-end RPC polling, including pre-Jade behavior and pagination.

Engine, payload, and dependency migration

Layer / File(s) Summary
Morph engine validation
crates/node/src/validator.rs, crates/consensus/src/validation.rs, crates/chainspec/src/hardfork.rs
Adds Morph tree validation, strict state-root handling, Jade-gated L1 message checks, and sorted post-state withdraw-trie-root validation.
Payload and EVM contracts
crates/payload/*, crates/evm/*, crates/revm/*, crates/engine-api/src/builder.rs
Migrates payload requests to target_gas_limit and state_root_handle, moves state-hook handling to the EVM database, and adopts return-based instruction execution results.
Workspace and supporting APIs
Cargo.toml, crates/node/Cargo.toml, crates/node/build.rs, crates/rpc/src/eth/*
Updates REth/alloy/revm dependencies, Rust and build-tool versions, node module wiring, and Ethereum RPC trait implementations.
Removed engine-tree extension
crates/engine-tree-ext/*
Removes the workspace member and its payload validation, trie update, gate, manifest, and integration-test contents.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: anylots, chengwenxi

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 98.06% 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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: replacing the reference-index ExEx with a canonical cursor runtime.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/reth-main-reference-index

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@panos-xyz
panos-xyz force-pushed the codex/reth-main-reference-index branch from fc7af55 to c38f45f Compare July 14, 2026 10:19
@panos-xyz panos-xyz changed the title refactor(node): migrate to Reth main and replace reference-index ExEx refactor(reference-index): replace ExEx with canonical cursor runtime Jul 14, 2026
@panos-xyz
panos-xyz changed the base branch from main to codex/reth-main-upgrade July 14, 2026 10:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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.

Inline comments:
In `@crates/node/src/validator.rs`:
- Around line 313-320: Ensure the validation flow consumes the withdraw-root
expectation for every failure path, including errors from
validate_next_l1_msg_index_for_block and inner validate_payload. Use block_hash
with post_execution_validator.take_withdraw_trie_root_expectation, preserving
successful validation and avoiding duplicate cleanup on any single path.

In `@crates/reference-index/src/runtime.rs`:
- Around line 263-304: Validate the jade_first_block boundary from both the
stored and resolve_jade_first_block paths before using it: block n must have
timestamp >= jade_timestamp and block n - 1 must have timestamp <
jade_timestamp. Revalidate the same boundary immediately before
commit_canonical_batch, and reject or retry when either condition fails so an
inconsistent concurrent-reorg boundary is never persisted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8758adb6-0f39-4f44-894e-cf4db309beca

📥 Commits

Reviewing files that changed from the base of the PR and between 43c3e59 and fc7af55.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (51)
  • Cargo.toml
  • bin/morph-reth/Cargo.toml
  • bin/morph-reth/src/main.rs
  • crates/chainspec/src/hardfork.rs
  • crates/consensus/src/validation.rs
  • crates/engine-api/src/builder.rs
  • crates/engine-tree-ext/Cargo.toml
  • crates/engine-tree-ext/src/gate.rs
  • crates/engine-tree-ext/src/lib.rs
  • crates/engine-tree-ext/src/payload_validator.rs
  • crates/engine-tree-ext/src/trie_updates.rs
  • crates/engine-tree-ext/tests/jade_boundary.rs
  • crates/evm/Cargo.toml
  • crates/evm/src/block/mod.rs
  • crates/evm/src/context.rs
  • crates/evm/src/evm.rs
  • crates/node/Cargo.toml
  • crates/node/build.rs
  • crates/node/src/add_ons.rs
  • crates/node/src/args.rs
  • crates/node/src/exex/mod.rs
  • crates/node/src/exex/reference_index.rs
  • crates/node/src/lib.rs
  • crates/node/src/node.rs
  • crates/node/src/test_utils.rs
  • crates/node/src/validator.rs
  • crates/node/tests/it/engine.rs
  • crates/node/tests/it/helpers.rs
  • crates/node/tests/it/reference_index.rs
  • crates/payload/builder/src/builder.rs
  • crates/payload/types/src/attributes.rs
  • crates/payload/types/src/lib.rs
  • crates/reference-index/Cargo.toml
  • crates/reference-index/src/backfill.rs
  • crates/reference-index/src/db.rs
  • crates/reference-index/src/lib.rs
  • crates/reference-index/src/metrics.rs
  • crates/reference-index/src/reader.rs
  • crates/reference-index/src/reconcile.rs
  • crates/reference-index/src/runtime.rs
  • crates/reference-index/src/source.rs
  • crates/reference-index/src/tables.rs
  • crates/reference-index/src/types.rs
  • crates/reference-index/src/writer.rs
  • crates/revm/src/evm.rs
  • crates/revm/src/precompiles.rs
  • crates/rpc/Cargo.toml
  • crates/rpc/src/eth/call.rs
  • crates/rpc/src/eth/mod.rs
  • crates/rpc/src/morph/handler.rs
  • crates/rpc/src/morph/rpc.rs
💤 Files with no reviewable changes (10)
  • crates/engine-tree-ext/src/lib.rs
  • crates/engine-tree-ext/src/gate.rs
  • crates/node/src/lib.rs
  • crates/engine-tree-ext/Cargo.toml
  • crates/engine-tree-ext/src/trie_updates.rs
  • crates/engine-tree-ext/src/payload_validator.rs
  • crates/node/src/exex/reference_index.rs
  • crates/node/src/exex/mod.rs
  • bin/morph-reth/Cargo.toml
  • crates/engine-tree-ext/tests/jade_boundary.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

🤖 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.

Inline comments:
In `@crates/node/src/validator.rs`:
- Around line 313-320: Ensure the validation flow consumes the withdraw-root
expectation for every failure path, including errors from
validate_next_l1_msg_index_for_block and inner validate_payload. Use block_hash
with post_execution_validator.take_withdraw_trie_root_expectation, preserving
successful validation and avoiding duplicate cleanup on any single path.

In `@crates/reference-index/src/runtime.rs`:
- Around line 263-304: Validate the jade_first_block boundary from both the
stored and resolve_jade_first_block paths before using it: block n must have
timestamp >= jade_timestamp and block n - 1 must have timestamp <
jade_timestamp. Revalidate the same boundary immediately before
commit_canonical_batch, and reject or retry when either condition fails so an
inconsistent concurrent-reorg boundary is never persisted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8758adb6-0f39-4f44-894e-cf4db309beca

📥 Commits

Reviewing files that changed from the base of the PR and between 43c3e59 and fc7af55.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (51)
  • Cargo.toml
  • bin/morph-reth/Cargo.toml
  • bin/morph-reth/src/main.rs
  • crates/chainspec/src/hardfork.rs
  • crates/consensus/src/validation.rs
  • crates/engine-api/src/builder.rs
  • crates/engine-tree-ext/Cargo.toml
  • crates/engine-tree-ext/src/gate.rs
  • crates/engine-tree-ext/src/lib.rs
  • crates/engine-tree-ext/src/payload_validator.rs
  • crates/engine-tree-ext/src/trie_updates.rs
  • crates/engine-tree-ext/tests/jade_boundary.rs
  • crates/evm/Cargo.toml
  • crates/evm/src/block/mod.rs
  • crates/evm/src/context.rs
  • crates/evm/src/evm.rs
  • crates/node/Cargo.toml
  • crates/node/build.rs
  • crates/node/src/add_ons.rs
  • crates/node/src/args.rs
  • crates/node/src/exex/mod.rs
  • crates/node/src/exex/reference_index.rs
  • crates/node/src/lib.rs
  • crates/node/src/node.rs
  • crates/node/src/test_utils.rs
  • crates/node/src/validator.rs
  • crates/node/tests/it/engine.rs
  • crates/node/tests/it/helpers.rs
  • crates/node/tests/it/reference_index.rs
  • crates/payload/builder/src/builder.rs
  • crates/payload/types/src/attributes.rs
  • crates/payload/types/src/lib.rs
  • crates/reference-index/Cargo.toml
  • crates/reference-index/src/backfill.rs
  • crates/reference-index/src/db.rs
  • crates/reference-index/src/lib.rs
  • crates/reference-index/src/metrics.rs
  • crates/reference-index/src/reader.rs
  • crates/reference-index/src/reconcile.rs
  • crates/reference-index/src/runtime.rs
  • crates/reference-index/src/source.rs
  • crates/reference-index/src/tables.rs
  • crates/reference-index/src/types.rs
  • crates/reference-index/src/writer.rs
  • crates/revm/src/evm.rs
  • crates/revm/src/precompiles.rs
  • crates/rpc/Cargo.toml
  • crates/rpc/src/eth/call.rs
  • crates/rpc/src/eth/mod.rs
  • crates/rpc/src/morph/handler.rs
  • crates/rpc/src/morph/rpc.rs
💤 Files with no reviewable changes (10)
  • crates/engine-tree-ext/src/lib.rs
  • crates/engine-tree-ext/src/gate.rs
  • crates/node/src/lib.rs
  • crates/engine-tree-ext/Cargo.toml
  • crates/engine-tree-ext/src/trie_updates.rs
  • crates/engine-tree-ext/src/payload_validator.rs
  • crates/node/src/exex/reference_index.rs
  • crates/node/src/exex/mod.rs
  • bin/morph-reth/Cargo.toml
  • crates/engine-tree-ext/tests/jade_boundary.rs
🛑 Comments failed to post (2)
crates/node/src/validator.rs (1)

313-320: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Consume withdraw-root expectations on every validation failure.

The precheck at Line 314 and validate_block’s inner error path return without removing the shared expectation. A stale entry can later be applied to the same block hash and falsely reject a retry or block-input validation.

Proposed cleanup
         let block_hash = payload.block.hash();
-        self.validate_next_l1_msg_index_for_block(payload.block.as_ref(), &ctx)?;
+        if let Err(err) =
+            self.validate_next_l1_msg_index_for_block(payload.block.as_ref(), &ctx)
+        {
+            self.post_execution_validator
+                .take_withdraw_trie_root_expectation(block_hash);
+            return Err(err);
+        }

     fn validate_block(
         &mut self,
         block: SealedBlock<morph_primitives::Block>,
         ctx: TreeCtx<'_, MorphPrimitives>,
     ) -> reth_engine_tree::tree::ValidationOutcome<MorphPrimitives> {
+        let block_hash = block.hash();
         self.validate_next_l1_msg_index_for_block(&block, &ctx)?;
-        let output = self.inner.validate_block(block, ctx)?;
-        self.validate_withdraw_trie_root(output)
+        match self.inner.validate_block(block, ctx) {
+            Ok(output) => self.validate_withdraw_trie_root(output),
+            Err(err) => {
+                self.post_execution_validator
+                    .take_withdraw_trie_root_expectation(block_hash);
+                Err(err)
+            }
+        }
     }

Also applies to: 325-332

🤖 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/node/src/validator.rs` around lines 313 - 320, Ensure the validation
flow consumes the withdraw-root expectation for every failure path, including
errors from validate_next_l1_msg_index_for_block and inner validate_payload. Use
block_hash with post_execution_validator.take_withdraw_trie_root_expectation,
preserving successful validation and avoiding duplicate cleanup on any single
path.
crates/reference-index/src/runtime.rs (1)

263-304: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Validate the Jade boundary before trusting or persisting it.

resolve_jade_first_block uses separate provider reads, so a concurrent reorg can produce a canonical but incorrect boundary. Once persisted, later turns skip resolution and can permanently omit Jade blocks or index pre-Jade blocks.

Before using either the stored or resolved value, verify that block n has timestamp >= jade_timestamp and block n - 1 has timestamp < jade_timestamp; revalidate immediately before committing the first batch.

🤖 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/reference-index/src/runtime.rs` around lines 263 - 304, Validate the
jade_first_block boundary from both the stored and resolve_jade_first_block
paths before using it: block n must have timestamp >= jade_timestamp and block n
- 1 must have timestamp < jade_timestamp. Revalidate the same boundary
immediately before commit_canonical_batch, and reject or retry when either
condition fails so an inconsistent concurrent-reorg boundary is never persisted.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.

Tip: disable this comment in your organization's Code Review settings.

@panos-xyz
panos-xyz force-pushed the codex/reth-main-reference-index branch from e7f897c to 4a0d756 Compare July 16, 2026 03:27
Base automatically changed from codex/reth-main-upgrade to main July 16, 2026 08:47

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.

Tip: disable this comment in your organization's Code Review settings.

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