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 25 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
100 changes: 74 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,99 @@
# 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:
* [API 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.

```
python -m http.server 8080
```
And api spec will render on [http://localhost:8080](http://localhost:8080).
[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.

### Usage
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).

Local changes will be observable if "dev" is selected in the "Select a definition" drop-down in the web UI.
#### Builder software

Users may need to tick the "Disable Cache" box in their browser's developer tools to see changes after modifying the source.
Users will typically connect their 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]

## Contributing

API spec is checked for lint errors before merge.
The API specification is checked for lint errors before merge.
lightclient marked this conversation as resolved.
Show resolved Hide resolved

To run lint locally, install linter with
```
To run the linter locally, install it with:
```console
npm install -g @stoplight/spectral-cli@6.2.1
```
and run lint with
```
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
lightclient marked this conversation as resolved.
Show resolved Hide resolved
```

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.

It may be neccessary to tick the "Disable Cache" box in their browser's
lightclient marked this conversation as resolved.
Show resolved Hide resolved
developer tools to see changes after modifying the source.

## 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 `<tag>`
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 `<tag>` with real tag name from step 1.):
```javascript
{url: "https://github.com/ethereum/builder-apis/releases/download/<tag>/builder-oapi.yaml", name: "<tag>"},
{url: "https://github.com/ethereum/builder-apis/releases/download/<tag>/builder-oapi.yaml", name: "<tag>"},
```

[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
[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
56 changes: 56 additions & 0 deletions apis/builder/blinded_blocks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
post:
operationId: "submitBlindedBlock"
summary: Submit a signed blinded block and get unblinded execution payload.
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.
tags:
- Builder
requestBody:
description: A `SignedBlindedBeaconBlock`.
required: true
content:
application/json:
schema:
oneOf:
- $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.SignedBlindedBeaconBlock"
examples:
bellatrix:
$ref: "../../builder-oapi.yaml#/components/examples/Bellatrix.SignedBlindedBeaconBlock"
lightclient marked this conversation as resolved.
Show resolved Hide resolved

responses:
"200":
description: Success response.
content:
application/json:
schema:
title: SubmitBlindedBlockResponse
type: object
properties:
version:
type: string
enum: [ bellatrix ]
example: "bellatrix"
data:
oneOf:
- $ref: "../../builder-oapi.yaml#/components/schemas/Bellatrix.ExecutionPayload"
lightclient marked this conversation as resolved.
Show resolved Hide resolved
examples:
bellatrix:
$ref: "../../builder-oapi.yaml#/components/examples/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"
72 changes: 72 additions & 0 deletions apis/builder/header.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
get:
operationId: "getHeader"
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.
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`).
tags:
- Builder
parameters:
- name: slot
in: path
required: true
description: The slot for which the block should be proposed.
schema:
$ref: "../../builder-oapi.yaml#/components/schemas/Uint64"
- name: parent_hash
in: path
required: true
description: Hash of execution layer block the proposer will build on.
schema:
$ref: "../../builder-oapi.yaml#/components/schemas/Root"
- name: pubkey
in: path
required: true
description: The validator's BLS public key.
schema:
$ref: "../../builder-oapi.yaml#/components/schemas/Pubkey"
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/SignedBuilderBid"
lightclient marked this conversation as resolved.
Show resolved Hide resolved
examples:
bellatrix:
$ref: "../../builder-oapi.yaml#/components/examples/Bellatrix.SignedBuilderBid"
"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"
11 changes: 11 additions & 0 deletions apis/builder/status.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
get:
lightclient marked this conversation as resolved.
Show resolved Hide resolved
operationId: "status"
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"
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:
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` more than 10 seconds in
lightclient marked this conversation as resolved.
Show resolved Hide resolved
the future must error.
tags:
- Builder
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"
84 changes: 84 additions & 0 deletions builder-oapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
openapi: "3.0.3"

info:
title: Builder API
description: |
API specification for external builder nodes. This interface enables
validators to delegate block building duties, while allowing for
lightclient marked this conversation as resolved.
Show resolved Hide resolved
attribution 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
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: "CC0-1.0"
url: "https://creativecommons.org/publicdomain/zero/1.0/"

servers:
- url: "{server_url}"
variables:
server_url:
description: "Builder node URL"
default: "http://localhost:18550"

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/header/{slot}/{parent_hash}/{pubkey}:
$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:
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.SignedBlindedBeaconBlock:
$ref: "./beacon-apis/types/bellatrix/block.yaml#/Bellatrix/SignedBlindedBeaconBlock"

SignedValidatorRegistration:
$ref: "./types/registration.yaml#/SignedValidatorRegistration"
SignedBuilderBid:
$ref: "./types/bid.yaml#/SignedBuilderBid"

responses:
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"
Loading