Skip to content

Add POST /eth/v1/beacon/execution_payload_envelope#605

Closed
pk910 wants to merge 1 commit into
ethereum:masterfrom
pk910:pk910/publish-execution-payload-envelope
Closed

Add POST /eth/v1/beacon/execution_payload_envelope#605
pk910 wants to merge 1 commit into
ethereum:masterfrom
pk910:pk910/publish-execution-payload-envelope

Conversation

@pk910
Copy link
Copy Markdown
Member

@pk910 pk910 commented May 11, 2026

Motivation

PR #552 standardized the bid POST and envelope-by-block GET but left the envelope publish path unspecified. Issue #575 raised an envelope construction endpoint for builders to sign against; it was closed without merging, and the publish path it implied was never spec'd.

Result: every Gloas CL that wants to support external builders today either ships its own path under its own conventions (Prysm exposes POST /eth/v1/beacon/execution_payload_envelope with a wrapped body; Lighthouse exposes the same path but takes only a bare envelope and ignores externally-supplied blobs; Lodestar accepts the same path but only for the self-build cached case) or does not expose any REST publish path at all (Grandine, Nimbus, Teku). External builder tooling - e.g. ethpandaops/buildoor - already targets the Prysm-style endpoint.

This PR specifies that endpoint so the surface converges before more clients ship divergent variants.

Changes

New endpoint

POST /eth/v1/beacon/execution_payload_envelope

  • Header: Eth-Consensus-Version: gloas (required).
  • Body: application/json (Gloas.SignedExecutionPayloadEnvelopeContents)
    or application/octet-stream (SSZ).
  • Responses: 200 / 202 / 400 / 415 / 500, matching the existing block
    publish and bid publish conventions.

On 20x the beacon node has gossip-validated the envelope and broadcast it on the execution_payload topic; it is also expected to integrate the envelope via on_execution_payload_envelope though it MAY broadcast before integration completes.

New type

Gloas.SignedExecutionPayloadEnvelopeContents wraps:

  • signed_execution_payload_envelope: SignedExecutionPayloadEnvelope
  • blobs: List[Blob, MAX_BLOB_COMMITMENTS_PER_BLOCK]
  • kzg_proofs: List[KZGProof, MAX_BLOB_COMMITMENTS_PER_BLOCK]

The wrapper name and field names mirror Prysm's existing SignedExecutionPayloadEnvelopeContents.

Blob array semantics

The envelope itself, gossiped on the execution_payload topic, does not contain blobs - blobs ride on DataColumnSidecar gossip, which the publishing beacon node derives from these arrays. So this endpoint is also the only path the beacon node has to obtain blobs from an external builder.

  • External builder. MUST supply the full blobs and kzg_proofs arrays. This is the primary use case.
  • Self-build over REST. When the same beacon node built the payload, the caller MAY send empty blobs and kzg_proofs arrays; the beacon node MUST reconstruct from its local self-build cache and MUST reject with 400 if it cannot.

When non-empty, blobs.length and kzg_proofs.length MUST equal ExecutionPayloadBid.blob_kzg_commitments.length, the entries MUST be in the same order, and the beacon node MUST verify them against the committed commitments before broadcasting. kzg_proofs are cell proofs, matching compute_cells_and_kzg_proofs (the same shape used by DataColumnSidecar.kzg_proofs).

Related

@pk910 pk910 force-pushed the pk910/publish-execution-payload-envelope branch from 37d0a89 to bd5d148 Compare May 11, 2026 23:14
Adds the missing reveal-publish counterpart to the bid POST added in
ethereum#552. External builders that build the `ExecutionPayload` out-of-process
need a beacon-API endpoint to publish their signed envelope; today
every Gloas CL invents its own path (or none) for this.

The request body is a new `Gloas.SignedExecutionPayloadEnvelopeContents`
wrapping the signed envelope together with the `blobs` and `kzg_proofs`
arrays the beacon node uses to derive and broadcast the
`DataColumnSidecar`s for the revealed payload. External builders MUST
supply the full arrays. The arrays MAY be empty only when the same
beacon node built the payload itself and can reconstruct them from its
local self-build cache; in that case the node MUST reject with 400 if
the cache miss. Non-empty arrays MUST match the committed
`blob_kzg_commitments` in length and order, and the node MUST verify
the blobs against the commitments before broadcasting.

Issue ethereum#575 raised an envelope-construction endpoint for builders to
sign against. That issue was closed without conclusion; the publish
side it implied remained unspecified. This PR addresses that publish
gap. (Construction is not needed: the current envelope is fully
derivable client-side from the Engine API output plus the standard
beacon-block lookup.)

Prysm already ships this endpoint with this wrapper struct
(`api/server/structs/block.go: SignedExecutionPayloadEnvelopeContents`)
on its glamsterdam-devnet-3 branch, and ethpandaops/buildoor already
calls it. Goal of this PR is to converge the surface before more CLs
implement it divergently.
@bharath-123
Copy link
Copy Markdown
Contributor

I believe its already been specified here: https://github.com/ethereum/beacon-APIs/pull/580/changes#diff-962ea34dc6ec0e65d4e1d6c8682e97c547e6e0d2f1168925210ff7ee47ef6ce0R109

@pk910 pk910 closed this May 12, 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.

2 participants