From 40119002dd1b3d390c70802e0da4f6a545022944 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Wed, 3 Sep 2025 14:38:48 -0700 Subject: [PATCH 01/17] modified block production end points --- apis/beacon/blocks/blocks.v2.yaml | 3 +- apis/validator/block.v3.yaml | 87 +++++++++++++++----------- beacon-node-oapi.yaml | 21 ++++--- types/gloas/block.yaml | 77 +++++++++++++++++++++++ types/gloas/execution_payload_bid.yaml | 34 ++++++++++ types/gloas/payload_attestations.yaml | 28 +++++++++ 6 files changed, 205 insertions(+), 45 deletions(-) create mode 100644 types/gloas/block.yaml create mode 100644 types/gloas/execution_payload_bid.yaml create mode 100644 types/gloas/payload_attestations.yaml diff --git a/apis/beacon/blocks/blocks.v2.yaml b/apis/beacon/blocks/blocks.v2.yaml index 7019e0d5..ef4eb0a0 100644 --- a/apis/beacon/blocks/blocks.v2.yaml +++ b/apis/beacon/blocks/blocks.v2.yaml @@ -11,7 +11,7 @@ post: The beacon node is also expected to integrate the block into the state, but may broadcast it before doing so, so as to aid timely delivery of the block. Should the block fail full validation, a separate success response code (202) is used to indicate that the block was - successfully broadcast but failed integration. After Deneb, this additionally instructs + successfully broadcast but failed integration. After Deneb and before Gloas, this additionally instructs the beacon node to broadcast all given blobs. The broadcast behaviour may be adjusted via the `broadcast_validation` query parameter. parameters: @@ -49,6 +49,7 @@ post: application/json: schema: anyOf: + - $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Gloas.SignedBeaconBlock" - $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Fulu.SignedBlockContents" - $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Electra.SignedBlockContents" - $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Deneb.SignedBlockContents" diff --git a/apis/validator/block.v3.yaml b/apis/validator/block.v3.yaml index a581d463..e5bf25ac 100644 --- a/apis/validator/block.v3.yaml +++ b/apis/validator/block.v3.yaml @@ -5,13 +5,13 @@ get: operationId: "produceBlockV3" summary: "Produce a new block, without signature." description: | - Requests a beacon node to produce a valid block, which can then be signed by a validator. The - returned block may be blinded or unblinded, depending on the current state of the network as - decided by the execution and beacon nodes. + Requests a beacon node to produce a valid block, which can then be signed by a validator. - The beacon node must return an unblinded block if it obtains the execution payload from its - paired execution node. It must only return a blinded block if it obtains the execution payload - header from an MEV relay. + Post-gloas, proposers submit execution payload + bids rather than full execution payloads, so there is no longer a concept of blinded or unblinded blocks. Builders release the payload later. For pre-Gloas forks, the returned block may be blinded or unblinded, depending on the current + state of the network as decided by the execution and beacon nodes. The beacon node returns an + unblinded block if it obtains the execution payload from its paired execution node, or a + blinded block if it obtains the execution payload header from an MEV relay. Metadata in the response indicates the type of block produced, and the supported types of block will be added to as forks progress. @@ -83,36 +83,51 @@ get: content: application/json: schema: - title: ProduceBlockV3Response - type: object - required: [version, execution_payload_blinded, execution_payload_value, consensus_block_value, data] - properties: - version: - type: string - enum: [phase0, altair, bellatrix, capella, deneb, electra, fulu] - example: "electra" - execution_payload_blinded: - type: boolean - example: false - execution_payload_value: - type: string - example: "12345" - consensus_block_value: - type: string - example: "12345" - data: - anyOf: - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Fulu.BlockContents" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Electra.BlockContents" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Electra.BlindedBeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Deneb.BlockContents" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Deneb.BlindedBeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Capella.BeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Capella.BlindedBeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Bellatrix.BeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Bellatrix.BlindedBeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Altair.BeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Phase0.BeaconBlock" + oneOf: + - title: "ProduceBlockV3Response (Gloas)" + type: object + required: [version, data, consensus_block_value] + properties: + version: + type: string + enum: [gloas] + example: "gloas" + consensus_block_value: + type: string + example: "12345" + description: "Consensus rewards for this block in Wei" + data: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.BeaconBlock" + - title: "ProduceBlockV3Response (Pre-Gloas)" + type: object + required: [version, data, consensus_block_value] + properties: + version: + type: string + enum: [phase0, altair, bellatrix, capella, deneb, electra, fulu] + example: "electra" + execution_payload_blinded: + type: boolean + example: false + execution_payload_value: + type: string + example: "12345" + consensus_block_value: + type: string + example: "12345" + data: + anyOf: + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Fulu.BlockContents" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Electra.BlockContents" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Electra.BlindedBeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Deneb.BlockContents" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Deneb.BlindedBeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Capella.BeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Capella.BlindedBeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Bellatrix.BeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Bellatrix.BlindedBeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Altair.BeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Phase0.BeaconBlock" application/octet-stream: schema: description: "SSZ serialized block or blinded block bytes. Use Accept header to choose this response type, version string is sent in header `Eth-Consensus-Version` and block type in `Eth-Blinded-Payload`." diff --git a/beacon-node-oapi.yaml b/beacon-node-oapi.yaml index 2bd511f2..36f134f3 100644 --- a/beacon-node-oapi.yaml +++ b/beacon-node-oapi.yaml @@ -333,8 +333,8 @@ components: $ref: './types/bellatrix/block.yaml#/Bellatrix/SignedBlindedBeaconBlock' ConsensusVersion: type: string - enum: [phase0, altair, bellatrix, capella, deneb, electra, fulu] - example: "electra" + enum: [phase0, altair, bellatrix, capella, deneb, electra, fulu, gloas] + example: "gloas" SignedValidatorRegistration: $ref: './types/registration.yaml#/SignedValidatorRegistration' Capella.BeaconState: @@ -425,6 +425,10 @@ components: $ref: './types/electra/consolidation.yaml#/Electra/PendingConsolidation' Electra.PendingPartialWithdrawal: $ref: './types/electra/withdrawal.yaml#/Electra/PendingPartialWithdrawal' + Gloas.BeaconBlock: + $ref: "./types/gloas/block.yaml#/Gloas/BeaconBlock" + Gloas.SignedBeaconBlock: + $ref: "./types/gloas/block.yaml#/Gloas/SignedBeaconBlock" Fulu.BlockContents: $ref: "./types/fulu/block_contents.yaml#/Fulu/BlockContents" Fulu.SignedBlockContents: @@ -471,21 +475,22 @@ components: headers: Eth-Consensus-Version: description: | - The active consensus version to which the data belongs. Required in response so client can deserialize returned json or ssz data + The active consensus version to which the data belongs. Required in response so client can deserialize returned json or ssz data more effectively. required: true schema: $ref: '#/components/schemas/ConsensusVersion' Eth-Execution-Payload-Blinded: - description: Required in response so client can deserialize returned json or ssz data to the correct object. - required: true + description: "DEPRECATED: Not applicable for gloas fork. For pre-gloas forks, this is required in response so client can deserialize returned json or ssz data to the correct object pre-gloas. Post-gloas, there is no concept of blinded blocks." + required: false schema: type: boolean Eth-Execution-Payload-Value: description: | - Execution payload value in Wei. Required in response so client can determine relative value - of execution payloads. - required: true + DEPRECATED: Not applicable for gloas fork. + For pre-gloas forks, this is the execution payload value in Wei. Required in response so client can determine relative value + of execution payloads pre-gloas. Post-gloas, the ExecutionPayloadBid defines the value of an execution payload. + required: false schema: $ref: './types/primitive.yaml#/Wei' Eth-Consensus-Block-Value: diff --git a/types/gloas/block.yaml b/types/gloas/block.yaml new file mode 100644 index 00000000..defc7bfd --- /dev/null +++ b/types/gloas/block.yaml @@ -0,0 +1,77 @@ +Gloas: + BeaconBlockBodyCommon: + # An abstract object to collect the common fields between the BeaconBlockBody and the BlindedBeaconBlockBody objects + type: object + description: "The [`BeaconBlockBody`](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#beaconblockbody) object from the CL Gloas spec." + required: [randao_reveal, eth1_data, graffiti, proposer_slashings, attester_slashings, attestations, deposits, voluntary_exits, sync_aggregate, bls_to_execution_changes] + properties: + randao_reveal: + allOf: + - $ref: "../primitive.yaml#/Signature" + - description: "The RANDAO reveal value provided by the validator." + eth1_data: + $ref: "../phase0/eth1.yaml#/Phase0/Eth1Data" + graffiti: + $ref: "../primitive.yaml#/Graffiti" + proposer_slashings: + type: array + items: + $ref: "../phase0/proposer_slashing.yaml#/Phase0/ProposerSlashing" + attester_slashings: + type: array + items: + $ref: "../electra/attester_slashing.yaml#/Electra/AttesterSlashing" + attestations: + type: array + items: + $ref: "../electra/attestation.yaml#/Electra/Attestation" + deposits: + type: array + items: + $ref: "../phase0/deposit.yaml#/Phase0/Deposit" + voluntary_exits: + type: array + items: + $ref: "../phase0/voluntary_exit.yaml#/Phase0/SignedVoluntaryExit" + sync_aggregate: + $ref: "../altair/sync_aggregate.yaml#/Altair/SyncAggregate" + bls_to_execution_changes: + type: array + items: + $ref: "../capella/bls_to_execution_change.yaml#/Capella/SignedBLSToExecutionChange" + + BeaconBlockBody: + allOf: + - $ref: "#/Gloas/BeaconBlockBodyCommon" + - type: object + required: [signed_execution_payload_bid, payload_attestations] + properties: + signed_execution_payload_bid: + $ref: "./execution_payload_bid.yaml#/Gloas/SignedExecutionPayloadBid" + payload_attestations: + type: array + description: "Array of payload attestations from gloas." + items: + $ref: "./payload_attestations.yaml#/Gloas/PayloadAttestation" + minItems: 0 + maxItems: 4 + + BeaconBlock: + description: "The [`BeaconBlock`](https://github.com/ethereum/consensus-specs/blob/v1.5.0/specs/phase0/beacon-chain.md#beaconblock) object from the CL Gloas spec." + allOf: + - $ref: "../altair/block.yaml#/Altair/BeaconBlockCommon" + - type: object + required: [body] + properties: + body: + $ref: "#/Gloas/BeaconBlockBody" + + SignedBeaconBlock: + type: object + description: "The [`SignedBeaconBlock`](https://github.com/ethereum/consensus-specs/blob/v1.5.0/specs/phase0/beacon-chain.md#signedbeaconblock) object envelope from the CL Gloas spec." + required: [message, signature] + properties: + message: + $ref: "#/Gloas/BeaconBlock" + signature: + $ref: "../primitive.yaml#/Signature" diff --git a/types/gloas/execution_payload_bid.yaml b/types/gloas/execution_payload_bid.yaml new file mode 100644 index 00000000..771d2d77 --- /dev/null +++ b/types/gloas/execution_payload_bid.yaml @@ -0,0 +1,34 @@ +Gloas: + ExecutionPayloadBid: + type: object + description: "The [ExecutionPayloadBid](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#executionpayloadbid) object from the CL gloas spec." + required: [parent_block_hash, parent_block_root, block_hash, fee_recipient, gas_limit, builder_index, slot, value, blob_kzg_commitments_root] + properties: + parent_block_hash: + $ref: "../primitive.yaml#/Root" + parent_block_root: + $ref: "../primitive.yaml#/Root" + block_hash: + $ref: "../primitive.yaml#/Root" + fee_recipient: + $ref: "../primitive.yaml#/ExecutionAddress" + gas_limit: + $ref: "../primitive.yaml#/Uint64" + builder_index: + $ref: "../primitive.yaml#/Uint64" + slot: + $ref: "../primitive.yaml#/Uint64" + value: + $ref: "../primitive.yaml#/Gwei" + blob_kzg_commitments_root: + $ref: "../primitive.yaml#/Root" + + SignedExecutionPayloadBid: + type: object + description: "The [SignedExecutionPayloadBid](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#signedexecutionpayloadbid) object from the CL gloas spec." + required: [message, signature] + properties: + message: + $ref: "#/Gloas/ExecutionPayloadBid" + signature: + $ref: "../primitive.yaml#/Signature" diff --git a/types/gloas/payload_attestations.yaml b/types/gloas/payload_attestations.yaml new file mode 100644 index 00000000..80f654a0 --- /dev/null +++ b/types/gloas/payload_attestations.yaml @@ -0,0 +1,28 @@ +Gloas: + PayloadAttestation: + type: object + description: "The [PayloadAttestation](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#payloadattestation) object from the CL gloas spec." + required: [aggregation_bits, data, signature] + properties: + aggregation_bits: + $ref: "../primitive.yaml#/BitList" + data: + $ref: "#/Gloas/PayloadAttestationData" + signature: + $ref: "../primitive.yaml#/Signature" + + PayloadAttestationData: + type: object + description: "The [PayloadAttestationData](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#payloadattestationdata) object from the CL gloas spec." + required: [beacon_block_root, slot, payload_present, blob_data_available] + properties: + beacon_block_root: + $ref: "../primitive.yaml#/Root" + slot: + $ref: "../primitive.yaml#/Uint64" + payload_present: + type: boolean + description: "Whether the execution payload is present" + blob_data_available: + type: boolean + description: "Whether blob data is available" From d0ba3ba7c0564fa5997fd79fa56764f7f28d2775 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Thu, 4 Sep 2025 14:24:02 -0700 Subject: [PATCH 02/17] epbs execution_payload_bid get and post --- CHANGES.md | 4 ++ apis/beacon/execution_payload/bid.yaml | 41 ++++++++++++++ apis/validator/execution_payload_bid.yaml | 69 +++++++++++++++++++++++ beacon-node-oapi.yaml | 8 +++ wordlist.txt | 1 + 5 files changed, 123 insertions(+) create mode 100644 apis/beacon/execution_payload/bid.yaml create mode 100644 apis/validator/execution_payload_bid.yaml diff --git a/CHANGES.md b/CHANGES.md index 6d07d69a..1251bcc6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,10 @@ There are likely to be descriptions etc outside of the list below, but new query | [#537](https://github.com/ethereum/beacon-APIs/pull/537) `GET /eth/v1/debug/beacon/data_column_sidecars/{block_id}` added | | | | | | | [#539](https://github.com/ethereum/beacon-APIs/pull/539) `GET /eth/v1/beacon/states/{state_id}/proposer_lookahead` added | | | | | | | [#546](https://github.com/ethereum/beacon-APIs/pull/546) `GET /eth/v1/beacon/blobs/{block_id}` added | | | | | | +| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/execution_payload_bid/{slot}` added | | | | | | +| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/execution_payload_bid` added | | | | | | +| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v3/validator/blocks/{slot}` updated | | | | | | +| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v2/beacon/blocks` updated | | | | | | The Following are no longer in the Standard API, removed since the latest version. diff --git a/apis/beacon/execution_payload/bid.yaml b/apis/beacon/execution_payload/bid.yaml new file mode 100644 index 00000000..96dec67f --- /dev/null +++ b/apis/beacon/execution_payload/bid.yaml @@ -0,0 +1,41 @@ +post: + operationId: publishExecutionPayloadBid + summary: Publish signed execution payload bid + description: | + Instructs the beacon node to broadcast a signed execution payload bid to the beacon network, + to be gossiped for potential inclusion in block building. A success response indicates + that the bid passed gossip validation and was successfully broadcast onto the network. + tags: + - Beacon + requestBody: + description: "The `SignedExecutionPayloadBid` object to be broadcast." + required: true + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.SignedExecutionPayloadBid" + application/octet-stream: + schema: + description: "SSZ serialized SignedExecutionPayloadBid bytes. Use Content-Type header to specify this format" + responses: + "200": + description: "The bid was validated successfully and has been broadcast." + content: + text/plain: + schema: + type: string + "400": + description: "The SignedExecutionPayloadBid object is invalid or failed gossip validation" + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 400 + message: "Invalid signed execution payload bid" + "406": + $ref: "../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" + "415": + $ref: "../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType" + "500": + $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" diff --git a/apis/validator/execution_payload_bid.yaml b/apis/validator/execution_payload_bid.yaml new file mode 100644 index 00000000..b7f14b1a --- /dev/null +++ b/apis/validator/execution_payload_bid.yaml @@ -0,0 +1,69 @@ +get: + operationId: getExecutionPayloadBid + summary: Get execution payload bid + description: | + Retrieves execution payload bid for a given slot and builder. Depending on `Accept` header, it can be returned either as json or as bytes serialized by SSZ. + tags: + - Validator + parameters: + - name: slot + in: path + required: true + description: "Slot for which the execution payload bid is requested. Must be current slot or next slot." + schema: + $ref: '../../beacon-node-oapi.yaml#/components/schemas/Uint64' + - name: builder_index + in: path + required: true + description: "Index of the builder from which the execution payload bid is requested." + schema: + $ref: '../../beacon-node-oapi.yaml#/components/schemas/Uint64' + responses: + "200": + description: "Successful response" + headers: + Eth-Consensus-Version: + $ref: '../../beacon-node-oapi.yaml#/components/headers/Eth-Consensus-Version' + required: true + content: + application/json: + schema: + title: GetExecutionPayloadBidResponse + type: object + required: [data] + properties: + version: + type: string + enum: [gloas] + example: "gloas" + execution_optimistic: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ExecutionOptimistic" + finalized: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Finalized" + data: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.ExecutionPayloadBid" + application/octet-stream: + schema: + description: "SSZ serialized execution payload bid bytes. Use Accept header to choose this response type" + "400": + description: "The slot supplied could not be parsed or is invalid" + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 400 + message: "Invalid slot: must be current slot or next slot" + "404": + description: "Execution payload bid not available for the requested slot and builder" + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 404 + message: "Execution payload bid not available for slot and builder" + "406": + $ref: "../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" + "500": + $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" diff --git a/beacon-node-oapi.yaml b/beacon-node-oapi.yaml index 36f134f3..85a7ec6e 100644 --- a/beacon-node-oapi.yaml +++ b/beacon-node-oapi.yaml @@ -104,6 +104,8 @@ paths: $ref: "./apis/beacon/blocks/blinded_blocks.v2.yaml" /eth/v2/beacon/blocks: $ref: "./apis/beacon/blocks/blocks.v2.yaml" + /eth/v1/beacon/execution_payload_bid: + $ref: "./apis/beacon/execution_payload/bid.yaml" /eth/v2/beacon/blocks/{block_id}: $ref: "./apis/beacon/blocks/block.v2.yaml" /eth/v1/beacon/blocks/{block_id}/root: @@ -206,6 +208,8 @@ paths: $ref: "./apis/validator/register_validator.yaml" /eth/v1/validator/liveness/{epoch}: $ref: "./apis/validator/liveness.yaml" + /eth/v1/validator/execution_payload_bid/{slot}/{builder_index}: + $ref: "./apis/validator/execution_payload_bid.yaml" /eth/v1/events: $ref: "./apis/eventstream/index.yaml" @@ -429,6 +433,10 @@ components: $ref: "./types/gloas/block.yaml#/Gloas/BeaconBlock" Gloas.SignedBeaconBlock: $ref: "./types/gloas/block.yaml#/Gloas/SignedBeaconBlock" + Gloas.ExecutionPayloadBid: + $ref: "./types/gloas/execution_payload_bid.yaml#/Gloas/ExecutionPayloadBid" + Gloas.SignedExecutionPayloadBid: + $ref: "./types/gloas/execution_payload_bid.yaml#/Gloas/SignedExecutionPayloadBid" Fulu.BlockContents: $ref: "./types/fulu/block_contents.yaml#/Fulu/BlockContents" Fulu.SignedBlockContents: diff --git a/wordlist.txt b/wordlist.txt index d4ac324c..d802300c 100644 --- a/wordlist.txt +++ b/wordlist.txt @@ -37,3 +37,4 @@ KZGProofs KZGCommitmentInclusionProof LMD fulu +gloas From 953fd2920aefc92aa33898a7cf134fdb5b8596eb Mon Sep 17 00:00:00 2001 From: shane-moore Date: Thu, 4 Sep 2025 19:13:06 -0700 Subject: [PATCH 03/17] epbs execution_payload_envelope get and post --- CHANGES.md | 4 +- apis/beacon/execution_payload/envelope.yaml | 41 +++++++++++ .../validator/execution_payload_envelope.yaml | 71 +++++++++++++++++++ beacon-node-oapi.yaml | 8 +++ types/gloas/execution_payload_envelope.yaml | 45 ++++++++++++ 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 apis/beacon/execution_payload/envelope.yaml create mode 100644 apis/validator/execution_payload_envelope.yaml create mode 100644 types/gloas/execution_payload_envelope.yaml diff --git a/CHANGES.md b/CHANGES.md index 1251bcc6..faa42750 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,8 +12,10 @@ There are likely to be descriptions etc outside of the list below, but new query | [#537](https://github.com/ethereum/beacon-APIs/pull/537) `GET /eth/v1/debug/beacon/data_column_sidecars/{block_id}` added | | | | | | | [#539](https://github.com/ethereum/beacon-APIs/pull/539) `GET /eth/v1/beacon/states/{state_id}/proposer_lookahead` added | | | | | | | [#546](https://github.com/ethereum/beacon-APIs/pull/546) `GET /eth/v1/beacon/blobs/{block_id}` added | | | | | | -| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/execution_payload_bid/{slot}` added | | | | | | +| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/execution_payload_bid/{slot}/{builder_index}` added | | | | | | +| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/execution_payload_envelope/{slot}/{builder_index}` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/execution_payload_bid` added | | | | | | +| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/execution_payload_envelope` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v3/validator/blocks/{slot}` updated | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v2/beacon/blocks` updated | | | | | | diff --git a/apis/beacon/execution_payload/envelope.yaml b/apis/beacon/execution_payload/envelope.yaml new file mode 100644 index 00000000..d4b8f2ed --- /dev/null +++ b/apis/beacon/execution_payload/envelope.yaml @@ -0,0 +1,41 @@ +post: + operationId: publishExecutionPayloadEnvelope + summary: Publish signed execution payload envelope + description: | + Instructs the beacon node to broadcast a signed execution payload envelope to the beacon network, + to be gossiped for payload validation. A success response (20x) indicates + that the envelope passed gossip validation and was successfully broadcast onto the network. + tags: + - Beacon + requestBody: + description: "The `SignedExecutionPayloadEnvelope` object to be broadcast." + required: true + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.SignedExecutionPayloadEnvelope" + application/octet-stream: + schema: + description: "SSZ serialized SignedExecutionPayloadEnvelope bytes. Use Content-Type header to specify this format" + responses: + "200": + description: "The envelope was validated successfully and has been broadcast." + content: + text/plain: + schema: + type: string + "400": + description: "The SignedExecutionPayloadEnvelope object is invalid or failed gossip validation" + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 400 + message: "Invalid signed execution payload envelope" + "406": + $ref: "../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" + "415": + $ref: "../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType" + "500": + $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" diff --git a/apis/validator/execution_payload_envelope.yaml b/apis/validator/execution_payload_envelope.yaml new file mode 100644 index 00000000..14a451a3 --- /dev/null +++ b/apis/validator/execution_payload_envelope.yaml @@ -0,0 +1,71 @@ +get: + operationId: getExecutionPayloadEnvelope + summary: Get execution payload envelope + description: | + Retrieves execution payload envelope for a given slot and builder. The envelope contains the full + execution payload along with associated metadata. Depending on `Accept` header, it can be returned + either as json or as bytes serialized by SSZ. + tags: + - Validator + parameters: + - name: slot + in: path + required: true + description: "Slot for which the execution payload envelope is requested." + schema: + $ref: '../../beacon-node-oapi.yaml#/components/schemas/Uint64' + - name: builder_index + in: path + required: true + description: "Index of the builder from which the execution payload envelope is requested." + schema: + $ref: '../../beacon-node-oapi.yaml#/components/schemas/Uint64' + responses: + "200": + description: "Successful response" + headers: + Eth-Consensus-Version: + $ref: '../../beacon-node-oapi.yaml#/components/headers/Eth-Consensus-Version' + required: true + content: + application/json: + schema: + title: GetExecutionPayloadEnvelopeResponse + type: object + required: [data] + properties: + version: + type: string + enum: [gloas] + example: "gloas" + execution_optimistic: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ExecutionOptimistic" + finalized: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Finalized" + data: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.ExecutionPayloadEnvelope" + application/octet-stream: + schema: + description: "SSZ serialized execution payload envelope bytes. Use Accept header to choose this response type" + "400": + description: "Invalid execution payload envelope request" + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 400 + message: "Invalid slot or builder_index parameter" + "404": + description: "Execution payload envelope not available for the requested slot and builder" + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 404 + message: "Execution payload envelope not available for slot and builder" + "406": + $ref: "../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" + "500": + $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" diff --git a/beacon-node-oapi.yaml b/beacon-node-oapi.yaml index 85a7ec6e..78b3bbd9 100644 --- a/beacon-node-oapi.yaml +++ b/beacon-node-oapi.yaml @@ -106,6 +106,8 @@ paths: $ref: "./apis/beacon/blocks/blocks.v2.yaml" /eth/v1/beacon/execution_payload_bid: $ref: "./apis/beacon/execution_payload/bid.yaml" + /eth/v1/beacon/execution_payload_envelope: + $ref: "./apis/beacon/execution_payload/envelope.yaml" /eth/v2/beacon/blocks/{block_id}: $ref: "./apis/beacon/blocks/block.v2.yaml" /eth/v1/beacon/blocks/{block_id}/root: @@ -210,6 +212,8 @@ paths: $ref: "./apis/validator/liveness.yaml" /eth/v1/validator/execution_payload_bid/{slot}/{builder_index}: $ref: "./apis/validator/execution_payload_bid.yaml" + /eth/v1/validator/execution_payload_envelope/{slot}/{builder_index}: + $ref: "./apis/validator/execution_payload_envelope.yaml" /eth/v1/events: $ref: "./apis/eventstream/index.yaml" @@ -437,6 +441,10 @@ components: $ref: "./types/gloas/execution_payload_bid.yaml#/Gloas/ExecutionPayloadBid" Gloas.SignedExecutionPayloadBid: $ref: "./types/gloas/execution_payload_bid.yaml#/Gloas/SignedExecutionPayloadBid" + Gloas.ExecutionPayloadEnvelope: + $ref: "./types/gloas/execution_payload_envelope.yaml#/Gloas/ExecutionPayloadEnvelope" + Gloas.SignedExecutionPayloadEnvelope: + $ref: "./types/gloas/execution_payload_envelope.yaml#/Gloas/SignedExecutionPayloadEnvelope" Fulu.BlockContents: $ref: "./types/fulu/block_contents.yaml#/Fulu/BlockContents" Fulu.SignedBlockContents: diff --git a/types/gloas/execution_payload_envelope.yaml b/types/gloas/execution_payload_envelope.yaml new file mode 100644 index 00000000..8b74464c --- /dev/null +++ b/types/gloas/execution_payload_envelope.yaml @@ -0,0 +1,45 @@ +Gloas: + ExecutionPayloadEnvelope: + type: object + description: "The [ExecutionPayloadEnvelope](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#executionpayloadenvelope) object from the CL gloas spec." + required: [payload, execution_requests, builder_index, beacon_block_root, slot, blob_kzg_commitments, state_root] + properties: + payload: + $ref: "../deneb/execution_payload.yaml#/Deneb/ExecutionPayload" + execution_requests: + $ref: "../electra/execution_requests.yaml#/Electra/ExecutionRequests" + builder_index: + allOf: + - $ref: "../primitive.yaml#/Uint64" + - description: "Index of the builder that created this execution payload" + beacon_block_root: + allOf: + - $ref: "../primitive.yaml#/Root" + - description: "Root of the beacon block for this payload" + slot: + allOf: + - $ref: "../primitive.yaml#/Uint64" + - description: "Slot number for this execution payload" + blob_kzg_commitments: + type: array + items: + $ref: "../primitive.yaml#/KZGCommitment" + minItems: 0 + maxItems: 4096 + description: "KZG commitments for the blobs included in this execution payload" + state_root: + allOf: + - $ref: "../primitive.yaml#/Root" + - description: "Beacon state root after executing this payload" + + SignedExecutionPayloadEnvelope: + type: object + description: "The [SignedExecutionPayloadEnvelope](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#signedexecutionpayloadenvelope) object from the CL gloas spec." + required: [message, signature] + properties: + message: + $ref: "#/Gloas/ExecutionPayloadEnvelope" + signature: + allOf: + - $ref: "../primitive.yaml#/BLSSignature" + - description: "BLS signature of the execution payload envelope" From a1d3accdd5e0935e987a8dca5adec43b9a7f8433 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Fri, 5 Sep 2025 11:17:43 -0700 Subject: [PATCH 04/17] new epbs ptc assignment POST --- CHANGES.md | 1 + apis/validator/duties/ptc.yaml | 71 ++++++++++++++++++++++++++++++++++ beacon-node-oapi.yaml | 4 ++ types/duty.yaml | 13 +++++++ 4 files changed, 89 insertions(+) create mode 100644 apis/validator/duties/ptc.yaml diff --git a/CHANGES.md b/CHANGES.md index faa42750..f4da085b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ There are likely to be descriptions etc outside of the list below, but new query | [#546](https://github.com/ethereum/beacon-APIs/pull/546) `GET /eth/v1/beacon/blobs/{block_id}` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/execution_payload_bid/{slot}/{builder_index}` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/execution_payload_envelope/{slot}/{builder_index}` 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_bid` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/execution_payload_envelope` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v3/validator/blocks/{slot}` updated | | | | | | diff --git a/apis/validator/duties/ptc.yaml b/apis/validator/duties/ptc.yaml new file mode 100644 index 00000000..c4708b78 --- /dev/null +++ b/apis/validator/duties/ptc.yaml @@ -0,0 +1,71 @@ +post: + tags: + - Validator + summary: "Get PTC duties" + operationId: "getPtcDuties" + description: "Requests the beacon node to provide a set of Payload Timeliness Committee (PTC) duties, + which should be performed by validators, for a particular epoch. + + Duties should only need to be checked once per epoch, + however a chain reorganization (of > MIN_SEED_LOOKAHEAD epochs) could occur, resulting in a change of duties. For full safety, + you should monitor head events and confirm the dependent root in this response matches: + + - event.previous_duty_dependent_root when `compute_epoch_at_slot(event.slot) == epoch` + + - event.current_duty_dependent_root when `compute_epoch_at_slot(event.slot) + 1 == epoch` + + - event.block otherwise + + + The dependent_root value is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch - 1) - 1)` + or the genesis block root in the case of underflow." + parameters: + - name: epoch + description: "Should only be allowed 1 epoch ahead" + in: path + required: true + schema: + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Uint64" + requestBody: + description: "An array of the validator indices for which to obtain the duties." + required: true + content: + application/json: + schema: + title: GetPtcDutiesBody + type: array + minItems: 1 + uniqueItems: true + items: + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Uint64" + responses: + "200": + description: Success response + content: + application/json: + schema: + title: GetPtcDutiesResponse + type: object + required: [dependent_root, execution_optimistic, data] + properties: + dependent_root: + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/DependentRoot" + execution_optimistic: + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/ExecutionOptimistic" + data: + type: array + items: + $ref: '../../../beacon-node-oapi.yaml#/components/schemas/PtcDuty' + "400": + description: "Invalid epoch or index" + content: + application/json: + schema: + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 400 + message: "Invalid epoch: -2" + "500": + $ref: "../../../beacon-node-oapi.yaml#/components/responses/InternalError" + "503": + $ref: "../../../beacon-node-oapi.yaml#/components/responses/CurrentlySyncing" diff --git a/beacon-node-oapi.yaml b/beacon-node-oapi.yaml index 78b3bbd9..65d30bda 100644 --- a/beacon-node-oapi.yaml +++ b/beacon-node-oapi.yaml @@ -184,6 +184,8 @@ paths: $ref: "./apis/validator/duties/proposer.yaml" /eth/v1/validator/duties/sync/{epoch}: $ref: "./apis/validator/duties/sync.yaml" + /eth/v1/validator/duties/ptc/{epoch}: + $ref: "./apis/validator/duties/ptc.yaml" /eth/v3/validator/blocks/{slot}: $ref: "./apis/validator/block.v3.yaml" /eth/v1/validator/attestation_data: @@ -237,6 +239,8 @@ components: $ref: './types/duty.yaml#/AttesterDuty' ProposerDuty: $ref: './types/duty.yaml#/ProposerDuty' + PtcDuty: + $ref: './types/duty.yaml#/PtcDuty' Altair.SyncDuty: $ref: './types/duty.yaml#/Altair/SyncDuty' BeaconCommitteeSelection: diff --git a/types/duty.yaml b/types/duty.yaml index f9ff9314..eae60438 100644 --- a/types/duty.yaml +++ b/types/duty.yaml @@ -52,3 +52,16 @@ Altair: minItems: 1 items: $ref: './primitive.yaml#/Uint64' + +PtcDuty: + type: object + required: [pubkey, validator_index, slot] + properties: + pubkey: + $ref: './primitive.yaml#/Pubkey' + validator_index: + $ref: "./primitive.yaml#/Uint64" + description: "Index of validator in validator registry." + slot: + $ref: "./primitive.yaml#/Uint64" + description: "The slot at which the validator must perform PTC duties." From 2953725a5971f86d1d4f3cc7eb73e9c27817c9c4 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Fri, 5 Sep 2025 12:44:24 -0700 Subject: [PATCH 05/17] new epbs payload_attestations get and post --- CHANGES.md | 2 + apis/beacon/pool/payload_attestations.yaml | 83 ++++++++++++++++++++ apis/validator/duties/ptc.yaml | 1 + apis/validator/payload_attestation_data.yaml | 43 ++++++++++ beacon-node-oapi.yaml | 10 +++ types/gloas/block.yaml | 2 +- types/gloas/payload_attestation.yaml | 48 +++++++++++ types/gloas/payload_attestations.yaml | 28 ------- 8 files changed, 188 insertions(+), 29 deletions(-) create mode 100644 apis/beacon/pool/payload_attestations.yaml create mode 100644 apis/validator/payload_attestation_data.yaml create mode 100644 types/gloas/payload_attestation.yaml delete mode 100644 types/gloas/payload_attestations.yaml diff --git a/CHANGES.md b/CHANGES.md index f4da085b..af6c5471 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,9 +14,11 @@ There are likely to be descriptions etc outside of the list below, but new query | [#546](https://github.com/ethereum/beacon-APIs/pull/546) `GET /eth/v1/beacon/blobs/{block_id}` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/execution_payload_bid/{slot}/{builder_index}` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/execution_payload_envelope/{slot}/{builder_index}` added | | | | | | +| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v1/validator/payload_attestation_data` 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_bid` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/execution_payload_envelope` added | | | | | | +| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/pool/payload_attestations` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v3/validator/blocks/{slot}` updated | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v2/beacon/blocks` updated | | | | | | diff --git a/apis/beacon/pool/payload_attestations.yaml b/apis/beacon/pool/payload_attestations.yaml new file mode 100644 index 00000000..3026a9d0 --- /dev/null +++ b/apis/beacon/pool/payload_attestations.yaml @@ -0,0 +1,83 @@ +get: + operationId: getPoolPayloadAttestations + summary: Get payload attestations from operations pool + description: Retrieves payload attestations known by the node but not necessarily incorporated into any block + parameters: + - name: slot + in: query + required: false + schema: + $ref: '../../../beacon-node-oapi.yaml#/components/schemas/Uint64' + tags: + - Beacon + responses: + "200": + description: Successful response + content: + application/json: + schema: + title: GetPoolPayloadAttestationsResponse + type: object + required: [version, data] + properties: + version: + type: string + enum: [gloas] + example: "gloas" + data: + type: array + items: + $ref: '../../../beacon-node-oapi.yaml#/components/schemas/Gloas.PayloadAttestationMessage' + "400": + description: "The slot could not be parsed" + content: + application/json: + schema: + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 400 + message: "Invalid slot parameter" + "500": + $ref: '../../../beacon-node-oapi.yaml#/components/responses/InternalError' + +post: + operationId: submitPayloadAttestationMessage + summary: Submit payload attestation message + description: | + Submits a payload attestation message to the beacon node. + + The beacon node will validate the payload attestation message according to the gossip validation rules + and, if valid, store it in the pool and broadcast it globally to the network. + + A success response indicates that the payload attestation message passed validation and was + successfully stored and broadcast. + tags: + - Beacon + - ValidatorRequiredApi + requestBody: + description: "The PayloadAttestationMessage object to be submitted." + required: true + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.PayloadAttestationMessage" + application/octet-stream: + schema: + description: "SSZ serialized PayloadAttestationMessage bytes. Use Content-Type header to indicate that SSZ data is contained in the request body." + responses: + "200": + description: "The payload attestation message was stored in the pool and has been broadcast." + content: + text/plain: + schema: + type: string + "400": + description: "The PayloadAttestationMessage object is invalid or failed gossip validation" + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + "415": + $ref: "../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType" + "500": + $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" diff --git a/apis/validator/duties/ptc.yaml b/apis/validator/duties/ptc.yaml index c4708b78..002936ac 100644 --- a/apis/validator/duties/ptc.yaml +++ b/apis/validator/duties/ptc.yaml @@ -1,6 +1,7 @@ post: tags: - Validator + - ValidatorRequiredApi summary: "Get PTC duties" operationId: "getPtcDuties" description: "Requests the beacon node to provide a set of Payload Timeliness Committee (PTC) duties, diff --git a/apis/validator/payload_attestation_data.yaml b/apis/validator/payload_attestation_data.yaml new file mode 100644 index 00000000..0932dc2e --- /dev/null +++ b/apis/validator/payload_attestation_data.yaml @@ -0,0 +1,43 @@ +get: + tags: + - ValidatorRequiredApi + - Validator + operationId: "producePayloadAttestationData" + summary: "Produce payload attestation data" + description: | + Requests that the beacon node produce a PayloadAttestationData. + + This endpoint is used by PTC validators to obtain the data structure they need to attest to + regarding payload presence and blob data availability for a specific slot. + + A 503 error must be returned if the beacon node is currently syncing. + parameters: + - name: slot + in: query + required: true + description: "The slot for which payload attestation data should be created." + schema: + $ref: ../../beacon-node-oapi.yaml#/components/schemas/Uint64 + responses: + "200": + description: "Success response" + content: + application/json: + schema: + title: ProducePayloadAttestationDataResponse + type: object + required: [data] + properties: + data: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.PayloadAttestationData" + application/octet-stream: + schema: + description: "SSZ serialized PayloadAttestationData bytes. Use Accept header to choose this response type" + "400": + $ref: '../../beacon-node-oapi.yaml#/components/responses/InvalidRequest' + "406": + $ref: '../../beacon-node-oapi.yaml#/components/responses/NotAcceptable' + "500": + $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" + "503": + $ref: "../../beacon-node-oapi.yaml#/components/responses/CurrentlySyncing" diff --git a/beacon-node-oapi.yaml b/beacon-node-oapi.yaml index 65d30bda..c15d68e5 100644 --- a/beacon-node-oapi.yaml +++ b/beacon-node-oapi.yaml @@ -138,6 +138,8 @@ paths: $ref: "./apis/beacon/light_client/optimistic_update.yaml" /eth/v2/beacon/pool/attestations: $ref: "./apis/beacon/pool/attestations.v2.yaml" + /eth/v1/beacon/pool/payload_attestations: + $ref: "./apis/beacon/pool/payload_attestations.yaml" /eth/v2/beacon/pool/attester_slashings: $ref: "./apis/beacon/pool/attester_slashings.v2.yaml" /eth/v1/beacon/pool/proposer_slashings: @@ -190,6 +192,8 @@ paths: $ref: "./apis/validator/block.v3.yaml" /eth/v1/validator/attestation_data: $ref: "./apis/validator/attestation_data.yaml" + /eth/v1/validator/payload_attestation_data: + $ref: "./apis/validator/payload_attestation_data.yaml" /eth/v2/validator/aggregate_attestation: $ref: "./apis/validator/aggregate_attestation.v2.yaml" /eth/v2/validator/aggregate_and_proofs: @@ -449,6 +453,12 @@ components: $ref: "./types/gloas/execution_payload_envelope.yaml#/Gloas/ExecutionPayloadEnvelope" Gloas.SignedExecutionPayloadEnvelope: $ref: "./types/gloas/execution_payload_envelope.yaml#/Gloas/SignedExecutionPayloadEnvelope" + Gloas.PayloadAttestationData: + $ref: "./types/gloas/payload_attestation.yaml#/Gloas/PayloadAttestationData" + Gloas.PayloadAttestation: + $ref: "./types/gloas/payload_attestation.yaml#/Gloas/PayloadAttestation" + Gloas.PayloadAttestationMessage: + $ref: "./types/gloas/payload_attestation.yaml#/Gloas/PayloadAttestationMessage" Fulu.BlockContents: $ref: "./types/fulu/block_contents.yaml#/Fulu/BlockContents" Fulu.SignedBlockContents: diff --git a/types/gloas/block.yaml b/types/gloas/block.yaml index defc7bfd..a849a691 100644 --- a/types/gloas/block.yaml +++ b/types/gloas/block.yaml @@ -52,7 +52,7 @@ Gloas: type: array description: "Array of payload attestations from gloas." items: - $ref: "./payload_attestations.yaml#/Gloas/PayloadAttestation" + $ref: "./payload_attestation.yaml#/Gloas/PayloadAttestation" minItems: 0 maxItems: 4 diff --git a/types/gloas/payload_attestation.yaml b/types/gloas/payload_attestation.yaml new file mode 100644 index 00000000..435a5832 --- /dev/null +++ b/types/gloas/payload_attestation.yaml @@ -0,0 +1,48 @@ +Gloas: + PayloadAttestationData: + type: object + description: "The [`PayloadAttestationData`](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#payloadattestationdata) object from the CL Gloas spec." + required: [beacon_block_root, slot, payload_present, blob_data_available] + properties: + beacon_block_root: + allOf: + - $ref: "../primitive.yaml#/Root" + - description: "Hash tree root of the beacon block associated with this ptc attestation" + slot: + allOf: + - $ref: "../primitive.yaml#/Uint64" + - description: "The slot for which the payload attestation is being made" + payload_present: + type: boolean + description: "True if a SignedExecutionPayloadEnvelope has been seen referencing this block" + blob_data_available: + type: boolean + description: "True if blob data is available for this block" + + PayloadAttestation: + type: object + description: "The [PayloadAttestation](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#payloadattestation) object from the CL gloas spec." + required: [aggregation_bits, data, signature] + properties: + aggregation_bits: + $ref: "../primitive.yaml#/BitList" + data: + $ref: "#/Gloas/PayloadAttestationData" + signature: + $ref: "../primitive.yaml#/Signature" + + PayloadAttestationMessage: + type: object + description: "The [`PayloadAttestationMessage`](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#payloadattestationmessage) object from the CL Gloas spec." + required: [validator_index, data, signature] + properties: + validator_index: + allOf: + - $ref: "../primitive.yaml#/Uint64" + - description: "Index of the validator submitting the payload attestation" + data: + $ref: "#/Gloas/PayloadAttestationData" + signature: + allOf: + - $ref: "../primitive.yaml#/Signature" + - description: "BLS signature of the payload attestation data" diff --git a/types/gloas/payload_attestations.yaml b/types/gloas/payload_attestations.yaml deleted file mode 100644 index 80f654a0..00000000 --- a/types/gloas/payload_attestations.yaml +++ /dev/null @@ -1,28 +0,0 @@ -Gloas: - PayloadAttestation: - type: object - description: "The [PayloadAttestation](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#payloadattestation) object from the CL gloas spec." - required: [aggregation_bits, data, signature] - properties: - aggregation_bits: - $ref: "../primitive.yaml#/BitList" - data: - $ref: "#/Gloas/PayloadAttestationData" - signature: - $ref: "../primitive.yaml#/Signature" - - PayloadAttestationData: - type: object - description: "The [PayloadAttestationData](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#payloadattestationdata) object from the CL gloas spec." - required: [beacon_block_root, slot, payload_present, blob_data_available] - properties: - beacon_block_root: - $ref: "../primitive.yaml#/Root" - slot: - $ref: "../primitive.yaml#/Uint64" - payload_present: - type: boolean - description: "Whether the execution payload is present" - blob_data_available: - type: boolean - description: "Whether blob data is available" From b96e7891360579b58807f4456fb221d6156b47d9 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Fri, 5 Sep 2025 14:36:14 -0700 Subject: [PATCH 06/17] small fixes --- apis/beacon/execution_payload/bid.yaml | 10 +++++----- apis/beacon/execution_payload/envelope.yaml | 10 +++++----- apis/beacon/pool/payload_attestations.yaml | 14 +++++++------- apis/validator/duties/ptc.yaml | 2 +- apis/validator/execution_payload_bid.yaml | 9 ++++----- apis/validator/execution_payload_envelope.yaml | 9 ++++----- apis/validator/payload_attestation_data.yaml | 6 +++--- types/gloas/execution_payload_envelope.yaml | 2 +- 8 files changed, 30 insertions(+), 32 deletions(-) diff --git a/apis/beacon/execution_payload/bid.yaml b/apis/beacon/execution_payload/bid.yaml index 96dec67f..27acab68 100644 --- a/apis/beacon/execution_payload/bid.yaml +++ b/apis/beacon/execution_payload/bid.yaml @@ -13,7 +13,7 @@ post: content: application/json: schema: - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.SignedExecutionPayloadBid" + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Gloas.SignedExecutionPayloadBid" application/octet-stream: schema: description: "SSZ serialized SignedExecutionPayloadBid bytes. Use Content-Type header to specify this format" @@ -29,13 +29,13 @@ post: content: application/json: schema: - $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" example: code: 400 message: "Invalid signed execution payload bid" "406": - $ref: "../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" + $ref: "../../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" "415": - $ref: "../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType" + $ref: "../../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType" "500": - $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" + $ref: "../../../beacon-node-oapi.yaml#/components/responses/InternalError" diff --git a/apis/beacon/execution_payload/envelope.yaml b/apis/beacon/execution_payload/envelope.yaml index d4b8f2ed..6c5c1228 100644 --- a/apis/beacon/execution_payload/envelope.yaml +++ b/apis/beacon/execution_payload/envelope.yaml @@ -13,7 +13,7 @@ post: content: application/json: schema: - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.SignedExecutionPayloadEnvelope" + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Gloas.SignedExecutionPayloadEnvelope" application/octet-stream: schema: description: "SSZ serialized SignedExecutionPayloadEnvelope bytes. Use Content-Type header to specify this format" @@ -29,13 +29,13 @@ post: content: application/json: schema: - $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" example: code: 400 message: "Invalid signed execution payload envelope" "406": - $ref: "../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" + $ref: "../../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" "415": - $ref: "../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType" + $ref: "../../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType" "500": - $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" + $ref: "../../../beacon-node-oapi.yaml#/components/responses/InternalError" diff --git a/apis/beacon/pool/payload_attestations.yaml b/apis/beacon/pool/payload_attestations.yaml index 3026a9d0..3bcc47cb 100644 --- a/apis/beacon/pool/payload_attestations.yaml +++ b/apis/beacon/pool/payload_attestations.yaml @@ -7,7 +7,7 @@ get: in: query required: false schema: - $ref: '../../../beacon-node-oapi.yaml#/components/schemas/Uint64' + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Uint64" tags: - Beacon responses: @@ -27,7 +27,7 @@ get: data: type: array items: - $ref: '../../../beacon-node-oapi.yaml#/components/schemas/Gloas.PayloadAttestationMessage' + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Gloas.PayloadAttestationMessage" "400": description: "The slot could not be parsed" content: @@ -38,7 +38,7 @@ get: code: 400 message: "Invalid slot parameter" "500": - $ref: '../../../beacon-node-oapi.yaml#/components/responses/InternalError' + $ref: "../../../beacon-node-oapi.yaml#/components/responses/InternalError" post: operationId: submitPayloadAttestationMessage @@ -60,7 +60,7 @@ post: content: application/json: schema: - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.PayloadAttestationMessage" + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Gloas.PayloadAttestationMessage" application/octet-stream: schema: description: "SSZ serialized PayloadAttestationMessage bytes. Use Content-Type header to indicate that SSZ data is contained in the request body." @@ -76,8 +76,8 @@ post: content: application/json: schema: - $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" "415": - $ref: "../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType" + $ref: "../../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType" "500": - $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" + $ref: "../../../beacon-node-oapi.yaml#/components/responses/InternalError" diff --git a/apis/validator/duties/ptc.yaml b/apis/validator/duties/ptc.yaml index 002936ac..c8691f59 100644 --- a/apis/validator/duties/ptc.yaml +++ b/apis/validator/duties/ptc.yaml @@ -56,7 +56,7 @@ post: data: type: array items: - $ref: '../../../beacon-node-oapi.yaml#/components/schemas/PtcDuty' + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/PtcDuty" "400": description: "Invalid epoch or index" content: diff --git a/apis/validator/execution_payload_bid.yaml b/apis/validator/execution_payload_bid.yaml index b7f14b1a..34901a33 100644 --- a/apis/validator/execution_payload_bid.yaml +++ b/apis/validator/execution_payload_bid.yaml @@ -11,26 +11,25 @@ get: required: true description: "Slot for which the execution payload bid is requested. Must be current slot or next slot." schema: - $ref: '../../beacon-node-oapi.yaml#/components/schemas/Uint64' + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Uint64" - name: builder_index in: path required: true description: "Index of the builder from which the execution payload bid is requested." schema: - $ref: '../../beacon-node-oapi.yaml#/components/schemas/Uint64' + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Uint64" responses: "200": description: "Successful response" headers: Eth-Consensus-Version: - $ref: '../../beacon-node-oapi.yaml#/components/headers/Eth-Consensus-Version' - required: true + $ref: "../../beacon-node-oapi.yaml#/components/headers/Eth-Consensus-Version" content: application/json: schema: title: GetExecutionPayloadBidResponse type: object - required: [data] + required: [version, execution_optimistic, finalized, data] properties: version: type: string diff --git a/apis/validator/execution_payload_envelope.yaml b/apis/validator/execution_payload_envelope.yaml index 14a451a3..d2c86f02 100644 --- a/apis/validator/execution_payload_envelope.yaml +++ b/apis/validator/execution_payload_envelope.yaml @@ -13,26 +13,25 @@ get: required: true description: "Slot for which the execution payload envelope is requested." schema: - $ref: '../../beacon-node-oapi.yaml#/components/schemas/Uint64' + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Uint64" - name: builder_index in: path required: true description: "Index of the builder from which the execution payload envelope is requested." schema: - $ref: '../../beacon-node-oapi.yaml#/components/schemas/Uint64' + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Uint64" responses: "200": description: "Successful response" headers: Eth-Consensus-Version: - $ref: '../../beacon-node-oapi.yaml#/components/headers/Eth-Consensus-Version' - required: true + $ref: "../../beacon-node-oapi.yaml#/components/headers/Eth-Consensus-Version" content: application/json: schema: title: GetExecutionPayloadEnvelopeResponse type: object - required: [data] + required: [version, execution_optimistic, finalized, data] properties: version: type: string diff --git a/apis/validator/payload_attestation_data.yaml b/apis/validator/payload_attestation_data.yaml index 0932dc2e..e13973b6 100644 --- a/apis/validator/payload_attestation_data.yaml +++ b/apis/validator/payload_attestation_data.yaml @@ -17,7 +17,7 @@ get: required: true description: "The slot for which payload attestation data should be created." schema: - $ref: ../../beacon-node-oapi.yaml#/components/schemas/Uint64 + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Uint64" responses: "200": description: "Success response" @@ -34,9 +34,9 @@ get: schema: description: "SSZ serialized PayloadAttestationData bytes. Use Accept header to choose this response type" "400": - $ref: '../../beacon-node-oapi.yaml#/components/responses/InvalidRequest' + $ref: "../../beacon-node-oapi.yaml#/components/responses/InvalidRequest" "406": - $ref: '../../beacon-node-oapi.yaml#/components/responses/NotAcceptable' + $ref: "../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" "500": $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" "503": diff --git a/types/gloas/execution_payload_envelope.yaml b/types/gloas/execution_payload_envelope.yaml index 8b74464c..de6d3431 100644 --- a/types/gloas/execution_payload_envelope.yaml +++ b/types/gloas/execution_payload_envelope.yaml @@ -41,5 +41,5 @@ Gloas: $ref: "#/Gloas/ExecutionPayloadEnvelope" signature: allOf: - - $ref: "../primitive.yaml#/BLSSignature" + - $ref: "../primitive.yaml#/Signature" - description: "BLS signature of the execution payload envelope" From 8faafdf62ee2b6dd17eb9f76014e4c6fe7ed723c Mon Sep 17 00:00:00 2001 From: shane-moore Date: Fri, 5 Sep 2025 15:22:53 -0700 Subject: [PATCH 07/17] epbs documentation updates --- apis/validator/attestation_data.yaml | 4 +-- apis/validator/block.v3.yaml | 2 +- validator-flow.md | 41 ++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/apis/validator/attestation_data.yaml b/apis/validator/attestation_data.yaml index 0b62f277..56f12835 100644 --- a/apis/validator/attestation_data.yaml +++ b/apis/validator/attestation_data.yaml @@ -6,7 +6,7 @@ get: summary: "Produce an attestation data" description: | Requests that the beacon node produce an AttestationData. For `slot`s in - Electra and later, this AttestationData must have a `committee_index` of 0. + Electra and Fulu, this AttestationData must have a `committee_index` of 0. In Gloas, this `committee_index` field is repurposed to signal payload status: 0 if the execution payload is not present in the canonical chain (EMPTY), or 1 if the payload is present (FULL). For current slot attestations, always use 0. A 503 error must be returned if the block identified by the response `beacon_block_root` is optimistic (i.e. the attestation attests to a block @@ -22,7 +22,7 @@ get: in: query description: | The committee index for which an attestation data should be created. For `slot`s in - Electra and later, this parameter MAY always be set to 0. + Electra and Fulu, this parameter MAY always be set to 0. In Gloas, it signals payload status: 0 for EMPTY payload status, 1 for FULL payload status. required: true schema: $ref: "../../beacon-node-oapi.yaml#/components/schemas/Uint64" diff --git a/apis/validator/block.v3.yaml b/apis/validator/block.v3.yaml index e5bf25ac..355629d2 100644 --- a/apis/validator/block.v3.yaml +++ b/apis/validator/block.v3.yaml @@ -100,7 +100,7 @@ get: $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.BeaconBlock" - title: "ProduceBlockV3Response (Pre-Gloas)" type: object - required: [version, data, consensus_block_value] + required: [version, data, consensus_block_value, execution_payload_blinded, execution_payload_value] properties: version: type: string diff --git a/validator-flow.md b/validator-flow.md index 37120fed..86eddc3b 100644 --- a/validator-flow.md +++ b/validator-flow.md @@ -36,15 +36,52 @@ Attesting: been assigned to. If any validators in the committee are aggregators, set `is_aggregator` to `True`, 2. Wait for new BeaconBlock for the assigned slot (either stream updates or poll) - - Max wait: `SECONDS_PER_SLOT / 3` seconds into the assigned slot + - Max wait: `SECONDS_PER_SLOT / 4` seconds into the assigned slot 3. [Fetch AttestationData](#/ValidatorRequiredApi/produceAttestationData) 4. [Submit Attestation](#/ValidatorRequiredApi/submitPoolAttestations) (AttestationData + aggregation bits) - Aggregation bits are `Bitlist` with length of committee (received in AttesterDuty) with bit on position `validator_committee_index` (see AttesterDuty) set to true 5. If aggregator: - - Wait for `SECONDS_PER_SLOT * 2 / 3` seconds into the assigned slot + - Wait for `SECONDS_PER_SLOT / 2` seconds into the assigned slot - [Fetch aggregated Attestation](#/ValidatorRequiredApi/getAggregatedAttestation) from Beacon Node you've subscribed to your subnet - [Publish SignedAggregateAndProofs](#/ValidatorRequiredApi/publishAggregateAndProofs) Monitor chain block reorganization events (TBD) as they could change attesters and aggregators. If reorg is detected, ask for new attester duties and proceed from 1.. + +### PTC Attesting + +On start of every epoch, validator should [fetch PTC duties](#/Validator/getPtcDuties) for epoch + 1. +Result are array of objects with validator index and assigned slot for payload timeliness committee participation. + +PTC Attesting: +1. Wait for new BeaconBlock for the assigned slot + - Max wait: `SECONDS_PER_SLOT / 4` seconds into the assigned slot +2. [Fetch PayloadAttestationData](#/ValidatorRequiredApi/producePayloadAttestationData) for the assigned slot +3. Sign PayloadAttestationData to create PayloadAttestationMessage +4. [Submit PayloadAttestationMessage](#/ValidatorRequiredApi/submitPayloadAttestationMessage) + - Must be submitted by `3/4` of slot duration (`PAYLOAD_ATTESTATION_DUE_BPS` = 75% of slot) + - Attestation indicates whether execution payload envelope has been seen for the block and if blobs were received + +Monitor chain block reorganization events (TBD) as they could change PTC assignments. +If reorg is detected, ask for new PTC duties and proceed from 1.. + +### Builder (Optional) + +Validators may optionally act as builders to submit execution payload bids for block inclusion. +This requires registering with builder-specific withdrawal credentials (`BUILDER_WITHDRAWAL_PREFIX`). + +Building: +1. [Fetch ExecutionPayloadBid](#/Validator/getExecutionPayloadBid) from beacon node + - Beacon node obtains payload via `engine_getPayload` call to execution client +2. Cache fields required to form an [ExecutionPayloadEnvelope](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#executionpayloadenvelope) +2. Sign ExecutionPayloadBid to create SignedExecutionPayloadBid +3. [Submit SignedExecutionPayloadBid](#/Beacon/publishExecutionPayloadBid) to network for proposer consideration +4. If bid is selected by proposer in their block: + - [Fetch ExecutionPayloadEnvelope](#/Validator/getExecutionPayloadEnvelope) from beacon node + - Sign envelope and [submit SignedExecutionPayloadEnvelope](#/Beacon/publishExecutionPayloadEnvelope) + - Must submit early enough for PTC attestation by `3/4` of slot duration + +Monitor for block proposals containing your bid to trigger envelope release. + + From 0ae952cb3f3d66e78a5c4808e264d1efe0d65a11 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Thu, 11 Sep 2025 15:46:45 -0700 Subject: [PATCH 08/17] updates per pr review --- apis/validator/attestation_data.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apis/validator/attestation_data.yaml b/apis/validator/attestation_data.yaml index 56f12835..b25f71e1 100644 --- a/apis/validator/attestation_data.yaml +++ b/apis/validator/attestation_data.yaml @@ -6,7 +6,7 @@ get: summary: "Produce an attestation data" description: | Requests that the beacon node produce an AttestationData. For `slot`s in - Electra and Fulu, this AttestationData must have a `committee_index` of 0. In Gloas, this `committee_index` field is repurposed to signal payload status: 0 if the execution payload is not present in the canonical chain (EMPTY), or 1 if the payload is present (FULL). For current slot attestations, always use 0. + Electra and Fulu, this AttestationData must have a `committee_index` of 0. In Gloas, this `committee_index` field is repurposed to signal payload status: 0 if the execution payload is not present in the canonical chain (EMPTY), or 1 if the payload is present (FULL). For current slot attestations, which means the head block root is a block proposed in the same slot as the AttestationData.slot, always use 0. A 503 error must be returned if the block identified by the response `beacon_block_root` is optimistic (i.e. the attestation attests to a block From 30643749af001ef6f98bc5c8d69ee972aedb5cd5 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Fri, 12 Sep 2025 09:08:04 -0700 Subject: [PATCH 09/17] add produceBlockV4 endpoint --- CHANGES.md | 2 +- apis/validator/block.v3.yaml | 89 ++++++++++++---------------- apis/validator/block.v4.yaml | 111 +++++++++++++++++++++++++++++++++++ beacon-node-oapi.yaml | 13 ++-- 4 files changed, 156 insertions(+), 59 deletions(-) create mode 100644 apis/validator/block.v4.yaml diff --git a/CHANGES.md b/CHANGES.md index af6c5471..94cf698f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,7 +19,7 @@ There are likely to be descriptions etc outside of the list below, but new query | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/execution_payload_bid` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/execution_payload_envelope` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v1/beacon/pool/payload_attestations` added | | | | | | -| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v3/validator/blocks/{slot}` updated | | | | | | +| [#552](https://github.com/ethereum/beacon-APIs/pull/552) `GET /eth/v4/validator/blocks/{slot}` added | | | | | | | [#552](https://github.com/ethereum/beacon-APIs/pull/552) `POST /eth/v2/beacon/blocks` updated | | | | | | The Following are no longer in the Standard API, removed since the latest version. diff --git a/apis/validator/block.v3.yaml b/apis/validator/block.v3.yaml index 355629d2..87baa13f 100644 --- a/apis/validator/block.v3.yaml +++ b/apis/validator/block.v3.yaml @@ -5,16 +5,16 @@ get: operationId: "produceBlockV3" summary: "Produce a new block, without signature." description: | - Requests a beacon node to produce a valid block, which can then be signed by a validator. + Requests a beacon node to produce a valid block, which can then be signed by a validator. The + returned block may be blinded or unblinded, depending on the current state of the network as + decided by the execution and beacon nodes. - Post-gloas, proposers submit execution payload - bids rather than full execution payloads, so there is no longer a concept of blinded or unblinded blocks. Builders release the payload later. For pre-Gloas forks, the returned block may be blinded or unblinded, depending on the current - state of the network as decided by the execution and beacon nodes. The beacon node returns an - unblinded block if it obtains the execution payload from its paired execution node, or a - blinded block if it obtains the execution payload header from an MEV relay. + The beacon node must return an unblinded block if it obtains the execution payload from its + paired execution node. It must only return a blinded block if it obtains the execution payload + header from an MEV relay. Metadata in the response indicates the type of block produced, and the supported types of block - will be added to as forks progress. + are for all pre-Gloas forks. This endpoint is not forwards compatible after the Fulu fork. parameters: - name: slot in: path @@ -83,51 +83,36 @@ get: content: application/json: schema: - oneOf: - - title: "ProduceBlockV3Response (Gloas)" - type: object - required: [version, data, consensus_block_value] - properties: - version: - type: string - enum: [gloas] - example: "gloas" - consensus_block_value: - type: string - example: "12345" - description: "Consensus rewards for this block in Wei" - data: - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.BeaconBlock" - - title: "ProduceBlockV3Response (Pre-Gloas)" - type: object - required: [version, data, consensus_block_value, execution_payload_blinded, execution_payload_value] - properties: - version: - type: string - enum: [phase0, altair, bellatrix, capella, deneb, electra, fulu] - example: "electra" - execution_payload_blinded: - type: boolean - example: false - execution_payload_value: - type: string - example: "12345" - consensus_block_value: - type: string - example: "12345" - data: - anyOf: - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Fulu.BlockContents" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Electra.BlockContents" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Electra.BlindedBeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Deneb.BlockContents" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Deneb.BlindedBeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Capella.BeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Capella.BlindedBeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Bellatrix.BeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Bellatrix.BlindedBeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Altair.BeaconBlock" - - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Phase0.BeaconBlock" + title: ProduceBlockV3Response + type: object + required: [version, execution_payload_blinded, execution_payload_value, consensus_block_value, data] + properties: + version: + type: string + enum: [phase0, altair, bellatrix, capella, deneb, electra, fulu] + example: "electra" + execution_payload_blinded: + type: boolean + example: false + execution_payload_value: + type: string + example: "12345" + consensus_block_value: + type: string + example: "12345" + data: + anyOf: + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Fulu.BlockContents" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Electra.BlockContents" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Electra.BlindedBeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Deneb.BlockContents" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Deneb.BlindedBeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Capella.BeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Capella.BlindedBeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Bellatrix.BeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Bellatrix.BlindedBeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Altair.BeaconBlock" + - $ref: "../../beacon-node-oapi.yaml#/components/schemas/Phase0.BeaconBlock" application/octet-stream: schema: description: "SSZ serialized block or blinded block bytes. Use Accept header to choose this response type, version string is sent in header `Eth-Consensus-Version` and block type in `Eth-Blinded-Payload`." diff --git a/apis/validator/block.v4.yaml b/apis/validator/block.v4.yaml new file mode 100644 index 00000000..3c2dfb9a --- /dev/null +++ b/apis/validator/block.v4.yaml @@ -0,0 +1,111 @@ +get: + tags: + - ValidatorRequiredApi + - Validator + operationId: "produceBlockV4" + summary: "Produce a new block, without signature." + description: | + Requests a beacon node to produce a valid block, which can then be signed by a validator. + + Post-Gloas, proposers submit execution payload bids rather than full execution payloads, + so there is no longer a concept of blinded or unblinded blocks. Builders release the + payload later. This endpoint is specific to the post-Gloas forks and is not backwards compatible + with previous forks. + parameters: + - name: slot + in: path + required: true + description: "The slot for which the block should be proposed." + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Uint64" + - name: randao_reveal + in: query + required: true + description: "The validator's randao reveal value." + schema: + $ref: '../../beacon-node-oapi.yaml#/components/schemas/Signature' + - name: graffiti + in: query + required: false + description: "Arbitrary data validator wants to include in block." + schema: + $ref: '../../beacon-node-oapi.yaml#/components/schemas/Graffiti' + - name: skip_randao_verification + $ref: '../../beacon-node-oapi.yaml#/components/parameters/SkipRandaoVerification' + - name: builder_boost_factor + in: query + required: false + description: | + Percentage multiplier to apply to the builder's payload value when choosing between a + builder payload header and payload from the paired execution node. This parameter is only + relevant if the beacon node is connected to a builder, deems it safe to produce a builder + payload, and receives valid responses from both the builder endpoint _and_ 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)`, + then return a full (unblinded) block containing the execution node payload. + * otherwise, return a blinded block containing the builder payload header. + + Servers must support the following values of the boost factor which encode common + preferences: + + * `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=2**64 - 1`: prefer the external builder payload unless an error or + beacon node health check makes it unviable. + + Servers should use saturating arithmetic or another technique to ensure that large values of + the `builder_boost_factor` do not trigger overflows or errors. If this parameter is + provided and the beacon node is not configured with a builder then the beacon node MUST + respond with a full block, which the caller can choose to reject if it wishes. + If the value is provided but out of range for a 64-bit unsigned integer, then an error + response with status code 400 MUST be returned. + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Uint64" + responses: + "200": + description: Success response + headers: + Eth-Consensus-Version: + $ref: '../../beacon-node-oapi.yaml#/components/headers/Eth-Consensus-Version' + Eth-Consensus-Block-Value: + $ref: '../../beacon-node-oapi.yaml#/components/headers/Eth-Consensus-Block-Value' + content: + application/json: + schema: + title: "ProduceBlockV4Response" + type: object + required: [version, data, consensus_block_value] + properties: + version: + type: string + enum: [gloas] + example: "gloas" + consensus_block_value: + type: string + example: "12345" + description: "Consensus rewards for this block in Wei" + data: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.BeaconBlock" + application/octet-stream: + schema: + description: "SSZ serialized block bytes. Use Accept header to choose this response type, version string is sent in header `Eth-Consensus-Version`." + "400": + description: "Invalid block production request" + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + examples: + InvalidRequest: + value: + code: 400 + message: "Invalid request to produce a block" + "406": + $ref: "../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" + "500": + $ref: '../../beacon-node-oapi.yaml#/components/responses/InternalError' + "503": + $ref: '../../beacon-node-oapi.yaml#/components/responses/CurrentlySyncing' diff --git a/beacon-node-oapi.yaml b/beacon-node-oapi.yaml index c15d68e5..9da1974b 100644 --- a/beacon-node-oapi.yaml +++ b/beacon-node-oapi.yaml @@ -190,6 +190,8 @@ paths: $ref: "./apis/validator/duties/ptc.yaml" /eth/v3/validator/blocks/{slot}: $ref: "./apis/validator/block.v3.yaml" + /eth/v4/validator/blocks/{slot}: + $ref: "./apis/validator/block.v4.yaml" /eth/v1/validator/attestation_data: $ref: "./apis/validator/attestation_data.yaml" /eth/v1/validator/payload_attestation_data: @@ -511,16 +513,15 @@ components: schema: $ref: '#/components/schemas/ConsensusVersion' Eth-Execution-Payload-Blinded: - description: "DEPRECATED: Not applicable for gloas fork. For pre-gloas forks, this is required in response so client can deserialize returned json or ssz data to the correct object pre-gloas. Post-gloas, there is no concept of blinded blocks." - required: false + description: Required in response so client can deserialize returned json or ssz data to the correct object. + required: true schema: type: boolean Eth-Execution-Payload-Value: description: | - DEPRECATED: Not applicable for gloas fork. - For pre-gloas forks, this is the execution payload value in Wei. Required in response so client can determine relative value - of execution payloads pre-gloas. Post-gloas, the ExecutionPayloadBid defines the value of an execution payload. - required: false + Execution payload value in Wei. Required in response so client can determine relative value + of execution payloads. + required: true schema: $ref: './types/primitive.yaml#/Wei' Eth-Consensus-Block-Value: From 164f1d869bc4d4d86c043a3383ec7c0550c6f516 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Fri, 12 Sep 2025 10:02:35 -0700 Subject: [PATCH 10/17] epbs related copy changes --- apis/beacon/blocks/blocks.v2.yaml | 2 +- apis/beacon/execution_payload/bid.yaml | 4 ++-- apis/beacon/execution_payload/envelope.yaml | 3 ++- apis/validator/block.v4.yaml | 2 +- apis/validator/execution_payload_envelope.yaml | 1 + validator-flow.md | 14 +++++++++----- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/apis/beacon/blocks/blocks.v2.yaml b/apis/beacon/blocks/blocks.v2.yaml index ef4eb0a0..e96562a1 100644 --- a/apis/beacon/blocks/blocks.v2.yaml +++ b/apis/beacon/blocks/blocks.v2.yaml @@ -11,7 +11,7 @@ post: The beacon node is also expected to integrate the block into the state, but may broadcast it before doing so, so as to aid timely delivery of the block. Should the block fail full validation, a separate success response code (202) is used to indicate that the block was - successfully broadcast but failed integration. After Deneb and before Gloas, this additionally instructs + successfully broadcast but failed integration. For Deneb/Electra/Fulu, this additionally instructs the beacon node to broadcast all given blobs. The broadcast behaviour may be adjusted via the `broadcast_validation` query parameter. parameters: diff --git a/apis/beacon/execution_payload/bid.yaml b/apis/beacon/execution_payload/bid.yaml index 27acab68..5609db69 100644 --- a/apis/beacon/execution_payload/bid.yaml +++ b/apis/beacon/execution_payload/bid.yaml @@ -2,8 +2,8 @@ post: operationId: publishExecutionPayloadBid summary: Publish signed execution payload bid description: | - Instructs the beacon node to broadcast a signed execution payload bid to the beacon network, - to be gossiped for potential inclusion in block building. A success response indicates + Instructs the beacon node to broadcast a signed execution payload bid to the network, + to be gossiped for potential inclusion in block building. A success response (20x) indicates that the bid passed gossip validation and was successfully broadcast onto the network. tags: - Beacon diff --git a/apis/beacon/execution_payload/envelope.yaml b/apis/beacon/execution_payload/envelope.yaml index 6c5c1228..57503623 100644 --- a/apis/beacon/execution_payload/envelope.yaml +++ b/apis/beacon/execution_payload/envelope.yaml @@ -2,11 +2,12 @@ post: operationId: publishExecutionPayloadEnvelope summary: Publish signed execution payload envelope description: | - Instructs the beacon node to broadcast a signed execution payload envelope to the beacon network, + Instructs the beacon node to broadcast a signed execution payload envelope to the network, to be gossiped for payload validation. A success response (20x) indicates that the envelope passed gossip validation and was successfully broadcast onto the network. tags: - Beacon + - ValidatorRequiredApi requestBody: description: "The `SignedExecutionPayloadEnvelope` object to be broadcast." required: true diff --git a/apis/validator/block.v4.yaml b/apis/validator/block.v4.yaml index 3c2dfb9a..38cdbe5d 100644 --- a/apis/validator/block.v4.yaml +++ b/apis/validator/block.v4.yaml @@ -1,7 +1,7 @@ get: tags: - - ValidatorRequiredApi - Validator + - ValidatorRequiredApi operationId: "produceBlockV4" summary: "Produce a new block, without signature." description: | diff --git a/apis/validator/execution_payload_envelope.yaml b/apis/validator/execution_payload_envelope.yaml index d2c86f02..3748e745 100644 --- a/apis/validator/execution_payload_envelope.yaml +++ b/apis/validator/execution_payload_envelope.yaml @@ -7,6 +7,7 @@ get: either as json or as bytes serialized by SSZ. tags: - Validator + - ValidatorRequiredApi parameters: - name: slot in: path diff --git a/validator-flow.md b/validator-flow.md index 86eddc3b..7fbe5245 100644 --- a/validator-flow.md +++ b/validator-flow.md @@ -15,7 +15,9 @@ On start of every epoch, validator should [fetch proposer duties](#/Validator/ge Result is array of objects, each containing proposer pubkey and slot at which he is suppose to propose. If proposing block, then at immediate start of slot: -1. [Ask Beacon Node for BeaconBlock object](#/Validator/produceBlock) +1. Ask Beacon Node for BeaconBlock object: + - Pre-Gloas forks: [produceBlockV3](#/Validator/produceBlockV3) + - Post-Gloas fork: [produceBlockV4](#/Validator/produceBlockV4) 2. Sign block 3. [Submit SignedBeaconBlock](#/ValidatorRequiredApi/publishBlock) (BeaconBlock + signature) @@ -36,13 +38,15 @@ Attesting: been assigned to. If any validators in the committee are aggregators, set `is_aggregator` to `True`, 2. Wait for new BeaconBlock for the assigned slot (either stream updates or poll) - - Max wait: `SECONDS_PER_SLOT / 4` seconds into the assigned slot + - Pre-Gloas forks: Max wait `SECONDS_PER_SLOT / 3` seconds into the assigned slot + - Post-Gloas forks: Max wait `SECONDS_PER_SLOT / 4` seconds into the assigned slot 3. [Fetch AttestationData](#/ValidatorRequiredApi/produceAttestationData) 4. [Submit Attestation](#/ValidatorRequiredApi/submitPoolAttestations) (AttestationData + aggregation bits) - Aggregation bits are `Bitlist` with length of committee (received in AttesterDuty) with bit on position `validator_committee_index` (see AttesterDuty) set to true 5. If aggregator: - - Wait for `SECONDS_PER_SLOT / 2` seconds into the assigned slot + - Pre-Gloas forks: Wait for `SECONDS_PER_SLOT * 2 / 3` seconds into the assigned slot + - Post-Gloas forks: Wait for `SECONDS_PER_SLOT / 2` seconds into the assigned slot - [Fetch aggregated Attestation](#/ValidatorRequiredApi/getAggregatedAttestation) from Beacon Node you've subscribed to your subnet - [Publish SignedAggregateAndProofs](#/ValidatorRequiredApi/publishAggregateAndProofs) @@ -51,7 +55,7 @@ If reorg is detected, ask for new attester duties and proceed from 1.. ### PTC Attesting -On start of every epoch, validator should [fetch PTC duties](#/Validator/getPtcDuties) for epoch + 1. +On start of every epoch beginning with the Gloas fork, validator should [fetch PTC duties](#/Validator/getPtcDuties) for epoch + 1. Result are array of objects with validator index and assigned slot for payload timeliness committee participation. PTC Attesting: @@ -68,7 +72,7 @@ If reorg is detected, ask for new PTC duties and proceed from 1.. ### Builder (Optional) -Validators may optionally act as builders to submit execution payload bids for block inclusion. +Post-Gloas fork, validators may optionally act as builders to submit execution payload bids for block inclusion. This requires registering with builder-specific withdrawal credentials (`BUILDER_WITHDRAWAL_PREFIX`). Building: From 7929dfede0d7927933c874e58c75700ae1713423 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Sat, 13 Sep 2025 10:07:12 -0700 Subject: [PATCH 11/17] add consensus version to bid and envelope post --- apis/beacon/execution_payload/bid.yaml | 7 +++++++ apis/beacon/execution_payload/envelope.yaml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/apis/beacon/execution_payload/bid.yaml b/apis/beacon/execution_payload/bid.yaml index 5609db69..8f4f3959 100644 --- a/apis/beacon/execution_payload/bid.yaml +++ b/apis/beacon/execution_payload/bid.yaml @@ -7,6 +7,13 @@ post: that the bid passed gossip validation and was successfully broadcast onto the network. tags: - Beacon + parameters: + - in: header + schema: + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/ConsensusVersion" + required: true + name: Eth-Consensus-Version + description: "The active consensus version to which the execution payload bid being submitted belongs." requestBody: description: "The `SignedExecutionPayloadBid` object to be broadcast." required: true diff --git a/apis/beacon/execution_payload/envelope.yaml b/apis/beacon/execution_payload/envelope.yaml index 57503623..0837ec48 100644 --- a/apis/beacon/execution_payload/envelope.yaml +++ b/apis/beacon/execution_payload/envelope.yaml @@ -8,6 +8,13 @@ post: tags: - Beacon - ValidatorRequiredApi + parameters: + - in: header + schema: + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/ConsensusVersion" + required: true + name: Eth-Consensus-Version + description: "The active consensus version to which the execution payload envelope being submitted belongs." requestBody: description: "The `SignedExecutionPayloadEnvelope` object to be broadcast." required: true From 5eccf7f140c79ff3548f8b13b0be8ee6a6cd3b58 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Sat, 13 Sep 2025 10:39:31 -0700 Subject: [PATCH 12/17] gloas container links updated to use specific commit --- types/gloas/block.yaml | 2 +- types/gloas/execution_payload_bid.yaml | 4 ++-- types/gloas/execution_payload_envelope.yaml | 4 ++-- types/gloas/payload_attestation.yaml | 6 +++--- validator-flow.md | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/types/gloas/block.yaml b/types/gloas/block.yaml index a849a691..adc6dab0 100644 --- a/types/gloas/block.yaml +++ b/types/gloas/block.yaml @@ -2,7 +2,7 @@ Gloas: BeaconBlockBodyCommon: # An abstract object to collect the common fields between the BeaconBlockBody and the BlindedBeaconBlockBody objects type: object - description: "The [`BeaconBlockBody`](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#beaconblockbody) object from the CL Gloas spec." + description: "The [`BeaconBlockBody`](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/beacon-chain.md#beaconblockbody) object from the CL Gloas spec." required: [randao_reveal, eth1_data, graffiti, proposer_slashings, attester_slashings, attestations, deposits, voluntary_exits, sync_aggregate, bls_to_execution_changes] properties: randao_reveal: diff --git a/types/gloas/execution_payload_bid.yaml b/types/gloas/execution_payload_bid.yaml index 771d2d77..14ce0da4 100644 --- a/types/gloas/execution_payload_bid.yaml +++ b/types/gloas/execution_payload_bid.yaml @@ -1,7 +1,7 @@ Gloas: ExecutionPayloadBid: type: object - description: "The [ExecutionPayloadBid](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#executionpayloadbid) object from the CL gloas spec." + description: "The [`ExecutionPayloadBid`](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/beacon-chain.md#executionpayloadbid) object from the CL gloas spec." required: [parent_block_hash, parent_block_root, block_hash, fee_recipient, gas_limit, builder_index, slot, value, blob_kzg_commitments_root] properties: parent_block_hash: @@ -25,7 +25,7 @@ Gloas: SignedExecutionPayloadBid: type: object - description: "The [SignedExecutionPayloadBid](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#signedexecutionpayloadbid) object from the CL gloas spec." + description: "The [`SignedExecutionPayloadBid`](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/beacon-chain.md#signedexecutionpayloadbid) object from the CL gloas spec." required: [message, signature] properties: message: diff --git a/types/gloas/execution_payload_envelope.yaml b/types/gloas/execution_payload_envelope.yaml index de6d3431..e33ed350 100644 --- a/types/gloas/execution_payload_envelope.yaml +++ b/types/gloas/execution_payload_envelope.yaml @@ -1,7 +1,7 @@ Gloas: ExecutionPayloadEnvelope: type: object - description: "The [ExecutionPayloadEnvelope](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#executionpayloadenvelope) object from the CL gloas spec." + description: "The [`ExecutionPayloadEnvelope`](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/beacon-chain.md#executionpayloadenvelope) object from the CL gloas spec." required: [payload, execution_requests, builder_index, beacon_block_root, slot, blob_kzg_commitments, state_root] properties: payload: @@ -34,7 +34,7 @@ Gloas: SignedExecutionPayloadEnvelope: type: object - description: "The [SignedExecutionPayloadEnvelope](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#signedexecutionpayloadenvelope) object from the CL gloas spec." + description: "The [`SignedExecutionPayloadEnvelope`](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/beacon-chain.md#signedexecutionpayloadenvelope) object from the CL gloas spec." required: [message, signature] properties: message: diff --git a/types/gloas/payload_attestation.yaml b/types/gloas/payload_attestation.yaml index 435a5832..93aa9abc 100644 --- a/types/gloas/payload_attestation.yaml +++ b/types/gloas/payload_attestation.yaml @@ -1,7 +1,7 @@ Gloas: PayloadAttestationData: type: object - description: "The [`PayloadAttestationData`](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#payloadattestationdata) object from the CL Gloas spec." + description: "The [`PayloadAttestationData`](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/beacon-chain.md#payloadattestationdata) object from the CL Gloas spec." required: [beacon_block_root, slot, payload_present, blob_data_available] properties: beacon_block_root: @@ -21,7 +21,7 @@ Gloas: PayloadAttestation: type: object - description: "The [PayloadAttestation](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#payloadattestation) object from the CL gloas spec." + description: "The [`PayloadAttestation`](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/beacon-chain.md#payloadattestation) object from the CL gloas spec." required: [aggregation_bits, data, signature] properties: aggregation_bits: @@ -33,7 +33,7 @@ Gloas: PayloadAttestationMessage: type: object - description: "The [`PayloadAttestationMessage`](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#payloadattestationmessage) object from the CL Gloas spec." + description: "The [`PayloadAttestationMessage`](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/beacon-chain.md#payloadattestationmessage) object from the CL Gloas spec." required: [validator_index, data, signature] properties: validator_index: diff --git a/validator-flow.md b/validator-flow.md index 7fbe5245..7dd21f04 100644 --- a/validator-flow.md +++ b/validator-flow.md @@ -78,7 +78,7 @@ This requires registering with builder-specific withdrawal credentials (`BUILDER Building: 1. [Fetch ExecutionPayloadBid](#/Validator/getExecutionPayloadBid) from beacon node - Beacon node obtains payload via `engine_getPayload` call to execution client -2. Cache fields required to form an [ExecutionPayloadEnvelope](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#executionpayloadenvelope) +2. Cache fields required to form an [ExecutionPayloadEnvelope](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/beacon-chain.md#executionpayloadenvelope) 2. Sign ExecutionPayloadBid to create SignedExecutionPayloadBid 3. [Submit SignedExecutionPayloadBid](#/Beacon/publishExecutionPayloadBid) to network for proposer consideration 4. If bid is selected by proposer in their block: From b30273cfd600b7b8ce37108f2840d1e628571e32 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Mon, 15 Sep 2025 13:18:45 -0700 Subject: [PATCH 13/17] add get bid error message for invalid builder index --- apis/validator/execution_payload_bid.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/apis/validator/execution_payload_bid.yaml b/apis/validator/execution_payload_bid.yaml index 34901a33..7f8a0db1 100644 --- a/apis/validator/execution_payload_bid.yaml +++ b/apis/validator/execution_payload_bid.yaml @@ -64,5 +64,14 @@ get: message: "Execution payload bid not available for slot and builder" "406": $ref: "../../beacon-node-oapi.yaml#/components/responses/NotAcceptable" + "422": + description: "The builder_index does not correspond to a validator with builder withdrawal credentials (0x03 prefix)" + content: + application/json: + schema: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 422 + message: "Builder index does not correspond to a registered builder validator" "500": $ref: "../../beacon-node-oapi.yaml#/components/responses/InternalError" From 2d1438f52e9d91ed7545291ebe763ffc43b55ebb Mon Sep 17 00:00:00 2001 From: shane-moore Date: Wed, 17 Sep 2025 12:52:32 -0700 Subject: [PATCH 14/17] add slot voting time parameters to validator-flow --- validator-flow.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/validator-flow.md b/validator-flow.md index 7dd21f04..d4e0a284 100644 --- a/validator-flow.md +++ b/validator-flow.md @@ -39,14 +39,14 @@ Attesting: set `is_aggregator` to `True`, 2. Wait for new BeaconBlock for the assigned slot (either stream updates or poll) - Pre-Gloas forks: Max wait `SECONDS_PER_SLOT / 3` seconds into the assigned slot - - Post-Gloas forks: Max wait `SECONDS_PER_SLOT / 4` seconds into the assigned slot + - Post-Gloas forks: Max wait [ATTESTATION_DUE_BPS_GLOAS](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/validator.md#time-parameters) seconds into the assigned slot 3. [Fetch AttestationData](#/ValidatorRequiredApi/produceAttestationData) 4. [Submit Attestation](#/ValidatorRequiredApi/submitPoolAttestations) (AttestationData + aggregation bits) - Aggregation bits are `Bitlist` with length of committee (received in AttesterDuty) with bit on position `validator_committee_index` (see AttesterDuty) set to true 5. If aggregator: - Pre-Gloas forks: Wait for `SECONDS_PER_SLOT * 2 / 3` seconds into the assigned slot - - Post-Gloas forks: Wait for `SECONDS_PER_SLOT / 2` seconds into the assigned slot + - Post-Gloas forks: Wait for [AGGREGATE_DUE_BPS_GLOAS](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/validator.md#time-parameters) seconds into the assigned slot - [Fetch aggregated Attestation](#/ValidatorRequiredApi/getAggregatedAttestation) from Beacon Node you've subscribed to your subnet - [Publish SignedAggregateAndProofs](#/ValidatorRequiredApi/publishAggregateAndProofs) @@ -64,7 +64,7 @@ PTC Attesting: 2. [Fetch PayloadAttestationData](#/ValidatorRequiredApi/producePayloadAttestationData) for the assigned slot 3. Sign PayloadAttestationData to create PayloadAttestationMessage 4. [Submit PayloadAttestationMessage](#/ValidatorRequiredApi/submitPayloadAttestationMessage) - - Must be submitted by `3/4` of slot duration (`PAYLOAD_ATTESTATION_DUE_BPS` = 75% of slot) + - Must be submitted by [PAYLOAD_ATTESTATION_DUE_BPS](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/validator.md#time-parameters) of slot duration - Attestation indicates whether execution payload envelope has been seen for the block and if blobs were received Monitor chain block reorganization events (TBD) as they could change PTC assignments. @@ -84,7 +84,7 @@ Building: 4. If bid is selected by proposer in their block: - [Fetch ExecutionPayloadEnvelope](#/Validator/getExecutionPayloadEnvelope) from beacon node - Sign envelope and [submit SignedExecutionPayloadEnvelope](#/Beacon/publishExecutionPayloadEnvelope) - - Must submit early enough for PTC attestation by `3/4` of slot duration + - Must submit early enough for PTC attestation by [PAYLOAD_ATTESTATION_DUE_BPS](https://github.com/ethereum/consensus-specs/blob/00d531949b1f30516979b60ddd2a411e7f388299/specs/gloas/validator.md#time-parameters) of slot duration Monitor for block proposals containing your bid to trigger envelope release. From a4335fbfc3ea71c7291b31f8187a31d2f5442baf Mon Sep 17 00:00:00 2001 From: shane-moore Date: Wed, 17 Sep 2025 13:48:56 -0700 Subject: [PATCH 15/17] add eth-consensus-version for payload attestations --- apis/beacon/pool/payload_attestations.yaml | 10 ++++++++++ apis/validator/payload_attestation_data.yaml | 9 ++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/apis/beacon/pool/payload_attestations.yaml b/apis/beacon/pool/payload_attestations.yaml index 3bcc47cb..b8b4f5a2 100644 --- a/apis/beacon/pool/payload_attestations.yaml +++ b/apis/beacon/pool/payload_attestations.yaml @@ -13,6 +13,9 @@ get: responses: "200": description: Successful response + headers: + Eth-Consensus-Version: + $ref: '../../../beacon-node-oapi.yaml#/components/headers/Eth-Consensus-Version' content: application/json: schema: @@ -51,6 +54,13 @@ post: A success response indicates that the payload attestation message passed validation and was successfully stored and broadcast. + parameters: + - in: header + schema: + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/ConsensusVersion" + required: true + name: Eth-Consensus-Version + description: "The active consensus version to which the payload attestation message being submitted belongs." tags: - Beacon - ValidatorRequiredApi diff --git a/apis/validator/payload_attestation_data.yaml b/apis/validator/payload_attestation_data.yaml index e13973b6..693a6798 100644 --- a/apis/validator/payload_attestation_data.yaml +++ b/apis/validator/payload_attestation_data.yaml @@ -21,13 +21,20 @@ get: responses: "200": description: "Success response" + headers: + Eth-Consensus-Version: + $ref: "../../beacon-node-oapi.yaml#/components/headers/Eth-Consensus-Version" content: application/json: schema: title: ProducePayloadAttestationDataResponse type: object - required: [data] + required: [version, data] properties: + version: + type: string + enum: [gloas] + example: "gloas" data: $ref: "../../beacon-node-oapi.yaml#/components/schemas/Gloas.PayloadAttestationData" application/octet-stream: From 04a6d7a71ca890390174f8ebe19452aa0dcf8bd1 Mon Sep 17 00:00:00 2001 From: shane-moore Date: Thu, 18 Sep 2025 08:55:19 -0700 Subject: [PATCH 16/17] update payload attestation get to have slot in path --- apis/validator/payload_attestation_data.yaml | 2 +- beacon-node-oapi.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apis/validator/payload_attestation_data.yaml b/apis/validator/payload_attestation_data.yaml index 693a6798..f777b32b 100644 --- a/apis/validator/payload_attestation_data.yaml +++ b/apis/validator/payload_attestation_data.yaml @@ -13,7 +13,7 @@ get: A 503 error must be returned if the beacon node is currently syncing. parameters: - name: slot - in: query + in: path required: true description: "The slot for which payload attestation data should be created." schema: diff --git a/beacon-node-oapi.yaml b/beacon-node-oapi.yaml index 9da1974b..b3d3e3ab 100644 --- a/beacon-node-oapi.yaml +++ b/beacon-node-oapi.yaml @@ -194,7 +194,7 @@ paths: $ref: "./apis/validator/block.v4.yaml" /eth/v1/validator/attestation_data: $ref: "./apis/validator/attestation_data.yaml" - /eth/v1/validator/payload_attestation_data: + /eth/v1/validator/payload_attestation_data/{slot}: $ref: "./apis/validator/payload_attestation_data.yaml" /eth/v2/validator/aggregate_attestation: $ref: "./apis/validator/aggregate_attestation.v2.yaml" From aa8a6368d5f948aa397d7549235ab7db2980f0ad Mon Sep 17 00:00:00 2001 From: shane-moore Date: Fri, 19 Sep 2025 18:05:37 -0700 Subject: [PATCH 17/17] payload attestation post should support an array in the request --- apis/beacon/pool/payload_attestations.yaml | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/apis/beacon/pool/payload_attestations.yaml b/apis/beacon/pool/payload_attestations.yaml index b8b4f5a2..53c4ba92 100644 --- a/apis/beacon/pool/payload_attestations.yaml +++ b/apis/beacon/pool/payload_attestations.yaml @@ -47,13 +47,15 @@ post: operationId: submitPayloadAttestationMessage summary: Submit payload attestation message description: | - Submits a payload attestation message to the beacon node. + Submits payload attestation messages to the beacon node. - The beacon node will validate the payload attestation message according to the gossip validation rules + The beacon node will validate each payload attestation message according to the gossip validation rules and, if valid, store it in the pool and broadcast it globally to the network. A success response indicates that the payload attestation message passed validation and was successfully stored and broadcast. + + If one or more payload attestation messages fail validation, the node MUST return a 400 error with details of which messages have failed, and why. parameters: - in: header schema: @@ -65,28 +67,26 @@ post: - Beacon - ValidatorRequiredApi requestBody: - description: "The PayloadAttestationMessage object to be submitted." + description: "Array of PayloadAttestationMessage objects to be submitted." required: true content: application/json: schema: - $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Gloas.PayloadAttestationMessage" + type: array + items: + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/Gloas.PayloadAttestationMessage" application/octet-stream: schema: - description: "SSZ serialized PayloadAttestationMessage bytes. Use Content-Type header to indicate that SSZ data is contained in the request body." + description: "SSZ serialized array of PayloadAttestationMessage bytes. Use Content-Type header to indicate that SSZ data is contained in the request body." responses: "200": - description: "The payload attestation message was stored in the pool and has been broadcast." - content: - text/plain: - schema: - type: string + description: "Payload attestation messages are stored in pool and broadcasted to the network" "400": - description: "The PayloadAttestationMessage object is invalid or failed gossip validation" + description: "Errors with one or more payload attestation messages" content: application/json: schema: - $ref: "../../../beacon-node-oapi.yaml#/components/schemas/ErrorMessage" + $ref: "../../../beacon-node-oapi.yaml#/components/schemas/IndexedErrorMessage" "415": $ref: "../../../beacon-node-oapi.yaml#/components/responses/UnsupportedMediaType" "500":