From 899c416ef7d7fee011873a4b7b2fc1f8a8d43e07 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Fri, 6 May 2022 17:00:08 +0200 Subject: [PATCH 01/37] re-add schema --- apis/builder/blinded_blocks.yaml | 37 +++++++ apis/builder/header.yaml | 58 ++++++++++ apis/builder/validators.yaml | 32 ++++++ builder-oapi.yaml | 180 +++++++++++++++++++++++++++++++ types/registration.yaml | 29 +++++ 5 files changed, 336 insertions(+) create mode 100644 apis/builder/blinded_blocks.yaml create mode 100644 apis/builder/header.yaml create mode 100644 apis/builder/validators.yaml create mode 100644 builder-oapi.yaml create mode 100644 types/registration.yaml diff --git a/apis/builder/blinded_blocks.yaml b/apis/builder/blinded_blocks.yaml new file mode 100644 index 0000000..2d81f1b --- /dev/null +++ b/apis/builder/blinded_blocks.yaml @@ -0,0 +1,37 @@ +post: + tags: + - Builder + operationId: "submitBlindedBlock" + summary: Submit a signed blinded block. + description: | + Submits a `SignedBlindedBeaconBlock` to the builder, binding them to the + block. The builder is now able to unblind the transactions in the + `ExecutionPayloadHeader` without the possibility of the validator modifying + them. + requestBody: + description: | + The `SignedBlindedBeaconBlock` object composed of `BlindedBeaconBlock` + object (produced by beacon node with `ExecutionPayloadHeader` from + external builder) and validator signature. + required: true + content: + application/json: + schema: + oneOf: + - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.SignedBlindedBeaconBlock" + responses: + "200": + description: | + The block was validated successfully and has been sent to the builder. + "400": + description: The `SignedBeaconBlock` object is invalid + content: + application/json: + schema: + allOf: + - $ref: "../../builder-oapi.yaml#/components/schemas/ErrorMessage" + - example: + code: 400 + message: "Invalid block: missing signature" + "500": + $ref: '../../builder-oapi.yaml#/components/responses/InternalError' diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml new file mode 100644 index 0000000..8bc3a95 --- /dev/null +++ b/apis/builder/header.yaml @@ -0,0 +1,58 @@ +get: + tags: + - Builder + operationId: "getHeader" + summary: Get an ExecutionPayloadHeader. + description: | + Requests a builder node to produce a valid execution payload header, which can integrated into a blinded beacon block and signed. + + Metadata in the response indicates the type of block produced, and the supported types of block + will be added to as forks progress. + 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 use as the proposal's parent." + schema: + $ref: '../../builder-oapi.yaml#/components/schemas/Root' + - name: pubkey + in: query + required: true + description: "The validator's BLS public key." + schema: + $ref: '../../builder-oapi.yaml#/components/schemas/Pubkey' + responses: + "200": + description: Success response + content: + application/json: + schema: + title: ProduceBlockV2Response + type: object + properties: + version: + type: string + enum: [ phase0, altair, bellatrix ] + example: "phase0" + data: + oneOf: + - $ref: '../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayloadHeader' + "400": + description: "Invalid block production request" + content: + application/json: + schema: + $ref: "../../builder-oapi.yaml#/components/schemas/ErrorMessage" + examples: + InvalidRequest: + value: + code: 400 + message: "Invalid request to produce a block" + "500": + $ref: '../../builder-oapi.yaml#/components/responses/InternalError' diff --git a/apis/builder/validators.yaml b/apis/builder/validators.yaml new file mode 100644 index 0000000..9d8fd46 --- /dev/null +++ b/apis/builder/validators.yaml @@ -0,0 +1,32 @@ +post: + tags: + - Builder + operationId: "registerValidator" + summary: Register or update a validator's block building preferences. + description: | + Registers a validator's preferred fee recipient and gas limit target. + requestBody: + description: | + The `SignedBeaconBlock` object composed of `BeaconBlock` object (produced + by beacon node) and validator signature. + required: true + content: + application/json: + schema: + oneOf: + - $ref: '../../builder-oapi.yaml#/components/schemas/SignedValidatorRegistration' + responses: + "200": + description: Success response + "400": + description: The `SignedValidatorRegistration` is invalid. + content: + application/json: + schema: + allOf: + - $ref: "../../builder-oapi.yaml#/components/schemas/ErrorMessage" + - example: + code: 400 + message: "Unknown validator: 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95" + "500": + $ref: '../../builder-oapi.yaml#/components/responses/InternalError' diff --git a/builder-oapi.yaml b/builder-oapi.yaml new file mode 100644 index 0000000..86a0768 --- /dev/null +++ b/builder-oapi.yaml @@ -0,0 +1,180 @@ +openapi: "3.0.3" + +info: + title: "Builder API" + description: | + API specification for external builder clients, which enables validators to delegate block building duties. + + All requests by default send and receive JSON, and as such should have either or both of the "Content-Type: application/json" + and "Accept: application/json" headers. In addition, some requests can return data in the SSZ format. To indicate that SSZ + data is required in response to a request the header "Accept: application/octet-stream" should be sent. Note that only a subset + of requests can respond with data in SSZ format; these are noted in each individual request. + + API endpoints are individually versioned. As such, there is no direct relationship between all v1 endpoints, all v2 endpoints, + _etc._ and no such relationship should be inferred. All JSON responses return the requested data under a `data` key in the top + level of their response. Additional metadata may or may not be present in other keys at the top level of the response, dependent + on the endpoint. The rules that require an increase in version number are as follows: + + - no field that is listed in an endpoint shall be removed without an increase in the version number + - no field that is listed in an endpoint shall be altered in terms of format (_e.g._ from a string to an array) without an + increase in the version number + + Note that it is possible for a field to be added to an endpoint's data or metadata without an increase in the version number. + + version: "dev" + contact: + name: Ethereum Github + url: https://github.com/ethereum/builder-apis/issues + license: + name: "Apache 2.0" + url: "https://www.apache.org/licenses/LICENSE-2.0.html" + +servers: + - url: "{server_url}" + variables: + server_url: + description: "Builder node API url" + default: "???" + +tags: + - name: Builder + description: Set of endpoints to interact with an external block builder. +paths: + + /eth/v1/builder/validators: + $ref: "./apis/builder/validators.yaml" + /eth/v1/builder/{slot}/{parent_hash}/header: + $ref: "./apis/builder/header.yaml" + /eth/v1/builder/blinded_blocks: + $ref: "./apis/builder/blinded_blocks.yaml" + + +components: + schemas: + BeaconState: + $ref: './beacon-apis/types/state.yaml#/BeaconState' + BeaconBlock: + $ref: './beacon-apis/types/block.yaml#/BeaconBlock' + SignedBeaconBlock: + $ref: './beacon-apis/types/block.yaml#/SignedBeaconBlock' + SignedBeaconBlockHeader: + $ref: './beacon-apis/types/block.yaml#/SignedBeaconBlockHeader' + ValidatorResponse: + $ref: './beacon-apis/types/api.yaml#/ValidatorResponse' + ValidatorBalanceResponse: + $ref: './beacon-apis/types/api.yaml#/ValidatorBalanceResponse' + ValidatorStatus: + $ref: './beacon-apis/types/api.yaml#/ValidatorStatus' + Committee: + $ref: './beacon-apis/types/api.yaml#/Committee' + AttesterSlashing: + $ref: './beacon-apis/types/attester_slashing.yaml#/AttesterSlashing' + ProposerSlashing: + $ref: './beacon-apis/types/proposer_slashing.yaml#/ProposerSlashing' + SignedVoluntaryExit: + $ref: './beacon-apis/types/voluntary_exit.yaml#/SignedVoluntaryExit' + AttesterDuty: + $ref: './beacon-apis/types/validator.yaml#/AttesterDuty' + ProposerDuty: + $ref: './beacon-apis/types/validator.yaml#/ProposerDuty' + Altair.SyncDuty: + $ref: './beacon-apis/types/validator.yaml#/Altair/SyncDuty' + SignedAggregateAndProof: + $ref: './beacon-apis/types/validator.yaml#/SignedAggregateAndProof' + Attestation: + $ref: './beacon-apis/types/attestation.yaml#/Attestation' + AttestationData: + $ref: './beacon-apis/types/attestation.yaml#/AttestationData' + Fork: + $ref: './beacon-apis/types/misc.yaml#/Fork' + Checkpoint: + $ref: './beacon-apis/types/misc.yaml#/Checkpoint' + Uint64: + $ref: './beacon-apis/types/primitive.yaml#/Uint64' + GenesisTime: + $ref: './beacon-apis/types/primitive.yaml#/GenesisTime' + Version: + $ref: './beacon-apis/types/primitive.yaml#/Version' + ForkVersion: + $ref: './beacon-apis/types/primitive.yaml#/ForkVersion' + DependentRoot: + $ref: './beacon-apis/types/primitive.yaml#/DependentRoot' + ExecutionOptimistic: + $ref: './beacon-apis/types/primitive.yaml#/ExecutionOptimistic' + Root: + $ref: './beacon-apis/types/primitive.yaml#/Root' + Hex: + $ref: './beacon-apis/types/primitive.yaml#/Hex' + Graffiti: + $ref: './beacon-apis/types/primitive.yaml#/Graffiti' + Pubkey: + $ref: './beacon-apis/types/primitive.yaml#/Pubkey' + Signature: + $ref: './beacon-apis/types/primitive.yaml#/Signature' + ErrorMessage: + $ref: './beacon-apis/types/http.yaml#/ErrorMessage' + IndexedErrorMessage: + $ref: './beacon-apis/types/http.yaml#/IndexedErrorMessage' + Altair.SignedBeaconBlock: + $ref: './beacon-apis/types/altair/block.yaml#/Altair/SignedBeaconBlock' + Altair.BeaconBlock: + $ref: './beacon-apis/types/altair/block.yaml#/Altair/BeaconBlock' + Altair.BeaconState: + $ref: './beacon-apis/types/altair/state.yaml#/Altair/BeaconState' + Altair.SyncCommitteeSignature: + $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/SyncCommitteeSignature' + Altair.SyncCommitteeSubscription: + $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/SyncCommitteeSubscription' + Altair.ContributionAndProof: + $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/ContributionAndProof' + Altair.SignedContributionAndProof: + $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/SignedContributionAndProof' + Altair.SyncCommitteeContribution: + $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/SyncCommitteeContribution' + Altair.SyncCommittee: + $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/SyncCommitteeByValidatorIndices' + ExecutionAddress: + $ref: './beacon-apis/types/primitive.yaml#/ExecutionAddress' + Bellatrix.BeaconState: + $ref: './beacon-apis/types/bellatrix/state.yaml#/Bellatrix/BeaconState' + Bellatrix.ExecutionPayload: + $ref: './beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayload' + Bellatrix.ExecutionPayloadHeader: + $ref: './beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader' + Bellatrix.BeaconBlock: + $ref: './beacon-apis/types/bellatrix/block.yaml#/Bellatrix/BeaconBlock' + Bellatrix.SignedBeaconBlock: + $ref: './beacon-apis/types/bellatrix/block.yaml#/Bellatrix/SignedBeaconBlock' + Bellatrix.BlindedBeaconBlock: + $ref: './beacon-apis/types/bellatrix/block.yaml#/Bellatrix/BlindedBeaconBlock' + Bellatrix.SignedBlindedBeaconBlock: + $ref: './beacon-apis/types/bellatrix/block.yaml#/Bellatrix/SignedBlindedBeaconBlock' + + ValidatorRegistration: + $ref: './types/registration.yaml#/ValidatorRegistration' + SignedValidatorRegistration: + $ref: './types/registration.yaml#/SignedValidatorRegistration' + + parameters: + StateId: + $ref: './beacon-apis/params/index.yaml#/StateId' + BlockId: + $ref: './beacon-apis/params/index.yaml#/BlockId' + + responses: + InvalidRequest: + $ref: './beacon-apis/types/http.yaml#/InvalidRequest' + NotFound: + $ref: './beacon-apis/types/http.yaml#/NotFound' + InternalError: + $ref: './beacon-apis/types/http.yaml#/InternalError' + CurrentlySyncing: + $ref: './beacon-apis/types/http.yaml#/CurrentlySyncing' + + headers: + Eth-Consensus-Version: + description: Required in response so client can deserialize returned json or ssz data more effectively. + schema: + type: string + enum: [phase0, altair, bellatrix] + example: "phase0" diff --git a/types/registration.yaml b/types/registration.yaml new file mode 100644 index 0000000..9f4646f --- /dev/null +++ b/types/registration.yaml @@ -0,0 +1,29 @@ +ValidatorRegistration: + type: object + description: "The [`ValidatorRegistration`]() object from the Builder API spec." + properties: + fee_recipient: + allOf: + - $ref: '../beacon-apis/types/primitive.yaml#/ExecutionAddress' + - description: "Address to receive fees from the block." + gas_limit: + allOf: + - $ref: "../beacon-apis/types/primitive.yaml#/Uint64" + - description: "Gas limit the validator desires to target." + timestamp: + allOf: + - $ref: '../beacon-apis/types/primitive.yaml#/Uint64' + - description: "Unix timestamp of registration." + pubkey: + allOf: + - $ref: '../beacon-apis/types/primitive.yaml#/Pubkey' + - description: "BLS public key of validator." + +SignedValidatorRegistration: + type: object + description: "The [`SignedValidatorRegistration`]() object from the Builder API spec." + properties: + message: + $ref: "#/ValidatorRegistration" + signature: + $ref: "../beacon-apis/types/primitive.yaml#/Signature" From 7ae1541a44f6b3b781a3f21e8a3e922e9aa6b7ca Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Fri, 6 May 2022 17:34:06 +0200 Subject: [PATCH 02/37] return execution payload after blinded block is posted --- apis/builder/blinded_blocks.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apis/builder/blinded_blocks.yaml b/apis/builder/blinded_blocks.yaml index 2d81f1b..d1bd9bb 100644 --- a/apis/builder/blinded_blocks.yaml +++ b/apis/builder/blinded_blocks.yaml @@ -23,6 +23,11 @@ post: "200": description: | The block was validated successfully and has been sent to the builder. + content: + application/json: + schema: + oneOf: + - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayload" "400": description: The `SignedBeaconBlock` object is invalid content: From 079f9097f1bbfd1e2813c87f20bce6d57f638bef Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Fri, 6 May 2022 17:39:35 +0200 Subject: [PATCH 03/37] remove unused components --- builder-oapi.yaml | 106 ---------------------------------------------- 1 file changed, 106 deletions(-) diff --git a/builder-oapi.yaml b/builder-oapi.yaml index 86a0768..8cf1042 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -51,130 +51,24 @@ paths: components: schemas: - BeaconState: - $ref: './beacon-apis/types/state.yaml#/BeaconState' - BeaconBlock: - $ref: './beacon-apis/types/block.yaml#/BeaconBlock' - SignedBeaconBlock: - $ref: './beacon-apis/types/block.yaml#/SignedBeaconBlock' - SignedBeaconBlockHeader: - $ref: './beacon-apis/types/block.yaml#/SignedBeaconBlockHeader' - ValidatorResponse: - $ref: './beacon-apis/types/api.yaml#/ValidatorResponse' - ValidatorBalanceResponse: - $ref: './beacon-apis/types/api.yaml#/ValidatorBalanceResponse' - ValidatorStatus: - $ref: './beacon-apis/types/api.yaml#/ValidatorStatus' - Committee: - $ref: './beacon-apis/types/api.yaml#/Committee' - AttesterSlashing: - $ref: './beacon-apis/types/attester_slashing.yaml#/AttesterSlashing' - ProposerSlashing: - $ref: './beacon-apis/types/proposer_slashing.yaml#/ProposerSlashing' - SignedVoluntaryExit: - $ref: './beacon-apis/types/voluntary_exit.yaml#/SignedVoluntaryExit' - AttesterDuty: - $ref: './beacon-apis/types/validator.yaml#/AttesterDuty' - ProposerDuty: - $ref: './beacon-apis/types/validator.yaml#/ProposerDuty' - Altair.SyncDuty: - $ref: './beacon-apis/types/validator.yaml#/Altair/SyncDuty' - SignedAggregateAndProof: - $ref: './beacon-apis/types/validator.yaml#/SignedAggregateAndProof' - Attestation: - $ref: './beacon-apis/types/attestation.yaml#/Attestation' - AttestationData: - $ref: './beacon-apis/types/attestation.yaml#/AttestationData' - Fork: - $ref: './beacon-apis/types/misc.yaml#/Fork' - Checkpoint: - $ref: './beacon-apis/types/misc.yaml#/Checkpoint' Uint64: $ref: './beacon-apis/types/primitive.yaml#/Uint64' - GenesisTime: - $ref: './beacon-apis/types/primitive.yaml#/GenesisTime' - Version: - $ref: './beacon-apis/types/primitive.yaml#/Version' - ForkVersion: - $ref: './beacon-apis/types/primitive.yaml#/ForkVersion' - DependentRoot: - $ref: './beacon-apis/types/primitive.yaml#/DependentRoot' - ExecutionOptimistic: - $ref: './beacon-apis/types/primitive.yaml#/ExecutionOptimistic' Root: $ref: './beacon-apis/types/primitive.yaml#/Root' - Hex: - $ref: './beacon-apis/types/primitive.yaml#/Hex' - Graffiti: - $ref: './beacon-apis/types/primitive.yaml#/Graffiti' Pubkey: $ref: './beacon-apis/types/primitive.yaml#/Pubkey' - Signature: - $ref: './beacon-apis/types/primitive.yaml#/Signature' ErrorMessage: $ref: './beacon-apis/types/http.yaml#/ErrorMessage' - IndexedErrorMessage: - $ref: './beacon-apis/types/http.yaml#/IndexedErrorMessage' - Altair.SignedBeaconBlock: - $ref: './beacon-apis/types/altair/block.yaml#/Altair/SignedBeaconBlock' - Altair.BeaconBlock: - $ref: './beacon-apis/types/altair/block.yaml#/Altair/BeaconBlock' - Altair.BeaconState: - $ref: './beacon-apis/types/altair/state.yaml#/Altair/BeaconState' - Altair.SyncCommitteeSignature: - $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/SyncCommitteeSignature' - Altair.SyncCommitteeSubscription: - $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/SyncCommitteeSubscription' - Altair.ContributionAndProof: - $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/ContributionAndProof' - Altair.SignedContributionAndProof: - $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/SignedContributionAndProof' - Altair.SyncCommitteeContribution: - $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/SyncCommitteeContribution' - Altair.SyncCommittee: - $ref: './beacon-apis/types/altair/sync_committee.yaml#/Altair/SyncCommitteeByValidatorIndices' - ExecutionAddress: - $ref: './beacon-apis/types/primitive.yaml#/ExecutionAddress' - Bellatrix.BeaconState: - $ref: './beacon-apis/types/bellatrix/state.yaml#/Bellatrix/BeaconState' Bellatrix.ExecutionPayload: $ref: './beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayload' Bellatrix.ExecutionPayloadHeader: $ref: './beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader' - Bellatrix.BeaconBlock: - $ref: './beacon-apis/types/bellatrix/block.yaml#/Bellatrix/BeaconBlock' - Bellatrix.SignedBeaconBlock: - $ref: './beacon-apis/types/bellatrix/block.yaml#/Bellatrix/SignedBeaconBlock' - Bellatrix.BlindedBeaconBlock: - $ref: './beacon-apis/types/bellatrix/block.yaml#/Bellatrix/BlindedBeaconBlock' Bellatrix.SignedBlindedBeaconBlock: $ref: './beacon-apis/types/bellatrix/block.yaml#/Bellatrix/SignedBlindedBeaconBlock' - ValidatorRegistration: - $ref: './types/registration.yaml#/ValidatorRegistration' SignedValidatorRegistration: $ref: './types/registration.yaml#/SignedValidatorRegistration' - parameters: - StateId: - $ref: './beacon-apis/params/index.yaml#/StateId' - BlockId: - $ref: './beacon-apis/params/index.yaml#/BlockId' - responses: - InvalidRequest: - $ref: './beacon-apis/types/http.yaml#/InvalidRequest' - NotFound: - $ref: './beacon-apis/types/http.yaml#/NotFound' InternalError: $ref: './beacon-apis/types/http.yaml#/InternalError' - CurrentlySyncing: - $ref: './beacon-apis/types/http.yaml#/CurrentlySyncing' - - headers: - Eth-Consensus-Version: - description: Required in response so client can deserialize returned json or ssz data more effectively. - schema: - type: string - enum: [phase0, altair, bellatrix] - example: "phase0" From 0fdd92a0152d619ce0fb49cf343c2e53351b6ef8 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 11:00:19 +0200 Subject: [PATCH 04/37] clean up endpoint defns --- apis/builder/blinded_blocks.yaml | 16 +++++++------- apis/builder/header.yaml | 37 +++++++++++++++++++++----------- apis/builder/validators.yaml | 21 +++++++++++------- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/apis/builder/blinded_blocks.yaml b/apis/builder/blinded_blocks.yaml index d1bd9bb..eba5d89 100644 --- a/apis/builder/blinded_blocks.yaml +++ b/apis/builder/blinded_blocks.yaml @@ -4,15 +4,16 @@ post: operationId: "submitBlindedBlock" summary: Submit a signed blinded block. description: | - Submits a `SignedBlindedBeaconBlock` to the builder, binding them to the - block. The builder is now able to unblind the transactions in the + Submits a `SignedBlindedBeaconBlock` to the builder, binding the proposer + to the block. The builder is now able to unblind the transactions in `ExecutionPayloadHeader` without the possibility of the validator modifying them. + + If the builder is not able to unblind the corresponding + `ExecutionPayloadHeader`, it must error. requestBody: description: | - The `SignedBlindedBeaconBlock` object composed of `BlindedBeaconBlock` - object (produced by beacon node with `ExecutionPayloadHeader` from - external builder) and validator signature. + A `SignedBlindedBeaconBlock`. required: true content: application/json: @@ -21,15 +22,14 @@ post: - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.SignedBlindedBeaconBlock" responses: "200": - description: | - The block was validated successfully and has been sent to the builder. + description: Success response. content: application/json: schema: oneOf: - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayload" "400": - description: The `SignedBeaconBlock` object is invalid + description: Error response. content: application/json: schema: diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index 8bc3a95..176c541 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -2,49 +2,60 @@ get: tags: - Builder operationId: "getHeader" - summary: Get an ExecutionPayloadHeader. + summary: Get an `ExecutionPayloadHeader`. description: | - Requests a builder node to produce a valid execution payload header, which can integrated into a blinded beacon block and signed. + Requests a builder node to produce a valid execution payload header, which + can integrated into a blinded beacon block and signed. - Metadata in the response indicates the type of block produced, and the supported types of block - will be added to as forks progress. + Builder must immediately return the header that is able to pay + `feeRecipient` the most. If the builder is unaware of `parent_hash`, it + must error. If `pubkey` does not match the builder's expected proposer + `pubkey` for `slot, it must error. If the builder has not received a + validator registration associated with `pubkey`, it must error. + + When possibe, the builder must return a header with `gas_limit` equal to + proposer's registered value. If this isn't possible due to the large + difference between `parent.gas_limit` and the preferred `gas_limit`, the + builder must return a header that moves `gas_limit` the maximum amount + allowed under the rules of consensus (currently `parent.gas_limit +/- + parent.gas_limit / 1024`). parameters: - name: slot in: path required: true - description: "The slot for which the block should be proposed." + 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 use as the proposal's parent." + description: Hash of execution layer block the proposer will build on. schema: $ref: '../../builder-oapi.yaml#/components/schemas/Root' - name: pubkey in: query required: true - description: "The validator's BLS public key." + description: The validator's BLS public key. schema: $ref: '../../builder-oapi.yaml#/components/schemas/Pubkey' responses: "200": - description: Success response + description: Success response. content: application/json: schema: - title: ProduceBlockV2Response + title: GetHeaderResponse type: object properties: version: type: string - enum: [ phase0, altair, bellatrix ] - example: "phase0" + enum: [ bellatrix ] + example: "bellatrix" data: oneOf: - $ref: '../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayloadHeader' "400": - description: "Invalid block production request" + description: Error response. content: application/json: schema: @@ -53,6 +64,6 @@ get: InvalidRequest: value: code: 400 - message: "Invalid request to produce a block" + message: "Unknown hash: missing parent hash" "500": $ref: '../../builder-oapi.yaml#/components/responses/InternalError' diff --git a/apis/builder/validators.yaml b/apis/builder/validators.yaml index 9d8fd46..fb5b379 100644 --- a/apis/builder/validators.yaml +++ b/apis/builder/validators.yaml @@ -4,22 +4,27 @@ post: operationId: "registerValidator" summary: Register or update a validator's block building preferences. description: | - Registers a validator's preferred fee recipient and gas limit target. + Registers a validator's preferred fee recipient and gas limit. + + Builders should verify that `pubkey` corresponds to an active or pending + validator, and that `signature` is valid under `pubkey`. Otherwise, builder + must error. Requests with `timestamp` less than or equal to the previous + announcement must error. Requests with `timestamp` greater than 10 seconds + +/- the builder's local time must error. requestBody: - description: | - The `SignedBeaconBlock` object composed of `BeaconBlock` object (produced - by beacon node) and validator signature. + description: An array of signed validator block building preferences. required: true content: application/json: schema: - oneOf: - - $ref: '../../builder-oapi.yaml#/components/schemas/SignedValidatorRegistration' + type: array + items: + $ref: '../../builder-oapi.yaml#/components/schemas/SignedValidatorRegistration' responses: "200": - description: Success response + description: Success response. "400": - description: The `SignedValidatorRegistration` is invalid. + description: Error response. content: application/json: schema: From 198f9e15c3764b7c3b0fbd9ec8bef3391ceeab61 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 12:39:46 +0200 Subject: [PATCH 05/37] add ssz defns --- specs/README.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 specs/README.md diff --git a/specs/README.md b/specs/README.md new file mode 100644 index 0000000..ad0f506 --- /dev/null +++ b/specs/README.md @@ -0,0 +1,81 @@ +# Builder Specification + +This document specifies the behaviour of external block builders not already +covered in the corresponding API schema. + +## Structures + +### SSZ Objects + +Consider the following definitions supplementary to the definitions in +[`consensus-specs`][consensus-specs]. + +##### `ValidatorRegistrationV1` + +```python +class ValidatorRegistrationV1(Container): + feeRecipient: Bytes20 + gasLimit: uint64 + timestamp: uint64 + pubkey: BLSPubkey +``` + +##### `BuilderBidV1` + +```python +class BuilderBidV1(Container): + header: ExecutionPayloadHeader + value: uint256 + pubkey: BLSPubkey +``` + +###### `BlindedBeaconBlock` + +```python +class BlindedBeaconBlock(Container): + slot: Slot + proposer_index: ValidatorIndex + parent_root: Root + state_root: Root + body: BlindedBeaconBlockBody +``` + +###### `BlindedBeaconBlockBody` + +```python +class BlindedBeaconBlockBody(Container): + randao_reveal: BLSSignature + eth1_data: Eth1Data + graffiti: Bytes32 + proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS] + attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS] + attestations: List[Attestation, MAX_ATTESTATIONS] + deposits: List[Deposit, MAX_DEPOSITS] + voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS] + sync_aggregate: SyncAggregate + execution_payload_header: ExecutionPayloadHeader +``` + +## Routines + +### Signing + +All signature operations should follow the [standard BLS operations][bls] +interface defined in `consensus-specs`. + +There are two types of data to sign over in the Builder API: +* In-protocol messages, e.g. [`BlindedBeaconBlock`](#blindedbeaconblock), which + should compute the signing root using [`compute_signing_root`][compute-root] + and use the domain specified for beacon block proposals. +* Builder API messages, e.g. validator registration, which should compute the + signing root using [`compute_signing_root`][compute-root] and the domain + `DomainType('0xXXXXXXXX')` (TODO: get a proper domain). + +As `compute_signing_root` takes `SSZObject` as input, client software should +convert in-protocol messages to their SSZ representation to compute the signing +root and Builder API messages to the SSZ representations defined +[above](#sszobjects). + +[consensus-specs]: https://github.com/ethereum/consensus-specs +[bls]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#bls-signatures +[compute-root]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_signing_root From 50411ce801a6c1a79ff71050a1c8856d435ad6ef Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 18:38:02 +0200 Subject: [PATCH 06/37] add builder bid --- apis/builder/header.yaml | 2 +- builder-oapi.yaml | 6 ++---- types/bid.yaml | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 types/bid.yaml diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index 176c541..dcb1278 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -53,7 +53,7 @@ get: example: "bellatrix" data: oneOf: - - $ref: '../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayloadHeader' + - $ref: '../../builder-oapi.yaml#/components/schemas/SignedBuilderBid' "400": description: Error response. content: diff --git a/builder-oapi.yaml b/builder-oapi.yaml index 8cf1042..a143402 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -40,7 +40,6 @@ tags: - name: Builder description: Set of endpoints to interact with an external block builder. paths: - /eth/v1/builder/validators: $ref: "./apis/builder/validators.yaml" /eth/v1/builder/{slot}/{parent_hash}/header: @@ -48,7 +47,6 @@ paths: /eth/v1/builder/blinded_blocks: $ref: "./apis/builder/blinded_blocks.yaml" - components: schemas: Uint64: @@ -61,13 +59,13 @@ components: $ref: './beacon-apis/types/http.yaml#/ErrorMessage' Bellatrix.ExecutionPayload: $ref: './beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayload' - Bellatrix.ExecutionPayloadHeader: - $ref: './beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader' Bellatrix.SignedBlindedBeaconBlock: $ref: './beacon-apis/types/bellatrix/block.yaml#/Bellatrix/SignedBlindedBeaconBlock' SignedValidatorRegistration: $ref: './types/registration.yaml#/SignedValidatorRegistration' + SignedBuilderBid: + $ref: './types/bid.yaml#/SignedBuilderBid' responses: InternalError: diff --git a/types/bid.yaml b/types/bid.yaml new file mode 100644 index 0000000..a8c3bc4 --- /dev/null +++ b/types/bid.yaml @@ -0,0 +1,22 @@ +BuilderBid: + type: object + description: "The `BuilderBid` object from the Builder API spec." + properties: + header: + $ref: '../beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader' + description: "`ExecutionPayloadHeader` for validator to sign." + value: + $ref: "../beacon-apis/types/primitive.yaml#/Uint64" + description: "Payment in wei that will be paid to the feeRecipient account." + pubkey: + $ref: '../beacon-apis/types/primitive.yaml#/Pubkey' + description: "BLS public key of builder." + +SignedBuilderBid: + type: object + description: "The `SignedBuilderBid` object from the Builder API spec." + properties: + message: + $ref: "#/BuilderBid" + signature: + $ref: "../beacon-apis/types/primitive.yaml#/Signature" From abae9939a9be136cf73ae1978eff4a3a39d634b9 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 18:54:46 +0200 Subject: [PATCH 07/37] adjust get header path and few other fixes Co-authored-by: lightclient@protonmail.com Co-authored-by: Chris Hager --- apis/builder/header.yaml | 4 ++-- apis/builder/validators.yaml | 4 ++-- builder-oapi.yaml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index dcb1278..1e71465 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -10,7 +10,7 @@ get: Builder must immediately return the header that is able to pay `feeRecipient` the most. If the builder is unaware of `parent_hash`, it must error. If `pubkey` does not match the builder's expected proposer - `pubkey` for `slot, it must error. If the builder has not received a + `pubkey` for `slot`, it must error. If the builder has not received a validator registration associated with `pubkey`, it must error. When possibe, the builder must return a header with `gas_limit` equal to @@ -33,7 +33,7 @@ get: schema: $ref: '../../builder-oapi.yaml#/components/schemas/Root' - name: pubkey - in: query + in: path required: true description: The validator's BLS public key. schema: diff --git a/apis/builder/validators.yaml b/apis/builder/validators.yaml index fb5b379..6acc585 100644 --- a/apis/builder/validators.yaml +++ b/apis/builder/validators.yaml @@ -9,8 +9,8 @@ post: Builders should verify that `pubkey` corresponds to an active or pending validator, and that `signature` is valid under `pubkey`. Otherwise, builder must error. Requests with `timestamp` less than or equal to the previous - announcement must error. Requests with `timestamp` greater than 10 seconds - +/- the builder's local time must error. + announcement must error. Requests with `timestamp` more than 10 seconds in + the future must error. requestBody: description: An array of signed validator block building preferences. required: true diff --git a/builder-oapi.yaml b/builder-oapi.yaml index a143402..8e1dce8 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -42,7 +42,7 @@ tags: paths: /eth/v1/builder/validators: $ref: "./apis/builder/validators.yaml" - /eth/v1/builder/{slot}/{parent_hash}/header: + /eth/v1/builder/header/{slot}/{parent_hash}/{pubkey}: $ref: "./apis/builder/header.yaml" /eth/v1/builder/blinded_blocks: $ref: "./apis/builder/blinded_blocks.yaml" From a4ec2dccc57ea57ca832a671d574c2f973e1ef8d Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 19:10:36 +0200 Subject: [PATCH 08/37] update oapi --- builder-oapi.yaml | 54 ++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/builder-oapi.yaml b/builder-oapi.yaml index 8e1dce8..372d743 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -1,33 +1,35 @@ openapi: "3.0.3" info: - title: "Builder API" + title: Builder API description: | - API specification for external builder clients, which enables validators to delegate block building duties. + API specification for external builder nodes. This interface enables + validators to delegate block building duties, while allowing for + attribution in the case of most faults (e.g. producing an invalid block). - All requests by default send and receive JSON, and as such should have either or both of the "Content-Type: application/json" - and "Accept: application/json" headers. In addition, some requests can return data in the SSZ format. To indicate that SSZ - data is required in response to a request the header "Accept: application/octet-stream" should be sent. Note that only a subset - of requests can respond with data in SSZ format; these are noted in each individual request. + API endpoints are individually versioned. As such, there is no direct + relationship between all v1 endpoints, all v2 endpoints, _etc._ and no such + relationship should be inferred. All JSON responses return the requested + data under a `data` key in the top level of their response. Additional + metadata may or may not be present in other keys at the top level of the + response, dependent on the endpoint. The rules that require an increase in + version number are as follows: - API endpoints are individually versioned. As such, there is no direct relationship between all v1 endpoints, all v2 endpoints, - _etc._ and no such relationship should be inferred. All JSON responses return the requested data under a `data` key in the top - level of their response. Additional metadata may or may not be present in other keys at the top level of the response, dependent - on the endpoint. The rules that require an increase in version number are as follows: - - - no field that is listed in an endpoint shall be removed without an increase in the version number - - no field that is listed in an endpoint shall be altered in terms of format (_e.g._ from a string to an array) without an + - no field that is listed in an endpoint shall be removed without an increase in the version number + - no field that is listed in an endpoint shall be altered in terms of + format (_e.g._ from a string to an array) without an increase in the + version number - Note that it is possible for a field to be added to an endpoint's data or metadata without an increase in the version number. - + Note that it is possible for a field to be added to an endpoint"s data or + metadata without an increase in the version number. version: "dev" contact: name: Ethereum Github url: https://github.com/ethereum/builder-apis/issues license: - name: "Apache 2.0" - url: "https://www.apache.org/licenses/LICENSE-2.0.html" + name: "CC0-1.0" + url: "https://creativecommons.org/publicdomain/zero/1.0/" servers: - url: "{server_url}" @@ -50,23 +52,23 @@ paths: components: schemas: Uint64: - $ref: './beacon-apis/types/primitive.yaml#/Uint64' + $ref: "./beacon-apis/types/primitive.yaml#/Uint64" Root: - $ref: './beacon-apis/types/primitive.yaml#/Root' + $ref: "./beacon-apis/types/primitive.yaml#/Root" Pubkey: - $ref: './beacon-apis/types/primitive.yaml#/Pubkey' + $ref: "./beacon-apis/types/primitive.yaml#/Pubkey" ErrorMessage: - $ref: './beacon-apis/types/http.yaml#/ErrorMessage' + $ref: "./beacon-apis/types/http.yaml#/ErrorMessage" Bellatrix.ExecutionPayload: - $ref: './beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayload' + $ref: "./beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayload" Bellatrix.SignedBlindedBeaconBlock: - $ref: './beacon-apis/types/bellatrix/block.yaml#/Bellatrix/SignedBlindedBeaconBlock' + $ref: "./beacon-apis/types/bellatrix/block.yaml#/Bellatrix/SignedBlindedBeaconBlock" SignedValidatorRegistration: - $ref: './types/registration.yaml#/SignedValidatorRegistration' + $ref: "./types/registration.yaml#/SignedValidatorRegistration" SignedBuilderBid: - $ref: './types/bid.yaml#/SignedBuilderBid' + $ref: "./types/bid.yaml#/SignedBuilderBid" responses: InternalError: - $ref: './beacon-apis/types/http.yaml#/InternalError' + $ref: "./beacon-apis/types/http.yaml#/InternalError" From 5cfc51e8cfe7e1892f97884d0cac160f408d649f Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 19:14:26 +0200 Subject: [PATCH 09/37] use double quotes instead of single quotes --- apis/builder/blinded_blocks.yaml | 2 +- apis/builder/header.yaml | 8 ++++---- apis/builder/validators.yaml | 4 ++-- builder-oapi.yaml | 2 +- types/bid.yaml | 4 ++-- types/registration.yaml | 16 +++++++++++----- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/apis/builder/blinded_blocks.yaml b/apis/builder/blinded_blocks.yaml index eba5d89..40df0f4 100644 --- a/apis/builder/blinded_blocks.yaml +++ b/apis/builder/blinded_blocks.yaml @@ -39,4 +39,4 @@ post: code: 400 message: "Invalid block: missing signature" "500": - $ref: '../../builder-oapi.yaml#/components/responses/InternalError' + $ref: "../../builder-oapi.yaml#/components/responses/InternalError" diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index 1e71465..8eb0f09 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -31,13 +31,13 @@ get: required: true description: Hash of execution layer block the proposer will build on. schema: - $ref: '../../builder-oapi.yaml#/components/schemas/Root' + $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' + $ref: "../../builder-oapi.yaml#/components/schemas/Pubkey" responses: "200": description: Success response. @@ -53,7 +53,7 @@ get: example: "bellatrix" data: oneOf: - - $ref: '../../builder-oapi.yaml#/components/schemas/SignedBuilderBid' + - $ref: "../../builder-oapi.yaml#/components/schemas/SignedBuilderBid" "400": description: Error response. content: @@ -66,4 +66,4 @@ get: code: 400 message: "Unknown hash: missing parent hash" "500": - $ref: '../../builder-oapi.yaml#/components/responses/InternalError' + $ref: "../../builder-oapi.yaml#/components/responses/InternalError" diff --git a/apis/builder/validators.yaml b/apis/builder/validators.yaml index 6acc585..1d3ce4f 100644 --- a/apis/builder/validators.yaml +++ b/apis/builder/validators.yaml @@ -19,7 +19,7 @@ post: schema: type: array items: - $ref: '../../builder-oapi.yaml#/components/schemas/SignedValidatorRegistration' + $ref: "../../builder-oapi.yaml#/components/schemas/SignedValidatorRegistration" responses: "200": description: Success response. @@ -34,4 +34,4 @@ post: code: 400 message: "Unknown validator: 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95" "500": - $ref: '../../builder-oapi.yaml#/components/responses/InternalError' + $ref: "../../builder-oapi.yaml#/components/responses/InternalError" diff --git a/builder-oapi.yaml b/builder-oapi.yaml index 372d743..9628bb5 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -21,7 +21,7 @@ info: format (_e.g._ from a string to an array) without an increase in the version number - Note that it is possible for a field to be added to an endpoint"s data or + Note that it is possible for a field to be added to an endpoint's data or metadata without an increase in the version number. version: "dev" contact: diff --git a/types/bid.yaml b/types/bid.yaml index a8c3bc4..bfef21f 100644 --- a/types/bid.yaml +++ b/types/bid.yaml @@ -3,13 +3,13 @@ BuilderBid: description: "The `BuilderBid` object from the Builder API spec." properties: header: - $ref: '../beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader' + $ref: "../beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader" description: "`ExecutionPayloadHeader` for validator to sign." value: $ref: "../beacon-apis/types/primitive.yaml#/Uint64" description: "Payment in wei that will be paid to the feeRecipient account." pubkey: - $ref: '../beacon-apis/types/primitive.yaml#/Pubkey' + $ref: "../beacon-apis/types/primitive.yaml#/Pubkey" description: "BLS public key of builder." SignedBuilderBid: diff --git a/types/registration.yaml b/types/registration.yaml index 9f4646f..1eeefee 100644 --- a/types/registration.yaml +++ b/types/registration.yaml @@ -1,10 +1,13 @@ ValidatorRegistration: type: object - description: "The [`ValidatorRegistration`]() object from the Builder API spec." + description: | + The `ValidatorRegistration` object from the Builder API spec. + + Note, this type will be removed once it is included in the Beacon API. properties: fee_recipient: allOf: - - $ref: '../beacon-apis/types/primitive.yaml#/ExecutionAddress' + - $ref: "../beacon-apis/types/primitive.yaml#/ExecutionAddress" - description: "Address to receive fees from the block." gas_limit: allOf: @@ -12,16 +15,19 @@ ValidatorRegistration: - description: "Gas limit the validator desires to target." timestamp: allOf: - - $ref: '../beacon-apis/types/primitive.yaml#/Uint64' + - $ref: "../beacon-apis/types/primitive.yaml#/Uint64" - description: "Unix timestamp of registration." pubkey: allOf: - - $ref: '../beacon-apis/types/primitive.yaml#/Pubkey' + - $ref: "../beacon-apis/types/primitive.yaml#/Pubkey" - description: "BLS public key of validator." SignedValidatorRegistration: type: object - description: "The [`SignedValidatorRegistration`]() object from the Builder API spec." + description: | + The `SignedValidatorRegistration` object from the Builder API spec. + + Note, this type will be removed once it is included in the Beacon API. properties: message: $ref: "#/ValidatorRegistration" From 74c66c114c6e108daead93775bc49aebea711b19 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 20:03:26 +0200 Subject: [PATCH 10/37] add more explanation in readme --- README.md | 82 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index cc03461..158bcbb 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,65 @@ -# Ethereum Builder Specification +# Ethereum Builder API Specification -![CI](https://github.com/ethereum/builder-specs/workflows/CI/badge.svg) +![CI][ci] -Collection of RESTful APIs provided by external builder nodes. +The Builder API is an interface for consensus layer clients to source blocks +built by external entities. -## Render +In this repository: +* [Specification][oas-spec] +* [Additional definitions][spec] -To render spec in browser you will need any http server to load `index.html` file -in root of the repo. +### Why? -##### Python +Block building is a specialized activity that requires high fixed costs to be +an efficient validator. This creates an advantage for staking pools as they can +effectively distribute the cost across many validators. +[Proposer-builder separation][pbs] (PBS) fixes this by spliting the roles of a +validator into block proposing and block building. However, PBS requires +modifications to the Beacon chain and will therefore not be possible at the +time of the merge. + +The Builder API is a temporary solution that requires higher trust assumptions +than PBS, but can be fully implemented without modification to the base +protocol. This is done by providing the proposer with a "blind" execution layer +header to incorporate into a block and a "value" amount which will be +transferred to the proposer once they create a block with the aforementioned +header. Once the proposer signs a block with the header, they are bound to the +choice (or risk being slashed due to equivocation). That allows the builder to +reveal the blinded transactions without the possibility of the proposer +tampering with them. + +This design is based on the original proposal for trusted external builders: +["MEV-Boost: Merge ready Flashbots Architecture"](mev-boost-ethr). + +#### Builder software + +Users will typically connect thier CL clients to builders with builder +multiplexers. Please see their respective repositories for more information: + +* [`mev-boost`][mev-boost] +* [`mev-boost-rs`][mev-boost-rs] + +## Render API Schema + +To render spec in browser, you will simply need a HTTP server to load +the `index.html` file in root of the repo. + +For example: ``` python -m http.server 8080 ``` -And api spec will render on [http://localhost:8080](http://localhost:8080). + +The spec will render at [http://localhost:8080](http://localhost:8080). ### Usage -Local changes will be observable if "dev" is selected in the "Select a definition" drop-down in the web UI. +Local changes will be observable if "dev" is selected in the "Select a +definition" drop-down in the web UI. -Users may need to tick the "Disable Cache" box in their browser's developer tools to see changes after modifying the source. +It may be neccessary to tick the "Disable Cache" box in their browser's +developer tools to see changes after modifying the source. ## Contributing @@ -38,14 +77,23 @@ spectral lint builder-oapi.yaml ## Releasing 1. Create and push tag + - Make sure `info.version` in `builder-oapi.yaml` file is updated before + tagging. + - CI will create a github release and upload bundled spec file +2. Add release entrypoint in `index.html` - - Make sure info.version in builder-oapi.yaml file is updated before tagging. - - CD will create github release and upload bundled spec file +In `SwaggerUIBundle` configuration (inside `index.html` file), add another +entry in `urls` field. Entry should be in following format (replace `` +with real tag name from step 1.): -2. Add release entrypoint in index.html - -In SwaggerUIBundle configuration (inside index.html file), add another entry in "urls" field (SwaggerUI will load first item as default). -Entry should be in following format(replace `` with real tag name from step 1.): ```javascript - {url: "https://github.com/ethereum/builder-apis/releases/download//builder-oapi.yaml", name: ""}, +{url: "https://github.com/ethereum/builder-apis/releases/download//builder-oapi.yaml", name: ""}, ``` + +[ci]: https://ethresear.ch/t/mev-boost-merge-ready-flashbots-architecture/11177 +[oas-spec]: https://ethereum.github.io/builder-specs/ +[spec]: specs/README.md +[pbs]: https://ethresear.ch/t/proposer-block-builder-separation-friendly-fee-market-designs/9725 +[mev-boost-ethr]: https://ethresear.ch/t/mev-boost-merge-ready-flashbots-architecture/11177 +[mev-boost]: https://github.com/flashbots/mev-boost +[mev-boost-rs]: https://github.com/ralexstokes/mev-boost-rs From 9800cdb9a46adec1c3499caae758df9e6889fdc2 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 20:04:30 +0200 Subject: [PATCH 11/37] fix ci badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 158bcbb..03fe51c 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ with real tag name from step 1.): {url: "https://github.com/ethereum/builder-apis/releases/download//builder-oapi.yaml", name: ""}, ``` -[ci]: https://ethresear.ch/t/mev-boost-merge-ready-flashbots-architecture/11177 +[ci]: https://github.com/ethereum/builder-specs/workflows/CI/badge.svg [oas-spec]: https://ethereum.github.io/builder-specs/ [spec]: specs/README.md [pbs]: https://ethresear.ch/t/proposer-block-builder-separation-friendly-fee-market-designs/9725 From a3ef9a12a6fae6ca84f2492169329999321db5f1 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 20:10:28 +0200 Subject: [PATCH 12/37] more updates to readme --- README.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 03fe51c..322ec07 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The Builder API is an interface for consensus layer clients to source blocks built by external entities. In this repository: -* [Specification][oas-spec] +* [API specification][oas-spec] * [Additional definitions][spec] ### Why? @@ -41,13 +41,26 @@ multiplexers. Please see their respective repositories for more information: * [`mev-boost`][mev-boost] * [`mev-boost-rs`][mev-boost-rs] -## Render API Schema +## Contributing -To render spec in browser, you will simply need a HTTP server to load -the `index.html` file in root of the repo. +The API specification is checked for lint errors before merge. -For example: +To run the linter locally, install it with: +```console +npm install -g @stoplight/spectral-cli@6.2.1 +``` +and then run it: +```console +spectral lint builder-oapi.yaml ``` + +### Render API Specification + +To render spec in browser, you will simply need an HTTP server to load the +`index.html` file in root of the repo. + +For example: +```console python -m http.server 8080 ``` @@ -61,19 +74,6 @@ definition" drop-down in the web UI. It may be neccessary to tick the "Disable Cache" box in their browser's developer tools to see changes after modifying the source. -## Contributing - -API spec is checked for lint errors before merge. - -To run lint locally, install linter with -``` -npm install -g @stoplight/spectral-cli@6.2.1 -``` -and run lint with -``` -spectral lint builder-oapi.yaml -``` - ## Releasing 1. Create and push tag From e6c62a4fea571751b4b7c21dfde2c003834b646b Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 20:19:01 +0200 Subject: [PATCH 13/37] move tags below description --- apis/builder/blinded_blocks.yaml | 4 ++-- apis/builder/header.yaml | 4 ++-- apis/builder/validators.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apis/builder/blinded_blocks.yaml b/apis/builder/blinded_blocks.yaml index 40df0f4..b72fba1 100644 --- a/apis/builder/blinded_blocks.yaml +++ b/apis/builder/blinded_blocks.yaml @@ -1,6 +1,4 @@ post: - tags: - - Builder operationId: "submitBlindedBlock" summary: Submit a signed blinded block. description: | @@ -11,6 +9,8 @@ post: If the builder is not able to unblind the corresponding `ExecutionPayloadHeader`, it must error. + tags: + - Builder requestBody: description: | A `SignedBlindedBeaconBlock`. diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index 8eb0f09..806f3bd 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -1,6 +1,4 @@ get: - tags: - - Builder operationId: "getHeader" summary: Get an `ExecutionPayloadHeader`. description: | @@ -19,6 +17,8 @@ get: builder must return a header that moves `gas_limit` the maximum amount allowed under the rules of consensus (currently `parent.gas_limit +/- parent.gas_limit / 1024`). + tags: + - Builder parameters: - name: slot in: path diff --git a/apis/builder/validators.yaml b/apis/builder/validators.yaml index 1d3ce4f..8fd4395 100644 --- a/apis/builder/validators.yaml +++ b/apis/builder/validators.yaml @@ -1,6 +1,4 @@ post: - tags: - - Builder operationId: "registerValidator" summary: Register or update a validator's block building preferences. description: | @@ -11,6 +9,8 @@ post: must error. Requests with `timestamp` less than or equal to the previous announcement must error. Requests with `timestamp` more than 10 seconds in the future must error. + tags: + - Builder requestBody: description: An array of signed validator block building preferences. required: true From 2be3b640660ccd19c8f3a44170a8d9782a4643cb Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sat, 7 May 2022 20:40:44 +0200 Subject: [PATCH 14/37] add execution payload versioning to blinded block endpoint --- apis/builder/blinded_blocks.yaml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/apis/builder/blinded_blocks.yaml b/apis/builder/blinded_blocks.yaml index b72fba1..c08b120 100644 --- a/apis/builder/blinded_blocks.yaml +++ b/apis/builder/blinded_blocks.yaml @@ -12,8 +12,7 @@ post: tags: - Builder requestBody: - description: | - A `SignedBlindedBeaconBlock`. + description: A `SignedBlindedBeaconBlock`. required: true content: application/json: @@ -26,8 +25,16 @@ post: content: application/json: schema: - oneOf: - - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayload" + title: SubmitBlindedBlockResponse + type: object + properties: + version: + type: string + enum: [ bellatrix ] + example: "bellatrix" + data: + oneOf: + - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayload" "400": description: Error response. content: From 5ef6847d30f178719f9e39ae66faab0ab64d6683 Mon Sep 17 00:00:00 2001 From: Chris Hager Date: Sat, 7 May 2022 20:59:47 +0200 Subject: [PATCH 15/37] status endpoint --- apis/builder/status.yaml | 10 ++++++++++ builder-oapi.yaml | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 apis/builder/status.yaml diff --git a/apis/builder/status.yaml b/apis/builder/status.yaml new file mode 100644 index 0000000..07cc8f6 --- /dev/null +++ b/apis/builder/status.yaml @@ -0,0 +1,10 @@ +get: + operationId: "status" + summary: Status endpoint to check if mev-boost is alive. + description: | + Endpoint for checking whether mev-boost is running. + tags: + - Builder + responses: + "200": + description: Success response. diff --git a/builder-oapi.yaml b/builder-oapi.yaml index 9628bb5..6886c49 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -48,6 +48,8 @@ paths: $ref: "./apis/builder/header.yaml" /eth/v1/builder/blinded_blocks: $ref: "./apis/builder/blinded_blocks.yaml" + /eth/v1/builder/status: + $ref: "./apis/builder/status.yaml" components: schemas: From 9554c8a208d687204fc05265ba850efe265dcc57 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sun, 8 May 2022 12:06:26 +0200 Subject: [PATCH 16/37] update status description, add internal error --- apis/builder/status.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apis/builder/status.yaml b/apis/builder/status.yaml index 07cc8f6..948888f 100644 --- a/apis/builder/status.yaml +++ b/apis/builder/status.yaml @@ -1,10 +1,11 @@ get: operationId: "status" - summary: Status endpoint to check if mev-boost is alive. - description: | - Endpoint for checking whether mev-boost is running. + summary: Check if builder is healthy. + description: Checks if builder can respond to requests normally. tags: - Builder responses: "200": description: Success response. + "500": + $ref: "../../builder-oapi.yaml#/components/responses/InternalError" From e0555119b9ae3929b2725fa11aa5e7b7415e042b Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sun, 8 May 2022 12:13:19 +0200 Subject: [PATCH 17/37] version payload header in bid, not bid itself --- apis/builder/blinded_blocks.yaml | 2 +- apis/builder/header.yaml | 11 +---------- types/bid.yaml | 11 ++++++++++- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apis/builder/blinded_blocks.yaml b/apis/builder/blinded_blocks.yaml index c08b120..ed0baf4 100644 --- a/apis/builder/blinded_blocks.yaml +++ b/apis/builder/blinded_blocks.yaml @@ -18,7 +18,7 @@ post: application/json: schema: oneOf: - - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.SignedBlindedBeaconBlock" + - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.SignedBlindedBeaconBlock" responses: "200": description: Success response. diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index 806f3bd..111b567 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -44,16 +44,7 @@ get: content: application/json: schema: - title: GetHeaderResponse - type: object - properties: - version: - type: string - enum: [ bellatrix ] - example: "bellatrix" - data: - oneOf: - - $ref: "../../builder-oapi.yaml#/components/schemas/SignedBuilderBid" + $ref: "../../builder-oapi.yaml#/components/schemas/SignedBuilderBid" "400": description: Error response. content: diff --git a/types/bid.yaml b/types/bid.yaml index bfef21f..4483867 100644 --- a/types/bid.yaml +++ b/types/bid.yaml @@ -3,8 +3,17 @@ BuilderBid: description: "The `BuilderBid` object from the Builder API spec." properties: header: - $ref: "../beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader" + title: VersionedExecutionPayloadHeader + type: object description: "`ExecutionPayloadHeader` for validator to sign." + properties: + version: + type: string + enum: [ bellatrix ] + example: "bellatrix" + data: + oneOf: + - $ref: "../beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader" value: $ref: "../beacon-apis/types/primitive.yaml#/Uint64" description: "Payment in wei that will be paid to the feeRecipient account." From 7d21dc08760a66e710f0ccf517291007482d35ab Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sun, 8 May 2022 13:09:23 +0200 Subject: [PATCH 18/37] add examples, update internal error to be builder specific --- apis/builder/blinded_blocks.yaml | 7 + apis/builder/header.yaml | 14 +- builder-oapi.yaml | 10 +- examples/bellatrix/execution_payload.json | 23 +++ .../signed_blinded_beacon_block.json | 147 ++++++++++++++++++ examples/bellatrix/signed_builder_bid.json | 28 ++++ types/http.yaml | 22 +++ 7 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 examples/bellatrix/execution_payload.json create mode 100644 examples/bellatrix/signed_blinded_beacon_block.json create mode 100644 examples/bellatrix/signed_builder_bid.json create mode 100644 types/http.yaml diff --git a/apis/builder/blinded_blocks.yaml b/apis/builder/blinded_blocks.yaml index ed0baf4..4676743 100644 --- a/apis/builder/blinded_blocks.yaml +++ b/apis/builder/blinded_blocks.yaml @@ -19,6 +19,10 @@ post: schema: oneOf: - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.SignedBlindedBeaconBlock" + examples: + bellatrix: + $ref: "../../builder-oapi.yaml#/components/examples/Bellatrix.SignedBlindedBeaconBlock" + responses: "200": description: Success response. @@ -35,6 +39,9 @@ post: data: oneOf: - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayload" + examples: + bellatrix: + $ref: "../../builder-oapi.yaml#/components/examples/Bellatrix.ExecutionPayload" "400": description: Error response. content: diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index 111b567..3e6f7a3 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -44,7 +44,19 @@ get: content: application/json: schema: - $ref: "../../builder-oapi.yaml#/components/schemas/SignedBuilderBid" + title: GetHeaderResponse + type: object + properties: + version: + type: string + enum: [ bellatrix ] + example: "bellatrix" + data: + oneOf: + - $ref: "../../builder-oapi.yaml#/components/schemas/SignedBuilderBid" + examples: + bellatrix: + $ref: "../../builder-oapi.yaml#/components/examples/Bellatrix.SignedBuilderBid" "400": description: Error response. content: diff --git a/builder-oapi.yaml b/builder-oapi.yaml index 6886c49..4f838b3 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -73,4 +73,12 @@ components: responses: InternalError: - $ref: "./beacon-apis/types/http.yaml#/InternalError" + $ref: "./types/http.yaml#/InternalError" + + examples: + Bellatrix.SignedBlindedBeaconBlock: + $ref: "./examples/bellatrix/signed_blinded_beacon_block.json" + Bellatrix.ExecutionPayload: + $ref: "./examples/bellatrix/execution_payload.json" + Bellatrix.SignedBuilderBid: + $ref: "./examples/bellatrix/signed_builder_bid.json" diff --git a/examples/bellatrix/execution_payload.json b/examples/bellatrix/execution_payload.json new file mode 100644 index 0000000..69bed39 --- /dev/null +++ b/examples/bellatrix/execution_payload.json @@ -0,0 +1,23 @@ +{ + "value": { + "version": "bellatrix", + "data": { + "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "block_number": "1", + "gas_limit": "1", + "gas_used": "1", + "timestamp": "1", + "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "base_fee_per_gas": "1", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "transactions": [ + "0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86" + ] + } + } +} diff --git a/examples/bellatrix/signed_blinded_beacon_block.json b/examples/bellatrix/signed_blinded_beacon_block.json new file mode 100644 index 0000000..298e57b --- /dev/null +++ b/examples/bellatrix/signed_blinded_beacon_block.json @@ -0,0 +1,147 @@ +{ + "value": { + "message": { + "slot": "1", + "proposer_index": "1", + "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "body": { + "randao_reveal": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "eth1_data": { + "deposit_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "deposit_count": "1", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "graffiti": "string", + "proposer_slashings": [ + { + "signed_header_1": { + "message": { + "slot": "1", + "proposer_index": "1", + "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "body_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + }, + "signed_header_2": { + "message": { + "slot": "1", + "proposer_index": "1", + "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "body_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + } + ], + "attester_slashings": [ + { + "attestation_1": { + "attesting_indices": [ + "1" + ], + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "data": { + "slot": "1", + "index": "1", + "beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "source": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "target": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + } + }, + "attestation_2": { + "attesting_indices": [ + "1" + ], + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "data": { + "slot": "1", + "index": "1", + "beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "source": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "target": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + } + } + } + ], + "attestations": [ + { + "aggregation_bits": "0x01", + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "data": { + "slot": "1", + "index": "1", + "beacon_block_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "source": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "target": { + "epoch": "1", + "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + } + } + ], + "deposits": [ + { + "proof": [ + "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + ], + "data": { + "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", + "withdrawal_credentials": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "amount": "1", + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + } + ], + "voluntary_exits": [ + { + "message": { + "epoch": "1", + "validator_index": "1" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } + ], + "sync_aggregate": { + "sync_committee_bits": "0x01", + "sync_committee_signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + }, + "execution_payload_header": { + "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "block_number": "1", + "gas_limit": "1", + "gas_used": "1", + "timestamp": "1", + "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "base_fee_per_gas": "1", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + } + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } +} diff --git a/examples/bellatrix/signed_builder_bid.json b/examples/bellatrix/signed_builder_bid.json new file mode 100644 index 0000000..b4cc397 --- /dev/null +++ b/examples/bellatrix/signed_builder_bid.json @@ -0,0 +1,28 @@ +{ + "value": { + "message": { + "header": { + "version": "bellatrix", + "data": { + "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "block_number": "1", + "gas_limit": "1", + "gas_used": "1", + "timestamp": "1", + "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "base_fee_per_gas": "1", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + }, + "value": "1", + "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } +} diff --git a/types/http.yaml b/types/http.yaml new file mode 100644 index 0000000..8ec5aae --- /dev/null +++ b/types/http.yaml @@ -0,0 +1,22 @@ +InternalError: + description: "Builder node internal error." + content: + application/json: + schema: + type: object + properties: + code: + description: "Either specific error code in case of invalid request or http status code" + type: number + example: 404 + message: + description: "Message describing error" + type: string + stacktraces: + description: "Optional stacktraces, sent when node is in debug mode" + type: array + items: + type: string + example: + code: 500 + message: "Internal server error" From bb138f4b924e22f0dfe3d407c5521b5b9f1df2df Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sun, 8 May 2022 13:15:45 +0200 Subject: [PATCH 19/37] insert sample builder node url --- builder-oapi.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder-oapi.yaml b/builder-oapi.yaml index 4f838b3..224b908 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -35,8 +35,8 @@ servers: - url: "{server_url}" variables: server_url: - description: "Builder node API url" - default: "???" + description: "Builder node URL" + default: "http://localhost:18550" tags: - name: Builder From fd2fe9a9739186fff33028f6a46dbb36985dbe84 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sun, 8 May 2022 13:18:32 +0200 Subject: [PATCH 20/37] update endpoint summaries --- apis/builder/blinded_blocks.yaml | 2 +- apis/builder/header.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apis/builder/blinded_blocks.yaml b/apis/builder/blinded_blocks.yaml index 4676743..d400a6d 100644 --- a/apis/builder/blinded_blocks.yaml +++ b/apis/builder/blinded_blocks.yaml @@ -1,6 +1,6 @@ post: operationId: "submitBlindedBlock" - summary: Submit a signed blinded block. + summary: Submit a signed blinded block and get execution payload. description: | Submits a `SignedBlindedBeaconBlock` to the builder, binding the proposer to the block. The builder is now able to unblind the transactions in diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index 3e6f7a3..1b01954 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -1,6 +1,6 @@ get: operationId: "getHeader" - summary: Get an `ExecutionPayloadHeader`. + summary: Get an execution payload header. description: | Requests a builder node to produce a valid execution payload header, which can integrated into a blinded beacon block and signed. From f8d1fc858771140c09a06bf386f31a43424e39e0 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sun, 8 May 2022 13:20:25 +0200 Subject: [PATCH 21/37] fix typo --- apis/builder/blinded_blocks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apis/builder/blinded_blocks.yaml b/apis/builder/blinded_blocks.yaml index d400a6d..affa7ad 100644 --- a/apis/builder/blinded_blocks.yaml +++ b/apis/builder/blinded_blocks.yaml @@ -1,6 +1,6 @@ post: operationId: "submitBlindedBlock" - summary: Submit a signed blinded block and get execution payload. + summary: Submit a signed blinded block and get unblinded execution payload. description: | Submits a `SignedBlindedBeaconBlock` to the builder, binding the proposer to the block. The builder is now able to unblind the transactions in From d9f4d11a6e76badcc31c91125e16a39c55d2b120 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Sun, 8 May 2022 15:42:42 +0200 Subject: [PATCH 22/37] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 322ec07..993ae9b 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ This design is based on the original proposal for trusted external builders: #### Builder software -Users will typically connect thier CL clients to builders with builder +Users will typically connect their CL clients to builders with builder multiplexers. Please see their respective repositories for more information: * [`mev-boost`][mev-boost] From 285c1c24bf38134e9c675517a2085299499c5ac4 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Mon, 9 May 2022 08:52:21 +0200 Subject: [PATCH 23/37] add signed objects, improve ssz defns --- specs/README.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/specs/README.md b/specs/README.md index ad0f506..cd16b12 100644 --- a/specs/README.md +++ b/specs/README.md @@ -10,6 +10,12 @@ covered in the corresponding API schema. Consider the following definitions supplementary to the definitions in [`consensus-specs`][consensus-specs]. +#### Independently Versioned + +Some objects can be updated independently of the `consensus-specs`, because +they originate soley from this specification. The objects are postfixed with +`VX` to denote their revision. + ##### `ValidatorRegistrationV1` ```python @@ -20,6 +26,14 @@ class ValidatorRegistrationV1(Container): pubkey: BLSPubkey ``` +###### `SignedValidatorRegistrationV1` + +```python +class SignedValidatorRegistrationV1(Container): + message: ValidatorRegistrationV1 + signature: BLSSignature +``` + ##### `BuilderBidV1` ```python @@ -29,6 +43,30 @@ class BuilderBidV1(Container): pubkey: BLSPubkey ``` +###### `SignedBuilderBidV1` + +```python +class SignedBuilderBidV1(Container): + message: BlindedBeaconBlock + signature: BLSSignature +``` + +#### Fork Versioned + +Other objects are derivatives of `consensus-specs` types and depend on the +latest canonical fork. These objects are namespaced by their fork (e.g. +Bellatrix). + +##### Bellatrix + +###### `SignedBlindedBeaconBlock` + +```python +class SignedBlindedBeaconBlock(Container): + message: BlindedBeaconBlock + signature: BLSSignature +``` + ###### `BlindedBeaconBlock` ```python From 90238e1b78e3c710e94f5bad01fa1f48ded34f99 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Mon, 9 May 2022 09:03:32 +0200 Subject: [PATCH 24/37] fix ssz def --- specs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/README.md b/specs/README.md index cd16b12..11332b1 100644 --- a/specs/README.md +++ b/specs/README.md @@ -47,7 +47,7 @@ class BuilderBidV1(Container): ```python class SignedBuilderBidV1(Container): - message: BlindedBeaconBlock + message: BuilderBidV1 signature: BLSSignature ``` From c449d4e9748afb0a08d6e377a02fcafe92f85f52 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Mon, 9 May 2022 12:31:49 +0200 Subject: [PATCH 25/37] use snake case in ssz --- specs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/README.md b/specs/README.md index 11332b1..5cc8509 100644 --- a/specs/README.md +++ b/specs/README.md @@ -20,8 +20,8 @@ they originate soley from this specification. The objects are postfixed with ```python class ValidatorRegistrationV1(Container): - feeRecipient: Bytes20 - gasLimit: uint64 + fee_recipient: Bytes20 + gas_limit: uint64 timestamp: uint64 pubkey: BLSPubkey ``` From 8b9f722e5e4db00949d349e799758be67c508349 Mon Sep 17 00:00:00 2001 From: lightclient <14004106+lightclient@users.noreply.github.com> Date: Mon, 9 May 2022 12:31:56 +0200 Subject: [PATCH 26/37] fix typo Co-authored-by: Rootul Patel --- apis/builder/header.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index 1b01954..67cd928 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -3,7 +3,7 @@ get: summary: Get an execution payload header. description: | Requests a builder node to produce a valid execution payload header, which - can integrated into a blinded beacon block and signed. + can be integrated into a blinded beacon block and signed. Builder must immediately return the header that is able to pay `feeRecipient` the most. If the builder is unaware of `parent_hash`, it From 2a069803af3b980e4cd0f1894c0b8415fda84c3c Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Mon, 9 May 2022 12:34:27 +0200 Subject: [PATCH 27/37] better wording --- builder-oapi.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder-oapi.yaml b/builder-oapi.yaml index 224b908..0689211 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -4,8 +4,8 @@ info: title: Builder API description: | API specification for external builder nodes. This interface enables - validators to delegate block building duties, while allowing for - attribution in the case of most faults (e.g. producing an invalid block). + validators to delegate block building duties such that attribution can be + had in the case of most faults (e.g. producing an invalid block). API endpoints are individually versioned. As such, there is no direct relationship between all v1 endpoints, all v2 endpoints, _etc._ and no such From b286dbae3e9d065c63df687a90cb9e9b1687519a Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Mon, 9 May 2022 12:52:34 +0200 Subject: [PATCH 28/37] make builder bid objects versioned by fork --- apis/builder/header.yaml | 2 +- builder-oapi.yaml | 5 +++-- specs/README.md | 26 +++++++++++++------------- types/bellatrix/bid.yaml | 23 +++++++++++++++++++++++ types/bid.yaml | 31 ------------------------------- 5 files changed, 40 insertions(+), 47 deletions(-) create mode 100644 types/bellatrix/bid.yaml delete mode 100644 types/bid.yaml diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index 67cd928..033ac06 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -53,7 +53,7 @@ get: example: "bellatrix" data: oneOf: - - $ref: "../../builder-oapi.yaml#/components/schemas/SignedBuilderBid" + - $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.SignedBuilderBid" examples: bellatrix: $ref: "../../builder-oapi.yaml#/components/examples/Bellatrix.SignedBuilderBid" diff --git a/builder-oapi.yaml b/builder-oapi.yaml index 0689211..822778b 100644 --- a/builder-oapi.yaml +++ b/builder-oapi.yaml @@ -66,10 +66,11 @@ components: Bellatrix.SignedBlindedBeaconBlock: $ref: "./beacon-apis/types/bellatrix/block.yaml#/Bellatrix/SignedBlindedBeaconBlock" + Bellatrix.SignedBuilderBid: + $ref: "./types/bellatrix/bid.yaml#/Bellatrix/SignedBuilderBid" SignedValidatorRegistration: $ref: "./types/registration.yaml#/SignedValidatorRegistration" - SignedBuilderBid: - $ref: "./types/bid.yaml#/SignedBuilderBid" + responses: InternalError: diff --git a/specs/README.md b/specs/README.md index 5cc8509..b07b7ea 100644 --- a/specs/README.md +++ b/specs/README.md @@ -34,31 +34,31 @@ class SignedValidatorRegistrationV1(Container): signature: BLSSignature ``` -##### `BuilderBidV1` +#### Fork Versioned + +Other objects are derivatives of `consensus-specs` types and depend on the +latest canonical fork. These objects are namespaced by their fork (e.g. +Bellatrix). + +##### Bellatrix + +##### `BuilderBid` ```python -class BuilderBidV1(Container): +class BuilderBid(Container): header: ExecutionPayloadHeader value: uint256 pubkey: BLSPubkey ``` -###### `SignedBuilderBidV1` +###### `SignedBuilderBid` ```python -class SignedBuilderBidV1(Container): - message: BuilderBidV1 +class SignedBuilderBid(Container): + message: BuilderBid signature: BLSSignature ``` -#### Fork Versioned - -Other objects are derivatives of `consensus-specs` types and depend on the -latest canonical fork. These objects are namespaced by their fork (e.g. -Bellatrix). - -##### Bellatrix - ###### `SignedBlindedBeaconBlock` ```python diff --git a/types/bellatrix/bid.yaml b/types/bellatrix/bid.yaml new file mode 100644 index 0000000..8bd9cd4 --- /dev/null +++ b/types/bellatrix/bid.yaml @@ -0,0 +1,23 @@ +Bellatrix: + BuilderBid: + type: object + description: "The `BuilderBid` object from the Builder API spec." + properties: + header: + $ref: "../../beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader" + description: "`ExecutionPayloadHeader` to use in block proposal." + value: + $ref: "../../beacon-apis/types/primitive.yaml#/Uint64" + description: "Payment in wei that will be paid to the `fee_recipient` account." + pubkey: + $ref: "../../beacon-apis/types/primitive.yaml#/Pubkey" + description: "BLS public key of builder." + + SignedBuilderBid: + type: object + description: "The `SignedBuilderBid` object from the Builder API spec." + properties: + message: + $ref: "#/Bellatrix/BuilderBid" + signature: + $ref: "../../beacon-apis/types/primitive.yaml#/Signature" diff --git a/types/bid.yaml b/types/bid.yaml deleted file mode 100644 index 4483867..0000000 --- a/types/bid.yaml +++ /dev/null @@ -1,31 +0,0 @@ -BuilderBid: - type: object - description: "The `BuilderBid` object from the Builder API spec." - properties: - header: - title: VersionedExecutionPayloadHeader - type: object - description: "`ExecutionPayloadHeader` for validator to sign." - properties: - version: - type: string - enum: [ bellatrix ] - example: "bellatrix" - data: - oneOf: - - $ref: "../beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader" - value: - $ref: "../beacon-apis/types/primitive.yaml#/Uint64" - description: "Payment in wei that will be paid to the feeRecipient account." - pubkey: - $ref: "../beacon-apis/types/primitive.yaml#/Pubkey" - description: "BLS public key of builder." - -SignedBuilderBid: - type: object - description: "The `SignedBuilderBid` object from the Builder API spec." - properties: - message: - $ref: "#/BuilderBid" - signature: - $ref: "../beacon-apis/types/primitive.yaml#/Signature" From a63e07082f91d61e4b1a8966fea029ac286376bc Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Mon, 9 May 2022 12:54:14 +0200 Subject: [PATCH 29/37] update builder bid example --- examples/bellatrix/signed_builder_bid.json | 49 ++++++++++++---------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/examples/bellatrix/signed_builder_bid.json b/examples/bellatrix/signed_builder_bid.json index b4cc397..7de732a 100644 --- a/examples/bellatrix/signed_builder_bid.json +++ b/examples/bellatrix/signed_builder_bid.json @@ -1,28 +1,31 @@ { "value": { - "message": { - "header": { - "version": "bellatrix", - "data": { - "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", - "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "block_number": "1", - "gas_limit": "1", - "gas_used": "1", - "timestamp": "1", - "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "base_fee_per_gas": "1", - "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" - } + "version": "bellatrix", + "data": { + "message": { + "header": { + "version": "bellatrix", + "data": { + "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "block_number": "1", + "gas_limit": "1", + "gas_used": "1", + "timestamp": "1", + "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "base_fee_per_gas": "1", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + } + }, + "value": "1", + "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" }, - "value": "1", - "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" - }, - "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } } } From def9ba6a0488d97f914b0d5db77c1c12671dd9e7 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Mon, 9 May 2022 13:43:44 +0200 Subject: [PATCH 30/37] fix builder bid example --- examples/bellatrix/signed_builder_bid.json | 31 ++++++++++------------ 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/examples/bellatrix/signed_builder_bid.json b/examples/bellatrix/signed_builder_bid.json index 7de732a..9e009f4 100644 --- a/examples/bellatrix/signed_builder_bid.json +++ b/examples/bellatrix/signed_builder_bid.json @@ -4,23 +4,20 @@ "data": { "message": { "header": { - "version": "bellatrix", - "data": { - "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", - "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "block_number": "1", - "gas_limit": "1", - "gas_used": "1", - "timestamp": "1", - "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "base_fee_per_gas": "1", - "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" - } + "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "block_number": "1", + "gas_limit": "1", + "gas_used": "1", + "timestamp": "1", + "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "base_fee_per_gas": "1", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" }, "value": "1", "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" From 7e0aa1bdab004fe526a74913eac2903d4ccccbaa Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Mon, 9 May 2022 14:32:10 +0200 Subject: [PATCH 31/37] clean up spec --- specs/README.md | 89 +++++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/specs/README.md b/specs/README.md index b07b7ea..40d7b23 100644 --- a/specs/README.md +++ b/specs/README.md @@ -1,22 +1,34 @@ -# Builder Specification - -This document specifies the behaviour of external block builders not already -covered in the corresponding API schema. - -## Structures - -### SSZ Objects +# Builder API + +## Table of Contents + +* [Containers](#containers) + * [Independently Versioned](#independentlyversioned) + * [`ValidatorRegistrationV1`](#validatorregistrationv1) + * [`SignedValidatorRegistrationV1`](#signedvalidatorregistrationv1) + * [Fork Versioned](#forkversioned) + * [Bellatrix](#forkversioned) + * [`BuilderBid`](#builderbid) + * [`SignedBuilderBid`](#signedbuilderbid) + * [`BlindedBeaconBlockBody`](#blindedbeaconblockbody) + * [`BlindedBeaconBlock`](#blindedbeaconblock) + * [`SignedBlindedBeaconBlock`](#signedblindedbeaconblock) + * [Signing](#signing) +* [Endpoints](#endpoints) + +## Containers Consider the following definitions supplementary to the definitions in -[`consensus-specs`][consensus-specs]. +[`consensus-specs`][consensus-specs]. For information on how containers are +signed, see [Signing](#signing). -#### Independently Versioned +### Independently Versioned Some objects can be updated independently of the `consensus-specs`, because they originate soley from this specification. The objects are postfixed with `VX` to denote their revision. -##### `ValidatorRegistrationV1` +#### `ValidatorRegistrationV1` ```python class ValidatorRegistrationV1(Container): @@ -26,7 +38,7 @@ class ValidatorRegistrationV1(Container): pubkey: BLSPubkey ``` -###### `SignedValidatorRegistrationV1` +#### `SignedValidatorRegistrationV1` ```python class SignedValidatorRegistrationV1(Container): @@ -34,13 +46,13 @@ class SignedValidatorRegistrationV1(Container): signature: BLSSignature ``` -#### Fork Versioned +### Fork Versioned Other objects are derivatives of `consensus-specs` types and depend on the latest canonical fork. These objects are namespaced by their fork (e.g. Bellatrix). -##### Bellatrix +#### Bellatrix ##### `BuilderBid` @@ -51,7 +63,7 @@ class BuilderBid(Container): pubkey: BLSPubkey ``` -###### `SignedBuilderBid` +##### `SignedBuilderBid` ```python class SignedBuilderBid(Container): @@ -59,15 +71,23 @@ class SignedBuilderBid(Container): signature: BLSSignature ``` -###### `SignedBlindedBeaconBlock` +##### `BlindedBeaconBlockBody` ```python -class SignedBlindedBeaconBlock(Container): - message: BlindedBeaconBlock - signature: BLSSignature +class BlindedBeaconBlockBody(Container): + randao_reveal: BLSSignature + eth1_data: Eth1Data + graffiti: Bytes32 + proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS] + attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS] + attestations: List[Attestation, MAX_ATTESTATIONS] + deposits: List[Deposit, MAX_DEPOSITS] + voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS] + sync_aggregate: SyncAggregate + execution_payload_header: ExecutionPayloadHeader ``` -###### `BlindedBeaconBlock` +##### `BlindedBeaconBlock` ```python class BlindedBeaconBlock(Container): @@ -78,24 +98,14 @@ class BlindedBeaconBlock(Container): body: BlindedBeaconBlockBody ``` -###### `BlindedBeaconBlockBody` +##### `SignedBlindedBeaconBlock` ```python -class BlindedBeaconBlockBody(Container): - randao_reveal: BLSSignature - eth1_data: Eth1Data - graffiti: Bytes32 - proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS] - attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS] - attestations: List[Attestation, MAX_ATTESTATIONS] - deposits: List[Deposit, MAX_DEPOSITS] - voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS] - sync_aggregate: SyncAggregate - execution_payload_header: ExecutionPayloadHeader +class SignedBlindedBeaconBlock(Container): + message: BlindedBeaconBlock + signature: BLSSignature ``` -## Routines - ### Signing All signature operations should follow the [standard BLS operations][bls] @@ -108,11 +118,18 @@ There are two types of data to sign over in the Builder API: * Builder API messages, e.g. validator registration, which should compute the signing root using [`compute_signing_root`][compute-root] and the domain `DomainType('0xXXXXXXXX')` (TODO: get a proper domain). - As `compute_signing_root` takes `SSZObject` as input, client software should convert in-protocol messages to their SSZ representation to compute the signing root and Builder API messages to the SSZ representations defined -[above](#sszobjects). +[above](#definitions). + + +## Endpoints + +Builder API endpoints are defined in `builder-oapi.yaml` in the root of the +repository. A rendered version can be viewed at +https://ethereum.github.io/builder-specs/. + [consensus-specs]: https://github.com/ethereum/consensus-specs [bls]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#bls-signatures From 3162878eeb2887c6c480a0e80b9de067931a953f Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Mon, 9 May 2022 14:34:29 +0200 Subject: [PATCH 32/37] use 0x10000001 as DomainType --- specs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/README.md b/specs/README.md index 40d7b23..8e90a52 100644 --- a/specs/README.md +++ b/specs/README.md @@ -117,7 +117,7 @@ There are two types of data to sign over in the Builder API: and use the domain specified for beacon block proposals. * Builder API messages, e.g. validator registration, which should compute the signing root using [`compute_signing_root`][compute-root] and the domain - `DomainType('0xXXXXXXXX')` (TODO: get a proper domain). + `DomainType('0x10000001')`. As `compute_signing_root` takes `SSZObject` as input, client software should convert in-protocol messages to their SSZ representation to compute the signing root and Builder API messages to the SSZ representations defined From 9573a87546e151ad7b038ab5abd0b2ce1abab953 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Mon, 9 May 2022 14:36:30 +0200 Subject: [PATCH 33/37] fix broken link --- specs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/README.md b/specs/README.md index 8e90a52..f763155 100644 --- a/specs/README.md +++ b/specs/README.md @@ -121,7 +121,7 @@ There are two types of data to sign over in the Builder API: As `compute_signing_root` takes `SSZObject` as input, client software should convert in-protocol messages to their SSZ representation to compute the signing root and Builder API messages to the SSZ representations defined -[above](#definitions). +[above](#containers). ## Endpoints From 40a8e6757c69b4eb830382bb9ad6653ef6f12fce Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Tue, 10 May 2022 10:18:28 +0200 Subject: [PATCH 34/37] apply pr feedback Co-authored-by: lightclient@protonmail.com Co-authored-by: Alex Stokes --- apis/builder/header.yaml | 2 +- examples/bellatrix/signed_blinded_beacon_block.json | 2 +- specs/README.md | 4 ++-- types/bellatrix/bid.yaml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index 033ac06..f56b866 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -11,7 +11,7 @@ get: `pubkey` for `slot`, it must error. If the builder has not received a validator registration associated with `pubkey`, it must error. - When possibe, the builder must return a header with `gas_limit` equal to + When possible, the builder must return a header with `gas_limit` equal to proposer's registered value. If this isn't possible due to the large difference between `parent.gas_limit` and the preferred `gas_limit`, the builder must return a header that moves `gas_limit` the maximum amount diff --git a/examples/bellatrix/signed_blinded_beacon_block.json b/examples/bellatrix/signed_blinded_beacon_block.json index 298e57b..993f49f 100644 --- a/examples/bellatrix/signed_blinded_beacon_block.json +++ b/examples/bellatrix/signed_blinded_beacon_block.json @@ -12,7 +12,7 @@ "deposit_count": "1", "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" }, - "graffiti": "string", + "graffiti": "0xdeadbeefc0ffee", "proposer_slashings": [ { "signed_header_1": { diff --git a/specs/README.md b/specs/README.md index f763155..b07ee76 100644 --- a/specs/README.md +++ b/specs/README.md @@ -25,14 +25,14 @@ signed, see [Signing](#signing). ### Independently Versioned Some objects can be updated independently of the `consensus-specs`, because -they originate soley from this specification. The objects are postfixed with +they originate solely from this specification. The objects are postfixed with `VX` to denote their revision. #### `ValidatorRegistrationV1` ```python class ValidatorRegistrationV1(Container): - fee_recipient: Bytes20 + fee_recipient: ExecutionAddress gas_limit: uint64 timestamp: uint64 pubkey: BLSPubkey diff --git a/types/bellatrix/bid.yaml b/types/bellatrix/bid.yaml index 8bd9cd4..3e9e7fb 100644 --- a/types/bellatrix/bid.yaml +++ b/types/bellatrix/bid.yaml @@ -7,7 +7,7 @@ Bellatrix: $ref: "../../beacon-apis/types/bellatrix/execution_payload.yaml#/Bellatrix/ExecutionPayloadHeader" description: "`ExecutionPayloadHeader` to use in block proposal." value: - $ref: "../../beacon-apis/types/primitive.yaml#/Uint64" + $ref: "../../beacon-apis/types/primitive.yaml#/Uint256" description: "Payment in wei that will be paid to the `fee_recipient` account." pubkey: $ref: "../../beacon-apis/types/primitive.yaml#/Pubkey" From 6513551088c493b005d50188d8bdccb56cfde5b4 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Tue, 10 May 2022 23:14:09 +0200 Subject: [PATCH 35/37] add feedback from review Co-authored-by: lightclient@protonmail.com Co-authored-by: Danny Ryan --- README.md | 4 ++-- apis/builder/header.yaml | 11 ++++++----- apis/builder/validators.yaml | 4 ++-- specs/README.md | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 993ae9b..ad08b05 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ multiplexers. Please see their respective repositories for more information: ## Contributing -The API specification is checked for lint errors before merge. +The API specification is checked for lint errors before merging pull requests. To run the linter locally, install it with: ```console @@ -71,7 +71,7 @@ The spec will render at [http://localhost:8080](http://localhost:8080). Local changes will be observable if "dev" is selected in the "Select a definition" drop-down in the web UI. -It may be neccessary to tick the "Disable Cache" box in their browser's +It may be necessary to tick the "Disable Cache" box in their browser's developer tools to see changes after modifying the source. ## Releasing diff --git a/apis/builder/header.yaml b/apis/builder/header.yaml index f56b866..3e06bc6 100644 --- a/apis/builder/header.yaml +++ b/apis/builder/header.yaml @@ -5,11 +5,12 @@ get: Requests a builder node to produce a valid execution payload header, which can be integrated into a blinded beacon block and signed. - Builder must immediately return the header that is able to pay - `feeRecipient` the most. If the builder is unaware of `parent_hash`, it - must error. If `pubkey` does not match the builder's expected proposer - `pubkey` for `slot`, it must error. If the builder has not received a - validator registration associated with `pubkey`, it must error. + Builder must immediately return the header that is able to pay the + proposer's registered `fee_recipient` the most. If the builder is unaware + of `parent_hash`, it must error. If `pubkey` does not match the builder's + expected proposer `pubkey` for `slot`, it must error. If the builder has + not received a validator registration associated with `pubkey`, it must + error. When possible, the builder must return a header with `gas_limit` equal to proposer's registered value. If this isn't possible due to the large diff --git a/apis/builder/validators.yaml b/apis/builder/validators.yaml index 8fd4395..b14a307 100644 --- a/apis/builder/validators.yaml +++ b/apis/builder/validators.yaml @@ -7,8 +7,8 @@ post: Builders should verify that `pubkey` corresponds to an active or pending validator, and that `signature` is valid under `pubkey`. Otherwise, builder must error. Requests with `timestamp` less than or equal to the previous - announcement must error. Requests with `timestamp` more than 10 seconds in - the future must error. + successful announcement must error. Requests with `timestamp` more than 10 + seconds in the future must error. tags: - Builder requestBody: diff --git a/specs/README.md b/specs/README.md index b07ee76..0ba4907 100644 --- a/specs/README.md +++ b/specs/README.md @@ -117,7 +117,7 @@ There are two types of data to sign over in the Builder API: and use the domain specified for beacon block proposals. * Builder API messages, e.g. validator registration, which should compute the signing root using [`compute_signing_root`][compute-root] and the domain - `DomainType('0x10000001')`. + `DomainType('0x00000001')`. As `compute_signing_root` takes `SSZObject` as input, client software should convert in-protocol messages to their SSZ representation to compute the signing root and Builder API messages to the SSZ representations defined From 565d1dbd1413af7e6ae333694309bb95ccd64234 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Tue, 10 May 2022 23:21:57 +0200 Subject: [PATCH 36/37] accept only single validator registrations --- apis/builder/validators.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apis/builder/validators.yaml b/apis/builder/validators.yaml index b14a307..afe852d 100644 --- a/apis/builder/validators.yaml +++ b/apis/builder/validators.yaml @@ -12,13 +12,12 @@ post: tags: - Builder requestBody: - description: An array of signed validator block building preferences. + description: | + A signed declaration of a validator's block building preferences. required: true content: application/json: schema: - type: array - items: $ref: "../../builder-oapi.yaml#/components/schemas/SignedValidatorRegistration" responses: "200": @@ -32,6 +31,6 @@ post: - $ref: "../../builder-oapi.yaml#/components/schemas/ErrorMessage" - example: code: 400 - message: "Unknown validator: 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95" + message: "unknown validator" "500": $ref: "../../builder-oapi.yaml#/components/responses/InternalError" From 85b0c4868bb8e115334f4bbe017a8078986ed992 Mon Sep 17 00:00:00 2001 From: "lightclient@protonmail.com" Date: Tue, 10 May 2022 23:40:48 +0200 Subject: [PATCH 37/37] add spellcheck to ci --- .github/workflows/spellcheck.yaml | 11 +++++++++ dictionary.dic | Bin 0 -> 1056 bytes spellcheck.yaml | 36 ++++++++++++++++++++++++++++++ wordlist.txt | 26 +++++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 .github/workflows/spellcheck.yaml create mode 100644 dictionary.dic create mode 100644 spellcheck.yaml create mode 100644 wordlist.txt diff --git a/.github/workflows/spellcheck.yaml b/.github/workflows/spellcheck.yaml new file mode 100644 index 0000000..79fde0c --- /dev/null +++ b/.github/workflows/spellcheck.yaml @@ -0,0 +1,11 @@ +name: Spellcheck +on: [push, pull_request, workflow_dispatch] + +jobs: + build: + name: Spellcheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - uses: rojopolis/spellcheck-github-actions@0.16.0 + name: Spellcheck diff --git a/dictionary.dic b/dictionary.dic new file mode 100644 index 0000000000000000000000000000000000000000..f8749aec5a65430163b230991e7e5429de553642 GIT binary patch literal 1056 zcmaiyy>HV{6va<$ry*Z2N!vs!3lRfFR#njf78dXTk>XlWZK*6EoW@mLT-%DB6m@1} zV`GAqjfDvYHvR)fCMG7>n1FNh!B7UCboG1pzMK1w&x@a>K@@dI!LdJ$^6oqfCf!ML z7IpV__io@n%ke+_)A5#-R9}=|6ORkPcMaI${>q{ZmLM%9hQVksR;wGtNXJPWuEW-_WMX-4&QPu2CKNNy1aDd{9jVxG`P zo}30V-Y8xwrN`+hng$K!h{jr+jDi!HL1)>SW#{Y^cWF&N6l-X)s_G+-s1y#Rd=`Wh zN2it2W=GgA(rnK~r%|2xQ8@DRWU`&{u<|#}EWz_F+MXcGq(7?$BZA`e`Uz5o6PSrWPhDJXWb^Nj7Qu*AZ7gliL|Kb literal 0 HcmV?d00001 diff --git a/spellcheck.yaml b/spellcheck.yaml new file mode 100644 index 0000000..8a75080 --- /dev/null +++ b/spellcheck.yaml @@ -0,0 +1,36 @@ +matrix: + - name: markdown + sources: + - '**/*.md|!beacon-apis/**' + aspell: + lang: en + d: en_US + ignore-case: true + run-together: true + run-together-min: 2 + run-together-limit: 256 + dictionary: + wordlists: + - wordlist.txt + encoding: utf-8 + pipeline: + - pyspelling.filters.markdown: + - pyspelling.filters.html: + comments: false + ignores: + - code + - pre + - name: yaml schemas + sources: + - '**/*.yaml|!beacon-apis/**|!spellcheck.yaml' + aspell: + lang: en + d: en_US + run-together: true + run-together-min: 2 + run-together-limit: 256 + dictionary: + wordlists: + - wordlist.txt + encoding: utf-8 + pipeline: null diff --git a/wordlist.txt b/wordlist.txt new file mode 100644 index 0000000..136669a --- /dev/null +++ b/wordlist.txt @@ -0,0 +1,26 @@ +apis +bellatrix +bls +bn +cli +dev +eth +http +https +json +mev +nodejs +npm +oapi +openapi +ssz +tbh +ui +uint +unblind +unblinded +url +validators +validator's +vc +wei