@@ -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