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 #209

Closed
wants to merge 41 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c374995
add builder api spec
lightclient Apr 21, 2022
e28576a
add bls and ssz to word list
lightclient Apr 21, 2022
075a2bb
fix typo
lightclient Apr 21, 2022
8d869f4
remove version from builder api spec
lightclient Apr 21, 2022
305d33e
address feedback from workshop
lightclient Apr 24, 2022
dc69e00
additional validity checks on timestamp
lightclient Apr 24, 2022
e6732a1
add link refs to stuct defs
lightclient Apr 24, 2022
40d5b44
fix typo
lightclient Apr 24, 2022
7a27240
missing v1 on proposer slashing def
lightclient Apr 24, 2022
069b2c4
another typo
lightclient Apr 24, 2022
79ea26e
missing v1
lightclient Apr 24, 2022
49c742d
fix some errors in ssz defs
lightclient Apr 24, 2022
4c44494
add status check to builder
lightclient Apr 25, 2022
b402f04
don't return null in happy case
lightclient Apr 25, 2022
b006213
rework signature defs a bit
lightclient Apr 25, 2022
4338877
missing closing backtick
lightclient Apr 25, 2022
25764b8
Update src/builder/specification.md
lightclient Apr 27, 2022
c814872
Update src/builder/specification.md
lightclient Apr 27, 2022
d0ae0d1
fix wrong message in get payload
lightclient Apr 27, 2022
f666d35
Update src/builder/specification.md
lightclient Apr 27, 2022
bd65467
Update src/builder/specification.md
lightclient Apr 28, 2022
6e73da2
Apply suggestions from code review
lightclient Apr 28, 2022
989c3bf
remove diagram
lightclient Apr 28, 2022
dfc10b6
soften requirement for ELs to implement interface
lightclient Apr 28, 2022
3614eec
Apply suggestions from code review
lightclient Apr 28, 2022
a90e003
change builder receipt to builder bid
lightclient Apr 28, 2022
e249cb3
blind -> blinded
lightclient Apr 29, 2022
66afd7f
verify registered validator
lightclient Apr 29, 2022
4ae07f3
typo fix
lightclient Apr 29, 2022
280bff1
relax get payload header assumptions
lightclient Apr 29, 2022
40547ba
competing chains note
lightclient Apr 29, 2022
1cbd4e7
add gas target to validator registration
lightclient Apr 30, 2022
4bba25c
rename to parent hash in get header
lightclient Apr 30, 2022
572f150
fix typo
lightclient Apr 30, 2022
3777486
fix numbering
lightclient May 2, 2022
190b7f3
fix incorrect error num
lightclient May 2, 2022
42e1fbe
wrong value ident
lightclient May 2, 2022
fcddc0d
better value ident
lightclient May 2, 2022
14963f3
use gas limit instead of gas target
lightclient May 2, 2022
d891d16
remove impl detail
lightclient May 3, 2022
e7dfb37
change validity delta on timestamps to 10 sec
lightclient May 3, 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
7 changes: 7 additions & 0 deletions src/builder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Builder JSON-RPC API

The Builder JSON-RPC API is a collection of methods that all execution clients implement.
lightclient marked this conversation as resolved.
Show resolved Hide resolved
This interface allows the communication between the consensus layer and external builders.

This API is in *active development* and currently [specified as a markdown document](./specification.md).
A schema will follow once the specification stabilizes.
217 changes: 217 additions & 0 deletions src/builder/specification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# Builder API

This document specifies the Builder API methods that the Consensus Layer uses to interact with external block builders.

lightclient marked this conversation as resolved.
Show resolved Hide resolved
```mermaid
sequenceDiagram
participant consensus
participant mev_boost
lightclient marked this conversation as resolved.
Show resolved Hide resolved
participant relays
Title: Block Proposal
Note over consensus: sign fee recipient announcement
consensus->>mev_boost: builder_setFeeRecipient
mev_boost->>relays: builder_setFeeRecipient
Note over consensus: wait for allocated slot
consensus->>mev_boost: builder_getHeader
mev_boost->>relays: builder_getHeader
relays-->>mev_boost: builder_getHeader response
Note over mev_boost: verify response matches expected
Note over mev_boost: select best payload
mev_boost-->>consensus: builder_getHeader response
Note over consensus: sign the block
consensus->>mev_boost: builder_getPayload
Note over mev_boost: identify payload source
mev_boost->>relays: builder_getPayload
Note over relays: validate signature
relays-->>mev_boost: builder_getPayload response
Note over mev_boost: verify response matches expected
mev_boost-->>consensus: builder_getPayload response
```

