Co-authored-by: Justin Traglia <95511699+jtraglia@users.noreply.github.com> Co-authored-by: Pop Chunhapanya <haxx.pop@gmail.com>
6.9 KiB
EIP-7594 -- Networking
Notice: This document is a work-in-progress for researchers and implementers.
Table of contents
- Modifications in EIP-7594
Modifications in EIP-7594
Preset
Name | Value | Description |
---|---|---|
KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH |
uint64(floorlog2(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments'))) (= 4) |
Merkle proof index for blob_kzg_commitments |
Containers
DataColumnIdentifier
class DataColumnIdentifier(Container):
block_root: Root
index: ColumnIndex
Helpers
verify_data_column_sidecar_kzg_proofs
def verify_data_column_sidecar_kzg_proofs(sidecar: DataColumnSidecar) -> bool:
"""
Verify if the proofs are correct
"""
assert sidecar.index < NUMBER_OF_COLUMNS
assert len(sidecar.column) == len(sidecar.kzg_commitments) == len(sidecar.kzg_proofs)
row_ids = [RowIndex(i) for i in range(len(sidecar.column))]
# KZG batch verifies that the cells match the corresponding commitments and proofs
return verify_cell_proof_batch(
row_commitments=sidecar.kzg_commitments,
row_indices=row_ids, # all rows
column_indices=[sidecar.index],
cells=sidecar.column,
proofs=sidecar.kzg_proofs,
)
verify_data_column_sidecar_inclusion_proof
def verify_data_column_sidecar_inclusion_proof(sidecar: DataColumnSidecar) -> bool:
"""
Verify if the given KZG commitments included in the given beacon block.
"""
gindex = get_subtree_index(get_generalized_index(BeaconBlockBody, 'blob_kzg_commitments'))
return is_valid_merkle_branch(
leaf=hash_tree_root(sidecar.kzg_commitments),
branch=sidecar.kzg_commitments_inclusion_proof,
depth=KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH,
index=gindex,
root=sidecar.signed_block_header.message.body_root,
)
compute_subnet_for_data_column_sidecar
def compute_subnet_for_data_column_sidecar(column_index: ColumnIndex) -> SubnetID:
return SubnetID(column_index % DATA_COLUMN_SIDECAR_SUBNET_COUNT)
The gossip domain: gossipsub
Some gossip meshes are upgraded in the EIP-7594 fork to support upgraded types.
Topics and messages
Samples subnets
data_column_sidecar_{subnet_id}
This topic is used to propagate column sidecars, where each column maps to some subnet_id
.
The type of the payload of this topic is DataColumnSidecar
.
The following validations MUST pass before forwarding the sidecar: DataColumnSidecar
on the network, assuming the alias block_header = sidecar.signed_block_header.message
:
- [REJECT] The sidecar's index is consistent with
NUMBER_OF_COLUMNS
-- i.e.sidecar.index < NUMBER_OF_COLUMNS
. - [REJECT] The sidecar is for the correct subnet -- i.e.
compute_subnet_for_data_column_sidecar(sidecar.index) == subnet_id
. - [IGNORE] The sidecar is not from a future slot (with a
MAXIMUM_GOSSIP_CLOCK_DISPARITY
allowance) -- i.e. validate thatblock_header.slot <= current_slot
(a client MAY queue future sidecars for processing at the appropriate slot). - [IGNORE] The sidecar is from a slot greater than the latest finalized slot -- i.e. validate that
block_header.slot > compute_start_slot_at_epoch(state.finalized_checkpoint.epoch)
- [REJECT] The proposer signature of
sidecar.signed_block_header
, is valid with respect to theblock_header.proposer_index
pubkey. - [IGNORE] The sidecar's block's parent (defined by
block_header.parent_root
) has been seen (via both gossip and non-gossip sources) (a client MAY queue sidecars for processing once the parent block is retrieved). - [REJECT] The sidecar's block's parent (defined by
block_header.parent_root
) passes validation. - [REJECT] The sidecar is from a higher slot than the sidecar's block's parent (defined by
block_header.parent_root
). - [REJECT] The current finalized_checkpoint is an ancestor of the sidecar's block -- i.e.
get_checkpoint_block(store, block_header.parent_root, store.finalized_checkpoint.epoch) == store.finalized_checkpoint.root
. - [REJECT] The sidecar's
kzg_commitments
field inclusion proof is valid as verified byverify_data_column_sidecar_inclusion_proof(sidecar)
. - [REJECT] The sidecar's column data is valid as verified by
verify_data_column_sidecar_kzg_proofs(sidecar)
. - [IGNORE] The sidecar is the first sidecar for the tuple
(block_header.slot, block_header.proposer_index, sidecar.index)
with valid header signature, sidecar inclusion proof, and kzg proof. - [REJECT] The sidecar is proposed by the expected
proposer_index
for the block's slot in the context of the current shuffling (defined byblock_header.parent_root
/block_header.slot
). If theproposer_index
cannot immediately be verified against the expected shuffling, the sidecar MAY be queued for later processing while proposers for the block's branch are calculated -- in such a case do notREJECT
, insteadIGNORE
this message.
Note: In the verify_data_column_sidecar_inclusion_proof(sidecar)
check, for all the sidecars of the same block, it verifies against the same set of kzg_commitments
of the given beacon block. Client can choose to cache the result of the arguments tuple (sidecar.kzg_commitments, sidecar.kzg_commitments_inclusion_proof, sidecar.signed_block_header)
.
The Req/Resp domain
Messages
DataColumnSidecarByRoot v1
Protocol ID: /eth2/beacon_chain/req/data_column_sidecar_by_root/1/
[New in Deneb:EIP4844]
The <context-bytes>
field is calculated as context = compute_fork_digest(fork_version, genesis_validators_root)
:
fork_version |
Chunk SSZ type |
---|---|
EIP7594_FORK_VERSION |
eip7594.DataColumnSidecar |
Request Content:
(
DataColumnIdentifier
)
Response Content:
(
DataColumnSidecar
)