flashbots / mev-boost

MEV-Boost allows Ethereum validators to source high-MEV blocks from a competitive builder marketplace
https://boost.flashbots.net
MIT License
1.16k stars 204 forks source link

Censorship Resistance: crlists in mev-boost #215

Open quintuskilbourn opened 2 years ago

quintuskilbourn commented 2 years ago

Censorship resistance lists (crlists) are designed to prevent builders from censoring users in PBS. The design was originally put together with in-protocol PBS in mind. Can we adapt this solution to improve mev-boost?

Why censorship resistance is important with MEV-Boost

We anticipate the builder market to be smaller than the total validator set, becoming more centralised over time. This higher degree of centralisation makes censorship much easier and much likelier, severely affecting the neutrality of the network. Additionally, it is unclear how the builder market will evolve (e.g. presence of EOF, fair-ordering builders etc.). This opacity makes it hard to reason about censorship resistance with MEV-boost as it is. Consequently, validators may find themselves in a position where they suspect the builder market of censoring users (e.g. because of a government sanction where most builders are located) and have to choose between the additional profit of PBS and the ideologically sound move which is building blocks locally. Building in a censorship resistance mechanism means that proposers can continue to run MEV-boost with assurance that the neutrality of mainnet isn’t being compromised. From the perspective of the system as a whole: crlists allow us to derive censorship resistance from the decentralisation of proposers rather than builders without requiring proposers to be sophisticated. Additionally, including crlists in mev-boost could provide useful insight into challenges and market dynamics in a low risk environment (discussed below) which would prove useful for designing in-protocol PBS.

What are crlists?

The basic idea is to allow a proposer to publish a list of transactions which it suspects are being censored. (e.g. a valid txn with sufficient basefee that hasn’t been included for several slots). Builders supplying blocks to this proposer must either supply completely full blocks or include as many of these transactions as possible until the block is full or they are all included.

The flow in mev-boost would look something like the following:

  1. The proposer announces its crlist at some point before receiving block headers
    1. one option is to send this list with the “getHeader” request, but this may be a bit late since builders may already have started building blocks, meaning that builders might have to restart building, leading to a loss of profit for proposers.
    2. another option is to leave the timing of the announcement up to the proposer (any time after they are assigned a slot and before the getHeader request). The longer they wait the more likely they are to reduce their bids but also the more fine-grained their crlist selection will be.
    3. We allow proposers not to participate by submitting an empty crlist or not submitting a crlist at all (depending on implementation).
  2. Relayer conveys crlist to partnered builders
  3. Upon receipt of blocks, relay checks that crlist conditions are satisfied before forwarding headers to the proposer. We have the option of adding some metadata (some json or binary map? not sure how these kinds of things work in practice) indicating which transactions are from the crlist for speed of checking conditions. The conditions would be:
    1. block is full (~30m gas)
    2. OR all valid (basefee and nonce) crlist transactions are in the block
  4. Header is signed and relayer/builder sends full block to the proposer
  5. Proposer conducts same check as in (3). If conditions are violated, relayer reputation is adjusted/proposer no longer accepts headers from relay

The original in-protocol design ideas attempt to make this a trustless process where builders would send proofs that the crlist conditions are satisfied along with their headers. Since mev-boost is still a trust-based system, proposers could simply outsource the checking of crlist conditions to relayers. If a relayer sends a block that does not satisfy the conditions, this should affect the relayer’s reputation score. This is the same mechanism which we use to address the problem of signed headers with a missing block body.

As for builders censoring users while fulfilling the crlist requirements (i.e. filling blocks), this becomes exponentially more expensive as time passes, since full blocks move up the basefee via EIP1559 and the censoring builder must continue to fill entire blocks.

Importantly, since crlists are optional in this design and there are no encoded slashing conditions or punishments for deviation, if unwanted effects arise from the implementation, proposers simply stopping submission of crlists could be a quick fix in many cases.

Risks, Obstacles and Problems

As far as I can tell, the biggest issues identified with crlists are related to their in-protocol enforcement and DAS. Neither of these topics relate to the trust-based PBS which mev-boost is implementing so crlists seem like a good fit.

Proposer protection

Relay burden

Objects of user intent

Account abstraction, EIP712 and similar designs may mean that users could express their intent in formats that are not currently recognised by the mempool. Hence, crlists in the design above do not capture censorship of these expressions of intent.

Formation of lists

As Jolene pointed out, implementing crlists may require changes to EL/CL clients. The problem, as I understand it, is that mev-boost doesn't have access to the mempool so either must be given access to the mempool via a communication channel with the EL or must have the crlist passed into mev-boost via some other means like changes to the Builder API.

charlescharles commented 2 years ago