## Structures

### `ExecutionPayloadV1`

Mirror of [`ExecutionPayloadV1`][execution-payload].

### `ExecutionPayloadHeaderV1`

Equivalent to `ExecutionPayloadV1`, except `transactions` is replaced with `transactionsRoot`.
- `parentHash`: `DATA`, 32 Bytes
- `feeRecipient`: `DATA`, 20 Bytes
- `stateRoot`: `DATA`, 32 Bytes
- `receiptsRoot`: `DATA`, 32 Bytes
- `logsBloom`: `DATA`, 256 Bytes
- `prevRandao`: `DATA`, 32 Bytes
- `blockNumber`: `QUANTITY`, 64 Bits
- `gasLimit`: `QUANTITY`, 64 Bits
- `gasUsed`: `QUANTITY`, 64 Bits
- `timestamp`: `QUANTITY`, 64 Bits
- `extraData`: `DATA`, 0 to 32 Bytes
- `baseFeePerGas`: `QUANTITY`, 256 Bits
- `blockHash`: `DATA`, 32 Bytes
- `transactionsRoot`: `DATA`, 32 Bytes

#### SSZ Objects

Consider the following definitions supplementary to the definitions in [`consensus-specs`][consensus-specs].

##### `builder_setFeeRecipientV1` Request

```python
class SetFeeRecipientRequestV1(Container):
feeRecipient: Bytes20
timestamp: uint64
lightclient marked this conversation as resolved.
Show resolved Hide resolved
```

##### `builder_getPayloadV1` Response

```python
class GetPayloadResponseV1(Container):
payload: ExecutionPayloadHeader
lightclient marked this conversation as resolved.
Show resolved Hide resolved
lightclient marked this conversation as resolved.
Show resolved Hide resolved
value: uint256
```

##### `builder_getPayloadV1` Request

###### `SignedBlindBeaconBlock`

```python
class SignedBlindBeaconBlock(Container):
message: BlindBeaconBlock
signature: BLSSignature
```

###### `BlindBeaconBlock`

```python
class BlindBeaconBlock(Container):
slot: Slot
proposer_index: ValidatorIndex
parent_root: Root
state_root: Root
body: BlindBeaconBlockBody
```

###### `BlindBeaconBlockBody`

```python
class BlindBeaconBlockBody(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: ExecutionPayloadHeader
lightclient marked this conversation as resolved.
Show resolved Hide resolved
```

## Errors

The list of error codes introduced by this specification can be found below.

| Code | Message | Meaning |
| - | - | - |
| -32000 | Server error | Generic client error while processing request. |
| -32001 | Unknown hash | No block with the provided hash is known. |
| -32002 | Unknown validator | No known mapping between validator and feeRecipient. |
| -32003 | Invalid SSZ | Unable to decode SSZ. |
| -32004 | Unknown block | Block does not match the provided header. |
| -32005 | Invalid signature | Provided signature is invalid. |
| -32006 | Invalid timestamp | Provided timestamp was invalid. |
| -32600 | Invalid request | The JSON sent is not a valid Request object. |
| -32601 | Method not found | The method does not exist / is not available. |
| -32602 | Invalid params | Invalid method parameter(s). |
| -32603 | Internal error | Internal JSON-RPC error. |
| -32700 | Parse error | Invalid JSON was received by the server. |

## Routines

### Signing

All signature operations should follow the [standard BLS operations][bls] interface defined in `consensus-specs`.
lightclient marked this conversation as resolved.
Show resolved Hide resolved

