erigontech / erigontech/erigon
Caplin: validate and tune the GLOAS EL build-window timing (payloadPublicationDivisor)
- Dominant language
- Go
- Stars
- 3.6k
- Forks
- 1.5k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 455
Description
Follow-up from #22032 (review discussion) — non-blocking, tracked separately so #22032 can merge.
## Context
#22032 makes Caplin's EL build window **deadline-relative**: it stops polling `GetAssembledBlock` at `attestationDue − attestationDue/payloadPublicationDivisor` (first attempt one `minPayloadPollingWindow` earlier), reserving a publication margin before the attestation deadline so the block stays timely and earns proposer boost. With `payloadPublicationDivisor = 4` that's ~1s margin pre-GLOAS (4s deadline) and ~750ms for GLOAS (3s / 25% deadline).
The margin is a **policy heuristic**: the consensus spec is silent on build-window / `getPayload` timing (it only requires the block be timely by the attestation deadline), so the divisor is a client tuning knob, not a spec-derived constant.
## Tasks
- [ ] **Validate on a GLOAS devnet** — payload fullness (txs/gas) and timeliness (proposer-boost rate, reorgs). The PR's live data was Fulu (pre-GLOAS, ~1s margin); GLOAS's tighter 750ms margin is unvalidated, and GLOAS isn't live on mainnet (`GloasForkEpoch = MaxUint64`).
- [ ] **Tune `payloadPublicationDivisor`** from that data (larger ⇒ fuller block / less margin; smaller ⇒ more timely / less build time).
- [ ] **Decide busy-EL behavior.** Polling currently stops at the margin point, so if `GetAssembledBlock` is busy (EL semaphore held during a forkchoice commit) through the ~100ms `minPayloadPollingWindow`, the proposer produces no block. Option: keep the early first attempt but let retries run to the hard attestation deadline — a busy EL then yields a late-but-published block (or a still-timely one if it frees in time) instead of a missed slot.
- [ ] **Document the build-window latency for operators.** Deadline-relative polling makes the `/eth/v3/validator/blocks/{slot}` response take up to ~3s pre-GLOAS / ~2.25s GLOAS before returning; a validator client with an aggressive sub-slot HTTP timeout would disconnect before the block is assembled and miss the slot. Not an Erigon-side defect (Lighthouse was fine in the #21989 live test) — worth a note in the PR description / operator docs so the CL-side `getPayload` timeout isn't set too low.
## Underlying worst case (raised in the #22032 review)
A single in-flight `GetAssembledBlock` isn't interruptible — the local execution-client path passes `context.Background()` and `ExecModule.GetAssembledBlock` ignores `ctx` — and the busy/commit window can be ~1s, so a slow grab can exceed the margin regardless of the divisor. A deeper fix would be EL-side: honor `ctx` / bound the call, or expose a non-destructive "peek" read instead of `Stop()`.
Refs: #22032, #21989.
Contributor guide
Assessment
This issue has not been assessed yet.