Skip to content

feat: integrate legacy migrate tool into bin/tools crate#196

Merged
louisliu2048 merged 6 commits intomainfrom
devin/1773388417-legacy-migrate-tool
Mar 16, 2026
Merged

feat: integrate legacy migrate tool into bin/tools crate#196
louisliu2048 merged 6 commits intomainfrom
devin/1773388417-legacy-migrate-tool

Conversation

@Vui-Chee
Copy link
Contributor

@Vui-Chee Vui-Chee commented Mar 13, 2026

Description

Ports the legacy data migration tool from PR #137 (which targeted the dev branch) into the main branch by integrating it as a new legacy-migrate subcommand in the existing bin/tools crate.

Key differences from the original PR #137:

  • Uses workspace reth dependencies (paradigmxyz/reth v1.11.0) instead of pinned okx/reth git deps at 9359e21f...
  • Imports chain spec from the existing xlayer-chainspec crate instead of duplicating chainspec/parser/genesis modules
  • Lives inside bin/tools as a subcommand rather than a standalone bin/legacy-migrate crate
  • Adapts StorageSettings to use the upstream StorageSettings::v2() API (see review note below)

Usage: xlayer-reth-tools legacy-migrate --chain xlayer-mainnet --datadir /path/to/data

Type of Change

  • New feature (non-breaking change which adds functionality)

Code Guidelines

  • Database Guide - This tool migrates data between MDBX → static files + RocksDB

⚠️ Important Items for Review

  1. StorageSettings::v2() vs granular settings: The original PR feat: legacy data migration tool #137 used fine-grained builder methods (with_receipts_in_static_files(bool), with_transaction_senders_in_static_files(bool), etc.) that don't exist in upstream reth v1.11.0. This PR uses StorageSettings::v2() which unconditionally enables all v2 features. If receipts can't be migrated (due to pruning) or senders have no data, the storage settings will still report v2-enabled for those segments. Please verify this is acceptable for your use case.

  2. num-traits dependency: Added to bin/tools/Cargo.toml but u64::is_multiple_of() may already be stable in Rust 1.92. This dep might be unnecessary — please verify.

  3. reth-cli-commands without edge feature: The original PR used features = ["edge"] on reth-cli-commands. This was dropped since we explicitly use StorageSettings::v2(). Verify no other behavior depends on edge.

  4. No unit tests for the migration logic (same as original PR feat: legacy data migration tool #137).

Checklist

  • I have reviewed the relevant code guidelines in the docs/ folder
  • My code follows the coding standards of this project
  • I have performed a self-review of my own code
  • tested locally on mainnet snapshot
  • New and existing unit tests pass locally with my changes

Testing

  • cargo check -p xlayer-reth-tools passes locally with Rust 1.92
  • No runtime testing was performed (requires a real MDBX database with legacy data)

Additional Notes

  • Adds reth-static-file-types as a new workspace dependency in the root Cargo.toml
  • Adds reth-db, reth-node-builder, reth-primitives-traits, reth-static-file-types to bin/tools/Cargo.toml; enables rocksdb feature on reth-provider

Port the legacy data migration tool from PR #137 into the existing
bin/tools crate as a new 'legacy-migrate' subcommand. Key changes:

- Use workspace reth deps (paradigmxyz/reth v1.11.0) instead of pinned
  okx/reth git deps
- Import chain spec from xlayer-chainspec crate instead of duplicating
- Add reth-static-file-types to workspace dependencies
- Adapt StorageSettings to use v2() API from upstream reth
- Add reth-db, reth-node-builder, reth-primitives-traits deps to tools
Copy link
Contributor Author

@Vui-Chee Vui-Chee left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

- Add clap value_parser range(1..) to prevent batch_size=0 panic
- Remove unnecessary num-traits dependency (u64::is_multiple_of is
  stable in Rust 1.92)
- Check prune_modes.receipts.is_none() in addition to receipts_log_filter
  to prevent migrating incomplete receipt data when general pruning is active
- Remove is_some() guard on ensure_at_block in changeset arms to fill leading
  gap (genesis → first block with data), and add ensure_at_block(to_block)
  after each changeset loop to fill the trailing gap
- Gate StorageSettings::v2() write on both migrations completing; skip it
  with a warning when --skip-static-files or --skip-rocksdb is passed so
  the node keeps reading from MDBX until migration is fully finalized

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_receipts

StorageSettings::v2() is all-or-nothing: it routes all static-file segment
queries (including Receipts) to static files. Writing it when receipts were
not migrated (due to pruning) would cause the node to look for receipt data
in static files that contain nothing, while the Receipts MDBX table (which
was not cleared) becomes unreachable via v1 routing.

Two related changes:
1. Add !can_migrate_receipts to the v2-write skip condition so we keep v1
   settings when receipts could not be migrated.
2. Guard MDBX static-file table clearing on can_migrate_receipts for the
   same reason: if v2 was not written, the node reads these tables via v1
   routing and they must remain intact.

Fixes: JimmyShi22 review comment on mod.rs:151
get_writer() and latest_writer() failures were propagated bare, making it
hard to know which segment caused the error. Wraps both call sites with
wrap_err_with so the error chain includes the segment name.

Addresses: JimmyShi22 nit on migrate.rs:70
@louisliu2048 louisliu2048 merged commit 471b077 into main Mar 16, 2026
12 of 18 checks passed
@Vui-Chee Vui-Chee deleted the devin/1773388417-legacy-migrate-tool branch March 16, 2026 06:44
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.

3 participants