Not directly related to crlists, but I was thinking that PBS generally makes large-scale censorship by eg state actors a lot easier. If you have a bunch of money and want to make Ethereum effectively stop processing txns for a bit, currently you have to send lots of txns from many accounts with sufficiently high priority fee to box everyone else out (and you can't even know this exactly due to private relays), but not too many txns that you increase gas target and make it quadratically expensive to continue censoring.

With unsealed-bid PBS (I think sealed-bid is not incentive-compatible), on the other hand, you can just construct a block with gastarget worth of noop txns along with a proposer payment of current_best_bid + epsilon.

come-maiz commented 2 years ago

Why would builders build blocks that are not full?

quintuskilbourn commented 2 years ago

Most blocks aren’t full. EIP1559 is designed so that blocks are always ~50% full (15m gas I think). It’s only at times when demand spikes that blocks are full. A “demand spike” means that you have enough transactions that are willing to pay the basefee to fill the block. But, this is rare because the basefee adjusts dynamically so that when the block is more than 50% full, the basefee increases to price out the excess demand.

beetrootkid commented 2 years ago

How does the proposer learn about "possibly censored" transactions? Does the idea assume use of the public mempool? Is that realistic?

quintuskilbourn commented 2 years ago

The idea does assume a public mempool. It could end up being the case that the majority of transactions end up moving to builders via other channels for a variety of reasons, but the public mempool would operate as a fallback. If a user suspects they are being censored, they can give up whatever benefits they received from their alternate channel of communication and submit via the public mempool.

come-maiz commented 2 years ago

What I'm thinking is that this could be just an expectation of how builders work, and it can be reflected on their monitoring and rating, or demanded on the specification.

So, if blocks are on average 50% full, and there's a builder that sends a block that's 30% full, we can say they are censoring or being lazy. If we require all builders to include a percentage of transactions from the mempool, sorted by gas, would that prevent censoring?

charlescharles commented 2 years ago

What I'm thinking is that this could be just an expectation of how builders work, and it can be reflected on their monitoring and rating, or demanded on the specification. So, if blocks are on average 50% full, and there's a builder that sends a block that's 30% full, we can say they are censoring or being lazy. If we require all builders to include a percentage of transactions from the mempool, sorted by gas, would that prevent censoring?

I'll play devil's advocate, as usual :)

ryanschneider commented 2 years ago

If conditions are violated, relayer reputation is adjusted/proposer no longer accepts headers from relay

This feels like a heavy punishment. What if the builder is legally required not to include a tx in the CRlist?

What if instead of punishing the builder, the relay only relays crlist-compatible blocks if they exist? Some something like:

Thus, to censor, you need to convince all builders to exclude a crlist tx. This also makes builders that specialize in "censorship likely" tx a possiblity, without unduly penalizing builders that for some reason cannot include a specific tx.

quintuskilbourn commented 2 years ago

If conditions are violated, relayer reputation is adjusted/proposer no longer accepts headers from relay

What if instead of punishing the builder, the relay only relays crlist-compatible blocks if they exist? Some something like:

  • a crlist is produced by whatever decided on means
  • if any builders produce crlist-compliant blocks (either full or containing the txs), those are relayed
  • if any builder produces crlist-violating blocks, and any crlist-compliant block is produced, the violating blocks are not relayed

Thus, to censor, you need to convince all builders to exclude a crlist tx. This also makes builders that specialize in "censorship likely" tx a possiblity, without unduly penalizing builders that for some reason cannot include a specific tx.

this is pretty much the idea! Apologies if it wasn’t clear. Relays can handle their relationships with builders in whatever way they see fit (either ignoring non-crlist-compliant blocks or requiring them not to be submitted to prevent undue load). The punishment above was referring to the proposer-relay relationship which is different because the proposer is blind when signing blocks and signing a block is much more impactful than simply sending one to a relay.

The punishment for relay misbehaviour also need not be ignoring relays forever - it could be blacklisting for a set time period or simply reducing a reputation score.

ryanschneider commented 2 years ago

Ah apologies, I definitely misread that as the relay no longer accepting blocks from the builder, but that's clearly on me for misreading it! 😊

quintuskilbourn commented 2 years ago

I've been thinking about the issue of forming crlists without changing the EL/CL clients and came up with two potential routes. I don't have sufficient technical familiarity with everything I touch so I'm mostly putting this out there for more knowledgeable people to build on. Among other things, I'm not clear on how the potential solutions affect disk or RAM requirements, although I suspect there may be some shortcuts like only storing hashes unless some censorship is suspected.

  1. RPC It looks like most (if not all) clients have an RPC call which returns mempool transactions.

    • Geth: txpool_content
    • Besu: txpool_besuTransactions
    • Nethermind: parity_pendingTransactions
    • Erigon: ?? MEV_boost could potentially make use of these RPC calls to keep track of missing transactions and form crlists like that. As far as I can tell, these RPCs aren't in the eth1 RPC API specification so we would be relying on something that isn't in the Ethereum spec - I'm not sure if that's something we would be willing to consider doing.
  2. P2P: Have mev-boost behave as a node in the p2p network. I'm very unclear on the feasibility given that mev-boost and the EL would potentially have to use the same IP (or would they?). I was hoping something like listening at different ports could do the trick. One could potentially also change the discovery protocol implementation so mev-boost is only ever discovered by its specified EL client and doesn't interact with anyone else.

Again, I'm mostly spitballing and would love if someone who's spent more time in the weeds could weigh in.

ralexstokes commented 2 years ago

I will chime in with a very low-res version of this idea: mandate that "honest" proposers forgo the builder network in lieu of their local builder w/ public mempool every N of M slots.

If this policy is hard-coded into consensus clients as a default, and there is an honest majority of the stake, you'd end up in practice getting some blocks every so often exclusively using the public mempool and I claim this is a very rough approximation of what crLists etc want to accomplish

quintuskilbourn commented 2 years ago

mandate that "honest" proposers forgo the builder network in lieu of their local builder w/ public mempool every N of M slots.

I agree that this is a reasonable intermediate solution, but its worth noting the crlists have some advantages: