2023-10-31 15:17:08 +00:00
# EIP-7549 -- The Beacon Chain
## Table of contents
<!-- TOC -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE - RUN doctoc TO UPDATE -->
- [Introduction ](#introduction )
2024-03-05 12:46:45 +00:00
- [Preset ](#preset )
2023-10-31 15:17:08 +00:00
- [Containers ](#containers )
2024-03-05 12:46:45 +00:00
- [Modified containers ](#modified-containers )
2024-03-06 15:28:07 +00:00
- [`Attestation` ](#attestation )
- [`IndexedAttestation` ](#indexedattestation )
2024-03-14 16:14:43 +00:00
- [`BeaconBlockBody` ](#beaconblockbody )
2023-10-31 15:17:08 +00:00
- [Helper functions ](#helper-functions )
2024-03-05 12:46:45 +00:00
- [Misc ](#misc )
- [`get_committee_indices` ](#get_committee_indices )
2023-10-31 15:17:08 +00:00
- [Beacon state accessors ](#beacon-state-accessors )
2024-03-05 12:46:45 +00:00
- [Modified `get_attesting_indices` ](#modified-get_attesting_indices )
- [Block processing ](#block-processing )
- [Modified `process_attestation` ](#modified-process_attestation )
2023-10-31 15:17:08 +00:00
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- /TOC -->
## Introduction
This is the beacon chain specification to move the attestation committee index outside of the signed message. For motivation, refer to [EIP-7549 ](https://eips.ethereum.org/EIPS/eip-7549 ).
*Note:* This specification is built upon [Deneb ](../../deneb/beacon_chain.md ) and is under active development.
2024-03-05 12:46:45 +00:00
## Preset
| Name | Value | Description |
| - | - | - |
2024-03-14 16:14:43 +00:00
| `MAX_ATTESTER_SLASHINGS_EIP7549` | `2**0` (= 1) |
| `MAX_ATTESTATIONS_EIP7549` | `2**3` (= 8) |
2024-03-05 12:46:45 +00:00
2023-10-31 15:17:08 +00:00
## Containers
2024-03-05 12:46:45 +00:00
### Modified containers
2023-10-31 15:17:08 +00:00
2024-03-06 15:24:21 +00:00
#### `Attestation`
2023-10-31 15:17:08 +00:00
```python
2024-03-05 12:46:45 +00:00
class Attestation(Container):
2024-03-25 10:19:11 +00:00
aggregation_bits: Bitlist[MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT] # [Modified in EIP7549]
2024-03-06 15:24:21 +00:00
data: AttestationData
committee_bits: Bitvector[MAX_COMMITTEES_PER_SLOT] # [New in EIP7549]
signature: BLSSignature
2023-10-31 15:17:08 +00:00
```
2024-03-06 15:24:21 +00:00
#### `IndexedAttestation`
2023-10-31 15:17:08 +00:00
```python
2024-03-05 12:46:45 +00:00
class IndexedAttestation(Container):
2024-03-06 15:24:21 +00:00
# [Modified in EIP7549]
attesting_indices: List[ValidatorIndex, MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT]
2023-10-31 15:17:08 +00:00
data: AttestationData
signature: BLSSignature
```
2024-03-14 16:14:43 +00:00
#### `BeaconBlockBody`
```python
class BeaconBlockBody(Container):
randao_reveal: BLSSignature
eth1_data: Eth1Data # Eth1 data vote
graffiti: Bytes32 # Arbitrary data
# Operations
proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS]
attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS_EIP7549] # [Modified in EIP7549]
attestations: List[Attestation, MAX_ATTESTATIONS_EIP7549] # [Modified in EIP7549]
deposits: List[Deposit, MAX_DEPOSITS]
voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS]
sync_aggregate: SyncAggregate
# Execution
execution_payload: ExecutionPayload
bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES]
blob_kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]
```
2023-10-31 15:17:08 +00:00
## Helper functions
2024-03-05 12:46:45 +00:00
### Misc
#### `get_committee_indices`
```python
2024-03-14 16:14:43 +00:00
def get_committee_indices(commitee_bits: Bitvector) -> Sequence[CommitteeIndex]:
return [CommitteeIndex(index) for index, bit in enumerate(commitee_bits) if bit]
2024-03-05 12:46:45 +00:00
```
2023-10-31 15:17:08 +00:00
### Beacon state accessors
2024-03-05 12:46:45 +00:00
#### Modified `get_attesting_indices`
2023-10-31 15:17:08 +00:00
```python
2024-03-05 12:46:45 +00:00
def get_attesting_indices(state: BeaconState, attestation: Attestation) -> Set[ValidatorIndex]:
"""
Return the set of attesting indices corresponding to ``aggregation_bits`` and ``committee_bits``.
"""
2024-04-01 01:43:38 +00:00
output: Set[ValidatorIndex] = set()
2024-03-05 12:46:45 +00:00
committee_indices = get_committee_indices(attestation.committee_bits)
2024-03-25 10:19:11 +00:00
committee_offset = 0
2024-03-05 12:46:45 +00:00
for index in committee_indices:
2024-03-11 03:10:41 +00:00
committee = get_beacon_committee(state, attestation.data.slot, index)
2024-03-25 10:19:11 +00:00
committee_attesters = set(
index for i, index in enumerate(committee) if attestation.aggregation_bits[committee_offset + i])
2024-03-05 12:46:45 +00:00
output = output.union(committee_attesters)
2024-03-25 10:19:11 +00:00
committee_offset += len(committee)
2024-03-05 12:46:45 +00:00
return output
2023-10-31 15:17:08 +00:00
```
2024-03-05 12:46:45 +00:00
### Block processing
#### Modified `process_attestation`
```python
def process_attestation(state: BeaconState, attestation: Attestation) -> None:
data = attestation.data
assert data.target.epoch in (get_previous_epoch(state), get_current_epoch(state))
assert data.target.epoch == compute_epoch_at_slot(data.slot)
assert data.slot + MIN_ATTESTATION_INCLUSION_DELAY < = state.slot
# [Modified in EIP7549]
assert data.index == 0
committee_indices = get_committee_indices(attestation.committee_bits)
2024-03-25 10:19:11 +00:00
participants_count = 0
2024-03-05 12:46:45 +00:00
for index in committee_indices:
assert index < get_committee_count_per_slot ( state , data . target . epoch )
committee = get_beacon_committee(state, data.slot, index)
2024-03-25 10:19:11 +00:00
participants_count += len(committee)
assert len(attestation.aggregation_bits) == participants_count
2024-03-05 12:46:45 +00:00
# Participation flag indices
participation_flag_indices = get_attestation_participation_flag_indices(state, data, state.slot - data.slot)
# Verify signature
assert is_valid_indexed_attestation(state, get_indexed_attestation(state, attestation))
# Update epoch participation flags
if data.target.epoch == get_current_epoch(state):
epoch_participation = state.current_epoch_participation
else:
epoch_participation = state.previous_epoch_participation
proposer_reward_numerator = 0
for index in get_attesting_indices(state, attestation):
for flag_index, weight in enumerate(PARTICIPATION_FLAG_WEIGHTS):
if flag_index in participation_flag_indices and not has_flag(epoch_participation[index], flag_index):
epoch_participation[index] = add_flag(epoch_participation[index], flag_index)
proposer_reward_numerator += get_base_reward(state, index) * weight
# Reward proposer
proposer_reward_denominator = (WEIGHT_DENOMINATOR - PROPOSER_WEIGHT) * WEIGHT_DENOMINATOR // PROPOSER_WEIGHT
proposer_reward = Gwei(proposer_reward_numerator // proposer_reward_denominator)
increase_balance(state, get_beacon_proposer_index(state), proposer_reward)
```