Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Builder API schema #2

Merged
merged 38 commits into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
899c416
re-add schema
lightclient May 6, 2022
7ae1541
return execution payload after blinded block is posted
lightclient May 6, 2022
079f909
remove unused components
lightclient May 6, 2022
0fdd92a
clean up endpoint defns
lightclient May 7, 2022
198f9e1
add ssz defns
lightclient May 7, 2022
50411ce
add builder bid
lightclient May 7, 2022
abae993
adjust get header path and few other fixes
lightclient May 7, 2022
a4ec2dc
update oapi
lightclient May 7, 2022
5cfc51e
use double quotes instead of single quotes
lightclient May 7, 2022
74c66c1
add more explanation in readme
lightclient May 7, 2022
9800cdb
fix ci badge
lightclient May 7, 2022
a3ef9a1
more updates to readme
lightclient May 7, 2022
e6c62a4
move tags below description
lightclient May 7, 2022
2be3b64
add execution payload versioning to blinded block endpoint
lightclient May 7, 2022
5ef6847
status endpoint
metachris May 7, 2022
5b78234
Merge pull request #1 from metachris/status-endpoint
lightclient May 8, 2022
9554c8a
update status description, add internal error
lightclient May 8, 2022
e055511
version payload header in bid, not bid itself
lightclient May 8, 2022
7d21dc0
add examples, update internal error to be builder specific
lightclient May 8, 2022
bb138f4
insert sample builder node url
lightclient May 8, 2022
fd2fe9a
update endpoint summaries
lightclient May 8, 2022
f8d1fc8
fix typo
lightclient May 8, 2022
d9f4d11
fix typo
lightclient May 8, 2022
285c1c2
add signed objects, improve ssz defns
lightclient May 9, 2022
90238e1
fix ssz def
lightclient May 9, 2022
c449d4e
use snake case in ssz
lightclient May 9, 2022
8b9f722
fix typo
lightclient May 9, 2022
2a06980
better wording
lightclient May 9, 2022
b286dba
make builder bid objects versioned by fork
lightclient May 9, 2022
a63e070
update builder bid example
lightclient May 9, 2022
def9ba6
fix builder bid example
lightclient May 9, 2022
7e0aa1b
clean up spec
lightclient May 9, 2022
3162878
use 0x10000001 as DomainType
lightclient May 9, 2022
9573a87
fix broken link
lightclient May 9, 2022
40a8e67
apply pr feedback
lightclient May 10, 2022
6513551
add feedback from review
lightclient May 10, 2022
565d1db
accept only single validator registrations
lightclient May 10, 2022
85b0c48
add spellcheck to ci
lightclient May 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions apis/builder/blinded_blocks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
post:
tags:
- Builder
operationId: "submitBlindedBlock"
summary: Submit a signed blinded block.
lightclient marked this conversation as resolved.
Show resolved Hide resolved
description: |
Submits a `SignedBlindedBeaconBlock` to the builder, binding the proposer
lightclient marked this conversation as resolved.
Show resolved Hide resolved
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: |
A `SignedBlindedBeaconBlock`.
required: true
content:
application/json:
schema:
oneOf:
- $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.SignedBlindedBeaconBlock"
lightclient marked this conversation as resolved.
Show resolved Hide resolved
responses:
"200":
description: Success response.
content:
application/json:
schema:
oneOf:
- $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayload"
"400":
description: Error response.
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'
69 changes: 69 additions & 0 deletions apis/builder/header.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
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.
lightclient marked this conversation as resolved.
Show resolved Hide resolved

Builder must immediately return the header that is able to pay
`feeRecipient` the most. If the builder is unaware of `parent_hash`, it
lightclient marked this conversation as resolved.
Show resolved Hide resolved
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
lightclient marked this conversation as resolved.
Show resolved Hide resolved
validator registration associated with `pubkey`, it must error.

When possibe, the builder must return a header with `gas_limit` equal to
lightclient marked this conversation as resolved.
Show resolved Hide resolved
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.
schema:
$ref: "../../builder-oapi.yaml#/components/schemas/Uint64"
- name: parent_hash
in: path
required: true
description: Hash of execution layer block the proposer will build on.
schema:
$ref: '../../builder-oapi.yaml#/components/schemas/Root'
- name: pubkey
in: 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: GetHeaderResponse
type: object
properties:
version:
type: string
enum: [ bellatrix ]
example: "bellatrix"
data:
oneOf:
- $ref: '../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayloadHeader'
lightclient marked this conversation as resolved.
Show resolved Hide resolved
"400":
description: Error response.
content:
application/json:
schema:
$ref: "../../builder-oapi.yaml#/components/schemas/ErrorMessage"
examples:
InvalidRequest:
value:
code: 400
message: "Unknown hash: missing parent hash"
"500":
$ref: '../../builder-oapi.yaml#/components/responses/InternalError'
37 changes: 37 additions & 0 deletions apis/builder/validators.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
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.

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.
lightclient marked this conversation as resolved.
Show resolved Hide resolved
requestBody:
description: An array of signed validator block building preferences.
lightclient marked this conversation as resolved.
Show resolved Hide resolved
required: true
content:
application/json:
schema:
type: array
items:
$ref: '../../builder-oapi.yaml#/components/schemas/SignedValidatorRegistration'
responses:
"200":
description: Success response.
"400":
description: Error response.
content:
application/json:
schema:
allOf:
- $ref: "../../builder-oapi.yaml#/components/schemas/ErrorMessage"
- example:
code: 400
message: "Unknown validator: 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95"
lightclient marked this conversation as resolved.
Show resolved Hide resolved
"500":
$ref: '../../builder-oapi.yaml#/components/responses/InternalError'
74 changes: 74 additions & 0 deletions builder-oapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
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: "???"
lightclient marked this conversation as resolved.
Show resolved Hide resolved

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:
lightclient marked this conversation as resolved.
Show resolved Hide resolved
$ref: "./apis/builder/header.yaml"
/eth/v1/builder/blinded_blocks:
$ref: "./apis/builder/blinded_blocks.yaml"


components:
schemas:
Uint64:
lightclient marked this conversation as resolved.
Show resolved Hide resolved
$ref: './beacon-apis/types/primitive.yaml#/Uint64'
Root:
$ref: './beacon-apis/types/primitive.yaml#/Root'
Pubkey:
$ref: './beacon-apis/types/primitive.yaml#/Pubkey'
ErrorMessage:
$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'

responses:
InternalError:
$ref: './beacon-apis/types/http.yaml#/InternalError'
81 changes: 81 additions & 0 deletions specs/README.md
Original file line number Diff line number Diff line change
@@ -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
lightclient marked this conversation as resolved.
Show resolved Hide resolved
gasLimit: uint64
lightclient marked this conversation as resolved.
Show resolved Hide resolved
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
29 changes: 29 additions & 0 deletions types/registration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
ValidatorRegistration:
lightclient marked this conversation as resolved.
Show resolved Hide resolved
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"
lightclient marked this conversation as resolved.
Show resolved Hide resolved