๐ณ๏ธ
Dreamboat
An Ethereum 2.0 Relay for proposer-builder separation (PBS) with MEV-boost. Commissioned, built, and put to sea by Blocknative.
Quickstart
Installation
Install with go get
, or download the latest release here.
$ go install github.com/blocknative/dreamboat
Usage
$ dreamboat --help
Documentation can be found here.
What is Dreamboat?
Dreamboat is a relay for Ethereum 2.0, it ships blocks from builders to validators. Dreamboat is for anyone who wants to strengthen the Eth network by running their own relay. Dreamboat's all-in-one design, modular code base and stunning performance will dazzle beginners and seasoned hackers alike. All aboard!
More precisely, Dreamboat is a spec-compliant builder and relay that allows block-builders and validators to interface with eachother through MEV-boost.
Eventually Dreamboat will vanish, as if a dream, once in-protocol PBS is live. Until then, it sails the ephemeral seas of block space, delivering its trusted cargo of blocks to validators, guided simply by a lighthouse.
Design Goals
Special thanks to Flashbots for their commiment to open source. This project was orginally based on the relay in Flashobot's boost-geth-builder and mev-boost-relay. We hope to continue to diverge in implementation over time to help strengthen #RelayDiversity as we continue to work on Dreamboat's core design goals:
- Extensibility. Dreamboat provides well-factored interfaces that make it easy to change its behavior. We use Go Datastore for its persistence layer, so you can swap out the default BadgerDB store with your favorite database, and provide a clean separation between core relay logic, the beacon-chain client, and the HTTP server.
- Reliability. Work is ongoing implement a supervision-tree architecture in Dreamboat, so that you never miss a block.
- Performance. We have put significant engineering effort into tuning Dreamboat's performance, and have much, much more in store. The HTTP server's hot paths are 100% lock-free, concurrency is carefully tuned, and there are ongoing efforts to optimize the garbage collector and speed up signature validation. The result is a ship that doesn't just sail... it glides.
- Transparency. Dreamboat implements the Relay Data API, so you can audit past proposals. But we take a much broader view of transparency, which includes code transparency. A major cleanup effort is underway to make -- and keep -- Dreamboat's code legible. We believe this is an essential part of ensuring transparency and reliability.
We are continuously improving Dreaboat's runtime performance, standards compliance, reliability and transparency.
Planned Features & Enhancements
The following features and enhancements are in-progress.
- Support for multiple storage backends (Redis, Postgres, BadgerDB, Filesystem, etc.)
- Runtime profiling & tracing endpoint
- Parallel validator-signature verification
- Contention-free execution along hot paths
- Support for multiple beacon clients (in testing stage)
- Support for multiple external block builders
Support
Stuck? Don't despair! Drop by our discord to ask for help, or just to say hello. We're friendly!
Developing
Building Locally
$ go run cmd/dreamboat
Architecture
Proposer Builder Separation is a solution to shield validators from the centralizing force the black hole of MEV has released. The next chapter in this saga is to protect builders from too extreme of centralizing forces.
API Compatibility
Dreamboat follows semantic versioning. Changes to the REST API are governed by the Flashbots specifications.
The main
branch is NOT guaranteed to be stable. Use the latest git tag in production!
Add extensibility for adding arbitrary networks
What ๐ต๏ธโโ๏ธ
This PR adds extensibility, by letting users to specify any arbitrary networks
How โ๏ธ
For adding new networks, users MUST do 1 things:
<datadir>/networks.json
A simple example of a network specification file would be:
This is only in case you want to extend the networks. The default networks (e.g., mainnet) are hardcoded.
Feature/multi builder support
What ๐ต๏ธโโ๏ธ
Explain what this PR accomplishes
check-builder
flag tosimulation
and adds validation. This is in preparation for adding support for external builders, the rest of this PR simply focuses on multiple builder support.Support for multiple builders:
Why ๐
Explain the need or decisions which make this change necessary
How โ๏ธ
Briefly explain what components you modified or added, and how, to give context to your reviewers
Testing ๐งช
go test ./...
from rootBuild seems broken?
What doesn't work
Build Binary + Run
Repro steps
Run directly
What does work
Additional metric set
What ๐ต๏ธโโ๏ธ
Enabling Prometheus default metrics over internal, additional, http port. Added badgerdb expvar metrics into prometheus.
Removed pprof bindings from regular http interface, moved it into internal http - always enabled.
Why ๐
To keep track of metrics and performance of the relay and database processed
Multiple builder submissions
What ๐ต๏ธโโ๏ธ
This PR makes Dreamboat to be multi-builder, so that multiple builders can submit blocks. The relay chooses the highest bid among different builders. The intuition of the implementation is that a separate list of max profit bids is stored. In this list we keep the latest submission of every builder. So when a validator queries for a header, we get the max profit headers list, we sort them by bid (descending), and we select the highest bid.
Testing ๐งช
fix registration logic
What ๐ต๏ธโโ๏ธ
This PR improves validator registration logic. Currently, as soon as registration fails, the remaining validators are not registered. However, with this PR even if a single registration fails, then the rest of validators are registered.
Fix/blocks received
What ๐ต๏ธโโ๏ธ
This PR fixes the builder_blocks_received Data API call, so that now all blocks for every slot are returned. previously just the latest block per slot was returned
Testing ๐งช
The corresponding tests have been fixed, and all pass
getPayload has insufficient checks, allows validator to access the block contents without slashing
The getPayload checks in https://github.com/blocknative/dreamboat/blob/main/pkg/api.go#L172 / https://github.com/blocknative/dreamboat/blob/main/pkg/relay.go#L312 are insufficient, and allow a validator to steal the payload without risk of slashing. besides checking the blockhash, also the correct slot and proposer index need to be verified.
See the mev-boost audit for more details: https://github.com/flashbots/mev-boost/blob/main/docs/audit-20220620.md#relayer-signedblindedbeaconblock-validation
fix submitBlock default error
What ๐ต๏ธโโ๏ธ
Explain what this PR accomplishes
"Manually fuzz testing" and noticed submitBlock returns errors like:
when it should be
like the other endpoints
Why ๐
Explain the need or decisions which make this change necessary
API consistency
Testing ๐งช
go test -race ./...
from rootData API error vs empty response
When Data API does not find a value based on a specific field like the slot, currently, we return an error. Instead we should return an empty array, in order to comply with the same format of Flashbots and the rest of the relays
Stable/log+bid
What ๐ต๏ธโโ๏ธ
This PR:
Typo: Dreaboat -> Dreamboat
Typo fix
What ๐ต๏ธโโ๏ธ
Explain what this PR accomplishes
Why ๐
Explain the need or decisions which make this change necessary
How โ๏ธ
Briefly explain what components you modified or added, and how, to give context to your reviewers
Testing ๐งช
go test -race ./...
from rootClean logs, add metrics and reorg code
What ๐ต๏ธโโ๏ธ
Why ๐
Currently there are too many logs and there is no clear rules to follow for implementing them. Moreover, there is no understanding on why a GetHeader fails, since it may fail because they query an old slot, or because there was no block submission for the slot
Testing ๐งช
go test -race ./...
from rootPublish beacon block to network
We should publish the beacon block to beacon network after sending the block through mev-boost. Inspiration: https://github.com/flashbots/mev-boost-relay/pull/103
Streaming layer for high performance bids
What ๐ต๏ธโโ๏ธ
This PR adds a streaming layer to the relay, so that when the relay is distributed it delivers bids and payloads from memory instead of an external DB
Why ๐
GetHeader and GetPayload requests are very critical and they have low latency requirements. So, it is important to optimize how fast the bids and payloads are retrieved
How โ๏ธ
We add a streaming layer, so that every block a relay receives it streams to the other relays. This way, if the other relays receive a payload request it is very likely they can serve it from memory instead of querying an external DB.
Testing ๐งช
go test -race ./...
from rootverify fee recipient of submitted block
What ๐ต๏ธโโ๏ธ
Explain what this PR accomplishes
Adds a check to verify that a block submissions proposer fee recipient matches the fee recipient validators have registered. Thanks to @metachris for pointing this out!
Why ๐
Explain the need or decisions which make this change necessary
Currently dreamboat does not support external builders, but instead a loosely defined trusted builder. We are in the process of hardening to be able to support any external builder with hopefully 0 trust.
How โ๏ธ
Briefly explain what components you modified or added, and how, to give context to your reviewers
On block submission we grab the validators registered fee recipient and compare it to the value in the block.
Testing ๐งช
go test -race ./...
from rootFix/prevrandao
What ๐ต๏ธโโ๏ธ
Implements randao validation on block submissions
Why ๐
Otherwise it may cause security vulnerabilities
How โ๏ธ
Query the randao from the beacon whenever the headslot is updated and check for validation on block submission
Testing ๐งช
go test -race ./...
from rootSpecial mentions
Thank you to @metachris for notifying about this, and help make the relay more robust.