Skip to content

Gloas checkpoint sync + range sync envelope wiring#72

Open
dapplion wants to merge 7 commits into
devnet-test-combinedfrom
checkpoint-sync-gloas
Open

Gloas checkpoint sync + range sync envelope wiring#72
dapplion wants to merge 7 commits into
devnet-test-combinedfrom
checkpoint-sync-gloas

Conversation

@dapplion
Copy link
Copy Markdown
Owner

@dapplion dapplion commented Apr 7, 2026

Summary

Makes Lighthouse checkpoint sync and range sync work with ePBS/Gloas by downloading and applying execution payload envelopes.

Changes

  • Checkpoint sync: Download envelope from checkpoint server, store in DB, patch state for child validation
  • PayloadEnvelopesByRoot: Wire single block lookup envelope requests through the sync layer
  • PayloadEnvelopesByRange: Download envelopes alongside blocks during range sync, couple them in the batch pipeline, pre-store in DB before block processing
  • load_parent Full state derivation: When Full state isn't cached, derive it from Pending + envelope via process_execution_payload_envelope
  • Status message fix: Use state's finalized checkpoint (not fork choice's inflated anchor epoch) during checkpoint sync
  • --ignore-ws-check fix: Actually skip the WS period error when flag is set

Test results (local Kurtosis ePBS devnet, 2 Prysm + 2 Geth, 4s slots)

  • Checkpoint sync initializes correctly with envelope
  • Range sync imports blocks with zero StateRootMismatch errors
  • Envelope state root verification passes
  • Peers drop due to Prysm rate limiting (only 2 peers) before reaching head
  • Lookup sync wired but untested (needs to reach head first)

Known issues

  • Prysm's CollocationLimit=5 blocks connections from IPs with >5 stored peer IDs (use --p2p-colocation-whitelist=0.0.0.0/0)
  • Rate limiting with few peers causes disconnections during range sync

dapplion added 7 commits April 4, 2026 04:16
…lidation

- Download execution payload envelope from checkpoint server during Gloas checkpoint sync
- Store envelope in DB (invariant 5 compliance)
- Patch in-memory state latest_block_hash in load_parent for Full->Pending fallback
- Fix proto_array is_genesis to distinguish checkpoint sync from actual genesis (slot != 0)
- Handle missing previous_state_root during checkpoint sync (Bug 1 fix)
- Add weak_subjectivity_state envelope parameter

Tested: zero block rejections, head advances ~100 slots from checkpoint.
Remaining: range sync needs PayloadEnvelopesByRange; Prysm Goodbye:Fault peer issue.
- Implement payload_lookup_request() (previously stubbed as NoRequestNeeded)
- Add PayloadEnvelopesByRoot RPC request/response handling
- Route envelope responses through router -> sync manager -> block lookups
- Add envelope processing via verify_envelope_for_gossip + import
- Add SinglePayloadEnvelope variant to SyncRequestId and BlockProcessType
- Wire PayloadRequest state machine transitions (Downloaded -> Processing -> Done)

Based on sigp#9039 by @eserilev, adapted for three-stream
lookup model from gloas-lookup-sync-fixes.
- status.rs: Use state's finalized checkpoint in status message when fork
  choice's finalized epoch exceeds the state's (happens during checkpoint
  sync where anchor_epoch = state.current_epoch()). Prevents advertising
  a finalized_epoch ahead of the network consensus.

- builder.rs: Fix --ignore-ws-check to actually skip the WS period error.
  Previously the flag only added a warning but still returned the error.
Prysm's peer store has 22 peer IDs from our IP (85.10.201.236),
exceeding its CollocationLimit=5 anti-Sybil check. This is NOT an
IP ban — it triggers `isfromBadIP` in handshake.go which sends
Goodbye:Fault before any status processing.

Confirmed by testing with genesis finalized (epoch 0) and different
status versions (V1/V2) — all rejected identically. Only solution
is a fresh IP or Prysm peer store reset.
Range sync now downloads execution payload envelopes alongside blocks
and data columns. Envelopes are stored in the DB before block processing
so that load_parent can find them for Full state transitions.

Tested against local Kurtosis ePBS devnet (2 Prysm + 2 Geth nodes):
- Checkpoint sync at slot 576, then range sync imported blocks
- PayloadEnvelopesByRange requests sent to Prysm peers successfully
- Most blocks import correctly with envelopes
When load_parent needs the Full state but only has the Pending state
(checkpoint sync / range sync), apply process_execution_payload_envelope
to correctly derive the Full state. Previously only latest_block_hash
was patched, missing deposits, withdrawals, builder payments, and
execution availability updates.

Tested: zero StateRootMismatch errors syncing 117 epochs on local
kurtosis ePBS devnet.
Load Pending state at the parent's slot (not advanced to child's slot)
before applying the envelope. Then advance to the child's slot after
envelope processing. Previously the state was advanced first, causing
SlotMismatch { envelope_slot: N, parent_state_slot: N+1 }.
@dapplion dapplion requested a review from michaelsproul as a code owner April 7, 2026 02:42
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