From 0a72b16a30ebaa76650d806754f899160b00b547 Mon Sep 17 00:00:00 2001 From: mike neuder Date: Wed, 20 Dec 2023 10:59:31 -0500 Subject: [PATCH] Add EIP: Inclusion lists Merged by EIP-Bot. --- EIPS/eip-7547.md | 177 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 EIPS/eip-7547.md diff --git a/EIPS/eip-7547.md b/EIPS/eip-7547.md new file mode 100644 index 0000000000000..c1aea2461893c --- /dev/null +++ b/EIPS/eip-7547.md @@ -0,0 +1,177 @@ +--- +eip: 7547 +title: Inclusion lists +description: Add an inclusion list mechanism to allow forced transaction inclusion. +author: mike (@michaelneuder), Vitalik (@vbuterin), Francesco (@fradamt), Terence (@terencechain), potuz (@potuz), Manav (@manav2401) +discussions-to: https://ethereum-magicians.org/t/eip-7547-inclusion-lists/17474 +status: Draft +type: Standards Track +category: Core +created: 2023-10-24 +--- +## 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:** + +- Proposer broadcasts a signed block and an inclusion list (summary and transactions objects) for `slot N+1`. +- Transactions will be included in `slot N` or `slot N+1`. +- Summaries include the originating address of the transactions and their respective gas limits. +- Summaries are signed, but transactions are not. + +**`slot N` validation:** + +- Validators only consider the block for validation and fork-choice if they have seen at least one inclusion list for that slot. +- They consider the block invalid if the inclusion list transactions are not executable at the start of `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:** + +- The proposer for `slot N+1` builds their block along with a signed summary from the `slot N` proposer. +- The payload includes a list of transaction indices from the `slot N` payload that satisfy some entry in the signed inclusion list summary. +- The payload is considered valid if: (a) the execution conditions are met, including satisfying the inclusion list summary and being executable from the execution layer perspective, and (b) the consensus conditions are met with a proposer signature of the previous block. + +#### Specific Changes + +**Beacon chain state transition spec:** + +- ***New** `inclusion_list` object:* Introduce a new `inclusion_list` for the proposer to submit and nodes to process. +- ***Modified** `ExecutionPayload` and `ExecutionPayloadHeader` objects:* Update these objects to meet the inclusion list requirements. +- ***Modified** `BeaconBlockBody`:* Modified to cache the inclusion list summary. +- ***Modified** `process_execution_payload` function:* Update this process to include checks for the inclusion list summary satisfaction. + +**Beacon chain fork-choice spec:** + +- ***New** `is_inclusion_list_available` check:* Introduce a new check to determine if the inclusion list is available within the visibility window. +- ***New** notification action:* Implement a new call to notify the Execution Layer (EL) client about a new inclusion list. The corresponding block is considered invalid if the EL client deems the inclusion list invalid. + +**Beacon chain P2P spec:** + +- ***New** gossipnet and validation rules for inclusion list:* Define new rules for handling the inclusion list in the gossip network and validation. +- ***New** RPC request and response network for inclusion list:* Establish a new network for sending and receiving inclusion lists. + + +**Validator spec:** + +- ***New** duty for `inclusion_list`:* Proposer to prepare and sign the inclusion list. +- ***Modified** duty for `BeaconBlockBody`:* Update the duty to prepare the beacon block body to include the `inclusion_list_summary`. + + +**Builder and API spec:** + +- ***Modified** payload attribute SSE endpoint:* Adjust the payload attribute SSE endpoint to include payload summaries. + +### Execution layer + +- ***New** `get_inclusion_list`:* Introduce a new function for proposers to retrieve inclusion lists. +- ***New** `new_inclusion_list`:* Define a new function for nodes to validate the execution side of the inclusion list. +- ***Modified** `forkchoice_updated`:* Update the function with a `payload_attribute` to include the inclusion list summary as part of the attribute. +- ***Modified** `new_payload`:* Update the function for EL clients to verify that `payload_transactions` satisfy `payload.inclusion_list_summary` and `payload.inclusion_list_exclusions`. +- ***New** validation rules:* Implement new validation rules based on the changes introduced in the Execution-API spec. + +## 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. +3. 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. +4. 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`. +3. 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. +4. `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. +5. 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](./eip-4844.md), 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](../LICENSE.md).