When engine_newPayloadV6 fails with a transient error (e.g. Besu's
ConcurrentModificationException), queue the envelope for retry instead
of permanently rejecting it. Matches Lodestar's behavior of retrying
on the next BlockImported event.
- Add RetryEnvelope variant to ReprocessQueueMessage
- On BlockImported, immediately dispatch any pending retry envelopes
- Fallback timeout of 1 slot in case no block arrives
- Max 3 retries per envelope to prevent infinite loops
- Only retry non-penalizing EL errors (transient failures)
Add a payload envelope monitor that subscribes to the
ExecutionPayloadAvailable SSE event (following the existing
beacon_head_monitor pattern). The inclusion list service now races
the IL deadline (66.67% into slot) against the payload envelope
event, matching Lodestar's Promise.race approach.
This ensures IL production fires as soon as the envelope is imported
(when the EL has fresh state) rather than at a fixed offset that may
be too early or too late.
In ePBS/Gloas, the execution payload is delivered via envelope, not
embedded in the beacon block. produce_inclusion_list was trying to
extract parent_hash from the beacon block's execution payload (which
doesn't exist), causing every IL fetch to fail.
Use cached_head.head_hash() which correctly tracks the execution
block hash through fork choice, including envelope imports.
Besu does not implement this method. Lodestar handles IL satisfaction
checking via the il_transactions param in newPayloadV6 instead of a
separate engine call. Skip the call and assume satisfied for now.
- Force engine_newPayloadV6 for Heze blocks (Besu supports V6 but
capability detection was falling through to broken V5 path)
- Pass parentHash to engine_getInclusionListV1 (was sending empty
params, Besu/Lodestar expect the parent block hash)
Update the ci workflow to use warpbuild snapshot image and test suit uses `Swatinew/rust-cache` to utilize warpbuild cache
Co-Authored-By: lemon <snyxmk@gmail.com>
The alpha-7 spec tests expect the Gloas genesis block body to contain
the execution payload bid from state. Restores the genesis_block()
function and body_root fixup that were removed in PR #9244.
The fork choice from_anchor fix (reading latest_block_hash when bid
hashes are zero) remains for Kurtosis/external genesis compatibility.
- Fix forkchoice update sending zero-hash head to EL at genesis by reading
latest_block_hash from state when the genesis bid hashes are all zeros
- Simplify genesis block construction — the genesis block body is empty per
spec, remove the incorrect bid-copying logic and body root override in
initialize_beacon_state_from_eth1
We yolo'd to alpha 7. We're just changing the proposer preference to include dependent root, instead of checkpoint root. This way we can actually construct it within the VC without needing a view of fork choice.
Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>
- test_utils: Heze branch uses DataColumnSidecarGloas (shared format), keeps
heze_enabled() check ahead of gloas_enabled() so Heze blocks are handled first
- genesis.rs: Keep both Gloas and Heze bid initialisation in genesis_block()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
We are not submitting ptc votes that we produce to our lcoal ptc op pool. So when we are the block producer we don't include our own ptc votes!
Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>