Skip to content

Carry the builder's block access list on a Gloas submission - #570

Open
0w3n-d wants to merge 1 commit into
od/gloas-sim-fork-gate-step1from
od/gloas-bal-wire-step2
Open

Carry the builder's block access list on a Gloas submission#570
0w3n-d wants to merge 1 commit into
od/gloas-sim-fork-gate-step1from
od/gloas-bal-wire-step2

Conversation

@0w3n-d

@0w3n-d 0w3n-d commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Issue: #561 (step 2 of 6)

What this PR does

Removes the TODO(gloas) that made a valid envelope impossible.
to_lighthouse_gloas_payload set block_access_list: Default::default(), and a
test asserted the result was empty — so any envelope the relay broadcast on a
real Gloas network would have carried an empty EIP-7928 list and been rejected.

Only an execution client can produce that list, so it now travels on the
submission and is threaded through to the conversion:

builder -> SignedBidSubmissionGloas.block_access_list
        -> decoder returns it beside merging_data / bid_adjustment_data
        -> SubmissionPayload.block_access_list
        -> to_lighthouse_gloas_payload(slot, bal)

Lighthouse's BlockAccessList is ProgressiveVariableList<u8> — an opaque
encoded blob — so BlockAccessListBytes mirrors none of its structure and uses
the existing ssz_bytes_wrapper! macro.

Two design decisions

A separate SignedBidSubmissionGloas, not a fork-gated field. Encode is
derived on SignedBidSubmission, so adding a field would change the wire bytes
for every fork and break existing builders. A flat extension type with
split() is exactly the existing SignedBidSubmissionWithAdjustments idiom.

Gloas with bid adjustments is refused, explicitly. Combining each extension
with Gloas multiplies the wire shapes four ways. Adjustments are a BuilderNet
feature that a Gloas testnet does not need, and a clear UnsupportedCombination
beats decoding into the wrong shape. Gloas + merging data is deliberately left
to step 5, where the merge builder needs it.

What this PR deliberately does not do

No builder changes — nothing sends a block access list yet; that is step 4. The
merge path returns None for it. decode's return grew from a 3-tuple to a
4-tuple (DecodedParts), which is mechanical churn at 14 test sites and 3
production ones, including a one-word fix in crates/simulator/src/ssz_server.rs
that the workspace needs to compile — the reth simulator is otherwise untouched,
per #561.

Tests

9 new, written before the implementation and signed off first.

  • Types (5): a Gloas submission round-trips through SSZ; split() yields the
    base and the list; the converted Gloas payload carries the submitted
    list
    — this replaces the assertion that it was empty; an empty list still
    converts; and the Gloas and Fulu shapes are mutually undecodable, so no
    existing path can silently accept the wrong one.
  • Decoder (3): the Gloas shape is selected by fork; the Fulu shape is
    unchanged
    , which is the compatibility guarantee; Gloas with adjustments is
    refused.
  • Relay (2): a stored submission keeps the list and it reaches the converted
    payload; a gossiped entry has none, so Gloas cannot be served from one.

Whole workspace green: 25 suites. helix-types 40, helix-common 52,
helix-relay 129, helix-builder 151.

A flaw found on the way, not fixed here

BlobsBundle::random_for_test produces one proof per blob while Decode
requires 128, so a randomly generated submission cannot round-trip at all.
These tests use empty bundles and say so. Worth its own fix.

Reviewer checklist

  • CI (lint, unit-test) is green
  • Matches the linked issue/step
  • No unexplained scope creep or unrelated files touched

`to_lighthouse_gloas_payload` left the EIP-7928 list empty, so the
envelope the relay broadcasts could never be valid. Only an execution
client can produce the list, so it travels on the submission.

A separate `SignedBidSubmissionGloas` rather than a fork-gated field:
`Encode` is derived on `SignedBidSubmission`, so an extra field would
change the bytes for every fork.

Refuse Gloas with bid adjustments. Combining every extension with Gloas
multiplies the wire shapes, and a testnet does not need adjustments.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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