ChainSafe / ChainSafe/lodestar
Track blinded payload-envelope storage + EL-backed sync serving (incl. BAL restore)
- Dominant language
- TypeScript
- Stars
- 1.4k
- Forks
- 483
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 150
Description
## Problem
We already know Lodestar should avoid persisting duplicate full execution payload bodies on the CL side and instead keep a blinded representation + reconstruct the missing EL-side body data on demand.
There is already a broad tracking issue for the storage dedup idea:
- #5671 `De-duplicate payload from persisted beacon blocks`
But we should keep a **more specific pre-testnet reminder** for the serve path:
> if Lodestar stores the execution payload envelope / block in blinded form, it must still be able to serve peers correctly during sync (especially `beacon_blocks_by_range` / `beacon_blocks_by_root` style serving), reconstructing the missing execution payload body data from EL and restoring any Gloas-specific fields such as BAL before serving.
Terence warned that Prysm hit a late bug in this area: they were not unblinding / re-adding BAL correctly when serving to peers.
## Why this needs a dedicated reminder
This can easily be missed if we only test:
- local import / processing
- proposer-side flows
- REST full-block reconstruction
The tricky part is the **sync serving** path:
- range sync serving works
- block/root serving works
- the served payload is reconstructed from EL correctly
- BAL / other body-only fields are restored correctly before serving
- peers can consume the served block/payload without blinded/full mismatch bugs
## Prysm reference points
I could not cleanly pull the exact `ethpandaops/prysm:glamsterdam-devnet-0` branch into the local checkout, but the current local Prysm repo already shows the relevant shape:
### 1. Store the envelope in blinded form
`beacon-chain/db/kv/execution_payload_envelope.go`
- `SaveExecutionPayloadEnvelope()` replaces the full payload with its `blockHash`
- keeps metadata like `executionRequests`, `builderIndex`, `beaconBlockRoot`, `slot`, `stateRoot`
- comment explicitly says the full payload can later be retrieved from EL via `engine_getPayloadBodiesByHash`
### 2. Reconstruct full payload bodies from EL on demand
`beacon-chain/execution/payload_body.go`
- `reconstructBlindedBlockBatch()`
- `requestBodiesByHash()` using `engine_getPayloadBodiesByHashV1`
- fallback `requestBodiesByRange()` using `engine_getPayloadBodiesByRangeV1`
- `fullPayloadFromPayloadBody()` rebuilds the full execution payload from the blinded header + EL body data
### 3. Use reconstructed full blocks for serving/API paths
`beacon-chain/rpc/eth/beacon/handlers.go`
- `GetBlockV2()` reconstructs the full block when the stored block is blinded:
- `ExecutionReconstructor.ReconstructFullBlock(ctx, blk)`
## Lodestar context
Lodestar already has the relevant TODO in:
- `packages/beacon-node/src/chain/blocks/writePayloadEnvelopeInputToDb.ts`
```ts
// TODO GLOAS: Persist envelope metadata (stateRoot, executionRequests, builderIndex, etc.) without the full
// execution payload body — only keep the blockHash reference. The EL already stores the payload.
// See https://github.com/ChainSafe/lodestar/issues/5671
```
Lodestar also already has EL payload body fetch methods:
- `packages/beacon-node/src/execution/engine/http.ts`
- `getPayloadBodiesByHash()`
- `getPayloadBodiesByRange()`
## Requested work / acceptance criteria
Before testnets, we should make sure Lodestar either implements or explicitly tests the full serve path for blinded envelope storage:
- [ ] Persist execution payload envelope / block metadata in blinded form without duplicating the full EL body
- [ ] Reconstruct missing execution payload body data from EL when serving full data back out
- [ ] Verify `beacon_blocks_by_range` serving works
- [ ] Verify `beacon_blocks_by_root` serving works
- [ ] Verify Gloas-specific body fields (including BAL) are restored correctly before serving
- [ ] Add a mixed-client interop / regression test so we do not repeat Prysm's late unblinding/BAL serve bug
## Related
- #5671 `De-duplicate payload from persisted beacon blocks`
Contributor guide
Assessment
This issue has not been assessed yet.