2021-03-17 23:20:53 +00:00
# Ethereum 2.0 Sharding -- Network specification
2021-01-04 21:47:42 +00:00
**Notice**: This document is a work-in-progress for researchers and implementers.
## Table of contents
2021-03-17 23:07:15 +00:00
<!-- TOC -->
2021-01-04 21:47:42 +00:00
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE - RUN doctoc TO UPDATE -->
- [Introduction ](#introduction )
2021-05-11 17:16:58 +00:00
- [Constants ](#constants )
- [Misc ](#misc )
2021-03-17 23:38:18 +00:00
- [New containers ](#new-containers )
2021-04-04 00:45:57 +00:00
- [ShardBlobBody ](#shardblobbody )
2021-03-17 23:38:18 +00:00
- [ShardBlob ](#shardblob )
- [SignedShardBlob ](#signedshardblob )
2021-03-17 23:20:53 +00:00
- [Gossip domain ](#gossip-domain )
2021-01-04 21:47:42 +00:00
- [Topics and messages ](#topics-and-messages )
2021-05-11 17:16:58 +00:00
- [Shard blobs: `shard_blob_{subnet_id}` ](#shard-blobs-shard_blob_subnet_id )
2021-01-04 21:47:42 +00:00
- [Shard header: `shard_header` ](#shard-header-shard_header )
2021-04-04 00:45:57 +00:00
- [Shard proposer slashing: `shard_proposer_slashing` ](#shard-proposer-slashing-shard_proposer_slashing )
2021-01-04 21:47:42 +00:00
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
2021-03-17 23:07:15 +00:00
<!-- /TOC -->
2021-01-04 21:47:42 +00:00
## Introduction
2021-03-17 23:53:55 +00:00
The specification of these changes continues in the same format as the [Phase0 ](../phase0/p2p-interface.md ) and
[Altair ](../altair/p2p-interface.md ) network specifications, and assumes them as pre-requisite.
The adjustments and additions for Shards are outlined in this document.
2021-01-04 21:47:42 +00:00
2021-05-11 17:16:58 +00:00
## Constants
### Misc
| Name | Value | Description |
| ---- | ----- | ----------- |
| `SHARD_BLOB_SUBNET_COUNT` | `64` | The number of `shard_blob_{subnet_id}` subnets used in the gossipsub protocol. |
2021-03-17 23:38:18 +00:00
## New containers
2021-04-04 00:45:57 +00:00
### ShardBlobBody
```python
class ShardBlobBody(Container):
# The actual data commitment
commitment: DataCommitment
# Proof that the degree < commitment.length
degree_proof: BLSCommitment
# The actual data. Should match the commitment and degree proof.
data: List[BLSPoint, POINTS_PER_SAMPLE * MAX_SAMPLES_PER_BLOCK]
2021-04-06 17:31:20 +00:00
# Latest block root of the Beacon Chain, before shard_blob.slot
beacon_block_root: Root
2021-04-04 00:45:57 +00:00
```
The user MUST always verify the commitments in the `body` are valid for the `data` in the `body` .
2021-03-17 23:38:18 +00:00
2021-04-04 00:45:57 +00:00
### ShardBlob
2021-03-17 23:38:18 +00:00
```python
class ShardBlob(Container):
2021-04-06 01:17:07 +00:00
# Slot and shard that this blob is intended for
2021-03-17 23:38:18 +00:00
slot: Slot
shard: Shard
2021-05-27 01:57:59 +00:00
# Shard data with related commitments and beacon anchor
2021-04-04 00:45:57 +00:00
body: ShardBlobBody
# Proposer of the shard-blob
proposer_index: ValidatorIndex
2021-03-17 23:38:18 +00:00
```
2021-04-04 00:45:57 +00:00
This is the expanded form of the `ShardBlobHeader` type.
2021-03-17 23:38:18 +00:00
### SignedShardBlob
```python
class SignedShardBlob(Container):
2021-03-17 23:53:55 +00:00
message: ShardBlob
2021-03-17 23:38:18 +00:00
signature: BLSSignature
```
2021-01-04 21:47:42 +00:00
2021-03-17 23:20:53 +00:00
## Gossip domain
2021-01-04 21:47:42 +00:00
### Topics and messages
Following the same scheme as the [Phase0 gossip topics ](../phase0/p2p-interface.md#topics-and-messages ), names and payload types are:
2021-03-17 23:20:53 +00:00
2021-01-04 21:47:42 +00:00
| Name | Message Type |
|----------------------------------|---------------------------|
2021-05-11 17:16:58 +00:00
| `shard_blob_{subnet_id}` | `SignedShardBlob` |
2021-01-04 21:47:42 +00:00
| `shard_header` | `SignedShardHeader` |
2021-04-04 00:45:57 +00:00
| `shard_proposer_slashing` | `ShardProposerSlashing` |
2021-01-04 21:47:42 +00:00
The [DAS network specification ](./das-p2p.md ) defines additional topics.
2021-05-11 17:16:58 +00:00
#### Shard blobs: `shard_blob_{subnet_id}`
2021-01-04 21:47:42 +00:00
2021-05-11 17:16:58 +00:00
Shard block data, in the form of a `SignedShardBlob` is published to the `shard_blob_{subnet_id}` subnets.
```python
def compute_subnet_for_shard_blob(state: BeaconState, slot: Slot, shard: Shard) -> uint64:
"""
Compute the correct subnet for a shard blob publication.
Note, this mimics compute_subnet_for_attestation().
"""
committee_index = compute_committee_index_from_shard(state, slot, shard)
committees_per_slot = get_committee_count_per_slot(state, compute_epoch_at_slot(slot))
slots_since_epoch_start = Slot(slot % SLOTS_PER_EPOCH)
committees_since_epoch_start = committees_per_slot * slots_since_epoch_start
return uint64((committees_since_epoch_start + committee_index) % SHARD_BLOB_SUBNET_COUNT)
```
2021-01-04 21:47:42 +00:00
2021-04-04 00:45:57 +00:00
The following validations MUST pass before forwarding the `signed_blob` (with inner `message` as `blob` ) on the horizontal subnet or creating samples for it.
2021-01-04 21:47:42 +00:00
- _[IGNORE]_ The `blob` is not from a future slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
i.e. validate that `blob.slot <= current_slot`
(a client MAY queue future blobs for processing at the appropriate slot).
2021-04-04 00:45:57 +00:00
- _[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)`
2021-05-11 17:16:58 +00:00
- _[REJECT]_ The shard blob is for the correct subnet --
i.e. `compute_subnet_for_shard_blob(state, blob.slot, blob.shard) == subnet_id`
2021-04-04 00:45:57 +00:00
- _[IGNORE]_ The blob is the first blob with valid signature received for the `(blob.proposer_index, blob.slot, blob.shard)` combination.
2021-01-04 21:47:42 +00:00
- _[REJECT]_ As already limited by the SSZ list-limit, it is important the blob is well-formatted and not too large.
2021-04-06 02:00:55 +00:00
- _[REJECT]_ The `blob.body.data` MUST NOT contain any point `p >= MODULUS` . Although it is a `uint256` , not the full 256 bit range is valid.
2021-04-04 00:45:57 +00:00
- _[REJECT]_ The proposer signature, `signed_blob.signature` , is valid with respect to the `proposer_index` pubkey.
- _[REJECT]_ The blob is proposed by the expected `proposer_index` for the blob's slot
2021-04-06 17:31:20 +00:00
in the context of the current shuffling (defined by `blob.body.beacon_block_root` /`slot`).
2021-04-04 00:45:57 +00:00
If the `proposer_index` cannot immediately be verified against the expected shuffling,
the block MAY be queued for later processing while proposers for the blob's branch are calculated --
in such a case _do not_ `REJECT` , instead `IGNORE` this message.
2021-01-04 21:47:42 +00:00
#### Shard header: `shard_header`
2021-04-04 00:45:57 +00:00
Shard header data, in the form of a `SignedShardBlobHeader` is published to the global `shard_header` subnet.
The following validations MUST pass before forwarding the `signed_shard_header` (with inner `message` as `header` ) on the network.
- _[IGNORE]_ The `header` is not from a future slot (with a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) --
i.e. validate that `header.slot <= current_slot`
(a client MAY queue future headers for processing at the appropriate slot).
- _[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 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
2021-04-06 17:31:20 +00:00
in the context of the current shuffling (defined by `header.body_summary.beacon_block_root` /`slot`).
2021-04-04 00:45:57 +00:00
If the `proposer_index` cannot immediately be verified against the expected shuffling,
the block MAY be queued for later processing while proposers for the block's branch are calculated --
in such a case _do not_ `REJECT` , instead `IGNORE` this message.
#### Shard proposer slashing: `shard_proposer_slashing`
2021-01-04 21:47:42 +00:00
2021-04-04 00:45:57 +00:00
Shard proposer slashings, in the form of `ShardProposerSlashing` , are published to the global `shard_proposer_slashing` topic.
2021-01-04 21:47:42 +00:00
2021-04-04 00:45:57 +00:00
The following validations MUST pass before forwarding the `shard_proposer_slashing` on to the network.
- _[IGNORE]_ The shard proposer slashing is the first valid shard proposer slashing received
for the proposer with index `proposer_slashing.signed_header_1.message.proposer_index` .
The `slot` and `shard` are ignored, there are no per-shard slashings.
- _[REJECT]_ All of the conditions within `process_shard_proposer_slashing` pass validation.