EIP-7547 - Inclusion lists

Created 2023-10-24
Status Stagnant
Category Core
Type Standards Track
Authors

Abstract

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.

Motivation

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.

Specification

Constants

Name Value
MAX_TRANSACTIONS_PER_INCLUSION_LIST 2**4 = 16
MAX_GAS_PER_INCLUSION_LIST 2**21
MIN_SLOTS_FOR_INCLUSION_LIST_REQUEST 1

Reference Objects

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

Consensus layer

High-level overview

slot N proposal:

slot N validation:

slot N+1 validation:

Specific Changes

Beacon chain state transition spec:

Beacon chain fork-choice spec:

Beacon chain P2P spec:

Validator spec:

Execution layer

Rationale

We consider a few design decisions present in this EIP.

  1. ReducedSummary versus Summary
    • The original proposal tries to improve data efficiency by using a ReducedSummary and a Rebuilder. This allows the full summary to be reconstructed.
    • This adds a lot of complexity to the spec, so in this initial version, we should consider just using the regular Summary and including that in the subsequent block.
  2. Gas limit vs no limit.
    • One consideration is whether the inclusion list should have a gas limit or use the block’s gas limit.
    • Having a separate gas limit simplifies complexity but opens up the possibility for validators to outsource their inclusion list construction for side payments (e.g., if a block is full, the proposer could auction off space in the inclusion list for guaranteed inclusion in the subsequent block).
    • Alternatively, inclusion lists could be part of the block gas limit and only satisfied if the block gas limit is not full. However, this could lead to situations where the next block proposer intentionally fills up the block to ignore the inclusion list, albeit at the potential expense of paying to waste the gas.
  3. Inclusion list ordering.
    • We assume that the inclusion list is processed at the top of the 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.
  4. Inclusion list transaction exclusion.
    • Inclusion list transactions proposed at 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.
    • Due to this, there exists an exclusion field, a node looks at each transaction in the payload’s 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.
  5. mev-boost compatibility.
    • There are no significant changes to mev-boost. Like any other hard fork, mev-boost, relays, and builders must adjust their beacon nodes.
    • Builders must know that execution payloads that don’t satisfy the inclusion list summary will be invalid.
    • Relays may have additional duties to verify such constraints before passing them to validators for signing.
    • When receiving the header, validators can check that the inclusion_list_summary_root matches their local version and skip building a block if there’s a mismatch, using the local block instead.
  6. Syncing using by range or by root.
    • To consider a block valid, a node syncing to the latest head must also have an inclusion list.
    • A block without an inclusion list cannot be processed during syncing.
    • To address this, there is a parameter called 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 is similar to EIP-4844, where a node skips blob sidecar data availability checks if it’s outside the retention window.

Backwards Compatibility

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.

Security Considerations

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

Copyright and related rights waived via CC0.