Skip to content

Commit 2e1e7f1

Browse files
committed
Add Cell Dissemination via Partial Message Specification
1 parent cd92a89 commit 2e1e7f1

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

specs/fulu/das-core.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,22 @@ class DataColumnSidecar(Container):
8585
kzg_commitments_inclusion_proof: Vector[Bytes32, KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH]
8686
```
8787

88+
#### `PartialDataColumnSidecar`
89+
90+
```python
91+
class PartialDataColumnSidecar(Container):
92+
# Only provided if the index can not be inferred from the Gossipsub topic
93+
index: ColumnIndex | None
94+
# Encoded the same as an IHAVE bitmap
95+
cells_present_bitmap: ByteVector[NUMBER_OF_COLUMNS/8] # ceiling if NUMBER_OF_COLUMNS is not divisible by 8
96+
column: List[Cell, MAX_BLOB_COMMITMENTS_PER_BLOCK]
97+
kzg_proofs: List[KZGProof, MAX_BLOB_COMMITMENTS_PER_BLOCK]
98+
# The following are only provided on eager pushes.
99+
kzg_commitments: None | List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]
100+
signed_block_header: None | SignedBeaconBlockHeader
101+
kzg_commitments_inclusion_proof: None | Vector[Bytes32, KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH]
102+
```
103+
88104
#### `MatrixEntry`
89105

90106
```python

specs/fulu/p2p-interface.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,116 @@ gossip. In particular, clients MUST:
292292
- Update gossip rule related data structures (i.e. update the anti-equivocation
293293
cache).
294294

295+
#### Partial Columns
296+
297+
Gossipsub's [Partial Message
298+
Extension](https://github.com/libp2p/specs/pull/685) enables exchanging
299+
selective parts of a message rather than the whole. The specification here
300+
describes how Consensus Clients use Partial Messages to disseminate cells.
301+
302+
*Editor Note*: This change MUST NOT be merged before the linked libp2p/specs.
303+
304+
##### `PartialDataColumnSidecar`
305+
306+
The `PartialDataColumnSidecar `is identical to the `DataColumnSidecar `container
307+
with the exception that fields and cells may be None.
308+
309+
Some fields are only set when a peer is eagerly pushing this container.
310+
Otherwise, if a peer is sending the container as a response, there is no need to
311+
include redundant fields.
312+
313+
```python
314+
class PartialDataColumnSidecar(Container):
315+
# Only provided if the index can not be inferred from the Gossipsub topic
316+
index: ColumnIndex | None
317+
cells_present_bitmap: ByteVector[NUMBER_OF_COLUMNS/8] # ceiling if NUMBER_OF_COLUMNS is not divisible by 8
318+
column: List[Cell, MAX_BLOB_COMMITMENTS_PER_BLOCK]
319+
kzg_proofs: List[KZGProof, MAX_BLOB_COMMITMENTS_PER_BLOCK]
320+
# The following are only provided on eager pushes.
321+
kzg_commitments: None | List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]
322+
signed_block_header: None | SignedBeaconBlockHeader
323+
kzg_commitments_inclusion_proof: None | Vector[Bytes32, KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH]
324+
```
325+
326+
##### Partial IHAVE/IWANT
327+
328+
Peers communicate IHAVE and IWANTS succintly with a bitmap. For IHAVE, a set bit (`1`)
329+
means that the peer has the corresponding cell. For IWANT, a set bit means the
330+
peer wants the corresponding cell. The bitmap is encoded by the following function:
331+
332+
```python
333+
def create_bitmap(set_indices, n):
334+
bitmap = [0] * ((n + 7) // 8)
335+
for i in set_indices:
336+
bitmap[i // 8] |= 1 << (i % 8)
337+
return bitmap
338+
```
339+
340+
For example, if the peer wanted cells at positions 0,3,9, the corresponding
341+
IWANT bitmap would be: `0000 1001 000 0010`.
342+
343+
##### Encoding and Decoding Responses
344+
345+
All responses should be encoded and decoded with the PartialDataColumnSidecar
346+
container.
347+
348+
##### Validation
349+
350+
TODO add full validation rules
351+
352+
###### `verify_partial_data_column_sidecar_kzg_proofs`
353+
354+
```python
355+
def verify_partial_data_column_sidecar_kzg_proofs(sidecar: PartialDataColumnSidecar, all_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]) -> bool:
356+
"""
357+
Verify if the KZG proofs are correct.
358+
"""
359+
# The column index also represents the cell index
360+
cell_indices = [i for i, b in enumerate(bin(bitmap)[:1:-1]) if b == '1']
361+
362+
# Batch verify that the cells match the corresponding commitments and proofs
363+
return verify_cell_kzg_proof_batch(
364+
commitments_bytes=[all_commitments[i] for i in cell_indices],
365+
cell_indices=cell_indices,
366+
cells=sidecar.column,
367+
proofs_bytes=sidecar.kzg_proofs,
368+
)
369+
```
370+
371+
##### Eager Pushing
372+
373+
In contrast to standard Gossipsub, A Client usually requests missing parts from
374+
a peer. A client can send its partial IWANT before receiving a peer's partial
375+
IHAVE to register interest in certain parts. This can introduce extra latency
376+
compared to a Client unconditionally pushing messages to a peer.
377+
378+
To address this tradeoff a Client may choose to eagerly push some (or all) of
379+
the cells it has. Clients SHOULD only do this when they are reasonably confident
380+
that a peer does not have the provided cells. For example, a proposer including
381+
private blobs SHOULD eagerly push the cells corresponding to the private blobs.
382+
383+
##### Interaction with standard Gossipsub
384+
385+
###### Mesh
386+
387+
The Partial Message Extension uses the same mesh peers and the same topic name
388+
as the standard Gossipsub topics for DataColumnSidecars.
389+
390+
###### Scoring
391+
392+
TODO: this needs to be discussed in the libp2p spec first.
393+
394+
###### Forwarding
395+
396+
Once Clients can construct the full DataColumnSidecar after receiving missing
397+
cells, they should forward the full DataColumnSidecar over standard Gossipsub to
398+
peers that do not support partial messages. This provides backwards
399+
compatibility with nodes that do not yet support partial messages
400+
401+
Avoid forwarding the full DataColumnSidecar message to peers that support
402+
partial messages. It is purely redundant information to send them a standard
403+
gossipsub message if they support partial mess
404+
295405
### The Req/Resp domain
296406

297407
#### Messages

0 commit comments

Comments
 (0)