EIP-7549 Moving the committee index out of the signature (Move committee index outside Attestation)
Final · Consensus & staking · EIP status Final · created 2023-11-01
Removes the committee number (index) from the signed vote message, so consensus votes with identical content can be merged into one regardless of committee. This greatly reduces the number of signature verifications needed to check consensus and lets more votes fit in a block.
Why it is needed
In Ethereum consensus, validators are split into several committees each slot and send votes (attestations). A vote carries both an LMD GHOST vote for fork choice and a Casper FFG vote for finalizing the chain, and currently the committee number (index) that the validator belongs to is also part of what is signed. So even if the vote contents are exactly the same, a different committee produces a different signature, and the votes cannot be merged into one. In a network with 262144 or more active validator indices, checking the two-thirds threshold requires verifying at least 1366 attestations. The pairing operations needed for signature verification grow accordingly, which burdens every client and costs the most in ZK circuits that prove Casper FFG consensus. A block can also hold only about 2 slots' worth of votes, so if few block proposers are online, not all votes may be included on chain.
What changes
Today
- The committee number is part of what is signed, so votes with identical content cannot be merged if the committees differ
- Checking the two-thirds threshold requires verifying at least 1366 attestations (for 262144 or more active indices)
- A block can hold only about 2 slots' worth of votes
After EIP-7549
- The committee number is moved out of the signature into committee_bits, so identical votes are merged into one regardless of committee
- The minimum number of verifications drops to 22 (one 62nd)
- A block can hold up to 8 slots' worth of votes, so all votes can be included even if only one eighth of proposers are online
Who is affected
- Client teams: Fewer pairing operations are needed to verify consensus rules, which improves efficiency, but the Attestation container change and the new aggregation logic must be implemented.
- ZK circuit developers: ZK circuits that prove Casper FFG consensus benefit most from this change.
- Validators: Attesters assigned to the last slot before the fork receive an offline penalty worth one epoch because of the format transition.
- Users and app developers: There are no execution layer changes, so there is no direct change to transactions or app behavior.
In depth
Container structure change
The consensus layer changes three things. It sets the index field of AttestationData to a fixed value of 0, moves the committee identification information to committee_bits in the outer Attestation container, and increases the aggregation_bits capacity so it can hold all committees of one slot. There is no change to the execution layer. The full specification is in /specs/electra/beacon-chain.md in the consensus-specs repository.
Why verifications drop to one 62nd
An Attestation message contains three elements: the LMD GHOST vote (beacon_block_root, slot), the FFG vote (source, target), and the committee index. If the third element is also signed, the signing root differs even when the vote content is the same. In a network with 262144 or more active indices, checking the two-thirds threshold requires verifying at least ceil(32*64 * 2/3) = 1366 attestations, but if index is moved out of the signature, this drops to ceil(32 * 2/3) = 22. That is a 62x difference. All clients benefit, but the original text explains that the effect is greatest for ZK circuits that prove Casper FFG consensus.
Why index is set to 0 instead of removed
Three ways to eliminate the index field were considered: removing the field, keeping the field and setting it to 0, and using StableContainer from EIP-7495 to turn it into an Optional type. This EIP chose the second. This is to avoid complicating the inclusion of AttesterSlashing objects, because the Attestation container changes but AttesterSlashing holds indexed attestations that have no committee data.
Adjusted to MAX_ATTESTATIONS 8 and MAX_ATTESTER_SLASHINGS 1
The maximum size of a single attestation grows. In a network with fully populated committees, the bitfield becomes 64 times larger. To limit block size while still increasing total voting capacity, MAX_ATTESTATIONS is reduced to 8. For a network with 1.2 million active indices, the value 8 keeps the space taken by attestations the same while quadrupling voting capacity. AttesterSlashing carries a list of participant indices, and in the worst case its size grows 64 times, reaching 488 KB uncompressed and still 320 KB after Snappy compression on a network with 1 million validators. To bound the maximum block size, MAX_ATTESTER_SLASHINGS is reduced from 2 to the minimum of 1.
Why committee_bits uses a Bitvector
committee_bits is a variable sequence of up to MAX_COMMITTEES_PER_SLOT = 64 entries. The Bitlist type includes the actual length in its encoding, which makes it twice the size of a Bitvector. So a fixed-length Bitvector is used. When a slot has fewer committees than the maximum, the beacon chain state transition guarantees that committee_bits is correct.
The voting gap in the first block after the fork
Because the on-chain Attestation container changes, attestations from the previous fork cannot be included in blocks after Electra. As a result, the first block after the fork may contain zero attestations. LMD votes continue to count toward fork choice through the on_attestation handler, so the loss is limited to 1/32 of the FFG votes. Attesters assigned to the last slot before the fork receive an offline penalty worth one epoch. A mitigation exists that changes the block body to allow attestations from both forks, but its complexity is high relative to what it gains, so this proposal does not adopt it.
Possible tampering over gossip and the defense
When index moves outside the signature, malicious tampering is possible only on the p2p gossip topic beacon_attestation_${subnet_id}. Everywhere else the Attestation is wrapped in an outer signature, which prevents tampering. The validation rules for this gossip topic include a REJECT rule that checks whether the attester is a member of the committee, that is, whether attestation.attester_index is in get_beacon_committee(state, attestation.data.slot, index). If an attacker changes index, this check fails and the message is dropped. If an implementation performs this check before registering the message in the first-seen cache, there is no risk of cache pollution either.
A Final proposal that requires a hard fork
This EIP changes the consensus layer's block validation rules in a way that is not backward compatible, so it must be applied together with a hard fork. The status in the source is Final, and the specification is integrated into the Electra beacon chain spec.