@@ -193,8 +193,9 @@ proc shouldGetBlobs[A, B](man: SyncManager[A, B], e: Epoch): bool =
193193 (wallEpoch < man.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS or
194194 e >= wallEpoch - man.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS )
195195
196- proc getBlobSidecars * [A, B](man: SyncManager [A, B], peer: A,
197- req: SyncRequest ): Future [BlobSidecarsRes ] {.async .} =
196+ proc getBlobSidecars [A, B](man: SyncManager [A, B], peer: A,
197+ req: SyncRequest
198+ ): Future [BlobSidecarsRes ] {.async .} =
198199 mixin getScore, `==`
199200
200201 logScope:
@@ -241,30 +242,46 @@ func groupBlobs*[T](req: SyncRequest[T],
241242 blocks: seq [ref ForkedSignedBeaconBlock ],
242243 blobs: seq [ref BlobSidecar ]):
243244 Result [seq [BlobSidecars ], string ] =
244- var grouped = newSeq [BlobSidecars ](len (blocks))
245- var blobCursor = 0
246- var i = 0
247- for blck in blocks:
248- let slot = blck[].slot
249- if blobCursor == len (blobs):
250- # reached end of blobs, have more blobless blocks
251- break
252- for blob in blobs[blobCursor.. len (blobs)- 1 ]:
253- if blob.signed_block_header.message.slot < slot:
254- return Result [seq [BlobSidecars ], string ].err " invalid blob sequence"
255- if blob.signed_block_header.message.slot == slot:
256- grouped[i].add (blob)
257- blobCursor = blobCursor + 1
258- i = i + 1
259-
260- if blobCursor != len (blobs):
245+ var
246+ grouped = newSeq [BlobSidecars ](len (blocks))
247+ blob_cursor = 0
248+ for block_idx, blck in blocks:
249+ withBlck (blck[]):
250+ when consensusFork >= ConsensusFork .Deneb :
251+ template kzgs : untyped = forkyBlck.message.body.blob_kzg_commitments
252+ if kzgs.len == 0 :
253+ continue
254+ # Clients MUST include all blob sidecars of each block from which they include blob sidecars.
255+ # The following blob sidecars, where they exist, MUST be sent in consecutive (slot, index) order.
256+ # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/p2p-interface.md#blobsidecarsbyrange-v1
257+ let header = forkyBlck.toSignedBeaconBlockHeader ()
258+ for blob_idx, kzg_commitment in kzgs:
259+ if blob_cursor >= blobs.len:
260+ return err (" BlobSidecar: response too short" )
261+ let blob_sidecar = blobs[blob_cursor]
262+ if blob_sidecar.index != BlobIndex blob_idx:
263+ return err (" BlobSidecar: unexpected index" )
264+ if blob_sidecar.kzg_commitment != kzg_commitment:
265+ return err (" BlobSidecar: unexpected kzg_commitment" )
266+ if blob_sidecar.signed_block_header != header:
267+ return err (" BlobSidecar: unexpected signed_block_header" )
268+ grouped[block_idx].add (blob_sidecar)
269+ inc blob_cursor
270+
271+ if blob_cursor != len (blobs):
261272 # we reached end of blocks without consuming all blobs so either
262273 # the peer we got too few blocks in the paired request, or the
263274 # peer is sending us spurious blobs.
264275 Result [seq [BlobSidecars ], string ].err " invalid block or blob sequence"
265276 else :
266277 Result [seq [BlobSidecars ], string ].ok grouped
267278
279+ func checkBlobs (blobs: seq [BlobSidecars ]): Result [void , string ] =
280+ for blob_sidecars in blobs:
281+ for blob_sidecar in blob_sidecars:
282+ ? blob_sidecar[].verify_blob_sidecar_inclusion_proof ()
283+ ok ()
284+
268285proc syncStep [A, B](man: SyncManager [A, B], index: int , peer: A) {.async .} =
269286 logScope:
270287 peer_score = peer.getScore ()
@@ -454,30 +471,24 @@ proc syncStep[A, B](man: SyncManager[A, B], index: int, peer: A) {.async.} =
454471 return
455472 let groupedBlobs = groupBlobs (req, blockData, blobData)
456473 if groupedBlobs.isErr ():
474+ peer.updateScore (PeerScoreNoValues )
475+ man.queue.push (req)
476+ info " Received blobs sequence is inconsistent" ,
477+ blobs_map = getShortMap (req, blobData), request = req, msg= groupedBlobs.error ()
478+ return
479+ if (let checkRes = groupedBlobs.get.checkBlobs (); checkRes.isErr):
457480 peer.updateScore (PeerScoreBadResponse )
458481 man.queue.push (req)
459482 warn " Received blobs sequence is invalid" ,
460- blobs_map = getShortMap (req, blobData), request = req, msg= groupedBlobs.error ()
483+ blobs_count = len (blobData),
484+ blobs_map = getShortMap (req, blobData),
485+ request = req,
486+ msg = checkRes.error
461487 return
462488 Opt .some (groupedBlobs.get ())
463489 else :
464490 Opt .none (seq [BlobSidecars ])
465491
466- if blobData.isSome:
467- let blobs = blobData.get ()
468- if len (blobs) != len (blockData):
469- peer.updateScore (PeerScoreNoValues )
470- man.queue.push (req)
471- info " block and blobs have different lengths" , blobs= len (blobs), blocks= len (blockData)
472- return
473- for i, blk in blockData:
474- if len (blobs[i]) > 0 and blk[].slot !=
475- blobs[i][0 ].signed_block_header.message.slot:
476- peer.updateScore (PeerScoreNoValues )
477- man.queue.push (req)
478- debug " block and blobs data have inconsistent slots"
479- return
480-
481492 if len (blockData) == 0 and man.direction == SyncQueueKind .Backward and
482493 req.contains (man.getSafeSlot ()):
483494 # The sync protocol does not distinguish between:
0 commit comments