Skip to content
Closed
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
11cd720
expand on EL changes
Marchhill Feb 19, 2025
7021f78
Update EIPS/eip-7805.md
Marchhill Feb 20, 2025
8059212
move IL building to EL section, undo block full quantification
Marchhill Feb 20, 2025
1bb8e94
undo more on block full
Marchhill Feb 20, 2025
534d586
remove txs being hex encoded
Marchhill Feb 22, 2025
1b461a6
rewrite IL building to be up to implementer
Marchhill Feb 22, 2025
fabb2ad
block is no invalid but will be reorged
Marchhill Feb 22, 2025
1a5f22f
reword
Marchhill Feb 22, 2025
a4a546b
IL building strategy
Marchhill Feb 22, 2025
3053382
introduce IL building in earlier section
Marchhill Feb 24, 2025
b7b4d11
comments
Marchhill Feb 24, 2025
227341f
Merge branch 'focil-execution-patch' into focil-execution-patch-2
Marchhill Feb 24, 2025
a749628
reword algorithm to suggestion to use nondeterminism and bias
Marchhill Feb 24, 2025
104d5d0
remove unused constant
Marchhill Feb 24, 2025
e505eae
Update EIPS/eip-7805.md
Marchhill May 20, 2025
2e6a6cf
respond to comments
Marchhill May 20, 2025
03b4445
specify nonce and balance checks
Marchhill May 20, 2025
265c96d
update execution apis link, clarify nonce and balance checks
Marchhill May 23, 2025
769681f
Merge remote-tracking branch 'origin/focil-execution-patch' into foci…
Marchhill May 27, 2025
9e0e4e3
add author
Marchhill May 27, 2025
376d025
thomas comments
Marchhill May 27, 2025
dd011cd
remove duplicate line
Marchhill May 27, 2025
4b95936
clarify id
Marchhill May 27, 2025
e7a30fa
specify txs should be RLP encoded for measuring IL size
Marchhill Jun 2, 2025
28ff3c2
remove execution APIs specs
Marchhill Jun 2, 2025
e4786f1
Merge branch 'focil-execution-patch' into focil-execution-patch-2
Marchhill Jun 2, 2025
1199d33
Merge remote-tracking branch 'upstream/master' into focil-execution-p…
Marchhill Jun 2, 2025
f745933
remove author
Marchhill Jun 3, 2025
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
41 changes: 28 additions & 13 deletions EIPS/eip-7805.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
eip: 7805
title: Fork-choice enforced Inclusion Lists (FOCIL)
description: Allow a committee of validators to force-include a set of transactions in every block
author: Thomas Thiery (@soispoke) <thomas.thiery@ethereum.org>, Francesco D'Amato <francesco.damato@ethereum.org>, Julian Ma <julian.ma@ethereum.org>, Barnabé Monnot <barnabe.monnot@ethereum.org>, Terence Tsao <ttsao@offchainlabs.com>, Jacob Kaufmann <jacob.kaufmann@ethereum.org>, Jihoon Song <jihoonsong.dev@gmail.com>
author: Thomas Thiery (@soispoke) <thomas.thiery@ethereum.org>, Francesco D'Amato <francesco.damato@ethereum.org>, Julian Ma <julian.ma@ethereum.org>, Barnabé Monnot <barnabe.monnot@ethereum.org>, Terence Tsao <ttsao@offchainlabs.com>, Jacob Kaufmann <jacob.kaufmann@ethereum.org>, Jihoon Song <jihoonsong.dev@gmail.com>, Marc Harvey-Hill (@Marchhill) <marc.harvey-hill@nethermind.io>
discussions-to: https://ethereum-magicians.org/t/eip-7805-committee-based-fork-choice-enforced-inclusion-lists-focil/21578
status: Draft
type: Standards Track
Expand All @@ -14,7 +14,7 @@ created: 2024-11-01

FOCIL implements a robust mechanism to preserve Ethereum’s censorship resistance properties by guaranteeing timely transaction inclusion.

FOCIL (**Fo**rk-choice enforced **I**nclusion **L**ists) is built in a few simple steps:
FOCIL (**Fo**rk-**c**hoice enforced **I**nclusion **L**ists) is built in a few simple steps:

- In each slot, a set of validators is selected as inclusion list (IL) committee members. Each member builds and gossips one IL according to their subjective view of the mempool.
- The proposer and all attesters of the next slot monitor, store and forward available ILs.
Expand All @@ -40,7 +40,7 @@ This section outlines the workflow of FOCIL, detailing the roles and responsibil
- **`Slot N`, `t=0 to 8s`**:
IL committee members construct their ILs by including transactions pending in the public mempool, and broadcast them over the P2P network after processing the block for `slot N` and confirming it as the head. If no block is received by `t=7s`, they should run `get_head` and build and release their ILs based on the node’s local head.

