Notice: This document is a work-in-progress for researchers and implementers.
The specification of these changes continues in the same format as the network specifications of previous upgrades, and assumes them as pre-requisite. The adjustments and additions for Shards are outlined in this document.
Name | Value | Description |
---|---|---|
SHARD_BLOB_SUBNET_COUNT |
64 |
The number of shard_blob_{subnet_id} subnets used in the gossipsub protocol. |
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]
# Latest block root of the Beacon Chain, before shard_blob.slot
beacon_block_root: Root
The user MUST always verify the commitments in the body
are valid for the data
in the body
.
class ShardBlob(Container):
# Slot and shard that this blob is intended for
slot: Slot
shard: Shard
# Shard data with related commitments and beacon anchor
body: ShardBlobBody
# Proposer of the shard-blob
proposer_index: ValidatorIndex
This is the expanded form of the ShardBlobHeader
type.
class SignedShardBlob(Container):
message: ShardBlob
signature: BLSSignature
Following the same scheme as the Phase0 gossip topics, names and payload types are:
Name | Message Type |
---|---|
shard_blob_{subnet_id} |
SignedShardBlob |
shard_header |
SignedShardBlobHeader |
shard_proposer_slashing |
ShardProposerSlashing |
The DAS network specification defines additional topics.
Shard blob subnets are used to propagate shard blobs to subsections of the network.
Shard block data, in the form of a SignedShardBlob
is published to the shard_blob_{subnet_id}
subnets.
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)
The following validations MUST pass before forwarding the signed_blob
(with inner message
as blob
) on the horizontal subnet or creating samples for it.
- [IGNORE] The
blob
is not from a future slot (with aMAXIMUM_GOSSIP_CLOCK_DISPARITY
allowance) -- i.e. validate thatblob.slot <= current_slot
(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 thatcompute_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)
doesn't raise an error - [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. - [REJECT] As already limited by the SSZ list-limit, it is important the blob is well-formatted and not too large.
- [REJECT] The
blob.body.data
MUST NOT contain any pointp >= MODULUS
. Although it is auint256
, not the full 256 bit range is valid. - [REJECT] The proposer signature,
signed_blob.signature
, is valid with respect to theproposer_index
pubkey. - [REJECT] The blob is proposed by the expected
proposer_index
for the blob's slot in the context of the current shuffling (defined byblob.body.beacon_block_root
/slot
). If theproposer_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 notREJECT
, insteadIGNORE
this message.
There are two additional global topics for Sharding, one is used to propagate shard blob headers (shard_header
) to
all nodes on the network. Another one is used to propagate validator message (shard_proposer_slashing
).
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_blob_header
(with inner message
as header
) on the network.
- [IGNORE] The
header
is not from a future slot (with aMAXIMUM_GOSSIP_CLOCK_DISPARITY
allowance) -- i.e. validate thatheader.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 thatcompute_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)
doesn't raise an error - [REJECT] The proposer signature,
signed_shard_blob_header.signature
, is valid with respect to theproposer_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 byheader.body_summary.beacon_block_root
/slot
). If theproposer_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 notREJECT
, insteadIGNORE
this message.
Shard proposer slashings, in the form of ShardProposerSlashing
, are published to the global shard_proposer_slashing
topic.
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
. Theslot
andshard
are ignored, there are no per-shard slashings. - [REJECT] All of the conditions within
process_shard_proposer_slashing
pass validation.