Skip to content

Add the offline EIP-8347 migration lap, pin every fork, fix what the final laps found - #25

Merged
CPerezz merged 1 commit into
mainfrom
offline-migration-lap
Oct 6, 2026
Merged

CPerezz merged 1 commit into
mainfrom
offline-migration-lap

Conversation

@CPerezz

@CPerezz CPerezz commented Oct 6, 2026

Copy link
Copy Markdown
Owner

make migration-offline (args/migration-offline.yaml) runs the full lap plus the offline path of EIP-8347.
A non-validating geth (P6) and erigon (P2) export a PBT snapshot and preimage file at a finalized anchor. Then
Nethermind (P5) and geth (P3) stop, import it, restart and replay to the tip, one at a time, while the network
keeps finalizing.

Added

  • cmd/migration-swap: the host-side orchestrator.
    • geth converts a copy of P6's datadir; erigon exports live.
    • Swaps run as a serial queue, gated on: anchor finalized and canonical, fresh finality, the other validators
      healthy, no partition, a chaos gap, the deadline.
    • Writes swaps.json and posts each step to the monitor.
  • images/geth, images/nethermind: thin layers over the client images that run the import on start.
  • main.star: pbt_migration.offline with plan-time checks. Observers (validator_count: 0) are kept out of
    stake, chaos and the gate.
  • Monitor: POST /api/lifecycle, per-node export/import steps, derived replaying/caught_up, a swap panel
    and anchor markers. README clip re-recorded.
  • Judge: artifact-produced, import-accepted, swaps-serialized, replay-caught-up and offline-coverage
    (INCONCLUSIVE on online laps).

Pins

scripts/sources.sh fetches each fork at a pinned commit into ../pbt-devnet-src/<name>. PBT_*_REF moves a
pin (a branch name tracks the tip); PBT_*_SRC builds a local checkout as-is.

Fork Branch Pin
geth pbt fbfd486b
erigon binary-trie 7b675afb
egg pbt-offset b56f205b
besu (matkt) glamsterdam-devnet-8-pbt ba419e5f
besu-stateless feat/partitioned-binary-trie 9a9a9817
Nethermind pbt-state 323217bc

Fixed

  • shadow-samples: after I* only "binary parked" is required, since geth freezes merkle at I*. Erigon stopping
    its hex shadow 96 blocks past activation counts as retirement once the fork block is finalized, not a stall.
  • The observer bridged every partition: it sat in no disruptoor group. Observers now join the anchor's group
    (--observer on migration-chaos, migration-gate and pbtchaos).
  • partitions-healed: a repeated isolate (the straddle hold) replaced the open chaos window, so a late fork
    crossing looked unscheduled.
  • lap.sh gave no verdict when an EL was stopped. The judge now gets an unreachable URL for it, so those
    checks fail with evidence.
  • swaps-serialized failed a skipped swap for having no stop time. Skipped swaps are excluded;
    offline-coverage still fails them.
  • lap-manifest failed the lap on a pbtchaos "inconclusive", which now gives INCONCLUSIVE.
  • caught_up was measured against the node's own head, which right after a restart is as stale as its
    cursor. It is now measured against node 1's head.
  • tree-at-genesis: erigon refused to write the bin-only genesis under its new parallel-commitment default.
    Both erigons set COMMITMENT_PARALLEL=false until db/state, cmd: let a bin-only datadir drop an unrequested parallel-commitment default erigontech/erigon#24617 lands.

Verification

  • go test -race ./... passes.
  • make migration-offline: exit 0, 21/21 PASS. Exports at anchors 161 and 159; Nethermind and geth caught up
    to the tip 59 s and 37 s after stopping.
  • make migration: exit 0, 16 PASS, with the 5 offline checks INCONCLUSIVE by design.
  • make migration-smoke: exit 0.
  • make tree-at-genesis: 8 clients agree over 100 blocks.

Client findings from these laps

…final laps found

make migration-offline runs the full lap plus the offline path: geth and erigon
export a PBT snapshot at a finalized anchor, then Nethermind and geth stop,
import it and replay to the tip one at a time (cmd/migration-swap, images/,
monitor lifecycle steps, five judge checks). scripts/sources.sh fetches every
fork at a pinned commit. Fixes the shadow-samples boundary rule and six harness
bugs the final laps found, and works around erigon's parallel-commitment default
on the bin-only tree-at-genesis datadirs.
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