process_attestation: Validate epoch before using it

`data.target.epoch` is used to count the active validator set.

Because `get_committee_count_per_slot` is extremely inefficient the way
the spec is written, clients cache it, or the underlying active
validator set.

Performing the checks in the given order leads to a (very unlikely)
security issue where the a cold and above all, distant value may get
used which may be costly - reordering the checks brings the value into a
more reasonable range before using it.
This commit is contained in:
Jacek Sieka 2020-07-24 07:26:37 +02:00
parent b6eeec52e2
commit 6f7652d330
No known key found for this signature in database
GPG Key ID: A1B09461ABB656B8
1 changed files with 1 additions and 1 deletions

View File

@ -1718,10 +1718,10 @@ def process_attester_slashing(state: BeaconState, attester_slashing: AttesterSla
```python ```python
def process_attestation(state: BeaconState, attestation: Attestation) -> None: def process_attestation(state: BeaconState, attestation: Attestation) -> None:
data = attestation.data data = attestation.data
assert data.index < get_committee_count_per_slot(state, data.target.epoch)
assert data.target.epoch in (get_previous_epoch(state), get_current_epoch(state)) 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.target.epoch == compute_epoch_at_slot(data.slot)
assert data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot <= data.slot + SLOTS_PER_EPOCH assert data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot <= data.slot + SLOTS_PER_EPOCH
assert data.index < get_committee_count_per_slot(state, data.target.epoch)
committee = get_beacon_committee(state, data.slot, data.index) committee = get_beacon_committee(state, data.slot, data.index)
assert len(attestation.aggregation_bits) == len(committee) assert len(attestation.aggregation_bits) == len(committee)