Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ There are likely to be descriptions etc outside of the list below, but new query

| Endpoint | [Lighthouse](https://github.com/sigp/lighthouse) | [Lodestar](https://github.com/ChainSafe/lodestar) | [Nimbus](https://github.com/status-im/nimbus-eth2) | [Prysm](https://github.com/prysmaticlabs/prysm) | [Teku](https://github.com/ConsenSys/teku) |
|---------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|---------------------------------------------------|----------------------------------------------------|-------------------------------------------------|-------------------------------------------|
| [#580](https://github.com/ethereum/beacon-APIs/pull/580) `GET /eth/v4/validator/blocks/{slot}` added | | | | | |
| [#580](https://github.com/ethereum/beacon-APIs/pull/580) / [#624](https://github.com/ethereum/beacon-APIs/pull/624) `GET /eth/v4/validator/blocks/{slot}` added | | | | | |
| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/execution_payload_bids/{slot}/{builder_index}` added | | | | | |
| [#580](https://github.com/ethereum/beacon-APIs/pull/580) `GET /eth/v1/validator/execution_payload_envelopes/{slot}/{beacon_block_root}` added | | | | | |
| [#580](https://github.com/ethereum/beacon-APIs/pull/580) / [#624](https://github.com/ethereum/beacon-APIs/pull/624) `GET /eth/v1/validator/execution_payload_envelopes/{slot}/{beacon_block_root}` added | | | | | |
| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/payload_attestation_data/{slot}` added | | | | | |
| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/validator/duties/ptc/{epoch}` added | | | | | |
| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/execution_payload_bids` added | | | | | |
| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/beacon/execution_payload_envelopes/{block_id}` added | | | | | |
| [#580](https://github.com/ethereum/beacon-APIs/pull/580) `POST /eth/v1/beacon/execution_payload_envelopes` added | | | | | |
| [#580](https://github.com/ethereum/beacon-APIs/pull/580) / [#624](https://github.com/ethereum/beacon-APIs/pull/624) `POST /eth/v1/beacon/execution_payload_envelopes` added | | | | | |
| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/beacon/pool/payload_attestations` added | | | | | |
| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/pool/payload_attestations` added | | | | | |
| [#614](https://github.com/ethereum/beacon-APIs/pull/614) `POST /eth/v1/beacon/states/{state_id}/builders` added | | | | | |
Expand Down
39 changes: 19 additions & 20 deletions apis/beacon/execution_payload/envelope_post.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,15 @@ post:
successfully broadcast but failed integration. The broadcast behaviour may be adjusted via
the `broadcast_validation` query parameter.

The request body can be either form, distinguished by the `Eth-Execution-Payload-Blinded`
The request body can be either form, distinguished by the `Eth-Blob-Data-Included`
header:
- A `SignedExecutionPayloadEnvelopeContents` object (header `false`) containing the signed
- A `SignedExecutionPayloadEnvelopeContents` object (header `true`) containing the signed
envelope along with blobs and KZG proofs. This is used in stateless operation (multi-BN
setups, distributed validators, failover) where the receiving beacon node does not have
the blobs cached.
- A `SignedBlindedExecutionPayloadEnvelope` object (header `true`) containing the signed
blinded envelope (transactions omitted). This is used in stateful operation where the
beacon node already has the full envelope and blobs cached from block production. The
beacon node reconstructs the full envelope from its cache before broadcasting; the
signature is valid over both forms by construction.
- A `SignedExecutionPayloadEnvelope` object (header `false`) containing only the signed
envelope. This is used in stateful operation where the beacon node has the blobs and
KZG proofs cached from block production and attaches them before broadcasting.
tags:
- Beacon
- ValidatorRequiredApi
Expand Down Expand Up @@ -56,39 +54,38 @@ post:
name: Eth-Consensus-Version
description: "The active consensus version to which the execution payload envelope being submitted belongs."
- in: header
name: Eth-Execution-Payload-Blinded
name: Eth-Blob-Data-Included

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can nit pick the header name, that was the best name I could come up with

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eth-Contains-Blob-Data ? Eth-Includes-Blob-Data? Eth-With-Blob-Data?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do have Eth-Execution-Payload-Included already, so I do prefer the -Included suffix to at least keep consistency between those two headers, but appreciate the suggestions

required: true
schema:
type: boolean
description: |
Indicates which body schema is submitted (see the
[`Eth-Execution-Payload-Blinded`](#/components/headers/Eth-Execution-Payload-Blinded)
header). When `false`, the body is a `SignedExecutionPayloadEnvelopeContents` (full
envelope plus blobs and KZG proofs, stateless flow). When `true`, the body is a
`SignedBlindedExecutionPayloadEnvelope` (blinded envelope only, stateful flow; the
beacon node must have cached the full envelope and blobs from block production).
Indicates which body schema is submitted. When `true`, the body is a
`SignedExecutionPayloadEnvelopeContents` (signed envelope plus blobs and KZG proofs,
stateless flow). When `false`, the body is a `SignedExecutionPayloadEnvelope`
(signed envelope only, stateful flow; the beacon node must have cached the blobs
and KZG proofs from block production).
requestBody:
description: "The `SignedExecutionPayloadEnvelopeContents` or `SignedBlindedExecutionPayloadEnvelope` object to be broadcast, selected via the `Eth-Execution-Payload-Blinded` header."
description: "The `SignedExecutionPayloadEnvelopeContents` or `SignedExecutionPayloadEnvelope` object to be broadcast, selected via the `Eth-Blob-Data-Included` header."
required: true
content:
application/json:
schema:
anyOf:
- $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Gloas.SignedExecutionPayloadEnvelopeContents"
- $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Gloas.SignedBlindedExecutionPayloadEnvelope"
- $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Gloas.SignedExecutionPayloadEnvelope"
application/octet-stream:
schema:
description: "SSZ serialized `SignedExecutionPayloadEnvelopeContents` or `SignedBlindedExecutionPayloadEnvelope` bytes. Use the `Eth-Execution-Payload-Blinded` header to select the schema."
description: "SSZ serialized `SignedExecutionPayloadEnvelopeContents` or `SignedExecutionPayloadEnvelope` bytes. Use the `Eth-Blob-Data-Included` header to select the schema."
responses:
"200":
description: "The envelope was validated successfully and has been broadcast. It has also been integrated into the beacon node's database."
"202":
description: "The envelope could not be integrated into the beacon node's database as it failed validation, but was successfully broadcast."
"400":
description: |
The signed envelope object is invalid, broadcast validation failed, or a blinded
envelope was submitted but the beacon node has no cached full envelope to reconstruct
from (e.g. because block production happened on a different beacon node).
The signed envelope object is invalid, broadcast validation failed, or an envelope
without blob data was submitted but the beacon node has no cached blobs and KZG
proofs to attach (e.g. because block production happened on a different beacon node).
content:
application/json:
schema:
Expand All @@ -100,3 +97,5 @@ post:
$ref: "../../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType"
"500":
$ref: "../../../beacon-node-oapi.yaml#/components/responses/InternalError"
"503":

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really related, but this PR has some follow ups for #580, so might as well include that, at least in our implementation we return 503 if node is syncing, and I couldn't come up with a good reason not to do that, we do the same in publishBlockV2 which has the 503 documented on the spec side

"503":
$ref: '../../../beacon-node-oapi.yaml#/components/responses/CurrentlySyncing'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the beacon node mistakenly thinks it's syncing, like we saw happen during the Holesky incident non-finality when very few blocks were being produced? Should the BN refuse a perfectly valid request to publish a payload envelope?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit tricky, the problem is that while the node is syncing it might not be able to validate the payload envelope easily, or have a bad view of the network state since it's not subscribed to gossip usually, so equivocation checks may not be possible

but I see what you are saying, this has been mostly addressed on the beacon node side to be able to configure this, eg. there is a flag in lodestar with which I can force it to build on very old heads. there is a trade-off there, but those scenario are being considered as part of the hardening efforts already

curious about other implementations and whether or not they return 503 currently

$ref: "../../../beacon-node-oapi.yaml#/components/responses/CurrentlySyncing"
22 changes: 11 additions & 11 deletions apis/validator/block.v4.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ get:
payload later. This endpoint is specific to the post-Gloas forks and is not backwards compatible
with previous forks.

When self-building (local execution payload), the response will include the full block contents
including the beacon block, execution payload envelope, blobs, and KZG proofs.
When self-building (local execution payload), the response includes the full block contents
(beacon block, execution payload envelope, blobs, and KZG proofs) if `include_payload` is
set to `true`, otherwise only the `BeaconBlock` is returned.
When using an external builder bid, only the `BeaconBlock` is returned as the beacon node
does not have access to the builder's execution payload.

Expand Down Expand Up @@ -42,12 +43,12 @@ get:
$ref: '../../beacon-node-oapi.yaml#/components/parameters/SkipRandaoVerification'
- name: include_payload
in: query
required: false
required: true
description: |
Controls whether the execution payload envelope and blobs are included in the response
when self-building (using local execution payload).

When `true` (default), the response includes the full block contents: beacon block,
When `true`, the response includes the full block contents: beacon block,
Comment on lines -45 to +51

@nflaig nflaig Jul 14, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two reasons for changing this

  • (1) I do not like optional parameters in general
  • (2) I want to de-opinionate the spec about what should be the default

eg. for (2), in lodestar we look at how many beacon node(s) are connected and if it's > 1, then we default to stateless, otherwise stateful, and allow to override via separate cli flag. All of this is configured on the vc side though, so making this parameter optional would mean the bn would have to decide if omitted, but that's not easily possible since the bn has no good view on whether or not other bns are connected to the vc that is requesting to prodcue a block

execution payload envelope, blobs, and KZG proofs. This enables stateless operation
where the validator client can use multiple beacon nodes (multi-BN setups, distributed validators, failover).

Expand All @@ -62,7 +63,6 @@ get:
have access to the builder's execution payload).
schema:
type: boolean
default: true
- name: builder_boost_factor
in: query
required: false
Expand All @@ -73,7 +73,7 @@ get:
receives a valid response from the paired execution node. When these preconditions are
met, the server MUST act as follows:

* if `exec_node_payload_value >= builder_boost_factor * (builder_payload_value // 100)`
* if `exec_node_payload_value >= builder_boost_factor * (builder_bid_value // 100)`
for the highest builder bid known to the beacon node, then return a block committing
to the local execution node payload (with the payload itself included if
`include_payload` is set to true).
Expand All @@ -85,8 +85,8 @@ get:

* `builder_boost_factor=0`: prefer the local execution node payload unless an error makes
it unviable.
* `builder_boost_factor=100`: profit maximization mode; choose whichever payload pays
more.
* `builder_boost_factor=100`: profit maximization mode; choose whichever of the local
execution node payload and the builder bid pays more.
* `builder_boost_factor=2**64 - 1`: prefer the builder bid unless an error or beacon node
health check makes it unviable.

Expand Down Expand Up @@ -127,9 +127,9 @@ get:
type: boolean
description: |
Indicates whether the execution payload envelope is included in the response.
When `true`, the `data` field contains the full
execution payload envelope, blobs, and KZG proofs. When `false`, the `data`
field contains only a `BeaconBlock`.
When `true`, the `data` field contains a `BlockContents` object with the
beacon block, execution payload envelope, KZG proofs, and blobs. When `false`,
the `data` field contains only a `BeaconBlock`.
example: false
data:
anyOf:
Expand Down
16 changes: 6 additions & 10 deletions apis/validator/execution_payload_envelope.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@ get:
operationId: getExecutionPayloadEnvelope
summary: Get execution payload envelope
description: |
Retrieves the cached execution payload envelope for the current proposer's slot as a
`BlindedExecutionPayloadEnvelope` (the `payload` field is replaced by `payload_root`, the
hash tree root of the full execution payload). The hash tree root of
`BlindedExecutionPayloadEnvelope` matches the hash tree root of the corresponding full
`ExecutionPayloadEnvelope`, so a signature produced over the blinded form is valid
against the full envelope.
Retrieves the cached execution payload envelope for the current proposer's slot, to be
signed and published via `publishExecutionPayloadEnvelope`.

The beacon node only caches the envelope for the current slot's self-built payload.
The beacon node only caches the envelope for the current slot's locally built payload.
Requests for older slots or slots where no envelope has been cached will return a 404
error. This endpoint does not fetch payloads from the execution layer.

Expand Down Expand Up @@ -53,10 +49,10 @@ get:
enum: [gloas]
example: "gloas"
data:
$ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.BlindedExecutionPayloadEnvelope"
$ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.ExecutionPayloadEnvelope"
application/octet-stream:
schema:
description: "SSZ serialized `BlindedExecutionPayloadEnvelope` bytes. Use Accept header to choose this response type"
description: "SSZ serialized `ExecutionPayloadEnvelope` bytes. Use Accept header to choose this response type"
"400":
description: "Invalid execution payload envelope request"
content:
Expand All @@ -67,7 +63,7 @@ get:
code: 400
message: "Invalid slot parameter"
"404":
description: "No cached execution payload envelope available for the requested slot. The beacon node only caches the envelope for the current proposer's self-built payload."
description: "No cached execution payload envelope available for the requested slot. The beacon node only caches the envelope for the current slot's locally built payload."
content:
application/json:
schema:
Expand Down
10 changes: 1 addition & 9 deletions beacon-node-oapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -475,10 +475,6 @@ components:
$ref: "./types/gloas/execution_payload_envelope.yaml#/Gloas/SignedExecutionPayloadEnvelope"
Gloas.SignedExecutionPayloadEnvelopeContents:
$ref: "./types/gloas/execution_payload_envelope.yaml#/Gloas/SignedExecutionPayloadEnvelopeContents"
Gloas.BlindedExecutionPayloadEnvelope:
$ref: "./types/gloas/execution_payload_envelope.yaml#/Gloas/BlindedExecutionPayloadEnvelope"
Gloas.SignedBlindedExecutionPayloadEnvelope:
$ref: "./types/gloas/execution_payload_envelope.yaml#/Gloas/SignedBlindedExecutionPayloadEnvelope"
Gloas.PayloadAttestationData:
$ref: "./types/gloas/payload_attestation.yaml#/Gloas/PayloadAttestationData"
Gloas.PayloadAttestation:
Expand Down Expand Up @@ -543,11 +539,7 @@ components:
schema:
$ref: '#/components/schemas/ConsensusVersion'
Eth-Execution-Payload-Blinded:
description: |
Indicates whether the execution payload (or envelope) is in blinded form. Sent in
responses so clients can deserialize returned JSON or SSZ data to the correct object,
and sent in requests on endpoints that accept either blinded or full forms so the
server can select the correct request schema.
description: Required in response so client can deserialize returned json or ssz data to the correct object.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this just reverts back to pre #580 description

required: true
schema:
type: boolean
Expand Down
Loading
Loading