From fea32e4679b0244a4606a4faee914b02691a5a55 Mon Sep 17 00:00:00 2001 From: Potuz Date: Wed, 8 Jul 2026 12:54:11 -0300 Subject: [PATCH] Add a POST produceBlockV4 This PR adds a POST version of produceBlockV4 in which the validator sends a list of `BuilderPreferences` objects. These object specify a per-builder list of preferences that helps the beacon node chose the right payload bid contained in the block to be produced. This solves issue #620. --- CHANGES.md | 1 + apis/validator/block.v4.yaml | 57 ++++++++++++------------------ beacon-node-oapi.yaml | 6 ++++ types/builder_preferences.yaml | 63 ++++++++++++++++++++++++++++++++++ types/gloas/request_auth.yaml | 26 ++++++++++++++ wordlist.txt | 1 + 6 files changed, 118 insertions(+), 36 deletions(-) create mode 100644 types/builder_preferences.yaml create mode 100644 types/gloas/request_auth.yaml diff --git a/CHANGES.md b/CHANGES.md index 5ece0aaf..bca7cd31 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -38,6 +38,7 @@ There are likely to be descriptions etc outside of the list below, but new query | [#608](https://github.com/ethereum/beacon-APIs/pull/608) `POST /eth/v1/validator/prepare_beacon_proposer` deprecated | | | | | | | [#608](https://github.com/ethereum/beacon-APIs/pull/608) `POST /eth/v1/validator/register_validator` deprecated | | | | | | | [#608](https://github.com/ethereum/beacon-APIs/pull/608) `POST /eth/v1/validator/beacon_committee_subscriptions` updated | | | | | | +| [#XXX](https://github.com/ethereum/beacon-APIs/pull/XXX) `GET /eth/v4/validator/blocks/{slot}` changed to `POST /eth/v4/validator/blocks/{slot}` | | | | | | The Following are no longer in the Standard API, removed since the latest version. diff --git a/apis/validator/block.v4.yaml b/apis/validator/block.v4.yaml index c06e8ae6..55aca624 100644 --- a/apis/validator/block.v4.yaml +++ b/apis/validator/block.v4.yaml @@ -1,4 +1,4 @@ -get: +post: tags: - Validator - ValidatorRequiredApi @@ -7,6 +7,11 @@ get: description: | Requests a beacon node to produce a valid block, which can then be signed by a validator. + The validator supplies in the request body a list of `BuilderPreferences`, one for each + builder that will be contacted, which the beacon node MUST apply when requesting bids from + external builders. The `builder_boost_factor` is expressed per builder in the request body + rather than as a query parameter. + 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 @@ -63,41 +68,21 @@ get: schema: type: boolean default: true - - name: builder_boost_factor - in: query - required: false - description: | - Percentage multiplier to apply to the builder's bid value when choosing between a - builder bid and payload from the paired execution node. This parameter is only relevant - if the beacon node has at least one viable builder `ExecutionPayloadBid` available and - receives a valid response from the paired execution node. When these preconditions are - met, the server MUST act as follows: - - * if `exec_node_payload_value >= builder_boost_factor * (builder_payload_value // 100)` - for the highest builder bid known to the beacon node, then return a block committing - to the local execution node payload (with the payload itself included if - `include_payload` is set to true). - * otherwise, return a block committing to the builder bid (without execution payload, - as it is not yet available). - - 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 builder bid 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 no builder bid is available, the beacon node MUST respond with a block - committing to the local execution node payload, 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" + requestBody: + required: true + description: | + A list of `BuilderPreferences`, one entry for each builder that will be contacted. When + contacting a builder, the beacon node MUST apply the entry whose `url` matches the URL used + to contact that builder. An entry with an empty `url` string denotes the default preferences, + which the beacon node MUST apply to any contacted builder for which no matching entry was + supplied. At most one entry with an empty `url` may be supplied, and no two entries may share + the same `url`. + content: + application/json: + schema: + type: array + items: + $ref: "../../beacon-node-oapi.yaml#/components/schemas/BuilderPreferences" responses: "200": description: Success response diff --git a/beacon-node-oapi.yaml b/beacon-node-oapi.yaml index 859e2eb1..256348ee 100644 --- a/beacon-node-oapi.yaml +++ b/beacon-node-oapi.yaml @@ -497,6 +497,12 @@ components: $ref: "./types/fulu/data_column_sidecar.yaml#/Fulu/DataColumnSidecars" Gloas.DataColumnSidecars: $ref: "./types/gloas/data_column_sidecar.yaml#/Gloas/DataColumnSidecars" + Gloas.RequestAuthV1: + $ref: "./types/gloas/request_auth.yaml#/Gloas/RequestAuthV1" + Gloas.SignedRequestAuthV1: + $ref: "./types/gloas/request_auth.yaml#/Gloas/SignedRequestAuthV1" + BuilderPreferences: + $ref: "./types/builder_preferences.yaml#/BuilderPreferences" Node: $ref: './types/fork_choice.yaml#/Node' ExtraData: diff --git a/types/builder_preferences.yaml b/types/builder_preferences.yaml new file mode 100644 index 00000000..b3c1510f --- /dev/null +++ b/types/builder_preferences.yaml @@ -0,0 +1,63 @@ +BuilderPreferences: + type: object + description: "Per-builder preferences supplied by a validator when requesting block production." + required: [url, builder_boost_factor, max_trusted_bid, min_bid] + properties: + signed_request_auth: + allOf: + - $ref: "./gloas/request_auth.yaml#/Gloas/SignedRequestAuthV1" + - description: | + Optional `SignedRequestAuthV1` object, as defined in the + [Builder API](https://ethereum.github.io/builder-specs/) specification, that the beacon + node MUST forward to the builder when requesting a bid so that the builder can + authenticate the request. If omitted, requests to this builder are sent without + authentication. + url: + type: string + description: | + URL that the beacon node should use to contact the builder. This URL MAY be equal to the + one contained in the `data` field of `signed_request_auth.message`, but it MAY also differ + from it. An empty string denotes the default preferences entry: these preferences are + applied to any contacted builder for which no entry with a matching `url` was supplied. + example: "https://builder.example.com" + builder_boost_factor: + allOf: + - $ref: "./primitive.yaml#/Uint64" + - description: | + Percentage multiplier to apply to this builder's bid value when choosing between a + builder bid and payload from the paired execution node. This value is only relevant + if the beacon node has a viable `ExecutionPayloadBid` available from this builder and + receives a valid response from the paired execution node. When these preconditions + are met, the server MUST act as follows: + + * if `exec_node_payload_value >= builder_boost_factor * (builder_payload_value // 100)` + for the highest builder bid known to the beacon node (each bid boosted by the + factor applicable to the builder it originates from), then return a block + committing to the local execution node payload. + * otherwise, return a block committing to the builder bid (without execution payload, + as it is not yet available). + + 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 this builder's bid 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. + max_trusted_bid: + allOf: + - $ref: "./primitive.yaml#/Gwei" + - description: | + The maximum trusted bid, in Gwei, that will be accepted from this builder. Bids with a + value exceeding this amount MUST NOT be accepted. + min_bid: + allOf: + - $ref: "./primitive.yaml#/Gwei" + - description: | + The minimum bid, in Gwei, that the validator will accept from this builder. Bids with a + value lower than this amount MUST NOT be accepted. diff --git a/types/gloas/request_auth.yaml b/types/gloas/request_auth.yaml new file mode 100644 index 00000000..86321cd9 --- /dev/null +++ b/types/gloas/request_auth.yaml @@ -0,0 +1,26 @@ +Gloas: + RequestAuthV1: + type: object + description: "The `RequestAuthV1` object from the [Builder API](https://ethereum.github.io/builder-specs/) Gloas spec." + required: [data, slot] + properties: + data: + type: string + format: hex + description: "Opaque authentication data, up to `MAX_DATA_SIZE` bytes. Typically set to the URL of the builder the request is intended for." + example: "0x68747470733a2f2f6275696c6465722e6578616d706c652e636f6d" + pattern: "^0x[a-fA-F0-9]{0,8192}$" + slot: + allOf: + - $ref: "../primitive.yaml#/Uint64" + - description: "The slot for which the bid is being requested." + + SignedRequestAuthV1: + type: object + description: "The `SignedRequestAuthV1` object from the [Builder API](https://ethereum.github.io/builder-specs/) Gloas spec." + required: [message, signature] + properties: + message: + $ref: "#/Gloas/RequestAuthV1" + signature: + $ref: "../primitive.yaml#/Signature" diff --git a/wordlist.txt b/wordlist.txt index b03ee999..e16374f4 100644 --- a/wordlist.txt +++ b/wordlist.txt @@ -47,3 +47,4 @@ produceBlockV stateful CGC RLP +auth