Try   HackMD

Flashbots Milestone 1 for Consensus Clients

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.

The Flashbots Scheme

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.

Avoiding Central Points of Failure

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.

Changes for Consensus Clients

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

Changes for Beacon Nodes

New Beacon API Endpoints

  1. Add a GET eth/v1/validator/blinded_block which returns a BeaconBlockHeader.
  2. Add a POST eth/v1/beacon/blinded_block which accepts a BeaconBlockHeader.

Add the Payload Builder

  1. Provide a --payload-builder flag which accepts a HTTP endpoint.
  2. Whenever an engine_forkchoiceUpdatedV1 message is being issued to the EE, also issue that message to the payload builder (PB).
  3. When producing a block, issue a engine_getPayloadHeaderV1 (TODO: confirm with Flashbots API) to the PB. If the PB fails to return an ExecutionPayloadHeader, request an ExecutionPayload from the EE.
  4. Do not use the engine_executePayloadV1 endpoint on the PB to verify payloads. Always use the EE. There is no requirement to call engine_executePayloadV1 on the PB.
  5. If an EE indicates that an 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.
  6. If the --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.
  7. If the --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).

Changes for Validator Clients

  1. Add a --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).