fix: response checking from RequestManager for blobs (#6755)

* rewrite: response checking from RequestManager for blobs

* clean whitespace

* use a comparator and std instead

* sort incoming blobs by index

* fix list traversal

---------

Co-authored-by: tersec <tersec@users.noreply.github.com>
This commit is contained in:
Agnish Ghosh 2024-12-12 21:07:22 +05:30 committed by GitHub
parent 031d24ff41
commit 98a7f446c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 13 deletions

View File

@ -10,6 +10,7 @@
# Uncategorized helper functions from the spec # Uncategorized helper functions from the spec
import import
std/sequtils,
# Status libraries # Status libraries
stew/[byteutils, endians2, objects], stew/[byteutils, endians2, objects],
nimcrypto/sha2, nimcrypto/sha2,
@ -542,7 +543,6 @@ proc compute_execution_block_hash*(blck: ForkyBeaconBlock): Eth2Digest =
rlpHash(blockToBlockHeader(blck)).to(Eth2Digest) rlpHash(blockToBlockHeader(blck)).to(Eth2Digest)
from std/math import exp, ln from std/math import exp, ln
from std/sequtils import foldl
func ln_binomial(n, k: int): float64 = func ln_binomial(n, k: int): float64 =
if k > n: if k > n:

View File

@ -18,6 +18,7 @@ import
"."/sync_protocol, "."/sync_manager, "."/sync_protocol, "."/sync_manager,
../gossip_processing/block_processor ../gossip_processing/block_processor
from std/algorithm import binarySearch, sort
from ../beacon_clock import GetBeaconTimeFn from ../beacon_clock import GetBeaconTimeFn
export block_quarantine, sync_manager export block_quarantine, sync_manager
@ -102,21 +103,32 @@ proc checkResponse(roots: openArray[Eth2Digest],
checks.del(res) checks.del(res)
true true
func cmpSidecarIdentifier(x: BlobIdentifier | DataColumnIdentifier,
y: ref BlobSidecar | ref DataColumnSidecar): int =
cmp(x.index, y.index)
proc checkResponse(idList: seq[BlobIdentifier], proc checkResponse(idList: seq[BlobIdentifier],
blobs: openArray[ref BlobSidecar]): bool = blobs: openArray[ref BlobSidecar]): bool =
if len(blobs) > len(idList): if blobs.len > idList.len:
return false return false
for blob in blobs: var i = 0
let block_root = hash_tree_root(blob.signed_block_header.message) while i < blobs.len:
var found = false let
for id in idList: block_root = hash_tree_root(blobs[i].signed_block_header.message)
if id.block_root == block_root and id.index == blob.index: id = idList[i]
found = true
break # Check if the blob response is a subset
if not found: if binarySearch(idList, blobs[i], cmpSidecarIdentifier) == -1:
return false return false
blob[].verify_blob_sidecar_inclusion_proof().isOkOr:
# Verify block_root and index match
if id.block_root != block_root or id.index != blobs[i].index:
return false return false
# Verify inclusion proof
blobs[i][].verify_blob_sidecar_inclusion_proof().isOkOr:
return false
inc i
true true
proc requestBlocksByRoot(rman: RequestManager, items: seq[Eth2Digest]) {.async: (raises: [CancelledError]).} = proc requestBlocksByRoot(rman: RequestManager, items: seq[Eth2Digest]) {.async: (raises: [CancelledError]).} =
@ -190,6 +202,9 @@ proc requestBlocksByRoot(rman: RequestManager, items: seq[Eth2Digest]) {.async:
if not(isNil(peer)): if not(isNil(peer)):
rman.network.peerPool.release(peer) rman.network.peerPool.release(peer)
func cmpBlobIndexes(x, y: ref BlobSidecar): int =
cmp(x.index, y.index)
proc fetchBlobsFromNetwork(self: RequestManager, proc fetchBlobsFromNetwork(self: RequestManager,
idList: seq[BlobIdentifier]) idList: seq[BlobIdentifier])
{.async: (raises: [CancelledError]).} = {.async: (raises: [CancelledError]).} =
@ -203,8 +218,9 @@ proc fetchBlobsFromNetwork(self: RequestManager,
let blobs = await blobSidecarsByRoot(peer, BlobIdentifierList idList) let blobs = await blobSidecarsByRoot(peer, BlobIdentifierList idList)
if blobs.isOk: if blobs.isOk:
let ublobs = blobs.get() var ublobs = blobs.get().asSeq()
if not checkResponse(idList, ublobs.asSeq()): ublobs.sort(cmpBlobIndexes)
if not checkResponse(idList, ublobs):
debug "Mismatched response to blobs by root", debug "Mismatched response to blobs by root",
peer = peer, blobs = shortLog(idList), ublobs = len(ublobs) peer = peer, blobs = shortLog(idList), ublobs = len(ublobs)
peer.updateScore(PeerScoreBadResponse) peer.updateScore(PeerScoreBadResponse)