Censorship resistance is a core value proposition of blockchains. Inclusion lists aim to provide a mechanism to improve the censorship resistance of Ethereum by allowing proposers to specify a set of transactions that must be promptly included for subsequent blocks to be considered valid.
Since the merge, validators have started outsourcing almost all block production to a specialized set of builders who compete to extract the most MEV (this is commonly referred to as Proposer-Builder Separation). As of October 2023, nearly 95% of blocks are built by builders rather than the proposer. While it is great that all proposers have access to competitive blocks through the mev-boost
ecosystem, a major downside of externally built blocks is the fact that the builders ultimately decide what transactions to include or exclude. Without any forced transaction inclusion mechanism, the proposer is faced with a difficult choice: they either have no say on the transactions that get included, or they build the block locally (thus have the final say on transactions) and sacrifice some MEV rewards.
Inclusion lists aim to allow proposers to retain some authority by providing a mechanism by which transactions can be forcibly included. The simplest design is for the slot N
proposer to specify a list of transactions that must be included in the block that is produced for their slot. However, this is not incentive-compatible because builders may choose to abstain from building blocks if the proposer sets some constraints on their behavior. This leads to the idea of "forward" inclusion lists, where the transactions specified by the slot N
proposer are enforced in the slot N+1
block. The naïve implementation of the forward inclusion lists presents a different issue of potentially exposing free data availability, which could be exploited to bloat the size of the chain without paying the requisite gas costs. The free data availability problem is solved with observations about nonce reuse and allowing multiple inclusion lists to be specified for each slot. With the incentive compatibility and free data availability problems addressed, we can more safely proceed with the implementation of inclusion lists.
Name | Value |
---|---|
MAX_TRANSACTIONS_PER_INCLUSION_LIST |
2**4 = 16 |
MAX_GAS_PER_INCLUSION_LIST |
2**21 |
MIN_SLOTS_FOR_INCLUSION_LIST_REQUEST |
1 |
class InclusionListSummaryEntry(Container):
address: ExecutionAddress
gas_limit: uint64
class InclusionListSummary(Container)
slot: Slot
proposer_index: ValidatorIndex
summary: List[InclusionListSummaryEntry, MAX_TRANSACTIONS_PER_INCLUSION_LIST]
class SignedInclusionListSummary(Container):
message: InclusionListSummary
signature: BLSSignature
class InclusionList(Container)
summary: SignedInclusionListSummary
transactions: List[Transaction, MAX_TRANSACTIONS_PER_INCLUSION_LIST]
class ExecutionPayload(Container):
...
inclusion_list_summary: List[InclusionListSummaryEntry, MAX_TRANSACTIONS_PER_INCLUSION_LIST]
inclusion_list_exclusions: List[uint64, MAX_TRANSACTIONS_PER_INCLUSION_LIST]
class ExecutionPayloadHeader(Container):
...
inclusion_list_summary_root: Root
inclusion_list_exclusions_root: Root
class BeaconBlockBody(Container):
...
inclusion_list_summary: SignedInclusionListSummary
slot N
proposal:
slot N+1
.slot N
or slot N+1
.slot N
validation:
slot N
or if the transactions' maxFeePerGas
are not at least 12.5% higher than the current slot (to ensure the transactions will be valid in slot N+1
).slot N+1
validation:
slot N+1
builds their block along with a signed summary from the slot N
proposer.slot N
payload that satisfy some entry in the signed inclusion list summary.Beacon chain state transition spec:
inclusion_list
object: Introduce a new inclusion_list
for the proposer to submit and nodes to process.ExecutionPayload
and ExecutionPayloadHeader
objects: Update these objects to meet the inclusion list requirements.BeaconBlockBody
: Modified to cache the inclusion list summary.process_execution_payload
function: Update this process to include checks for the inclusion list summary satisfaction.Beacon chain fork-choice spec:
is_inclusion_list_available
check: Introduce a new check to determine if the inclusion list is available within the visibility window.Beacon chain P2P spec:
Validator spec:
inclusion_list
: Proposer to prepare and sign the inclusion list.BeaconBlockBody
: Update the duty to prepare the beacon block body to include the inclusion_list_summary
.get_inclusion_list
: Introduce a new function for proposers to retrieve inclusion lists.new_inclusion_list
: Define a new function for nodes to validate the execution side of the inclusion list.forkchoice_updated
: Update the function with a payload_attribute
to include the inclusion list summary as part of the attribute.new_payload
: Update the function for EL clients to verify that payload_transactions
satisfy payload.inclusion_list_summary
and payload.inclusion_list_exclusions
.We consider a few design decisions present in this EIP.
ReducedSummary
versus Summary
ReducedSummary
and a Rebuilder
. This allows the full summary to be reconstructed. Summary
and including that in the subsequent block.slot N
block. Transactions in the inclusion list are evaluated for the pre-state of slot N
but are only guaranteed to be included in slot N+1
.slot N
may be satisfied in the same slot (e.g., by being included in the ExecutionPayload
). This is a side effect of validators using mev-boost
because they don’t know the contents of the block they propose.inclusion_list_exclusion
field and makes sure it matches with a transaction in the current inclusion list. When there’s a match, we remove that transaction from the inclusion list summary.mev-boost
compatibility.mev-boost
. Like any other hard fork, mev-boost
, relays, and builders must adjust their beacon nodes.inclusion_list_summary_root
matches their local version and skip building a block if there’s a mismatch, using the local block instead.MIN_SLOTS_FOR_INCLUSION_LIST_REQUEST
. A node can skip inclusion list checks if the block’s slot plus this parameter is lower than the current slot.This EIP introduces backward incompatible changes to the block validation rule set on the consensus layer and must be accompanied by a hard fork. These changes do not break anything related to current user activity and experience.
The main potential issue is around the incentivization of the inclusion lists. If the slot N
proposer constructs an inclusion list that negatively impacts the rewards of the slot N+1
proposer, the slot N+1
proposer may attempt to bribe the slot N
proposer to publish an empty list. This isn't a direct attack on the protocol, but rather a profit-sharing mechanism by which the inclusion list would go unutilized. It seems likely these commitment games could be played no matter the censorship resistance scheme in place, but this remains an active area of research.
Copyright and related rights waived via CC0.