You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: spec/p2p-interface.md
+201-1Lines changed: 201 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -213,6 +213,7 @@ Clients MUST locally store the following `MetaData`:
213
213
(
214
214
seq_number: uint64
215
215
attnets: Bitvector[ATTESTATION_SUBNET_COUNT]
216
+
syncnets: Bitvector[SYNC_COMMITTEE_SUBNET_COUNT]
216
217
)
217
218
```
218
219
@@ -221,6 +222,7 @@ Where
221
222
-`seq_number` is a `uint64` starting at `0` used to version the node's metadata.
222
223
If any other field in the local `MetaData` changes, the node MUST increment `seq_number` by 1.
223
224
-`attnets` is a `Bitvector` representing the node's persistent attestation subnet subscriptions.
225
+
-`syncnets` is a `Bitvector` representing the node's sync committee subnet subscriptions. This field should mirror the data in the node's ENR as outlined in the [validator guide](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/validator.md#sync-committee-subnet-stability).
224
226
225
227
*Note*: `MetaData.seq_number` is used for versioning of the node's metadata,
226
228
is entirely independent of the ENR sequence number,
@@ -289,6 +291,23 @@ The `message-id` of a gossipsub message MUST be the following 20 byte value comp
289
291
(1) multiple snappy `data` can decompress to the same value,
290
292
and (2) some message `data` can fail to snappy decompress altogether.
291
293
294
+
The derivation of the `message-id` has changed starting with Altair to incorporate the message `topic` along with the message `data`. These are fields of the `Message` Protobuf, and interpreted as empty byte strings if missing.
295
+
The `message-id` MUST be the following 20 byte value computed from the message:
296
+
* If `message.data` has a valid snappy decompression, set `message-id` to the first 20 bytes of the `SHA256` hash of
297
+
the concatenation of the following data: `MESSAGE_DOMAIN_VALID_SNAPPY`, the length of the topic byte string (encoded as little-endian `uint64`),
298
+
the topic byte string, and the snappy decompressed message data:
299
+
i.e. `SHA256(MESSAGE_DOMAIN_VALID_SNAPPY + uint_to_bytes(uint64(len(message.topic))) + message.topic + snappy_decompress(message.data))[:20]`.
300
+
* Otherwise, set `message-id` to the first 20 bytes of the `SHA256` hash of
301
+
the concatenation of the following data: `MESSAGE_DOMAIN_INVALID_SNAPPY`, the length of the topic byte string (encoded as little-endian `uint64`),
302
+
the topic byte string, and the raw message data:
303
+
i.e. `SHA256(MESSAGE_DOMAIN_INVALID_SNAPPY + uint_to_bytes(uint64(len(message.topic))) + message.topic + message.data)[:20]`.
304
+
305
+
Implementations may need to carefully handle the function that computes the `message-id`. In particular, messages on topics with the Phase 0
306
+
fork digest should use the `message-id` procedure specified in the Phase 0 document.
307
+
Messages on topics with the Altair fork digest should use the `message-id` procedure defined here.
308
+
If an implementation only supports a single `message-id` function, it can define a switch inline;
309
+
for example, `if topic in phase0_topics: return phase0_msg_id_fn(message) else return altair_msg_id_fn(message)`.
310
+
292
311
The payload is carried in the `data` field of a gossipsub message, and varies depending on the topic:
293
312
294
313
| Name | Message Type |
@@ -300,6 +319,14 @@ The payload is carried in the `data` field of a gossipsub message, and varies de
Clients MUST reject (fail validation) messages containing an incorrect type, or invalid payload.
304
331
305
332
When processing incoming gossip, clients MAY descore or disconnect peers who fail to observe these constraints.
@@ -325,6 +352,8 @@ There are three additional global topics that are used to propagate lower freque
325
352
The `beacon_block` topic is used solely for propagating new signed beacon blocks to all nodes on the networks.
326
353
Signed blocks are sent in their entirety.
327
354
355
+
Modified in Altair due to the inner `BeaconBlockBody` change.
356
+
328
357
The following validations MUST pass before forwarding the `signed_beacon_block` on the network.
329
358
-_[IGNORE]_ The block is not from a future slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
330
359
i.e. validate that `signed_beacon_block.message.slot <= current_slot`
@@ -415,6 +444,43 @@ Clients who receive an attester slashing on this topic MUST validate the conditi
415
444
verify if `any(attester_slashed_indices.difference(prior_seen_attester_slashed_indices))`).
416
445
-_[REJECT]_ All of the conditions within `process_attester_slashing` pass validation.
417
446
447
+
###### `sync_committee_contribution_and_proof`
448
+
449
+
This topic is used to propagate partially aggregated sync committee messages to be included in future blocks.
450
+
451
+
The following validations MUST pass before forwarding the `signed_contribution_and_proof` on the network; define `contribution_and_proof = signed_contribution_and_proof.message`, `contribution = contribution_and_proof.contribution`, and the following function `get_sync_subcommittee_pubkeys` for convenience:
-_[IGNORE]_ The contribution's slot is for the current slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance), i.e. `contribution.slot == current_slot`.
470
+
-_[REJECT]_ The subcommittee index is in the allowed range, i.e. `contribution.subcommittee_index < SYNC_COMMITTEE_SUBNET_COUNT`.
471
+
-_[REJECT]_ The contribution has participants --
472
+
that is, `any(contribution.aggregation_bits)`.
473
+
-_[REJECT]_`contribution_and_proof.selection_proof` selects the validator as an aggregator for the slot -- i.e. `is_sync_committee_aggregator(contribution_and_proof.selection_proof)` returns `True`.
474
+
-_[REJECT]_ The aggregator's validator index is in the declared subcommittee of the current sync committee --
475
+
i.e. `state.validators[contribution_and_proof.aggregator_index].pubkey in get_sync_subcommittee_pubkeys(state, contribution.subcommittee_index)`.
476
+
-_[IGNORE]_ A valid sync committee contribution with equal `slot`, `beacon_block_root` and `subcommittee_index` whose `aggregation_bits` is non-strict superset has _not_ already been seen.
477
+
-_[IGNORE]_ The sync committee contribution is the first valid contribution received for the aggregator with index `contribution_and_proof.aggregator_index`
478
+
for the slot `contribution.slot` and subcommittee index `contribution.subcommittee_index`
479
+
(this requires maintaining a cache of size `SYNC_COMMITTEE_SIZE` for this topic that can be flushed after each slot).
480
+
-_[REJECT]_ The `contribution_and_proof.selection_proof` is a valid signature of the `SyncAggregatorSelectionData` derived from the `contribution` by the validator with index `contribution_and_proof.aggregator_index`.
481
+
-_[REJECT]_ The aggregator signature, `signed_contribution_and_proof.signature`, is valid.
482
+
-_[REJECT]_ The aggregate signature is valid for the message `beacon_block_root` and aggregate pubkey derived from the participation info in `aggregation_bits` for the subcommittee specified by the `contribution.subcommittee_index`.
483
+
418
484
##### Attestation subnets
419
485
420
486
Attestation subnets are used to propagate unaggregated attestations to subsections of the network.
@@ -468,6 +534,59 @@ Unaggregated attestations are sent as `Attestation`s to the subnet topic,
468
534
469
535
Aggregated attestations are sent to the `beacon_aggregate_and_proof` topic as `AggregateAndProof`s.
470
536
537
+
##### Sync committee subnets
538
+
539
+
Sync committee subnets are used to propagate unaggregated sync committee messages to subsections of the network.
540
+
541
+
###### `sync_committee_{subnet_id}`
542
+
543
+
The `sync_committee_{subnet_id}` topics are used to propagate unaggregated sync committee messages to the subnet `subnet_id` to be aggregated before being gossiped to the global `sync_committee_contribution_and_proof` topic.
544
+
545
+
The following validations MUST pass before forwarding the `sync_committee_message` on the network:
546
+
547
+
-_[IGNORE]_ The message's slot is for the current slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance), i.e. `sync_committee_message.slot == current_slot`.
548
+
-_[REJECT]_ The `subnet_id` is valid for the given validator, i.e. `subnet_id in compute_subnets_for_sync_committee(state, sync_committee_message.validator_index)`.
549
+
Note this validation implies the validator is part of the broader current sync committee along with the correct subcommittee.
550
+
-_[IGNORE]_ There has been no other valid sync committee message for the declared `slot` for the validator referenced by `sync_committee_message.validator_index`
551
+
(this requires maintaining a cache of size `SYNC_COMMITTEE_SIZE // SYNC_COMMITTEE_SUBNET_COUNT` for each subnet that can be flushed after each slot).
552
+
Note this validation is _per topic_ so that for a given `slot`, multiple messages could be forwarded with the same `validator_index` as long as the `subnet_id`s are distinct.
553
+
-_[REJECT]_ The `signature` is valid for the message `beacon_block_root` for the validator referenced by `validator_index`.
554
+
555
+
##### Sync committees and aggregation
556
+
557
+
The aggregation scheme closely follows the design of the attestation aggregation scheme.
558
+
Sync committee messages are broadcast into "subnets" defined by a topic.
559
+
The number of subnets is defined by `SYNC_COMMITTEE_SUBNET_COUNT` in the [Altair validator guide](./validator.md#constants).
560
+
Sync committee members are divided into "subcommittees" which are then assigned to a subnet for the duration of tenure in the sync committee.
561
+
Individual validators can be duplicated in the broader sync committee such that they are included multiple times in a given subcommittee or across multiple subcommittees.
562
+
563
+
Unaggregated messages (along with metadata) are sent as `SyncCommitteeMessage`s on the `sync_committee_{subnet_id}` topics.
564
+
565
+
Aggregated sync committee messages are packaged into (signed) `SyncCommitteeContribution` along with proofs and gossiped to the `sync_committee_contribution_and_proof` topic.
566
+
567
+
#### Transitioning the gossip
568
+
569
+
With any fork, the fork version, and thus the `ForkDigestValue`, change.
570
+
Message types are unique per topic, and so for a smooth transition a node must temporarily subscribe to both the old and new topics.
571
+
572
+
The topics that are not removed in a fork are updated with a new `ForkDigestValue`. In advance of the fork, a node SHOULD subscribe to the post-fork variants of the topics.
573
+
574
+
Subscriptions are expected to be well-received, all updated nodes should subscribe as well.
575
+
Topic-meshes can be grafted quickly as the nodes are already connected and exchanging gossip control messages.
576
+
577
+
Messages SHOULD NOT be re-broadcast from one fork to the other.
578
+
A node's behavior before the fork and after the fork are as follows:
579
+
Pre-fork:
580
+
- Peers who propagate messages on the post-fork topics MAY be scored negatively proportionally to time till fork,
581
+
to account for clock discrepancy.
582
+
- Messages can be IGNORED on the post-fork topics, with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` margin.
583
+
584
+
Post-fork:
585
+
- Peers who propagate messages on the pre-fork topics MUST NOT be scored negatively. Lagging IWANT may force them to.
586
+
- Messages on pre and post-fork variants of topics share application-level caches.
587
+
E.g. an attestation on the both the old and new topic is ignored like any duplicate.
588
+
- Two epochs after the fork, pre-fork topics SHOULD be unsubscribed from. This is well after the configured `seen_ttl`.
589
+
471
590
#### Encodings
472
591
473
592
Topics are post-fixed with an encoding. Encodings define how the payload of a gossipsub message is encoded.
@@ -518,10 +637,15 @@ Request/response messages MUST adhere to the encoding specified in the protocol
Requests the MetaData of a peer, using the new `MetaData` definition given above
1093
+
that is extended from phase 0 in Altair. Other conditions for the `GetMetaData`
1094
+
protocol are unchanged from the phase 0 p2p networking document.
1095
+
1096
+
#### Transitioning from v1 to v2
1097
+
1098
+
In advance of the fork, implementations can opt in to both run the v1 and v2 for a smooth transition.
1099
+
This is non-breaking, and is recommended as soon as the fork specification is stable.
1100
+
1101
+
The v1 variants will be deprecated, and implementations should use v2 when available
1102
+
(as negotiated with peers via LibP2P multistream-select).
1103
+
1104
+
The v1 method MAY be unregistered at the fork boundary.
1105
+
In the event of a request on v1 for an Altair specific payload,
1106
+
the responder MUST return the **InvalidRequest** response code.
1107
+
916
1108
### The discovery domain: discv5
917
1109
918
1110
Discovery Version 5 ([discv5](https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md)) (Protocol version v5.1) is used for peer discovery.
@@ -959,6 +1151,14 @@ If a node's `MetaData.attnets` has any non-zero bit, the ENR MUST include the `a
959
1151
960
1152
If a node's `MetaData.attnets` is composed of all zeros, the ENR MAY optionally include the `attnets` entry or leave it out entirely.
961
1153
1154
+
##### `syncnets` bitfield
1155
+
1156
+
An additional bitfield is added to the ENR under the key `syncnets` to facilitate sync committee subnet discovery.
1157
+
The length of this bitfield is `SYNC_COMMITTEE_SUBNET_COUNT` where each bit corresponds to a distinct `subnet_id` for a specific sync committee subnet.
1158
+
The `i`th bit is set in this bitfield if the validator is currently subscribed to the `sync_committee_{i}` topic.
1159
+
1160
+
See the [validator document](./validator.md#sync-committee-subnet-stability) for further details on how the new bits are used.
1161
+
962
1162
##### `eth2` field
963
1163
964
1164
ENRs MUST carry a generic `eth2` key with an 16-byte value of the node's current fork digest, next fork version,
0 commit comments