This document describes the changes required for consensus clients to be compatible with Milestone 1 of Flashbots mev_boost
.
Flashbots mev_boost
is an application that builds ExecutionPayloads
for post-merge Beacon Chain validators. In short, does all the fancy MEV stuff for PoS Ethereum that Flashbots already does for PoW Ethereum.
In Flashbots, there is a series of entities invovled in producing an ExecutionPayload
. These include searchers/users who find transactions, builders who collate these transactions into an ExecutionPayload
and relays who transmit an ExecutionPayload
to validators.
From a consensus client perspective, a consensus node will interact with mev_boost
, a component which abstracts away searchers/users, builders and relays. There is only one factor which necessarily leaks into the consensus engine, hiding the payload transactions
from the validator.
In the Flashbots scheme, a validator must commit to a set of transactions without knowing those transactions. This prevents a validator from "stealing" transactions and breaking the Flashbots economic model.
This commitment can be achieved by having the validator sign over a block which contains only the root of the transactions. This means the validator doesn't know the transactions, but will be slashable if they produce a conflicting block. We call this blind transaction signing.
The simplest integration method for mev_boost
is for it to act as "middlware" between a beacon node (BN) and execution engine (EE). Hypothetically, if BNs support EEs that only provide an ExecutionPayloadHeader
rather than a full ExecutionPayload
then we have everything we need to support mev_boost
(at milestone 1, at least).
However, using mev_boost
as middleware means that the safety and liveness of the Beacon Chain rests upon it alone. This is a central point of failure.
A better solution, in my opinion, is to introduce the concept of a payload-builder to consensus engines. In such a scheme, a consensus engine will support a regular EE and a payload-builder.
When producing a block, a consensus engine queries the payload-builder for a payload. If the payload-builder doesn't respond, the consensus engine will defer to the EE to produce the payload.
When verifying a block, the consensus engine always defers to the EE. Consensus engines do not trust the payload-builder to verify payloads. Furthermore, if a local payload-builder is found to produce invalid payloads then it is excommunicated.
With this separate payload-builder and EE scheme, it's only possible for mev_boost
to temporarily halt the chain but it's not possible for mev_boost
to finalize invalid payloads (i.e., a correctness failure).
The rest of this document will assume the separate payload-builder and EE scheme.
I assume a separate beacon node (BN) and validator client (VC) architecture, with comms via the Standard Beacon Node API.
The mev_boost
API is documented here: https://github.com/flashbots/mev-boost/tree/d2f1d861e1acb5c067f02d3eeb70aa9b30ea1ed7#api-docs
GET eth/v1/validator/blinded_block
which returns a BeaconBlockHeader
.POST eth/v1/beacon/blinded_block
which accepts a BeaconBlockHeader
.--payload-builder
flag which accepts a HTTP endpoint.engine_forkchoiceUpdatedV1
message is being issued to the EE, also issue that message to the payload builder (PB).engine_getPayloadHeaderV1
(TODO: confirm with Flashbots API) to the PB. If the PB fails to return an ExecutionPayloadHeader
, request an ExecutionPayload
from the EE.engine_executePayloadV1
endpoint on the PB to verify payloads. Always use the EE. There is no requirement to call engine_executePayloadV1
on the PB.ExecutionPayload
produced by the PB is invalid, log an error to the user and disable the PB until next restart. This requires the BN to store a list of block roots roots which have been produced by a local PB.--payload-builder
flag is supplied, any request to GET eth/v1/validator/blinded_block
should attempt to use the PB. Without the flag supplied, use the EE.--payload-builder
flag is supplied, any request to POST eth/v1/beacon/blinded_block
should send the the blinded block to the PB via relay_proposePayloadV1
(TODO: propose payload needs a different type on the Flashbots API).--blinded-payload-builder
flag which, when supplied, causes the VC to use the validator/blinded_block
and beacon/blinded_block
endpoints (rather than thier full block
counterparts).