Add Gloas bid inclusion#9221
Merged
mergify[bot] merged 8 commits intosigp:unstablefrom Apr 29, 2026
Merged
Conversation
When producing a Gloas block, select between the locally-built bid and the highest gossip-verified builder bid for the same parent, using `builder_boost_factor` (mirroring the pre-Gloas builder/local race in `execution_layer`): - `boosted_bid = (cached_bid.value / 100) * boost_factor` (raw on `None`) - if `local_value_wei >= boosted_bid_wei` -> keep local - if EL signaled `should_override_builder` -> keep local - else -> use the cached builder bid and drop local payload data (the builder reveals the envelope) `cached_bid.value` is in gwei (u64); `payload_value` is in wei (Uint256); the comparison is performed in wei. `should_override_builder` is now plumbed from `GetPayloadResponseGloas` through `BlockProposalContentsGloas` into the new `LocalBuildResult` so the selection step can honor the EL hint. Selection logic is factored into a pure `select_payload_bid_pure` function with unit tests covering empty cache, no local build, override hook, boost=0, neutral boost, local-higher, tie, and boost amplification.
Two readability fixes after self-review: - `select_payload_bid_pure` now takes `LocalBuildResult` directly instead of `Option<LocalBuildResult>`. The `None` branch was scaffolding for a hypothetical "skip the EL build entirely" path, but in practice the local build is always needed as the fallback for empty-cache slots, so it never becomes None. `produce_execution_payload_bid` returns `LocalBuildResult` directly to match. - Tests collapsed onto a single positional `pick(local_payload_gwei, should_override, cached_gwei, boost) -> (BuilderIndex, bool)` helper, with arg semantics documented on the helper's doc comment so the call sites stay one-liners that read as truth-table rows.
Removes the explicit `unsupported fork for ExecutionPayloadHeader` error when decoding a `BuilderBid` for Gloas. The Gloas variant reuses the Fulu wire format (`ExecutionPayloadHeaderFulu` as the header) so existing relays can serve Gloas-fork lighthouses without a wire-protocol change — the bid is mapped onto a Gloas self-build wrapper at the producer (builder_index = u64::MAX, infinity sig). The auto-generated `map_ref_into(ExecutionPayloadHeaderRef)` macros are replaced with explicit match arms because `ExecutionPayloadHeader` has no Gloas variant; the Gloas builder bid maps to the Fulu header ref.
When a builder is configured, the Gloas producer now races local EL + relay using the existing pre-Gloas `get_payload` selection (with `builder_boost_factor`, `should_override_builder`, and the `builder-fallback-*` chain-health gates), and wraps whichever wins as a Gloas self-build bid (`builder_index = u64::MAX`, infinity sig, value 0). That self-build candidate is then compared against the highest p2p gossip-cache bid via `select_payload_bid_pure`, again using `builder_boost_factor`. The same operator knob applies at both layers. For the relay-won case `payload_data` is `None` at production time — the proposer must unblind via the existing mev-boost endpoint before envelope publication (relay never reveals up front). Adds: - `GloasPayloadSource` enum in `execution_layer` - `get_payload_gloas_with_builder` (delegates to pre-Gloas `get_payload`) `LocalBuildResult.payload_data` is now `Option<...>` so the relay-blinded case can flow through the existing select path unchanged.
Replaces the earlier "BuilderBid::Gloas reuses Fulu wire shape" hack
with the protocol-honest design: Gloas-aware relays return a
`SignedExecutionPayloadBid` directly (the native commitment type).
- Reverts the `BuilderBid::Gloas` variant (and the subsequent macro
expansion fallout). `BuilderBid` correctly stops at Fulu again — that
envelope shape is retired in Gloas.
- Adds a new builder-client endpoint:
`GET /eth/v1/builder/payload_bid/{slot}/{parent_hash}/{pubkey}`
returning `ForkVersionedResponse<SignedExecutionPayloadBid<E>>`.
- Adds `ForkVersionDecode for SignedExecutionPayloadBid<E>` (Gloas-only).
- `get_payload_gloas_with_builder` no longer routes through pre-Gloas
`get_payload`; instead races the new Gloas relay endpoint against
local EL using `builder_boost_factor`. The local EL's
`should_override_builder` flag still forces local.
- `GloasPayloadSource::Builder` now carries `SignedExecutionPayloadBid`
directly. Producer extracts bid fields from `signed_bid.message` —
no Fulu→Gloas translation.
The new builder-client method `get_builder_header_gloas` calls the same URL as the pre-Gloas `get_builder_header` — relays dispatch on the slot's fork (returning `SignedBuilderBid` for pre-Gloas slots, `SignedExecutionPayloadBid` for Gloas slots). The two Rust methods exist because the response types differ and Rust can't dispatch on return type, but the wire URL is identical (no new spec route invented). `BuilderBid` itself stops at Fulu — adding a Gloas variant would force 60+ pre-Gloas call sites to handle `Option<header>` since Gloas has no `ExecutionPayloadHeader`. The minimal-diff path keeps `BuilderBid` untouched and adds a parallel client method.
Drops the relay-side plumbing for Gloas (the get_payload_gloas_with_builder
race, the SignedExecutionPayloadBid ForkVersionDecode impl, the
get_builder_header_gloas method, the GloasPayloadSource enum) until the
relay wire format for Gloas is settled.
The constraint trilemma (existing macro / existing get_builder_header /
no new code) couldn't be resolved without either:
- adding a Gloas variant to BuilderBid (breaks the
map_builder_bid_ref_into_execution_payload_header_ref macro since
ExecutionPayloadHeader has no Gloas variant),
- adding a Gloas variant to ExecutionPayloadHeader (massive blast
radius across state_root/receipts_root/etc. accessors), or
- duplicating HTTP boilerplate.
Rather than ship a design that gets rewritten once the spec lands, this
PR ships only the gossip-cache selection (Path C — the proposer picks a
SignedExecutionPayloadBid from the gossip cache via select_payload_bid_pure
using builder_boost_factor). Path B (mev-boost-as-self-build) is a
follow-up that will revisit the wire-format question.
jimmygchen
reviewed
Apr 29, 2026
| SignedExecutionPayloadBid<T::EthSpec>, | ||
| BeaconState<T::EthSpec>, | ||
| Option<ExecutionPayloadData<T::EthSpec>>, | ||
| LocalBuildResult<T::EthSpec>, |
Member
There was a problem hiding this comment.
Doc comments may need update as we no longer return an Option here
jimmygchen
approved these changes
Apr 29, 2026
Member
jimmygchen
left a comment
There was a problem hiding this comment.
Nice, very clean with good tests!
Just a small comment on updating the doc and removing this TODO
jimmygchen
approved these changes
Apr 29, 2026
Merge Queue Status
|
Merge Queue Status
This pull request spent 30 minutes 4 seconds in the queue, including 27 minutes 23 seconds running CI. Required conditions to merge
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Select bid from p2p and local block building. Recycles boost factor flag. Once the builder API gloas design finalizes we can extend this logic to consider trusted and trustless bids over http queries.