By default, ILs are built by selecting raw transactions from the public mempool, ordered by priority fees, up to the IL’s maximum size in bytes of `MAX_BYTES_PER_INCLUSION_LIST = 8 KiB` per IL. Additional rules can be optionally applied to maximize censorship resistance, such as prioritizing valid transactions that have been pending in the mempool the longest.
IL committee members may follow different strategies for constructing their ILs as discussed in [IL Building](#il-building).

#### Validators

Expand Down Expand Up @@ -85,31 +85,46 @@ When validators receive ILs from the P2P network, they perform a series of valid

### Execution Layer

On the execution layer, the block validity conditions are extended such that, after all of the transactions in the block have been executed, we attempt to execute each valid transaction from ILs that was not present in the block.
If one of those transactions executes successfully, then the block is invalid.
On the execution layer, an additional check is introduced for new payloads. After all of the transactions in the payload have been executed, we check whether any transaction from ILs, that is not already present in the payload, could be validly included (i.e. nonce and balance checks pass). If that is the case for any transaction, then an error is returned to the CL. Although the block is valid, the CL will not attest to it.
Comment thread
Marchhill marked this conversation as resolved.

Let `B` denote the current block.
Let `S` denote the execution state following the execution of the last transaction in `B`.
Let `gas_left` be the gas remaining after execution of B.
Comment thread
Marchhill marked this conversation as resolved.

For each transaction `T` in ILs, perform the following:

1. Check whether `T` is present in `B`. If `T` is present, then jump to the next transaction, else continue with next step.

2. Validate `T` against `S`.
2. Check whether `B` has enough remaining gas to execute `T`. If `T.gas` > `gas_left`, then jump to the next transaction, else continue with next step.

3. Validate `T` against `S` by checking the nonce and balance of `T.origin`.
Comment thread
Marchhill marked this conversation as resolved.

- If `T` is invalid, then continue to the next transaction.
Comment thread
Marchhill marked this conversation as resolved.

- If `T` is valid, terminate process and assert block `B` as invalid.

3. Execute `T` on state `S`. Assert that the execution of `T` fails.
- If `T` is valid, terminate process and return an `INVALID_INCLUSION_LIST` error.

If `B` is full, the process terminates. Also note that we do not need to reset the state to `S`, since the only way for a transaction to alter the state is for it to execute successfully, in which case the block is invalid, and so the block will not be applied to the state.
#### Engine API Changes

We make the following changes to the engine API:

- Add `engine_getInclusionList` endpoint to retrieve an IL from the `ExecutionEngine`
- Modify `engine_newPayload` endpoint to include a parameter for transactions in ILs determined by the proposer
- Modify `engine_forkchoiceUpdated` endpoint to include a field in the payload attributes for transactions in ILs determined by the proposer
- Add `engine_getInclusionListV1` endpoint to retrieve an IL from the `ExecutionEngine`. It takes as an argument the IL committee member id, where the id is a value from `0`-`f` derived from ordering by validator index (i.e. lowest index has id `0`).
- Add `engine_updatePayloadWithInclusionListV1` endpoint to update a payload with the IL that should be used to build the block. This takes as an argument an 8-byte `payloadId` of the ongoing payload build process, along with the IL itself.
- Modify `engine_newPayload` endpoint to include a parameter for transactions in ILs determined by the IL committee member. If the IL is not satisfied an `INVALID_INCLUSION_LIST` error must be returned.
Comment thread
Marchhill marked this conversation as resolved.

The full Engine API changes can be found in the [Execution APIs](https://github.com/ethereum/execution-apis/blob/572c54cd9d003f700bb5a57ce201606adbc8fc1c/src/engine/experimental/eip7805.md) GitHub repository.

#### IL Building

The rules for building ILs are left to the discretion of implementers; a diverse set of strategies can strengthen censorship resistance. Transactions from the public mempool could be selected based on several factors such as:

- Time spent pending in the mempool.
- Priority fee.
- Byte size: prioritising smaller transactions.
Comment thread
Marchhill marked this conversation as resolved.
- Nondeterminism: Introducing randomness can reduce overlap between ILs, leading to a larger IL when they are combined. Note that some overlap is desirable, otherwise the 1 of N honesty assumption would be undermined.
- Bias: Picking some transactions more often than others in order to further reduce overlap between ILs. This should be done based on committee member id, for example the member with id `a` may be more likely to pick transactions with hashes that start with `a`.
- The number of times a transaction has been included in reorged payloads.

The IL has a maximum size of `MAX_BYTES_PER_INCLUSION_LIST = 8 KiB` for all of the unserialised transactions.
Comment thread
Marchhill marked this conversation as resolved.
Outdated

### Consensus Layer

Expand Down