diff --git a/apis/builder/beacon_block.yaml b/apis/builder/beacon_block.yaml new file mode 100644 index 0000000..6e9ddd8 --- /dev/null +++ b/apis/builder/beacon_block.yaml @@ -0,0 +1,54 @@ +post: + operationId: "submitSignedBeaconBlock" + summary: Submit a signed beacon block with the execution payload bid. + description: | + Submits a `SignedBeaconBlock` and `SignedBlindedExecutionPayloadEnvelope` to the builder, + binding the proposer to the bid. + + A success response (200) indicates that the signed beacon block was + valid. If the signed beacon block was invalid, then the builder + must return an error response (400) with a description of the validation + failure. + tags: + - Builder + parameters: + - in: header + schema: + $ref: "../../builder-oapi.yaml#/components/schemas/ConsensusVersion" + required: false + name: Eth-Consensus-Version + description: "The active consensus version to which the block being submitted belongs. Required if request is SSZ encoded." + requestBody: + description: A `SignedBeaconBlock`. + required: true + content: + application/json: + schema: + type: object + required: [block] + properties: + block: + $ref: "../../beacon-apis/types/gloas/block.yaml#/Gloas/SignedBeaconBlock" + description: "The signed beacon block." + blinded_envelope: + $ref: "../../types/gloas/blinded_execution_payload_envelope.yaml#/Gloas/SignedBlindedExecutionPayloadEnvelope" + description: "The signed blinded execution payload envelope." + application/octet-stream: + schema: + description: "SSZ serialized `SignedBeaconBlock` bytes. Use content type header to indicate that SSZ data is contained in the request body." + responses: + "202": + description: Success response. + "400": + description: Error response. + content: + application/json: + schema: + $ref: "../../builder-oapi.yaml#/components/schemas/ErrorMessage" + example: + code: 400 + message: "Invalid signed block and envelope root: missing signature" + "415": + $ref: "../../builder-oapi.yaml#/components/responses/UnsupportedMediaType" + "500": + $ref: "../../builder-oapi.yaml#/components/responses/InternalError" diff --git a/apis/builder/execution_payload_bid.yaml b/apis/builder/execution_payload_bid.yaml new file mode 100644 index 0000000..2d6ad4f --- /dev/null +++ b/apis/builder/execution_payload_bid.yaml @@ -0,0 +1,97 @@ +get: + operationId: "getExecutionPayloadBid" + summary: Get an execution payload bid. + description: | + Requests a builder node to produce a valid execution payload bid, which + can be integrated into a blinded beacon block and signed. + + If the builder is unable to produce a valid execution payload bid, then + the builder MUST return a 204 response. If the request is invalid, then the + builder MUST return an error response (400) with a description of the + validation failure. + + This API is applicable from Glamsterdam fork onwards. + tags: + - Builder + parameters: + - name: slot + in: path + required: true + description: The slot for which the block should be proposed. + schema: + $ref: "../../builder-oapi.yaml#/components/schemas/Uint64" + - name: parent_hash + in: path + required: true + description: Hash of execution layer block the proposer will build on. + schema: + $ref: "../../builder-oapi.yaml#/components/schemas/Root" + - name: pubkey + in: path + required: true + description: The validator's BLS public key. + schema: + $ref: "../../builder-oapi.yaml#/components/schemas/Pubkey" + - name: Date-Milliseconds + in: header + required: false + description: | + Optional header containing a Unix timestamp in milliseconds representing + the point-in-time the request was sent. This header can be used to measure + latency. + schema: + type: integer + format: int64 + example: 1710338135000 + - name: X-Timeout-Ms + in: header + required: false + description: | + Optional header containing the proposer's timeout for the request in milliseconds. + Relays should use this header to adjust the amount of time by which they delay getBid + requests to maximise block rewards. Otherwise, getBid requests will timeout and the proposer + will not receive the header in time. + schema: + type: integer + format: int64 + example: 10000 + responses: + "200": + description: Success response. + headers: + Eth-Consensus-Version: + $ref: "../../builder-oapi.yaml#/components/headers/Eth-Consensus-Version" + required: false + content: + application/json: + schema: + title: GetExecutionPayloadBidResponse + type: object + required: [version, data] + properties: + version: + type: string + enum: [ gloas ] + example: "gloas" + data: + $ref: "../../types/gloas/bid.yaml#/Gloas/SignedBuilderBid" + application/octet-stream: + schema: + description: "SSZ serialized `SignedBuilderBid` bytes. Use Accept header to choose this response type" + "204": + description: No header is available. + "400": + description: Error response. + content: + application/json: + schema: + $ref: "../../builder-oapi.yaml#/components/schemas/ErrorMessage" + examples: + InvalidRequest: + value: + code: 400 + message: "Unknown hash: missing parent hash" + "406": + $ref: "../../builder-oapi.yaml#/components/responses/NotAcceptable" + "500": + $ref: "../../builder-oapi.yaml#/components/responses/InternalError" diff --git a/beacon-apis b/beacon-apis index 69d2feb..8d90551 160000 --- a/beacon-apis +++ b/beacon-apis @@ -1 +1 @@ -Subproject commit 69d2feb12a6047c4f21e628dea8b0135b7e9013a +Subproject commit 8d9055187f5a8b8ed89b2160d9718eaa0c955726 diff --git a/builder-oapi.yaml b/builder-oapi.yaml index a9c05f0..dcfe7e0 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -53,6 +53,10 @@ paths: $ref: "./apis/builder/validators.yaml" /eth/v1/builder/header/{slot}/{parent_hash}/{pubkey}: $ref: "./apis/builder/header.yaml" + /eth/v1/builder/execution_payload_bid/{slot}/{parent_hash}/{pubkey}: + $ref: "./apis/builder/execution_payload_bid.yaml" + /eth/v1/builder/beacon_block: + $ref: "./apis/builder/beacon_block.yaml" /eth/v1/builder/blinded_blocks: $ref: "./apis/builder/blinded_blocks.yaml" /eth/v2/builder/blinded_blocks: @@ -72,7 +76,7 @@ components: $ref: "./beacon-apis/types/http.yaml#/ErrorMessage" ConsensusVersion: $ref: "./beacon-apis/beacon-node-oapi.yaml#/components/schemas/ConsensusVersion" - enum: [bellatrix, capella, deneb, electra, fulu] + enum: [bellatrix, capella, deneb, electra, fulu, gloas] example: "bellatrix" Bellatrix.ExecutionPayload: $ref: "./beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayload" @@ -102,6 +106,8 @@ components: $ref: "./types/fulu/blobs_bundle.yaml#/Fulu/BlobsBundle" Fulu.ExecutionPayloadAndBlobsBundle: $ref: "./types/fulu/execution_payload_and_blobs_bundle.yaml#/Fulu/ExecutionPayloadAndBlobsBundle" + Gloas.SignedBuilderBid: + $ref: "./types/gloas/bid.yaml#/Gloas/SignedBuilderBid" responses: InternalError: diff --git a/specs/gloas/builder.md b/specs/gloas/builder.md new file mode 100644 index 0000000..7c1a7b6 --- /dev/null +++ b/specs/gloas/builder.md @@ -0,0 +1 @@ +# Gloas - Builder Specification \ No newline at end of file diff --git a/specs/gloas/validator.md b/specs/gloas/validator.md new file mode 100644 index 0000000..75315f8 --- /dev/null +++ b/specs/gloas/validator.md @@ -0,0 +1,84 @@ + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [Gloas - Honest Validator](#gloas---honest-validator) + - [Introduction](#introduction) + - [Containers](#containers) + - [New Containers](#new-containers) + - [`BlindedExecutionPayloadEnvelope`](#blindedexecutionpayloadenvelope) + - [Extended Containers](#extended-containers) + - [`BuilderBid`](#builderbid) + - [Block proposal](#block-proposal) + - [Constructing the `BeaconBlockBody`](#constructing-the-beaconblockbody) + - [ExecutionPayloadBid](#executionpayloadbid) + + + +# Gloas - Honest Validator + + +## Introduction + +This document explains how a beacon-chain validator can participate in the external block building market post ePBS. + +Validators request an `ExecutionPayloadBid` from the external builder network to put it in their `SignedBeaconBlock`. The external builder network broadcasts the `SignedExecutionPayloadEnvelope` corresponding to the bid to the PTC commitee. + +## Containers + +### New Containers + +### `BlindedExecutionPayloadEnvelope` + +```python +class BlindedExecutionPayloadEnvelope(Container): + payload_root: Root + execution_requests_root: Root + builder_index: ValidatorIndex + beacon_block_root: Root + slot: Slot + blob_kzg_commitments_root: Root + state_root: Root +``` + +```python +class SignedBlindedExecutionPayloadEnvelope(Container): + message: BlindedExecutionPayloadEnvelope + signature: Signature +``` + +### Extended Containers + +### `BuilderBid` + +```python +class BuilderBid(Container): + bid: ExecutionPayloadBid + payload_root: Root + execution_requests_root: Root + pubkey: BLSPubkey +``` + +### Block proposal + +#### Constructing the `BeaconBlockBody` + +##### ExecutionPayloadBid + +To obtain an execution payload, a block proposer building a block on top of a beacon `state` in a given `slot` must take +the following actions: + +1. Call upstream builder software to get an `ExecutionPayloadBid` and the roots of the `payload` and `execution_requests` + with the required data `slot`, `parent_hash` and `pubkey`, where: + * `slot` is the proposal's slot + * `parent_hash` is the value `state.latest_execution_payload_header.block_hash` + * `pubkey` is the proposer's public key +2. Assemble a `SignedBeaconBlock` according to the process outlined in the [Gloas specs][gloas-specs] but with + the `ExecutionPayloadBid` from the prior step. +3. The proposer assembles a `SignedBlindedExecutionPayloadEnvelope` with the `payload` and `execution_requests` roots provided + from the prior step. +4. The proposer returns the `SignedBeaconBlock` and `SignedBlindedExecutionPayloadEnvelope` back to the upstream block + building software. +5. The upstream block building software constructs the `SignedExecutionPayloadEnvelope` from the + `SignedBlindedExecutionPayloadEnvelope` and broadcasts it to the PTC commitee. + diff --git a/types/gloas/bid.yaml b/types/gloas/bid.yaml new file mode 100644 index 0000000..a5c3272 --- /dev/null +++ b/types/gloas/bid.yaml @@ -0,0 +1,24 @@ +Gloas: + BuilderBid: + type: object + description: "The `BuilderBid` object from the Builder API spec. The bid is signed by the builder BLS key." + required: [execution_payload_bid] + properties: + execution_payload_bid: + $ref: "../../beacon-apis/types/gloas/execution_payload_bid.yaml#/Gloas/ExecutionPayloadBid" + payload_root: + $ref: "../../beacon-apis/types/primitive.yaml#/Root" + description: "Root of the execution payload" + execution_requests_root: + $ref: "../../beacon-apis/types/primitive.yaml#/Root" + description: "Root of the execution requests" + + SignedBuilderBid: + type: object + description: "The `SignedBuilderBid` object from the Builder API spec. The bid is signed by the builder BLS key." + required: [message, signature] + properties: + message: + $ref: "#/Gloas/BuilderBid" + signature: + $ref: "../../beacon-apis/types/primitive.yaml#/Signature" diff --git a/types/gloas/blinded_execution_payload_envelope.yaml b/types/gloas/blinded_execution_payload_envelope.yaml new file mode 100644 index 0000000..c94d29e --- /dev/null +++ b/types/gloas/blinded_execution_payload_envelope.yaml @@ -0,0 +1,36 @@ +Gloas: + BlindedExecutionPayloadEnvelope: + type: object + description: "The `BlindedExecutionPayloadEnvelope` object from the Builder API spec. The execution payload envelope is blinded by the builder BLS key." + required: [payload, execution_requests, builder_index, beacon_block_root, slot, blob_kzg_commitments_root, state_root] + properties: + payload_root: + $ref: "../../beacon-apis/types/primitive.yaml#/Root" + description: "Root of the execution payload" + execution_requests_root: + $ref: "../../beacon-apis/types/primitive.yaml#/Root" + description: "Root of the execution requests" + builder_index: + $ref: "../../beacon-apis/types/primitive.yaml#/Uint64" + description: "Index of the builder that created this execution payload envelope" + beacon_block_root: + $ref: "../../beacon-apis/types/primitive.yaml#/Root" + description: "Root of the beacon block for this payload" + slot: + $ref: "../../beacon-apis/types/primitive.yaml#/Uint64" + description: "Slot number for this execution payload" + blob_kzg_commitments_root: + $ref: "../../beacon-apis/types/primitive.yaml#/Root" + description: "Root of the blob KZG commitments" + state_root: + $ref: "../../beacon-apis/types/primitive.yaml#/Root" + description: "Beacon state root after executing this payload" + SignedBlindedExecutionPayloadEnvelope: + type: object + description: "The `SignedBlindedExecutionPayloadEnvelope` object from the Builder API spec. The execution payload envelope is signed by the proposer's BLS key." + required: [message, signature] + properties: + message: + $ref: "#/Gloas/BlindedExecutionPayloadEnvelope" + signature: + $ref: "../../beacon-apis/types/primitive.yaml#/Signature" \ No newline at end of file