Skip to content

Commit af72bae

Browse files
authored
Merge pull request #4002 from mkalinin/fix-committee-validation
eip7549: Ensure non-zero bits for each committee bitfield comprising an aggregate
2 parents a09d0c3 + 34918e9 commit af72bae

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

specs/electra/beacon-chain.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,8 @@ def process_operations(state: BeaconState, body: BeaconBlockBody) -> None:
12551255

12561256
###### Modified `process_attestation`
12571257

1258+
*Note*: The function is modified to support EIP7549.
1259+
12581260
```python
12591261
def process_attestation(state: BeaconState, attestation: Attestation) -> None:
12601262
data = attestation.data
@@ -1265,13 +1267,19 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None:
12651267
# [Modified in Electra:EIP7549]
12661268
assert data.index == 0
12671269
committee_indices = get_committee_indices(attestation.committee_bits)
1268-
participants_count = 0
1269-
for index in committee_indices:
1270-
assert index < get_committee_count_per_slot(state, data.target.epoch)
1271-
committee = get_beacon_committee(state, data.slot, index)
1272-
participants_count += len(committee)
1270+
committee_offset = 0
1271+
for committee_index in committee_indices:
1272+
assert committee_index < get_committee_count_per_slot(state, data.target.epoch)
1273+
committee = get_beacon_committee(state, data.slot, committee_index)
1274+
committee_attesters = set(
1275+
attester_index for i, attester_index in enumerate(committee)
1276+
if attestation.aggregation_bits[committee_offset + i]
1277+
)
1278+
assert len(committee_attesters) > 0
1279+
committee_offset += len(committee)
12731280

1274-
assert len(attestation.aggregation_bits) == participants_count
1281+
# Bitfield length matches total number of participants
1282+
assert len(attestation.aggregation_bits) == committee_offset
12751283

12761284
# Participation flag indices
12771285
participation_flag_indices = get_attestation_participation_flag_indices(state, data, state.slot - data.slot)

tests/core/pyspec/eth2spec/test/electra/block_processing/test_process_attestation.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def test_invalid_nonset_committee_bits(spec, state):
8888

8989
@with_electra_and_later
9090
@spec_state_test
91+
@with_presets([MINIMAL], "need multiple committees per slot")
9192
def test_invalid_nonset_multiple_committee_bits(spec, state):
9293
"""
9394
EIP-7549 test
@@ -148,3 +149,33 @@ def test_one_committee_with_gap(spec, state):
148149
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
149150

150151
yield from run_attestation_processing(spec, state, attestation)
152+
153+
154+
@with_electra_and_later
155+
@spec_state_test
156+
@with_presets([MINIMAL], "need multiple committees per slot")
157+
def test_invalid_nonset_bits_for_one_committee(spec, state):
158+
"""
159+
EIP-7549 test
160+
"""
161+
# Attestation with full committee participating
162+
committee_0 = spec.get_beacon_committee(state, state.slot, 0)
163+
attestation_1 = get_valid_attestation(spec, state, index=1, signed=True)
164+
165+
# Create an on chain aggregate
166+
aggregate = spec.Attestation(data=attestation_1.data, signature=attestation_1.signature)
167+
aggregate.committee_bits[0] = True
168+
aggregate.committee_bits[1] = True
169+
aggregate.aggregation_bits = get_empty_eip7549_aggregation_bits(
170+
spec, state, aggregate.committee_bits, aggregate.data.slot
171+
)
172+
committee_offset = len(committee_0)
173+
for i in range(len(attestation_1.aggregation_bits)):
174+
aggregate.aggregation_bits[committee_offset + i] = attestation_1.aggregation_bits[i]
175+
176+
# Check that only one committee is presented
177+
assert spec.get_attesting_indices(state, aggregate) == spec.get_attesting_indices(state, attestation_1)
178+
179+
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)
180+
181+
yield from run_attestation_processing(spec, state, aggregate, valid=False)

0 commit comments

Comments
 (0)