Skip to content
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

MEV SIP (v2) #25

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions sips/mev.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
| Author | Title | Category | Status |
| ------------------------- | ------------------------------- | -------- | ------------------- |
| Moshe Revah (@moshe-blox) | Support externally built blocks | Core | open-for-discussion |

## Summary

Support the production and proposal of blocks built by external entities, allowing operators to access blocks from a marketplace of builders such as [Flashbots](https://boost-relay.flashbots.net/).

## Rational & Design Goals

Block building is a computationally intensive task, and even more so when blockspace utilization and profit maximization are in mind. Additionally, many of the more profitable transactions, so-called MEV, are private and only accessible to validators through external block builders.

Currently, operators wishing to offer competitive returns must be sophisticated block builders with private transaction flows. This SIP aims to change that by allowing them to register with and propose blocks from external builders who comply to [ethereum/builder-specs](https://github.com/ethereum/builder-specs).

## Specification

### MEV-supporting operators

Operators who wish to propose blinded blocks must configure their node to do so, otherwise it will propose standard locally-built blocks.

### Validator registration

Builders require validators to publish a [`builder-specs/SignedValidatorRegistration`](https://ethereum.github.io/builder-specs/#model-SignedValidatorRegistration) to set their `fee_recipient` and `gas_limit` preferences.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how and when do they publish it? should it be in the spec?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section specifies when to publish.

There is no rule in the Ethereum builder-specs regarding when/how often this should be publish, but @lior-blox suggested that we should specify it in the spec so that future SSV implementations would be aligned on it.


When building a block for a validator, builders refer only to the registration with the highest timestamp.

In the wild, some Ethereum validator clients currently produce and publish this message every epoch.

#### Fee recipients

Validators may set their preferred `fee_receipient` address by calling `setFeeRecipientAddress` in the `SSVNetwork` contract. Validators may repeat this call as their preference changes over time.
moshe-blox marked this conversation as resolved.
Show resolved Hide resolved

#### Signing

At the start of every slot, operators select their active validators with `ShouldRegisterValidatorAtSlot`, and for those, produce a [`builder-specs/SignedValidatorRegistration`](https://ethereum.github.io/builder-specs/#model-SignedValidatorRegistration) with their preferred `fee_recipient`.
moshe-blox marked this conversation as resolved.
Show resolved Hide resolved

```go
ValidatorRegistrationSlotInterval = 16 * SlotsPerEpoch

func ShouldRegisterValidatorAtSlot(index phase0.ValidatorIndex, slot phase0.Slot) bool {
return (index + slot) % ValidatorRegistrationSlotInterval == 0
alonmuroch marked this conversation as resolved.
Show resolved Hide resolved
}
```

#### Publishing

At the end of every slot, operators publish registrations for the validators selected for signing in that slot, using their most recent successfully signed registration.

> Note: Since relays/builders can have some delay with registrations, producing a blinded block before and shortly thereafter publishing the first registration may result in either:
>
> 1. Builder doesn't build a block, and Beacon node falls back to locally-built block from it's execution layer.
> 2. Builder doesn't reward the validator's `fee_recipient` because it isn't aware of it yet.
> 3. Builder rewards a potentially different `fee_recipient` from the validator's latest registration (such as a registration prior to onboarding to SSV.)

#### Issue: Gas limits

Unlike standard validator clients, gas limits are not set by validators, but rather by their operators.

This SIP proposes to hardcode the gas limit to 30 million (which is the default in Prysm and Lighthouse), but recommends to keep watching it and modify if necessary.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set where?

Copy link
Contributor Author

@moshe-blox moshe-blox May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In validator clients, it's configurable with a default of 30 million. In SSV it's currently hardcoded to the same value: https://github.com/bloxapp/ssv/blob/38193908b145dbe29186de34a6c60df1085c92e4/beacon/goclient/proposer.go#L27

Copy link
Contributor Author

@moshe-blox moshe-blox May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it should be configurable? @alonmuroch

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's ethereum dependent so not sure

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can let operators configure this, but if they differ, they will not be able to reconstruct signatures for ValidatorRegistration because it contains this value.

Social consensus on gas limit hasn't changed (at least) since The Merge, and if it does we'd want operators to switch at roughly the same time to avoid differing ValidatorRegistration, so maybe waiting for this to change and then releasing a version with a transition scheduled at a specific epoch/slot is safer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they configure it differently it can cause consensus issues?

Copy link
Contributor Author

@moshe-blox moshe-blox May 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not QBFT consensus, they will just fail to aggregate signatures in pre-consensus of ValidatorRegistration: https://github.com/nkryuchkov/ssv-spec/blob/d0730a175f4543f325f4e798a047084a28744000/ssv/validator_registration.go#L67

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only reason I can think it is good to have it configurable is for testnets.
Other than that the operator shouldn't touch this value.
But the only reason to test different gas limit, is if ethereum will have a fork.

So I agree with @moshe-blox and have it non-configurable.
If someone disagrees please say so, because the spec will make it a constant.


### Blinded block proposals

When a validator has a proposal duty, their operators:

1. Produce a `BlindedBeaconBlock` from their Beacon node at [/eth/v1/validator/blinded_blocks](https://ethereum.github.io/beacon-APIs/#/Validator/produceBlindedBlock)
2. Reach consensus on and sign the round leader's `BlindedBeaconBlock`
3. Submit the `SignedBlindedBeaconBlock` to their Beacon nodes at [/eth/v1/beacon/blinded_blocks](https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlindedBlock)

Under the hood, each operator's Beacon node would attempt to unblind the block from it's connected builder(s) by revealing the signature to them, which would fail if they haven't built or don't know of this block.

Therefore, for unblinding to succeed, operators' Beacon nodes must share the same builder(s) with the round leader's Beacon node.
alonmuroch marked this conversation as resolved.
Show resolved Hide resolved

Since SSV can't enforce a specific set of builder(s) at the protocol-level, operators would have to reach social consensus on which builder(s) to configure their Beacon nodes with.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if there is a mix of both ssv operators proposing blinded and non blinded blocks in the same cluster?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently nodes with blinded proposals disabled are not rejecting blinded blocks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and viceversa?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we discussed it should be strict.
If Im an operator that doesn't want to support MEV, I should not participate in the Consensus if the leader proposed MEV

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

viceversa should be allowed

Copy link
Contributor Author

@moshe-blox moshe-blox May 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lior-blox
Let say in a 4 node cluster 2 operators don't want to support MEV?
So no block will ever be produced?

Also why would some operators oppose to use MEV? I can only think of idealogical reasons or deep mistrust of relays. In this case, I think it is more of the validator's choice and not the operator.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GalRogozinski
In the scenario, only proposals that the leader is non mev will be successful.
It could be various reasons like ideology or legal etc.

The operators will use metadata to let the validators If they MEV support and which relays

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to have a writeup somewhere on why we are doing this.
When I talked to @lior-blox and @moshe-blox they both gave me different reasons.

This feature may break consensus. Maybe there are good reasons to add the feature despite the risk, but they should be super clear to us!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This discussion can continue here:
#25 (comment)


#### Locally-built blinded blocks

Sometimes, Beacon nodes fallback to a locally-built `BlindedBeaconBlock`, either because it's configured to do so under certain conditions (profitability threshold; chain is unstable) or because the builder(s) are unavailable.

Locally-built blinded blocks can only be unblinded by the Beacon node which built it, which unfortunately means that only the round leader would successfully submit the block, thereby reducing the network outreach of the proposal down to a single Beacon node.

We should consider pushing operators to configure their node for less harsh fallback conditions, so that more of their blocks are externally-built and can be successfully submitted by other operators' Beacon nodes.
GalRogozinski marked this conversation as resolved.
Show resolved Hide resolved

#### Blinded block validation

Nowadays, there's no meaningful validation we can do on blinded blocks, but there's [active discussion](https://github.com/flashbots/mev-boost/issues/99) about requiring builders to attach payment proofs on bids so that they can't cheat and reward themselves instead of the validator's `fee_recipient`.

Ideally, payment proof validation should be handled by [mev-boost](https://github.com/flashbots/mev-boost), as it already examines the builders' bids, in which case operators would only have to ensure their Beacon nodes are always updated with the latest [`builder-specs/SignedValidatorRegistration`](https://ethereum.github.io/builder-specs/#model-SignedValidatorRegistration).