Skip to content

Rewrite submit_block relay communication to support SSZ and JSON - #468

Merged
JasonVranek merged 7 commits into
mainfrom
pr/ssz-submit-block
Jul 24, 2026
Merged

Rewrite submit_block relay communication to support SSZ and JSON#468
JasonVranek merged 7 commits into
mainfrom
pr/ssz-submit-block

Conversation

@JasonVranek

Copy link
Copy Markdown
Collaborator

Summary

Rewrites submit_block relay communication to support SSZ and JSON content negotiation.

What's in this PR

  • SSZ-first request encoding with automatic JSON fallback on 406/415 (per builder-spec)
  • Content-Type and Eth-Consensus-Version header handling for submit_block
  • Fork-aware SSZ decoding for relay responses
  • v2→v1 fallback now forwards the v1 payload to the beacon node instead of returning an empty 202 (prevents silent block loss)
  • V2_FALLBACK_TO_V1 metric counter for observability
  • Submit_block integration tests covering SSZ/JSON encoding, v1/v2 paths, and fallback behavior

Review notes

The v2→v1 fallback behavior is an intentional change from the previous code which silently discarded the v1 payload. The beacon node needs the unblinded execution payload to broadcast the block (returning an empty 202 on fallback would cause silent block loss).

Part 3 of 4: SSZ types → get_header → submit_block → validation bypassing

Attribution

This work builds on the SSZ builder flow originally implemented by @eserilev
in #252 and ported to the current codebase by @jclapis in #403.

Co-authored-by: Eitan Seri-Levi eserilev@ucsc.edu
Co-authored-by: Joe Clapis jclapis@outlook.com

@JasonVranek
JasonVranekforce-pushed the pr/ssz-routes branch 2 times, most recently from c800921 to cbf451dCompareJune 2, 2026 03:30
Base automatically changed from pr/ssz-routes to mainJuly 10, 2026 22:20
@JasonVranek
JasonVranek requested a review from a teamJuly 10, 2026 22:20
Comment threadcrates/pbs/src/mev_boost/submit_block.rs Outdated
Comment threadcrates/pbs/src/mev_boost/submit_block.rs Outdated
Comment threadcrates/pbs/src/mev_boost/submit_block.rs Outdated
Comment threadcrates/pbs/src/mev_boost/submit_block.rs Outdated
Comment threadcrates/pbs/src/mev_boost/submit_block.rs Outdated
Comment threadcrates/pbs/src/mev_boost/submit_block.rs Outdated
Comment threadcrates/pbs/src/mev_boost/submit_block.rs Outdated
Comment thread.github/workflows/security-audit.yml Fixed
Comment thread.github/workflows/security-audit.yml Fixed
ManuelBilbao
ManuelBilbao previously approved these changes Jul 14, 2026
Comment threadcrates/pbs/src/mev_boost/submit_block.rs
Comment threadcrates/pbs/src/mev_boost/register_validator.rs
Comment threadcrates/pbs/src/mev_boost/register_validator.rs
Comment threadcrates/pbs/src/mev_boost/register_validator.rs
content negotiation. Includes:
- SSZ-first request encoding with JSON fallback on 406/415
- Content-Type and Eth-Consensus-Version header handling
- Fork-aware SSZ decoding for relay responses
- MIME parameter tolerance on relay response Content-Type
- v2 to v1 fallback forwards payload to BN (prevents silent block loss)
- V2 fallback metric counter
- Comprehensive submit_block integration tests for both encodings
- L275 pass headers by ref
- L350 / L386 use content_type_header
- L508 drop redundant to_string
- bump transitive dep versions for CI
- JsonEncode error instead of unwrap() for both submit_block and
register_validators
- json timeout budget now accounts for prior ssz attempt
…n v1-only relays
Content negotiation (Builder API):
- Missing Accept defaults the response to JSON instead of inheriting the request
Content-Type; request and response encodings are independent.
- v2 succeeds with an empty 202 and has no body to negotiate, so it skips Accept
entirely -- a bad Accept no longer 406s a v2 submission before it reaches a relay.
- An unrecognized request Content-Type returns 415 instead of 400.
- Always request SSZ from the relay (JSON fallback) rather than mirroring the caller's
format: PBS decodes and re-validates the payload and the route re-encodes to the BN's
Accept regardless, so SSZ is the fastest wire format on the relay hop.
Fail loud on v1-only relays:
- Drop the v2->v1 fallback. It returned the relay's v1 payload as a 200 body, but a v2
caller (Lighthouse, Prysm) requires exactly 202 and never reads the body, so the block
was silently dropped. PBS cannot publish the payload itself, so a relay that 404s v2
now fails loud (RELAY_V2_UNSUPPORTED) and other relays still get a chance.
@JasonVranek
JasonVranek merged commit 1188046 into mainJul 24, 2026
6 checks passed
@JasonVranek
JasonVranek deleted the pr/ssz-submit-block branch July 24, 2026 22:07
JasonVranek added a commit that referenced this pull request Aug 11, 2026
Adds the ePBS (gloas) builder-API surface and the strict header rulings,
rebased onto main so it sits on top of the SSZ rewrite (#468) and the
fork-from-slot fix (#487).
ePBS endpoints:
- getExecutionPayloadBid, submitBuilderPreferences, submitSignedBeaconBlock,
with per-builder routing by SignedRequestAuth.data (no Eth-Builder-Url).
- SSZ-first request/response with JSON fallback; the bid poll ladder honors the
proposer's timing headers.
Header discipline (builder-specs #165):
- Eth-Consensus-Version required for JSON and SSZ on the request-auth endpoints;
absent -> MissingVersionHeader, present-but-unsupported -> InvalidVersionHeader,
both 400. The accepted set is Gloas only; any other fork name is a client bug.
- A relay bid whose response fork is not Gloas on the Gloas-only endpoint is a
bad relay response: dropped, never forwarded under the wrong fork.
Status + observability:
- zero addressed builders accepting an ePBS submission maps to 500, not 502
(neither endpoint declares 502); new PbsClientError::NoBuilderResponse.
- decode/accept rejections counted in BEACON_NODE_STATUS via record_client_error;
dropped relay responses in pbs_relay_invalid_response_total{reason,endpoint,relay_id}.
Legacy PBS, the websocket get_header stream (#483), and the #487 fork fix are
unchanged. Suite green, clippy clean.
Sign up for freeto 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.

6 participants

@JasonVranek@ManuelBilbao@github-advanced-security@0w3n-d@ltitanb@ninaiiad