Fix Blob Reconstruction (#14909)

* Fix Mutating Blob Mask

* Changelog

* Typo
This commit is contained in:
Nishant Das
2025-02-11 21:44:00 +08:00
committed by GitHub
parent 26d35474e9
commit 4b43f13e65
3 changed files with 40 additions and 17 deletions

View File

@@ -543,9 +543,11 @@ func (s *Service) ReconstructBlobSidecars(ctx context.Context, block interfaces.
// Collect KZG hashes for non-existing blobs
var kzgHashes []common.Hash
var kzgIndexes []int
for i, commitment := range kzgCommitments {
if !hasIndex(uint64(i)) {
kzgHashes = append(kzgHashes, primitives.ConvertKzgCommitmentToVersionedHash(commitment))
kzgIndexes = append(kzgIndexes, i)
}
}
if len(kzgHashes) == 0 {
@@ -568,27 +570,21 @@ func (s *Service) ReconstructBlobSidecars(ctx context.Context, block interfaces.
// Reconstruct verified blob sidecars
var verifiedBlobs []blocks.VerifiedROBlob
for i, blobIndex := 0, 0; i < len(kzgCommitments); i++ {
if hasIndex(uint64(i)) {
for i := 0; i < len(kzgHashes); i++ {
if blobs[i] == nil {
continue
}
if blobIndex >= len(blobs) || blobs[blobIndex] == nil {
blobIndex++
continue
}
blob := blobs[blobIndex]
blobIndex++
proof, err := blocks.MerkleProofKZGCommitment(blockBody, i)
blob := blobs[i]
blobIndex := kzgIndexes[i]
proof, err := blocks.MerkleProofKZGCommitment(blockBody, blobIndex)
if err != nil {
log.WithError(err).WithField("index", i).Error("failed to get Merkle proof for KZG commitment")
log.WithError(err).WithField("index", blobIndex).Error("failed to get Merkle proof for KZG commitment")
continue
}
sidecar := &ethpb.BlobSidecar{
Index: uint64(i),
Index: uint64(blobIndex),
Blob: blob.Blob,
KzgCommitment: kzgCommitments[i],
KzgCommitment: kzgCommitments[blobIndex],
KzgProof: blob.KzgProof,
SignedBlockHeader: header,
CommitmentInclusionProof: proof,
@@ -596,14 +592,14 @@ func (s *Service) ReconstructBlobSidecars(ctx context.Context, block interfaces.
roBlob, err := blocks.NewROBlobWithRoot(sidecar, blockRoot)
if err != nil {
log.WithError(err).WithField("index", i).Error("failed to create RO blob with root")
log.WithError(err).WithField("index", blobIndex).Error("failed to create RO blob with root")
continue
}
v := s.blobVerifier(roBlob, verification.ELMemPoolRequirements)
verifiedBlob, err := v.VerifiedROBlob()
if err != nil {
log.WithError(err).WithField("index", i).Error("failed to verify RO blob")
log.WithError(err).WithField("index", blobIndex).Error("failed to verify RO blob")
continue
}

View File

@@ -2455,6 +2455,25 @@ func TestReconstructBlobSidecars(t *testing.T) {
require.NoError(t, err)
require.Equal(t, 3, len(verifiedBlobs))
})
t.Run("recovered 3 missing blobs with mutated blob mask", func(t *testing.T) {
exists := []bool{true, false, true, false, true, false}
hi := mockSummary(t, exists)
srv := createBlobServer(t, 3, func() {
// Mutate blob mask
exists[1] = true
exists[3] = true
})
defer srv.Close()
rpcClient, client := setupRpcClient(t, srv.URL, client)
defer rpcClient.Close()
verifiedBlobs, err := client.ReconstructBlobSidecars(ctx, sb, r, hi)
require.NoError(t, err)
require.Equal(t, 3, len(verifiedBlobs))
})
}
func createRandomKzgCommitments(t *testing.T, num int) [][]byte {
@@ -2467,12 +2486,16 @@ func createRandomKzgCommitments(t *testing.T, num int) [][]byte {
return kzgCommitments
}
func createBlobServer(t *testing.T, numBlobs int) *httptest.Server {
func createBlobServer(t *testing.T, numBlobs int, callbackFuncs ...func()) *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
defer func() {
require.NoError(t, r.Body.Close())
}()
// Execute callback functions for each request.
for _, f := range callbackFuncs {
f()
}
blobs := make([]pb.BlobAndProofJson, numBlobs)
for i := range blobs {