Skip to content

Commit ecf42d8

Browse files
authored
Add executable gossip validation functions for gloas (#5294)
1 parent e762dd6 commit ecf42d8

47 files changed

Lines changed: 11059 additions & 1544 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pysetup/spec_builders/gloas.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ def deprecate_functions(cls) -> set[str]:
5656
"retrieve_column_sidecars",
5757
"upgrade_to_fulu",
5858
"verify_partial_data_column_header_inclusion_proof",
59-
# TODO(jtraglia): Temporarily deprecate these until we update them for Gloas.
60-
"validate_data_column_sidecar_gossip",
61-
"validate_partial_data_column_sidecar_gossip",
6259
}
6360

6461
@classmethod

specs/altair/p2p-interface.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ domain. Some Phase 0 features will be deprecated, but not removed immediately.
5353
```python
5454
@dataclass
5555
class Seen:
56-
proposer_slots: Set[Tuple[ValidatorIndex, Slot]]
57-
aggregator_epochs: Set[Tuple[ValidatorIndex, Epoch]]
56+
proposer_slots: Set[Tuple[Slot, ValidatorIndex]]
57+
aggregator_epochs: Set[Tuple[Epoch, ValidatorIndex]]
5858
aggregate_data_roots: Dict[Root, Set[Tuple[Boolean, ...]]]
5959
voluntary_exit_indices: Set[ValidatorIndex]
6060
proposer_slashing_indices: Set[ValidatorIndex]
6161
attester_slashing_indices: Set[ValidatorIndex]
62-
attestation_validator_epochs: Set[Tuple[ValidatorIndex, Epoch]]
62+
attestation_validator_epochs: Set[Tuple[Epoch, ValidatorIndex]]
6363
# [New in Altair]
64-
sync_contribution_aggregator_slots: Set[Tuple[ValidatorIndex, Slot, Uint64]]
64+
sync_contribution_aggregator_slots: Set[Tuple[Slot, ValidatorIndex, Uint64]]
6565
# [New in Altair]
6666
sync_contribution_data: Dict[Tuple[Slot, Root, Uint64], Set[Tuple[Boolean, ...]]]
6767
# [New in Altair]
@@ -84,15 +84,15 @@ def compute_fork_version(epoch: Epoch) -> Version:
8484

8585
```python
8686
def is_current_slot(
87-
state: BeaconState,
87+
store: Store,
8888
slot: Slot,
8989
current_time_ms: Uint64,
9090
) -> bool:
9191
"""
9292
Check if the given slot is the current slot
9393
(with MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance).
9494
"""
95-
return is_within_slot_range(state, slot, 0, current_time_ms)
95+
return is_within_slot_range(store, slot, 0, current_time_ms)
9696
```
9797

9898
#### New `get_sync_subcommittee_pubkeys`
@@ -217,6 +217,7 @@ be included in future blocks. The `state` parameter is the head state.
217217
```python
218218
def validate_sync_committee_contribution_and_proof_gossip(
219219
seen: Seen,
220+
store: Store,
220221
state: BeaconState,
221222
signed_contribution_and_proof: SignedContributionAndProof,
222223
current_time_ms: Uint64,
@@ -229,7 +230,7 @@ def validate_sync_committee_contribution_and_proof_gossip(
229230
contribution = contribution_and_proof.contribution
230231

231232
# [IGNORE] The contribution's slot is for the current slot
232-
if not is_current_slot(state, contribution.slot, current_time_ms):
233+
if not is_current_slot(store, contribution.slot, current_time_ms):
233234
raise GossipIgnore("contribution is not for the current slot")
234235

235236
# [REJECT] The subcommittee index is in the allowed range
@@ -269,11 +270,11 @@ def validate_sync_committee_contribution_and_proof_gossip(
269270
raise GossipIgnore("already seen contribution for this data")
270271

271272
# [IGNORE] The sync committee contribution is the first valid contribution received
272-
# for the aggregator with index contribution_and_proof.aggregator_index
273-
# for the slot contribution.slot and subcommittee index contribution.subcommittee_index
273+
# for the slot contribution.slot, aggregator with index contribution_and_proof.aggregator_index,
274+
# and subcommittee index contribution.subcommittee_index
274275
aggregator_key = (
275-
contribution_and_proof.aggregator_index,
276276
contribution.slot,
277+
contribution_and_proof.aggregator_index,
277278
contribution.subcommittee_index,
278279
)
279280
if aggregator_key in seen.sync_contribution_aggregator_slots:
@@ -334,6 +335,7 @@ gossiped to the global `sync_committee_contribution_and_proof` topic. The
334335
```python
335336
def validate_sync_committee_message_gossip(
336337
seen: Seen,
338+
store: Store,
337339
state: BeaconState,
338340
sync_committee_message: SyncCommitteeMessage,
339341
current_time_ms: Uint64,
@@ -344,7 +346,7 @@ def validate_sync_committee_message_gossip(
344346
Raises GossipIgnore or GossipReject on validation failure.
345347
"""
346348
# [IGNORE] The message's slot is for the current slot
347-
if not is_current_slot(state, sync_committee_message.slot, current_time_ms):
349+
if not is_current_slot(store, sync_committee_message.slot, current_time_ms):
348350
raise GossipIgnore("message is not for the current slot")
349351

350352
# [REJECT] The validator index is valid

specs/bellatrix/p2p-interface.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def validate_beacon_block_gossip(
128128

129129
# [IGNORE] The block is not from a future slot
130130
# (MAY be queued for processing at the appropriate slot)
131-
if not is_not_from_future_slot(state, block.slot, current_time_ms):
131+
if is_future_slot(store, block.slot, current_time_ms):
132132
raise GossipIgnore("block is from a future slot")
133133

134134
# [IGNORE] The block is from a slot greater than the latest finalized slot
@@ -138,9 +138,10 @@ def validate_beacon_block_gossip(
138138
if block.slot <= finalized_slot:
139139
raise GossipIgnore("block is not from a slot greater than the latest finalized slot")
140140

141-
# [IGNORE] The block is the first block with valid signature received for the proposer for the slot
142-
if (block.proposer_index, block.slot) in seen.proposer_slots:
143-
raise GossipIgnore("block is not the first valid block for this proposer and slot")
141+
# [IGNORE] The block is the first block with valid signature received for the slot and proposer
142+
proposer_slot_key = (block.slot, block.proposer_index)
143+
if proposer_slot_key in seen.proposer_slots:
144+
raise GossipIgnore("block is not the first valid block for this slot and proposer")
144145

145146
# [REJECT] The proposer index is a valid validator index
146147
if block.proposer_index >= len(state.validators):
@@ -190,10 +191,9 @@ def validate_beacon_block_gossip(
190191
raise GossipReject("block is not from a higher slot than its parent")
191192

192193
# [REJECT] The current finalized checkpoint is an ancestor of the block
193-
checkpoint_block = get_checkpoint_block(
194-
store, block.parent_root, store.finalized_checkpoint.epoch
195-
)
196-
if checkpoint_block != store.finalized_checkpoint.root:
194+
finalized_epoch = store.finalized_checkpoint.epoch
195+
finalized_checkpoint_block = get_checkpoint_block(store, block.parent_root, finalized_epoch)
196+
if finalized_checkpoint_block != store.finalized_checkpoint.root:
197197
raise GossipReject("finalized checkpoint is not an ancestor of block")
198198

199199
# [REJECT] The block is proposed by the expected proposer for the slot
@@ -205,7 +205,7 @@ def validate_beacon_block_gossip(
205205
raise GossipReject("block proposer_index does not match expected proposer")
206206

207207
# Mark this block as seen
208-
seen.proposer_slots.add((block.proposer_index, block.slot))
208+
seen.proposer_slots.add(proposer_slot_key)
209209
```
210210

211211
#### Transitioning the gossip

specs/capella/p2p-interface.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ specifications of previous upgrades, and assumes them as pre-requisite.
3737
```python
3838
@dataclass
3939
class Seen:
40-
proposer_slots: Set[Tuple[ValidatorIndex, Slot]]
41-
aggregator_epochs: Set[Tuple[ValidatorIndex, Epoch]]
40+
proposer_slots: Set[Tuple[Slot, ValidatorIndex]]
41+
aggregator_epochs: Set[Tuple[Epoch, ValidatorIndex]]
4242
aggregate_data_roots: Dict[Root, Set[Tuple[Boolean, ...]]]
4343
voluntary_exit_indices: Set[ValidatorIndex]
4444
proposer_slashing_indices: Set[ValidatorIndex]
4545
attester_slashing_indices: Set[ValidatorIndex]
46-
attestation_validator_epochs: Set[Tuple[ValidatorIndex, Epoch]]
47-
sync_contribution_aggregator_slots: Set[Tuple[ValidatorIndex, Slot, Uint64]]
46+
attestation_validator_epochs: Set[Tuple[Epoch, ValidatorIndex]]
47+
sync_contribution_aggregator_slots: Set[Tuple[Slot, ValidatorIndex, Uint64]]
4848
sync_contribution_data: Dict[Tuple[Slot, Root, Uint64], Set[Tuple[Boolean, ...]]]
4949
sync_message_validator_slots: Set[Tuple[Slot, ValidatorIndex, Uint64]]
5050
# [New in Capella]
@@ -124,7 +124,7 @@ def validate_beacon_block_gossip(
124124

125125
# [IGNORE] The block is not from a future slot
126126
# (MAY be queued for processing at the appropriate slot)
127-
if not is_not_from_future_slot(state, block.slot, current_time_ms):
127+
if is_future_slot(store, block.slot, current_time_ms):
128128
raise GossipIgnore("block is from a future slot")
129129

130130
# [IGNORE] The block is from a slot greater than the latest finalized slot
@@ -134,9 +134,10 @@ def validate_beacon_block_gossip(
134134
if block.slot <= finalized_slot:
135135
raise GossipIgnore("block is not from a slot greater than the latest finalized slot")
136136

137-
# [IGNORE] The block is the first block with valid signature received for the proposer for the slot
138-
if (block.proposer_index, block.slot) in seen.proposer_slots:
139-
raise GossipIgnore("block is not the first valid block for this proposer and slot")
137+
# [IGNORE] The block is the first block with valid signature received for the slot and proposer
138+
proposer_slot_key = (block.slot, block.proposer_index)
139+
if proposer_slot_key in seen.proposer_slots:
140+
raise GossipIgnore("block is not the first valid block for this slot and proposer")
140141

141142
# [REJECT] The proposer index is a valid validator index
142143
if block.proposer_index >= len(state.validators):
@@ -179,10 +180,9 @@ def validate_beacon_block_gossip(
179180
raise GossipReject("block is not from a higher slot than its parent")
180181

181182
# [REJECT] The current finalized checkpoint is an ancestor of the block
182-
checkpoint_block = get_checkpoint_block(
183-
store, block.parent_root, store.finalized_checkpoint.epoch
184-
)
185-
if checkpoint_block != store.finalized_checkpoint.root:
183+
finalized_epoch = store.finalized_checkpoint.epoch
184+
finalized_checkpoint_block = get_checkpoint_block(store, block.parent_root, finalized_epoch)
185+
if finalized_checkpoint_block != store.finalized_checkpoint.root:
186186
raise GossipReject("finalized checkpoint is not an ancestor of block")
187187

188188
# [REJECT] The block is proposed by the expected proposer for the slot
@@ -194,7 +194,7 @@ def validate_beacon_block_gossip(
194194
raise GossipReject("block proposer_index does not match expected proposer")
195195

196196
# Mark this block as seen
197-
seen.proposer_slots.add((block.proposer_index, block.slot))
197+
seen.proposer_slots.add(proposer_slot_key)
198198
```
199199

200200
###### New `bls_to_execution_change`

0 commit comments

Comments
 (0)