Skip to content

epbs builder api endpoints - #505

Merged
JasonVranek merged 7 commits into
mainfrom
epbs-pr1
Oct 8, 2026
Merged

JasonVranek merged 7 commits into
mainfrom
epbs-pr1

Conversation

@JasonVranek

@JasonVranek JasonVranek commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

This PR adds the core functionality for the three new builder-API endpoints and later PRs will extend it.

What it does

  • POST /eth/v1/builder/execution_payload_bid/{slot}/{parent_hash}/{parent_root}/{proposer_pubkey}: sends the request to the relay its auth data names and returns that relay's bid as 200, the builder's own 400 or 401, or 204 when it has no bid or fails (timeout, 5xx, unreachable, undecodable). Commit-Boost does not validate or rank the bid: the beacon node checks it against the builder registry and the key's builder config, and each request names exactly one builder.
  • POST /eth/v1/builder/builder_preferences/{proposer_pubkey}: forwards to the relay its auth data names and returns that builder's answer (202, or its 400/401).
  • POST /eth/v1/builder/beacon_blocks: forwards the SSZ block bytes unparsed to every configured relay and answers 202 when one accepts (only the winning builder does). A non-SSZ body is a 415.

Decisions

  • PBS routes are unchanged to remain backwards compatible through the fork
  • Routing to relays is done using auth data
  • For timing, Commit-Boost derives an absolute deadline from the beacon node's Date-Milliseconds and X-Timeout-Ms headers, and reserves proposer_deadline_buffer_ms (default 50) back for the return trip.

Left to later PRs

  • URL-form auth data, forwarding to builders outside the config, SSRF guard.
  • cb-km, a tool that writes validators' builder configs from the Commit-Boost config (including max_execution_payment with an explicit unclamped setting), and the config fields only it reads.
  • Bid streaming

Configuring it by hand

Until cb-km lands, each validator key's builder config is written through the validator client's keymanager API (keymanager-APIs PR88). For every builder, add an entry whose url is Commit-Boost's own URL and whose auth_data is the hex of the builder's hostname bytes (echo 0x$(printf builder-a.example.com | xxd -p | tr -d '\n')). A key without builder config sends Commit-Boost's own hostname, which matches no relay, so its bid requests get 400. The new docs/get_started/epbs.md page walks through it with a worked example.

Testing

  • Kurtosis devnets with the docs' manual config against the client releases Sepolia's Gloas upgrade uses: Lodestar v1.49.0, Prysm v7.2.0 and Lighthouse v8.3.0-rc.0 built from Commit-Boost's bid in 17 of 17 slots. Nimbus v26.10.0's validator client stores the config but its beacon node does not request bids; Teku 26.9.1 and Grandine 3.0.0-rc.0 do not implement the builder config endpoint yet.

Pin the lighthouse crates to sigp/lighthouse unstable at 31d8cfd, whose
gloas containers hash as EIP-7495 progressive containers, matching the
consensus specs. Mirror lighthouse's own [patch.crates-io] entries for the
progressive ssz stack (a consumer does not inherit a dependency's patches)
and pin the blstrs_plus patch to an explicit rev.

lighthouse dropped `TestRandom` for an `arbitrary` generator, so
`TestRandomSeed` now draws from `arbitrary::Arbitrary`. Validated BLS
points do not randomize under `arbitrary`, so tests that need a real key
use `BlsSecretKey::random()`. Also adapt to `ForkName::Heze` and to
`ExecutionRequests` no longer implementing `ssz::Decode`.
Tests discovered a free port, dropped the listener and let the server
rebind it, leaving a window where another process could take the port.
PbsService and SigningService gain `run_with_listener`, the mock SSV
servers take a bound listener, and the legacy suites hand their listeners
straight to the server. Also add `wait_for_ready`, which polls /status
instead of sleeping a fixed 100 ms.
From the Gloas fork the beacon node calls three builder-API endpoints on
Commit-Boost instead of get_header and get_payload:

- POST /eth/v1/builder/execution_payload_bid/{slot}/{parent_hash}/{parent_root}/{proposer_pubkey}
  sends the request to the one relay its auth data names and returns that
  relay's bid (200), its 400 or 401, or 204 when it has no bid or fails.
  Commit-Boost does not validate or rank the bid: the beacon node checks it,
  and each request names exactly one builder.
- POST /eth/v1/builder/builder_preferences/{proposer_pubkey} forwards to the
  relay the auth data names and returns that builder's answer.
- POST /eth/v1/builder/beacon_blocks forwards the SSZ block bytes unparsed to
  every configured relay and answers 202 when one accepts.

Requests must carry Eth-Consensus-Version: gloas. A body without
Content-Type is JSON and a request without Accept gets JSON, as
builder-specs requires. Bid requests need Date-Milliseconds and
X-Timeout-Ms; Commit-Boost clamps the deadline to one slot, keeps
proposer_deadline_buffer_ms back for the return trip and sends the rest to
the builder as its own X-Timeout-Ms, or returns 204 when nothing is left.

Routing follows builder-specs #168: auth data matches a relay when it equals
the lowercase hostname of the relay URL. The first match in config order wins
and unmatched auth data is a 400. Commit-Boost never verifies auth data; the
builder does. Relay-supplied amounts are saturated.

The new operator page (docs/get_started/epbs.md) covers writing each
validator key's builder config through the keymanager API, with a
copy-paste call, plus routing, timing, metrics and troubleshooting.
Unreleased, shipping from v0.12.0-rc1.
@JasonVranek
JasonVranek requested a review from a team October 6, 2026 04:53
Comment thread crates/pbs/src/utils.rs Outdated
Comment thread crates/pbs/src/routes/execution_payload_bid.rs Outdated
Comment thread crates/common/src/pbs/types/mod.rs Outdated
Comment thread crates/pbs/src/routes/execution_payload_bid.rs Outdated
Comment thread crates/pbs/src/routes/execution_payload_bid.rs Outdated
Comment thread crates/pbs/src/utils.rs Outdated
Comment thread crates/pbs/src/utils.rs Outdated
Comment thread crates/pbs/src/routes/execution_payload_bid.rs Outdated
Comment thread crates/pbs/src/routes/builder_preferences.rs Outdated
Comment thread crates/pbs/src/utils.rs
Comment thread crates/common/src/pbs/types/mod.rs
Comment thread crates/common/src/pbs/types/mod.rs
Comment thread crates/common/src/wire.rs Outdated
Comment thread crates/pbs/src/utils.rs Outdated
Comment thread crates/pbs/src/utils.rs
Comment thread crates/pbs/src/routes/submit_signed_beacon_block.rs
Comment thread crates/pbs/src/routes/submit_signed_beacon_block.rs
Comment thread crates/pbs/src/utils.rs Outdated
Comment thread crates/pbs/src/routes/router.rs
@JasonVranek
JasonVranek merged commit c649660 into main Oct 8, 2026
6 checks passed
@JasonVranek
JasonVranek deleted the epbs-pr1 branch October 8, 2026 15:02
JasonVranek added a commit that referenced this pull request Oct 8, 2026
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.

4 participants