allow for dual-db commit in runloop_monad_ethblocks - #2485
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the Monad “Ethereum blocks” replay runloop to support dual-DB commits (slot-encoded primary + page-encoded secondary), enabling full-history archive nodes to replay seamlessly across the MIP-8 storage-encoding fork.
Changes:
- Thread an optional
secondary_dbthroughrunloop_monad_ethblocksand pass it intocommit_blockso both timelines are committed during historical replay. - Factor repeated “apply to primary + secondary when present” logic into
for_each_db(...)and use it for metadata/finalization updates and prefix setup. - Align
cmd/monad/main.cppsecondary-timeline initialization so both the normal runloop and ethblocks runloop can use the same secondary timeline when active.
Verdict: CORRECT
Generated with Claude Code
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| cmd/monad/main.cpp | Opens/validates secondary timeline and passes it into the ethblocks runloop when available. |
| category/execution/runloop/runloop_monad.cpp | Uses for_each_db to mirror metadata/finalization updates across both timelines and consolidates state-root logging. |
| category/execution/runloop/runloop_monad_ethblocks.hpp | Extends the ethblocks runloop API to accept an optional secondary Db*. |
| category/execution/runloop/runloop_monad_ethblocks.cpp | Commits blocks to both DBs when secondary is present; mirrors finalize/verified updates and relaxes the MIP-8 encoding assertion under dual-DB. |
| category/execution/monad/db/commit_block_migration.hpp | Adds for_each_db helper to apply operations to primary + optional secondary DB. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Summary
The PR does two things: (1) plumbs secondary_db through runloop_monad_ethblocks and process_monad_block so historical archive replay can dual-write during the mip-8 migration, and (2) folds the primary/secondary mirroring boilerplate into a for_each_db template. The consolidation reads cleanly — call sites are one-liners and the semantics (primary first, then secondary if non-null) matches the code that was replaced.
The new startup assertion in main.cpp (primary must be slot-encoded when the secondary timeline is active) makes the dual-db invariant that commit_block already enforces internally visible at process startup and now applies uniformly across devnet/testnet/mainnet. Relaxing the mip_8_active(rev) == db.is_page_encoded() check to only fire when secondary_db == nullptr is consistent with commit_block's dual-db path, which picks a canonical db based on mip_8_active and works with either revision when both encodings are present.
Cross-check enabling for BlockState (via the secondary_db third argument) now applies to the eth_blocks path too — this is a real behavior change (roughly doubles storage reads during archive replay when secondary is active) but matches the "needed for full history archive nodes past mip-8 fork" motivation in the PR body.
No P0 / P1 issues found. Two P3 style comments posted inline.
PR hygiene
The PR is two commits (feature + refactor) — arguably squashable per CLAUDE.md, but the split is legitimate and reviewable so I'm not flagging it.
Verdict: CORRECT
🤖 Generated with Claude Code
07081ad to
a472066
Compare
a472066 to
fccf493
Compare
25904d0 to
c77240f
Compare
4fe1afe to
9647bca
Compare
9647bca to
daf6e0d
Compare
|
replaced by #2529 |
needed for full history archive nodes past mip-8 fork.