Handle the case when a shard may not have a committee at slot.
Block is invalid if contains ShardBlobHeader lacking committee Reject Gossip ShardBlobHeader and ShardBlob messages which lacks committee
This commit is contained in:
parent
671ed36212
commit
414ef614cb
|
@ -455,8 +455,15 @@ def compute_shard_from_committee_index(state: BeaconState, slot: Slot, index: Co
|
|||
|
||||
```python
|
||||
def compute_committee_index_from_shard(state: BeaconState, slot: Slot, shard: Shard) -> CommitteeIndex:
|
||||
"""
|
||||
Returns either committee index for ``shard`` at ``slot`` or ``None`` if no committee
|
||||
"""
|
||||
active_shards = get_active_shard_count(state, compute_epoch_at_slot(slot))
|
||||
return CommitteeIndex((active_shards + shard - get_start_shard(state, slot)) % active_shards)
|
||||
index = (active_shards + shard - get_start_shard(state, slot)) % active_shards
|
||||
if index >= get_committee_count_per_slot(state, compute_epoch_at_slot(slot)):
|
||||
return None
|
||||
else:
|
||||
return CommitteeIndex(index)
|
||||
```
|
||||
|
||||
|
||||
|
@ -559,6 +566,7 @@ def update_pending_votes(state: BeaconState, attestation: Attestation) -> None:
|
|||
def process_shard_header(state: BeaconState,
|
||||
signed_header: SignedShardBlobHeader) -> None:
|
||||
header = signed_header.message
|
||||
committee_index = compute_committee_index_from_shard(state, header.slot, header.shard)
|
||||
# Verify the header is not 0, and not from the future.
|
||||
assert Slot(0) < header.slot <= state.slot
|
||||
header_epoch = compute_epoch_at_slot(header.slot)
|
||||
|
@ -566,6 +574,8 @@ def process_shard_header(state: BeaconState,
|
|||
assert header_epoch in [get_previous_epoch(state), get_current_epoch(state)]
|
||||
# Verify that the shard is active
|
||||
assert header.shard < get_active_shard_count(state, header_epoch)
|
||||
# Verify that shard has a committee at slot
|
||||
assert committee_index is not None
|
||||
# Verify that the block root matches,
|
||||
# to ensure the header will only be included in this specific Beacon Chain sub-tree.
|
||||
assert header.body_summary.beacon_block_root == get_block_root_at_slot(state, header.slot - 1)
|
||||
|
@ -595,8 +605,7 @@ def process_shard_header(state: BeaconState,
|
|||
assert header_root not in [pending_header.root for pending_header in pending_headers]
|
||||
|
||||
# Include it in the pending list
|
||||
index = compute_committee_index_from_shard(state, header.slot, header.shard)
|
||||
committee_length = len(get_beacon_committee(state, header.slot, index))
|
||||
committee_length = len(get_beacon_committee(state, header.slot, committee_index))
|
||||
pending_headers.append(PendingShardHeader(
|
||||
slot=header.slot,
|
||||
shard=header.shard,
|
||||
|
@ -693,6 +702,9 @@ def process_pending_headers(state: BeaconState) -> None:
|
|||
|
||||
# The entire committee (and its balance)
|
||||
index = compute_committee_index_from_shard(state, slot, shard)
|
||||
if index is None:
|
||||
# the shard had no committee on this slot
|
||||
continue
|
||||
full_committee = get_beacon_committee(state, slot, index)
|
||||
# The set of voters who voted for each header (and their total balances)
|
||||
voting_sets = [
|
||||
|
|
|
@ -117,6 +117,8 @@ The following validations MUST pass before forwarding the `signed_blob` (with in
|
|||
(a client MAY queue future blobs for processing at the appropriate slot).
|
||||
- _[IGNORE]_ The `blob` is new enough to be still be processed --
|
||||
i.e. validate that `compute_epoch_at_slot(blob.slot) >= get_previous_epoch(state)`
|
||||
- _[REJECT]_ The shard should have a committee at slot --
|
||||
i.e. validate that `compute_committee_index_from_shard(state, blob.slot, blob.shard) is not None`
|
||||
- _[REJECT]_ The shard blob is for the correct subnet --
|
||||
i.e. `compute_subnet_for_shard_blob(state, blob.slot, blob.shard) == subnet_id`
|
||||
- _[IGNORE]_ The blob is the first blob with valid signature received for the `(blob.proposer_index, blob.slot, blob.shard)` combination.
|
||||
|
@ -141,6 +143,8 @@ The following validations MUST pass before forwarding the `signed_shard_header`
|
|||
- _[IGNORE]_ The `header` is new enough to be still be processed --
|
||||
i.e. validate that `compute_epoch_at_slot(header.slot) >= get_previous_epoch(state)`
|
||||
- _[IGNORE]_ The header is the first header with valid signature received for the `(header.proposer_index, header.slot, header.shard)` combination.
|
||||
- _[REJECT]_ The shard should have a committee at slot --
|
||||
i.e. validate that `compute_committee_index_from_shard(state, header.slot, header.shard) is not None`
|
||||
- _[REJECT]_ The proposer signature, `signed_shard_header.signature`, is valid with respect to the `proposer_index` pubkey.
|
||||
- _[REJECT]_ The header is proposed by the expected `proposer_index` for the block's slot
|
||||
in the context of the current shuffling (defined by `header.body_summary.beacon_block_root`/`slot`).
|
||||
|
|
Loading…
Reference in New Issue