Skip to content

Fix Morph trace replay on Cancun-active chains#57

Merged
chengwenxi merged 2 commits intomainfrom
codex/morph-trace-replay-cancun
Mar 25, 2026
Merged

Fix Morph trace replay on Cancun-active chains#57
chengwenxi merged 2 commits intomainfrom
codex/morph-trace-replay-cancun

Conversation

@panos-xyz
Copy link
Copy Markdown
Contributor

@panos-xyz panos-xyz commented Mar 25, 2026

Summary

  • override Morph trace replay pre-execution handling so Cancun-active chains do not require Ethereum beacon roots
  • add a Cancun-active Morph node regression test covering debug_trace and trace replay endpoints while asserting parent_beacon_block_root stays empty
  • add the trace type test dependency needed by the new integration coverage

Test Plan

  • cargo test -p morph-node
  • cargo test -p morph-rpc

Summary by CodeRabbit

  • New Features

    • Added integration test suite for debug and trace RPC endpoints on Cancun-enabled networks, including transaction tracing, block tracing, and replay operations.
  • Chores

    • Added tracing dependencies to support enhanced debugging capabilities.
    • Updated trace pre-execution handling for L2 block replay operations.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 25, 2026

📝 Walkthrough

Walkthrough

This pull request adds tracing RPC endpoint support for Morph L2 nodes by introducing the alloy-rpc-types-trace dependency, adding a comprehensive integration test that validates trace endpoints against a custom Cancun-enabled chain specification, and implementing a pre-execution behavior override in the Eth API.

Changes

Cohort / File(s) Summary
Dependency Management
Cargo.toml, crates/node/Cargo.toml
Added alloy-rpc-types-trace to workspace dependencies and introduced four new dev-dependencies (alloy-genesis, alloy-rpc-types-trace, reth-node-builder, serde_json) for testing infrastructure.
RPC Trace Implementation
crates/rpc/src/eth/mod.rs
Added apply_pre_execution_changes method override to the Trace trait implementation for MorphEthApi, implementing a no-op pre-execution behavior specific to Morph L2 tracing operations.
Trace Endpoint Integration Test
crates/node/tests/debug_trace.rs
Introduced comprehensive integration test trace_replay_endpoints_succeed_without_beacon_root_on_cancun_morph that validates multiple tracing RPC endpoints (debug trace, trace API, replay flows) against a custom Cancun-enabled Morph chain configuration, plus helper function custom_chain() for genesis setup.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • anylots
  • chengwenxi

Poem

🐰 A trace of endpoints, now crystalline clear,
Through Morph's L2 tunnels, the debug logs appear!
Pre-execution unwound, like carrots in rows,
Cancun's magic traced wherever it flows.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly corresponds to the main change: overriding Morph trace replay to fix handling on Cancun-active chains, which is the primary objective of the PR.

✏️ 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 codex/morph-trace-replay-cancun

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/rpc/src/eth/mod.rs (1)

368-378: Consider documenting the trace accuracy trade-offs.

The no-op implementation correctly avoids requiring parent_beacon_block_root on Cancun-active L2 chains, but it also skips setup that MorphBlockExecutor::apply_pre_execution_changes (crates/evm/src/block/mod.rs:227-275) performs:

  1. State clear flag for Spurious Dragon
  2. L1 Gas Price Oracle cache warming
  3. Curie hardfork system contract initialization

For most trace scenarios this is fine since actual execution already applied these. However, traces for blocks at the Curie activation boundary or transactions depending on L1 fee oracle reads may differ from actual execution. Consider adding a doc comment noting this is intentional L2 behavior and its scope.

📝 Suggested documentation addition
     fn apply_pre_execution_changes<DB: Send + reth_evm::Database + revm::DatabaseCommit>(
         &self,
         _block: &RecoveredBlock<ProviderBlock<Self::Provider>>,
         _db: &mut DB,
         _evm_env: &reth_evm::EvmEnvFor<Self::Evm>,
     ) -> Result<(), Self::Error> {
         // Morph L2 does not execute Ethereum pre-block system calls such as
         // EIP-2935/EIP-4788 during block replay. Using the upstream default here
         // incorrectly requires `parent_beacon_block_root` on Cancun-active chains.
+        //
+        // Note: This intentionally skips L1 Gas Price Oracle cache warming and
+        // Curie hardfork initialization that MorphBlockExecutor performs. For
+        // already-executed blocks this is safe; trace results should match
+        // actual execution in all but edge cases (Curie transition blocks).
         Ok(())
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/rpc/src/eth/mod.rs` around lines 368 - 378, Add a doc comment above
the apply_pre_execution_changes function in crates/rpc/src/eth/mod.rs that
explains this no-op is intentional for L2 to avoid requiring
parent_beacon_block_root, but that it skips the same setup
MorphBlockExecutor::apply_pre_execution_changes performs (state clear flag for
Spurious Dragon, L1 Gas Price Oracle cache warming, Curie hardfork system
contract initialization), and that traces at Curie activation boundaries or
transactions relying on L1 fee-oracle reads may differ from on-chain execution;
reference the function name apply_pre_execution_changes and
MorphBlockExecutor::apply_pre_execution_changes for context and clearly state
the scope where this trade-off is acceptable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/node/tests/debug_trace.rs`:
- Around line 134-135: Replace the post-default field assignment on the
GethDebugTracingCallOptions instance with struct update syntax: instead of
creating opts via GethDebugTracingCallOptions::default() and then setting
opts.tx_index = Some(0), construct opts using GethDebugTracingCallOptions {
tx_index: Some(0), ..Default::default() } so the tx_index is set during
initialization and avoids the clippy field-reassign-with-default lint.

---

Nitpick comments:
In `@crates/rpc/src/eth/mod.rs`:
- Around line 368-378: Add a doc comment above the apply_pre_execution_changes
function in crates/rpc/src/eth/mod.rs that explains this no-op is intentional
for L2 to avoid requiring parent_beacon_block_root, but that it skips the same
setup MorphBlockExecutor::apply_pre_execution_changes performs (state clear flag
for Spurious Dragon, L1 Gas Price Oracle cache warming, Curie hardfork system
contract initialization), and that traces at Curie activation boundaries or
transactions relying on L1 fee-oracle reads may differ from on-chain execution;
reference the function name apply_pre_execution_changes and
MorphBlockExecutor::apply_pre_execution_changes for context and clearly state
the scope where this trade-off is acceptable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c73ddef2-7ea2-4f87-abac-b66c12044097

📥 Commits

Reviewing files that changed from the base of the PR and between b246b10 and 295f657.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • Cargo.toml
  • crates/node/Cargo.toml
  • crates/node/tests/debug_trace.rs
  • crates/rpc/src/eth/mod.rs

@panos-xyz panos-xyz requested review from anylots and chengwenxi March 25, 2026 10:18
Copy link
Copy Markdown
Contributor

@chengwenxi chengwenxi left a comment

Choose a reason for hiding this comment

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

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@chengwenxi chengwenxi merged commit b2275d4 into main Mar 25, 2026
8 checks passed
@chengwenxi chengwenxi deleted the codex/morph-trace-replay-cancun branch March 25, 2026 10:41
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.

2 participants