Mev-boost: A middleware server written in Go

mev-boost

A middleware server written in Go, that sits between an ethereum PoS consensus client and an execution client. It allows consensus clients to outsource block construction to third party block builders as well as fallback to execution clients. See ethresearch post for the high level architecture.

Implementation Plan

A summary of consensus client changes can be found here.

milestone 1 - kintsugi testnet

simple middleware logic with minimal consensus client changes, simple networking, no authentication, and manual safety mechanism

middleware behavior

  • middleware sends feeRecipient to relay with direct engine_forkchoiceUpdatedV1 request at beginning of block
  • middleware fetches signed payloads from relay using unauthenticated getPayloadHeader request
  • middleware selects best payload that matches expected payloadId and requests signature from consensus client, this requires passing header object to the consensus client and flagging that it should be returned to the middleware once signed
  • middleware returns signed block + initial payload header to relay with direct request

required client modifications

milestone 2 - security & reputation

cleanup consensus client and add security fallbacks

middleware behavior

  • add middleware module for verifying previous relay payload validity and accuracy with hard or statistical blacklist (may require modifications to execution client)
  • add middleware module for subscribing to 3rd party relay monitoring service

required client modifications

  • in event of middleware crash, consensus client must be able to bypass the middleware to reach a local or remote execution client

milestone 3 - authentication & privacy (optional)

add authentication and p2p comms mechanisms to prevent validator deanonymization

middleware behavior

  • middleware signs feeRecipient message and gossips over p2p at regular interval
  • middleware gossips signed block + initial payload header over p2p

required client modifications

milestone 4 - configurations (optional)

add optional configurations to provide alternative guarantees

  • consider adding direct engine_forkchoiceUpdatedV1 call to relay for syncing state
  • consider returning full payload directly to validator as optimization
  • consider adding merkle proof of payment to shift verification requirements to the relay

API Docs

relay_proposePayloadV1

Request

Response

  • result: object
    • status: enum - "VALID" | "INVALID" | "SYNCING"
    • latestValidHash: DATA|null, 32 Bytes - the hash of the most recent valid block in the branch defined by payload and its ancestors
    • validationError: String|null - a message providing additional details on the validation error if the payload is deemed INVALID
  • error: code and message set in case an exception happens while executing the payload.

engine_executePayloadV1

Request

Response

  • result: object
    • status: enum - "VALID" | "INVALID" | "SYNCING"
    • latestValidHash: DATA|null, 32 Bytes - the hash of the most recent valid block in the branch defined by payload and its ancestors
    • validationError: String|null - a message providing additional details on the validation error if the payload is deemed INVALID
  • error: code and message set in case an exception happens while executing the payload.

engine_forkchoiceUpdatedV1

Request

Response

  • result: object
    • status: enum - "SUCCESS" | "SYNCING"
    • payloadId: DATA|null, 8 Bytes - identifier of the payload build process or null
  • error: code and message set in case an exception happens while updating the forkchoice or initiating the payload build process.

engine_getPayloadV1

Request

  • method: engine_getPayloadV1
  • params:
    1. payloadId: DATA, 8 Bytes - Identifier of the payload build process

Response

  • result: ExecutionPayloadV1
  • error: code and message set in case an exception happens while getting the payload.

Build

make build

and then run it with:

./mev-boost

Test

make test

Lint

We use revive as a linter. You need to install it with go install github.com/mgechev/revive@latest

