erigontech / erigontech/erigon

cl: complete payload preparation coverage and hardening

Open
#23,419 1 comment 0 reactions 2 assignees Claimed by @domiwei View on GitHub
Caplin
Dominant language
Go
Stars
3.6k
Forks
1.5k
Avg merge
1d 16h
Merged PRs (30d)
455

Description

Follow-up to #23399 and #23436. Payload preparation is best effort: production must keep its normal path whenever a prepared build cannot be reused.

#23436 covers scheduling, timing, input derivation, payload-ID matching, and direct builder startup for pre-Gloas, first-Gloas-slot, and genuine Gloas EMPTY paths. #23551 separately tracks the canonical execution-head update needed before a steady-state Gloas FULL path can be primed safely. The remaining work here is to prove the supported handler-to-execution-module handoff, complete network-import coordination, add bounded operator metrics, provide an independent operational control, improve execution-builder reuse across head flips, reduce avoidable preparation cost, and fix payload-ID encoding in the hybrid engine client.

## End-to-end collection coverage

- Exercise preparation through the beacon handler with the real execution module, then run the normal production path and collect the existing build.
- Cover an ordinary pre-Gloas slot and a pre-Fulu epoch boundary, where preparation must advance a copied beacon state before deriving the proposer and payload attributes.
- Cover the first Gloas slot, where the build uses the pre-fork execution parent without waiting for a PTC decision.
- Cover a genuine steady-state Gloas EMPTY path where the execution layer already follows the bid's parent block hash.
- Cover a FULL path as a deliberate preparation skip followed by successful normal production. End-to-end FULL priming belongs to #23551.
- Cover a FULL-to-EMPTY decision separately. Preparation must stand down because direct builder startup cannot move the execution head without a fork-choice update; ordinary production must still succeed through its normal FCU and collection window.
- Assert that warmup changes collection timing only for the exact prepared payload ID. A missing, failed, skipped, or mismatched build must retain normal production timing in every path.

## Observability

- Count preparation attempts and outcomes with a bounded set of reasons, including success, an unregistered proposer, a stale head, active execution work, a late attempt, and Gloas paths that require a fork-choice update.
- Count production requests that reuse a prepared payload and requests that continue without one because the record is absent or has a different payload ID.
- Keep mismatches diagnostic rather than proposal errors: a legitimate head or input change must continue through ordinary production.
- Keep the existing informational logs useful, but use metrics for aggregation and alerting.

## Operational control

- Add a setting that disables payload preparation without disabling the validator API.
- Keep preparation enabled by default, document the setting, and cover enabled and disabled startup.

## Execution builder reuse

- Avoid creating another builder when an exact live build request reappears after an intra-slot head flip, such as A to B to A. The timestamp index currently points only to the latest request, although the earlier matching builder can still be alive.
- Keep builder lookup and eviction bounded, and add coverage for the repeated-request sequence.

## Preparation cost

- Avoid repeatedly reading, decompressing, and decoding a Gloas execution payload envelope when production or path resolution revisits the same FULL root. Reuse the decoded execution requests through a bounded cache or a narrower shared lookup, with explicit eviction.
- Memoize a derivation failure only when it is guaranteed to remain unchanged for the complete preparation key. Cancellation, handler-gate contention, storage errors, and execution-layer errors must remain retryable.
- Add tests that prove stable failures avoid repeated state work while transient failures are retried.

## Network-import coordination

- Define slot-aware coordination between preparation and network block or envelope imports. The handler gate intentionally does not cover `blockService -> ForkChoiceStore.OnBlock`, and `BlockProcessing` is only an advisory pre-copy signal.
- Cover an import that starts after preparation samples `BlockProcessing`, plus blocks and envelopes parked between retry attempts.
- Keep canonical imports ahead of speculative preparation without adding a blocking lock acquisition to the network path.

## Hybrid engine-client payload IDs

- Use one byte order for payload IDs returned by the local Engine API path and consumed by `ExecutionClientEngine.GetAssembledBlock`. The current path produces an Engine API payload ID in big-endian order but decodes it as little-endian before calling the execution module.
- Share the encoding and decoding helpers where practical, require the exact payload-ID length, and test with an ID whose byte order is observable.
- Keep the direct execution client on its existing execution-module wire format unless that interface is changed explicitly.

## Done when

- Handler-level tests with the real execution module collect the prepared build in ordinary and pre-Fulu epoch-boundary slots.
- The same real-module handoff is covered for the first Gloas slot and a genuine EMPTY path.
- FULL and FULL-to-EMPTY decisions are covered as deliberate preparation skips followed by successful normal production.
- Missing, failed, skipped, and mismatched preparation retain normal collection timing in every covered path.
- Operators can measure whether preparation succeeds and whether production reuses it.
- Operators can disable preparation independently without changing normal block production.
- Repeating an exact live build request after a head flip does not create an avoidable third builder.
- Gloas envelope data is decoded at most once per relevant root while retained by the bounded reuse mechanism.
- Stable preparation failures avoid repeated state derivation, while transient failures remain retryable.
- Relevant network imports cannot overlap builder startup in a way that puts speculative preparation ahead of canonical processing.
- Hybrid engine-client payload IDs round-trip with the Engine API byte order and reject malformed lengths.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.