There are two types of data to sign over in the Builder API:
* In-protocol messages, e.g. [`BlindBeaconBlock`](#blindbeaconblock), which should compute the signing root using [`compute_signing_root`][compute-signing-root] and use the domain specified for beacon block proposals.
* Builder API messages, e.g. [`builder_setFeeRecipientV1`](#builder_setFeeRecipientV1) and the response to [`builder_getHeader`](#response-2), which should compute the signing root using [`compute_signing_root`][compute-signing-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).

## Methods
lightclient marked this conversation as resolved.
Show resolved Hide resolved

### `builder_setFeeRecipientV1`
lightclient marked this conversation as resolved.
Show resolved Hide resolved

#### Request

- method: `builder_setFeeRecipientV1`
- params:
1. `message`: `object`
1. `feeRecipient`: `DATA`, 20 Bytes - Address of account which should receive fees.
2. `timestamp`: `QUANTITY`, uint64 - Unix timestamp of announcement.
2. `publicKey`: `DATA`, 48 Bytes - Public key of validator.
3. `signature`: `DATA`, 96 Bytes - Signature over `feeRecipient` and `timestamp`.
lightclient marked this conversation as resolved.
Show resolved Hide resolved

#### Response

- result: `null`
lightclient marked this conversation as resolved.
Show resolved Hide resolved
- error: code and message set in case an exception happens while getting the payload.

#### Specification
1. Builder software **MUST** verify `signature` is valid under `publicKey`.
2. Builder software **MUST** respond to requests where `timestamp` is before the latest announcement from the validator with `-32006: Invalid timestamp`.
3. Builder software **MUST** store `feeRecipient` in a map keyed by `publicKey`.
lightclient marked this conversation as resolved.
Show resolved Hide resolved

### `builder_getHeaderV1`

#### Request

- method: `builder_getHeaderV1`
- params:
1. `hash`: `DATA`, 32 Bytes - Hash of Execution Layer block which the validator intends to use as the parent for its proposal.
lightclient marked this conversation as resolved.
Show resolved Hide resolved

#### Response

- result: `object`
- `message`: `object`
- `header`: [`ExecutionPayloadHeaderV1`](#executionpayloadheaderv1).
- `value`: `DATA`, 32 Bytes - the payment in wei that will be directed to the `feeRecipient` account.
- `publicKey`: `DATA`, 48 Bytes - the public key associated with the builder.
- `signature`: `DATA`, 96 Bytes - BLS signature of the builder over `payload` and `value`.
lightclient marked this conversation as resolved.
Show resolved Hide resolved
- error: code and message set in case an exception happens while getting the payload.

#### Specification
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a restriction to disallow requests where input slot is in the future?
I'm not 100% sure if that's necessary, but I wonder what would be the intended behavior if anyone calls builder_getHeaderV1 earlier than the assigned slot. Curious to hear ppl's thoughts

Copy link

@metachris metachris May 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relay/builder should perhaps just return an error, or nothing at all. Seems similar to the situation where a relay does not (yet) have a block for the requested parentHash.

1. Builder software **SHOULD** respond immediately with the `header` that increases the `feeRecipient`'s balance by the most.
2. Builder software **MUST** return `-32001: Unknown hash` if the block identified by `hash` does not exist.
3. Builder software **MUST** return `-32002: Unknown validator` if the validator the builder expects to propose in the current slot has not been mapped to a `feeRecipient`.
4. Builder software **MAY** set the `feeRecipient` for the block to a different address than the address mapped to the validator so long as a payment equal to `value` is made to `feeRecipient`.

### `builder_getPayloadV1`

#### Request

- method: `builder_getPayloadV1`
- params:
1. `block`: `DATA`, arbitray length - SSZ encoded [`SignedBlindBeaconBlock`](#blindbeaconblock).
lightclient marked this conversation as resolved.
Show resolved Hide resolved

#### Response

- result: [`ExecutionPayloadV1`](#executionpayloadv1).
lightclient marked this conversation as resolved.
Show resolved Hide resolved
- error: code and message set in case an exception happens while proposing the payload.

#### Specification
1. Builder software **MUST** verify that `block` is an SSZ encoded [`SignBlindBeaconBlock`](#blindbeaconblock). If the block is encoded incorrectly, the builder **MUST** return `-32003: Invalid SSZ`. If the block is encoded correctly, but does not include a matching `ExecutionPayloadHeaderV1` provided from `builder_getHeaderV1`, the builder **SHOULD** return `-32004: Unknown block`.
2. Builder software **MUST** verify that `signature` is a BLS signature over `block` using [`verify_block_signature`][verify-block-signature] from the validator that is expected to propose in the given slot. If the signature is determined to be invalid or from a different validator than expected, the builder **MUST** return `-32005: Invalid signature`.

[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-signing-root]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_signing_root
[bytes20]: https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md#aliases
[uint256]: https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md#basic-types
[execution-payload-header]: https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#executionpayloadheader
[execution-payload]: https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#executionpayloadv1
[hash-tree-root]: https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md#merkleization
[beacon-block]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblock
[verify-block-signature]: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function
4 changes: 3 additions & 1 deletion wordlist.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
apis
attributesv
bls
bytecode
configurationv
eip
Expand All @@ -21,9 +22,10 @@ rlp
rpc
schemas
secp
sha
ssz
statev
statusv
sha
uint
updatedv
url
Expand Down