make lint
Comments
  • Do you want to run a builder?

    Do you want to run a builder?

    So, we heard you want to run a builder! Tell us more :)

    The builder API specification is open and every validator can select their own builders. However, there are still open questions that we need to resolve with the humans in the ethereum ecosystem to get a permissionless and fully decentralized design. Following the plan towards proposer/builder separation we are researching and prototyping solutions for decentralization. Coming next is the addition of independent block builders to the Flashbots relay. You can find the initial Relay API specification here, which outlines how builders can interact with the Flashbots Relay.

    Tell us more about who you are, what is your role in the ecosystem, how will you profit from running a builder, how are you going to contribute to answer the open questions, in order to get us to the trustless proposer/builder separation. Leave a comment in this issue so we can talk about collaboration.

  • Upcoming mev-boost release: v1.4.0

    Upcoming mev-boost release: v1.4.0

    A number of improvements have accumulated since the last release (v1.3.2 on September 22, 2022), and it's time to think about the next release v1.4.0!

    These are the already merged changes since the last release:

    • https://github.com/flashbots/mev-boost/compare/v1.3.2...main

    Would love to hear any comments, concerns, thoughts!

    The process would be:

    1. merge any remaining PRs that we want in the release
    2. test for a few some time on testnets (Goerli, Sepolia) in partnership with node operators
    3. release
  • Run gocritic linter

    Run gocritic linter

    📝 Summary

    Run gocritic linter and fix warnings

    ⛱ Motivation and Context

    Improve code quality

    📚 References

    According to Effective Go switch is more idiomatic than if-else chain

    ✅ I have run these commands

    • [x] make lint
    • [x] make test-race
    • [x] go mod tidy
  • Frequent

    Frequent "no bid received"

    Environment

    We're rocking 2500 validators with..

    Lighthouse: v2.5.1
    mev-boost: v0.7.10
    Network: prater
    Relay: https://0xafa4c6985aa049fb79dd37010438cfebeb0f2bd42b115b89dd678dab0670c1de38da0c4e9138c9290a398ecd9a0b3110@builder-relay-goerli.flashbots.net
    

    Issue

    About 60% of the proposals fallback to local EE (the other 40% are successfully built via mev-boost).

    When it happens, we see these errors in Lighthouse:

    Aug 21 14:02:25.958 INFO Requesting blinded header from connected builder, parent_hash: ..., pubkey: ..., slot: Slot(...), service: exec
    Aug 21 14:02:26.258 INFO No payload provided by connected builder. Attempting to propose through local execution engine, service: exec
    

    And these errors in mev-boost:

    time="2022-08-21T14:02:26Z" level=info msg="no bid received" method=getHeader module=service parentHash=0xdffccc7de563f586e027d563c7e5df860155d2c0aecc87f392aac8aece7e9fc4 pubkey=0x884fcee670d202053d48e64561d3f53f8478fa682f6f2a9676db082c8aa409e3b9fc6f132665d1f968758346a612c8cd slot=3715212
    time="2022-08-21T14:02:26Z" level=info msg="http: GET /eth/v1/builder/header/3715212/0xdffccc7de563f586e027d563c7e5df860155d2c0aecc87f392aac8aece7e9fc4/0x884fcee670d202053d48e64561d3f53f8478fa682f6f2a9676db082c8aa409e3b9fc6f132665d1f968758346a612c8cd 204" duration=0.096443931 method=GET module=service path=/eth/v1/builder/header/3715212/0xdffccc7de563f586e027d563c7e5df860155d2c0aecc87f392aac8aece7e9fc4/0x884fcee670d202053d48e64561d3f53f8478fa682f6f2a9676db082c8aa409e3b9fc6f132665d1f968758346a612c8cd
    

    Notes

    • Reproduced on Sepolia with Flashbots' relay (2 weeks ago)
    • We run a custom-built VC (instead of Lighthouse's), but correct me if I'm wrong, since VC isn't involved in the bidding flow, it's unlikely to be the culprit?

    Does anyone else have this issue as frequently or at all? Thanks 🙏

  • Remove use of `engine_forkchoiceUpdatedV1`

    Remove use of `engine_forkchoiceUpdatedV1`

    Currently engine_forkchoiceUpdatedV1 is used to communicate to relays the feeRecipient that a validator will be using. As a side effect, a lot of unnecessary information is communicated to the relays.

    I propose two potential alternatives:

    1. builder_getPayloadHeader(hash, feeRecipient) -> PayloadHeader
    2. builder_preparePayload(hash, feeRecipient) -> uint64 + builder_getPayloadHeader(payloadId) -> PayloadHeader

    I don't know if I have enough of an understanding of the latency of 1) to choose it over 2), but it is naively my preference.

  • accept gzip encoding

    accept gzip encoding

    📝 Summary

    From a discussion with @zeroecco on how to lower bandwidth on the blocknative relay we came to the idea that we could utilize well known compression like gzip, but only if requests coming from mev-boost specified that.

    Minimum transmittable unit is 1500 Bytes total w/ 1250 Bytes realistically usable and a block is around ~12KB, gzip will compress ~60% to ~6Kb which would be a packet reduction from 10 to 5 for the total packet train. This also reduces time to last packet and bandwidth, which could be 1 - 5ms based on response time at this size.

    If a system doesn't have this enabled the content-encoding will simply be ignored. On top of that, this improvement will really only be visible for GetPayload response.

    To benefit from this in your relay or other components make sure you configure your reverse proxy [HA Proxy, NGINX, etc] to support gzip!

    ⛱ Motivation and Context

    I want to go fast

    📚 References

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding

    https://www.rfc-editor.org/rfc/rfc2616#section-3.5

    ✅ I have run these commands

    • [x] make lint
    • [x] make test-race
    • [x] go mod tidy
  • Recently proposed blocks

    Recently proposed blocks

    I'd like to discuss the idea of adding a method to relay API that returns blocks that have recently been proposed using relay.

    Goal

    The goal is to understand whether MEV-Boost was used to build a particular block and which relay was used for it. This is useful for participants such as staking pools to organize monitoring after validators that are operated by a third party.

    Proposed solution

    The goal can be achieved by adding a method that returns a block if it has been proposed using the current relay. Blocks can be stored in memory, and the stored number can be limited. Data for the last 32 slots should be enough for a third-party service to collect data about the last proposed blocks. All necessary data can be collected after a successful call to relay_proposeBlindedBlockV1 method.

    relay_getProposedBlindedBlockV1

    Request

    • method: relay_getProposedBlindedBlockV1
    • params:
      1. slot: slot number

    Response

    • result: ProposedBlock
    • error: code and message set in case an exception happens while performing the request.

    Types

    ProposedBlock

    Specification

    • Relay software MUST return proposed block if it has been proposed using the relay in the last 32 slots, otherwise return -32004: Unknown block.

    Alternatives

    This may not be the best solution, and I suggest discuss how to achieve the goal. Since Flashbots has a centralized API (blocks.flashbots.net) and probably want to support it after the Merge, I assume you may have a vision of collecting such data.

  • SIGILL: illegal instruction

    SIGILL: illegal instruction

    Since version 0.7.10 I'm getting the following error when trying to run -help or -version..

    SIGILL: illegal instruction
    PC=0x6db7ae m=0 sigcode=2
    signal arrived during cgo execution
    instruction bytes: 0xf3 0x4c 0xf 0x38 0xf6 0xcf 0x66 0x4c 0xf 0x38 0xf6 0xd5 0xc4 0xe2 0xc3 0xf6
    
    goroutine 1 [syscall, locked to thread]:
    runtime.cgocall(0x6bda00, 0xc00013dba8)
    	/usr/local/go/src/runtime/cgocall.go:157 +0x5c fp=0xc00013db80 sp=0xc00013db48 pc=0x4097bc
    github.com/supranational/blst/bindings/go._Cfunc_blst_sk_to_pk2_in_g1(0x0, 0xc00012a240, 0xc000132ce0)
    	_cgo_gotypes.go:1317 +0x45 fp=0xc00013dba8 sp=0xc00013db80 pc=0x66f7e5
    github.com/supranational/blst/bindings/go.(*_Ctype_struct___4).From(...)
    	/home/ethereum/go/pkg/mod/github.com/supranational/[email protected]/bindings/go/blst.go:219
    github.com/flashbots/go-boost-utils/bls.PublicKeyFromSecretKey(...)
    	/home/ethereum/go/pkg/mod/github.com/flashbots/[email protected]/bls/bls.go:40
    github.com/flashbots/mev-boost/server.init()
    	/home/ethereum/go/pkg/mod/github.com/flashbots/[email protected]/server/mock_relay.go:25 +0xec fp=0xc00013dbf0 sp=0xc00013dba8 pc=0x6bb1cc
    runtime.doInit(0x990f40)
    	/usr/local/go/src/runtime/proc.go:6222 +0x126 fp=0xc00013dd20 sp=0xc00013dbf0 pc=0x4491e6
    runtime.doInit(0x98f000)
    	/usr/local/go/src/runtime/proc.go:6199 +0x71 fp=0xc00013de50 sp=0xc00013dd20 pc=0x449131
    runtime.doInit(0x98a600)
    	/usr/local/go/src/runtime/proc.go:6199 +0x71 fp=0xc00013df80 sp=0xc00013de50 pc=0x449131
    runtime.main()
    	/usr/local/go/src/runtime/proc.go:233 +0x1d3 fp=0xc00013dfe0 sp=0xc00013df80 pc=0x43c373
    runtime.goexit()
    	/usr/local/go/src/runtime/asm_amd64.s:1571 +0x1 fp=0xc00013dfe8 sp=0xc00013dfe0 pc=0x468ac1
    
    rax    0x0
    rbx    0x7f9f20
    rcx    0x7f99a0
    rdx    0x7817fc679976fff5
    rdi    0xc25f1572e1a87b0e
    rsi    0x7f9ea0
    rbp    0x2b7cd71362065849
    rsp    0x7ffc88619968
    r8     0x1f36a914d1d1ca54
    r9     0xe3f09cc9f448ab2c
    r10    0x53ae4ce3194e4adf
    r11    0x988f6b1f351f9469
    r12    0xf0030d9fa553ae92
    r13    0x8e738258ad84f1f6
    r14    0x685276af035ca2f
    r15    0x0
    rip    0x6db7ae
    rflags 0x10246
    cs     0x33
    fs     0x0
    gs     0x0
    
    

    I did not get this error with the previous two versions. How can I resolve this problem?

  • Open-source relay - which license to use?

    Open-source relay - which license to use?

    We will open source our mev-boost relay!

    (ETA early September)

    For context, this is our Ropsten relay: https://builder-relay-ropsten.flashbots.net (see also the Relay API Documentation)

    What's your opinions on the license we should use, and why?

    See also https://choosealicense.com/licenses

    Note: We were strongly considering AGPL, which would oblige anyone making changes to publish them as well, in order to foster a thriving development ecosystem around the mev-boost relays.

  • Reflect relays statuses in `status` endpoint

    Reflect relays statuses in `status` endpoint

    I think mev-boost status endpoint should call status endpoints for each relays and return OK if at least one returned OK. Otherwise it should return KO (503?).

  • Simplify spec, update based on recent discussions

    Simplify spec, update based on recent discussions

    I took a stab at updating the spec based on our recent discussions about the spec. I need to update sequence diagram and the process overview, but I think it's relatively straightforward.

    A few notes:

    • I removed the concept of builder vs. relay methods and combined them. The CL can ignore things like feeRecipientDiff and signatures, or it can use that info to compare against it's local payload. I think this really simplifies things a lot.
    • I decided to go with SSZ encoding the block because it simplifies the spec a lot and is already the form that the builder will need it in to validate the signature.
  • Capella decode and fallback to bellatrix

    Capella decode and fallback to bellatrix

    📝 Summary

    More context in https://github.com/flashbots/mev-boost/pull/411.

    As part of https://github.com/flashbots/mev-boost/issues/392 this PR attempts to decode the getPayload call with capella types (from attestant) and then decode with bellatrix types (from go-boost-utils) as a fallback.

    ⛱ Motivation and Context

    📚 References

    waiting on https://github.com/attestantio/go-builder-client/pull/2 as attestant types don't have support for capella yet for relay responses.


    ✅ I have run these commands

    • [x] make lint
    • [x] make test-race
    • [x] go mod tidy
  • ✨ Refactoring mev-boost

    ✨ Refactoring mev-boost

    Description

    Server

    In the process of implementing features such as the relay selection, I faced some issues related to the current architecture of the server package.

    I have identified the following potential refactors that, once implemented, would make granular updates easier for developers:

    • Add a cache package
      • It would hold the bid cache specific types and methods
    • Add an internal/testing package
      • It would hold the mocked types and mock relay
    • Add a package for relay-dedicated components
      • It would hold relay entries types and methods
    • Move client methods in a dedicated package
      • It would hold all methods used to make requests currently in the utils.go file
    • Refactor the mocked relay and associated tests

    CLI

    In my opinion, I also think that the current implementation of the CLI could be improved by taking advantage of the combined powers of Cobra and Viper. Using this combination in a good way could lead to the usage of configuration files for mev-boost, which can be used by future features.

    Discussion

    I would like to have your opinion / critisims about these. If you have any a question or need more details, please ask.

  • Allow operating a builder with no fee and no payout TX

    Allow operating a builder with no fee and no payout TX

    Rationale

    Why should this feature exist?

    • when the builder doesn't collect any fee it is very enificient to create a payout TX on every block. some validators use a contract which consumes 70-100k gas so without the payout TX the total block value will be higher.

    What are the use-cases?

    • operating a builder that doesn't collect block fees.

    Implementation

    Do you have ideas regarding the implementation of this feature?

    • yes the simulation checks -
      • if the coinbase address is the same as the validator's address
      • the coinbase balance difference is the same as the bid value

    Are you willing to implement this feature?

    • yes

    cc @Ruteri

  • Validator level relay configuration

    Validator level relay configuration

    Given our infrastructure, we have begun exploring enabling validator level configuration of relays for a single instance of MEV-Boost. This was originally raised in https://github.com/flashbots/mev-boost/issues/154 .

    We are currently developing a document and POC to prove out the ideas in the doc and will publish both here once we have some level of verification for the community to assess...

  • Replace go-boost-utils types with Attestant types

    Replace go-boost-utils types with Attestant types

    📝 Summary

    Pr for issue #404, replacing with types from attestant to reduce maintenance for go-boost-utils

    ⛱ Motivation and Context

    📚 References


    ✅ I have run these commands

    • [x] make lint
    • [x] make test-race
    • [x] go mod tidy
  • feature-request: Weighted relays

    feature-request: Weighted relays

    Diversify relay usage

    There is a community driven pressure to diversify the relays, mostly because having a single relay control a big percentage of the block production gives that relay powers to censor or delay some transactions.

    Right now if a user wants to avoid using a relayer due to those concerns it has to avoid including this relay when setting up mev-boost. The problem with this approach is that the user is now deprived from any offers from the relay, even when those offers are on-off opportunities that doesn't affect regular block production.

    Adding weights to relays would allow users to give priority to relays who align with their principles while still having access to other relays in case they have a good offer. It allows expressing intents like "use relayer Y unless X pays double".

    Better risk management

    Weighted relays would also allow users to include "less trusted" relays but only when these relays have substantial better offers, expressing things like "I don't fully trust relay X but if it pays ten times more I'm willing to take the chances".

Related tags
server-to-server sync application, written in go/golang.

svcpy: server to server copy a basic server-to-server copy application. on a single binary, it can be a server or a client. example usage: on the serv

Nov 4, 2021
Pape-server - A small server written in golang to serve a random wallpaper.

pape-server I like to inject custom CSS themes into a lot of websites and electron apps, however browsers don't let websites access local disk through

Dec 31, 2021
Server - Dupman server written in Go

server dupman server written in Go Requirements Go (>=1.17) Installation Usage C

Feb 22, 2022
HTTP API traffic recording and replay middleware based on GoReplay, can be used for migration and refactoring testing

gorc HTTP API traffic recording and replay middleware based on GoReplay, can be used for migration and refactoring testing. English | 中文 Requirements

Feb 13, 2022
The seed repository for your Flamego middleware modules

seed This repository contains seed files that almost every repository of Flamego middleware module should have. Using the content Create an empty repo

Dec 11, 2021
Header Block is a middleware plugin for Traefik to block request and response headers which regex matched by their name and/or value

Header Block is a middleware plugin for Traefik to block request and response headers which regex matched by their name and/or value Conf

May 24, 2022
Log4Shell is a middleware plugin for Traefik which blocks JNDI attacks based on HTTP header values.

Log4Shell Mitigation Log4Shell is a middleware plugin for Traefik which blocks JNDI attacks based on HTTP header values. Related to the Log4J CVE: htt

Dec 20, 2022
Middleware for Blocking IP ranges by inserting CIDR Blocks and searching IPs through those blocks

firewall Middleware for Blocking IP ranges by inserting CIDR Blocks and searching IPs through those blocks. Features Easy to use Efficient and Fast Co

Oct 9, 2022
SubCenter is a middleware that integrate task subscriptions and real-time push

Subscription Center SubCenter是一个集成各种任务并进行实时推送的中间件,本身不提供数据与推送服务。

Oct 31, 2022
🧬 fiber middleware to automatically generate RESTful API documentation with Swagger

Swagger fiber middleware to automatically generate RESTful API documentation with Swagger Usage Add comments to your API source code, See Declarative

Jan 1, 2023
A Language Server Protocol (LSP) server for Jsonnet

Jsonnet Language Server Warning: This project is in active development and is likely very buggy. A Language Server Protocol (LSP) server for Jsonnet.

Nov 22, 2022
The server-pubsub is the main backend of DATAVOC project that manages all the other web-server modules of the same project such as the processor

server-pubsub The server-pubsub is the main backend of DATAVOC project that manages all the other web-server modules of the same project such as the p

Dec 3, 2021
Server and client implementation of the grpc go libraries to perform unary, client streaming, server streaming and full duplex RPCs from gRPC go introduction

Description This is an implementation of a gRPC client and server that provides route guidance from gRPC Basics: Go tutorial. It demonstrates how to u

Nov 24, 2021
Cert bound sts server - Certificate Bound Tokens using Security Token Exchange Server (STS)
Cert bound sts server - Certificate Bound Tokens using Security Token Exchange Server (STS)

Certificate Bound Tokens using Security Token Exchange Server (STS) Sample demonstration of Certificate Bound Tokens acquired from a Security Token Ex

Jan 2, 2022
Echo-server - An HTTP echo server designed for testing applications and proxies

echo-server An HTTP echo server designed for testing applications and proxies. R

Dec 20, 2022
Broadcast-server - A simple Go server that broadcasts any data/stream

broadcast A simple Go server that broadcasts any data/stream usage data You can

Oct 21, 2022
Videos2gether-server - Server for the Realtime video streaming app Videos2Gether

Videos Together server Server source code for the https://videos2gether.com Arch

Jan 9, 2022
JPRQ Customizer is a customizer that helps to use the JPRQ server code and make it compatible with your own server with custom subdomain and domain
JPRQ Customizer is a customizer that helps to use the JPRQ server code and make it compatible with your own server with custom subdomain and domain

JPRQ Customizer is a customizer that helps to use the JPRQ server code and make it compatible with your own server with custom subdomain and domain.You can upload the generated directory to your web server and expose user localhost to public internet. You can use this to make your local machine a command center for your ethical hacking purpose ;)

Jan 19, 2022
Envoy-eds-server - Envoy EDS server is a working Envoy Discovery Service implementation

envoy-eds-server Intro Envoy EDS server is a working Envoy Discovery Service imp

Apr 2, 2022