-
Notifications
You must be signed in to change notification settings - Fork 118
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
Optimistic Relay #380
Optimistic Relay #380
Conversation
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## main #380 +/- ##
===========================================
+ Coverage 20.35% 30.68% +10.32%
===========================================
Files 21 24 +3
Lines 4082 4507 +425
===========================================
+ Hits 831 1383 +552
+ Misses 3149 2960 -189
- Partials 102 164 +62
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
As discussed previously (i.e. in #285), we want to merge this PR next. Going through a final round of review and testing before. |
Heads up: we're chasing some sort of issue where |
services/api/service.go
Outdated
ignoreError := simErr.Error() == ErrBlockAlreadyKnown || simErr.Error() == ErrBlockRequiresReorg || strings.Contains(simErr.Error(), ErrMissingTrieNode) | ||
if !ignoreError { | ||
// Mark builder as non-optimistic. | ||
opts.builder.status.IsOptimistic = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the effect of this? opts
doesn't seem to be used further down 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
opts.builder has the type *blockBuilderCacheEntry, so we are modifying the status of the entry so the builders blocks are immediately rejected as non-optimistic (on this instance of the builder api).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmm i see, this is a bit non-obvious, opts
is also passed in as value.
i'm not feeling great about this function having side-effects.
would it maybe be cleaner if the handling of the errors happens outside of simulateBlock
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, thats fine! we can easily move it to processOptimisticBlock
. it is probably cleaner there anyways, because we only need to flip the bit when we are in optimistic mode.
📝 Summary
tl;dr; This PR implements an "optimistic" version of Flashbots' mev-boost-relay. The core idea is that we can improve the throughput and latency of block submissions by using asynchronous processing. Instead of validating each block that comes in immediately, we return early and mark the block as eligible to win the auction before checking its validity. This allows builders to submit more blocks and critically, submit blocks later in the time period of the slot. Later blocks will have more MEV and thus a higher probability of winning the block auction. All blocks sent to the relay are still validated, and only a single slot at a time is being processed optimistically. In practice we expect that the first few milliseconds of
Slot n
will handle the remainingSlot n-1
optimistic blocks, which may have been received very close to the slot boundary. Proposers still use the Proposer API to select the highest bid, but there is no longer a guarantee that this block is valid (because we may not have had time to asynchronously validate it). To submit blocks in the optimistic mode, a builder must put up a collateral that is greater than the value of the blocks they are proposing. If a proposer ends up signing an invalid block, collateral from the builder of that block will be used to refund the proposer for the missed slot.📚 References
This joint work from Justin Drake, AlphaMonad, and I is a revision of michaelneuder#2. Many thanks to Chris Hager, Alex Stokes, Mateusz Morusiewicz, and Builder0x69 for feedback and support thus far!!
⛱ Motivation and Context
The changes can be described through 3 sequences:
1. Submitting optimistic blocks.
Builder API
endpoint of the relay.a. if the builder collateral is greater than the value of the block and the builder is
optimistic
, run the block simulation optimistically in a different goroutine.b. the
optimistic block processor
adds 1 to theoptBlock waitgroup
, which is a used to synchronize all the optimistic block validations happening concurrently during the slot.c. otherwise if the builder is
highPrio
send the block to thehighPrio
queue of theprio-load-balancer
.d. else send the block to the
lowPrio
queue of theprio-load-balancer
.2. Validating optimistic blocks.
optimistic block processor
sends the block aslow-prio
to theprio-load-balancer
for simulation.optimistic block processor
.optBlock waitgroup
is decremented by one, indicating that this goroutine has completed its tasks.3. Proposing optimistic blocks
mev-boost
callsgetHeader
on theProposer API
of the relay. This is part of theMEV-Block Block Proposal
as documented in https://docs.flashbots.net/flashbots-mev-boost/architecture-overview/block-proposal.mev-boost
callsgetPayload
on theProposer API
of the relay. This triggers the publication of aSignedBeaconBlock
.optBlock waitgroup
is waited on. This ensures that there are no more optimistic blocks to be simulated for that slot.proposer API
checks the database for a demotion that matches the header of the winning block. If it is present, then the simulation of the winning block must have failed, and thus a refund in necessary.proposer API
updates the demotion table with the refund justification, which is theSignedBeaconBlock
andSignedValidatorRegistration
.Misc notes
✅ I have run these commands
make lint
make test-race
(this gave a few errors, but i think it is likely because we are doing a lot of asynchronous processing now, not quite sure how to deal with this)go mod tidy
CONTRIBUTING.md