mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Fix Blob Reconstruction (#14909)
* Fix Mutating Blob Mask * Changelog * Typo
This commit is contained in:
@@ -543,9 +543,11 @@ func (s *Service) ReconstructBlobSidecars(ctx context.Context, block interfaces.
|
|||||||
|
|
||||||
// Collect KZG hashes for non-existing blobs
|
// Collect KZG hashes for non-existing blobs
|
||||||
var kzgHashes []common.Hash
|
var kzgHashes []common.Hash
|
||||||
|
var kzgIndexes []int
|
||||||
for i, commitment := range kzgCommitments {
|
for i, commitment := range kzgCommitments {
|
||||||
if !hasIndex(uint64(i)) {
|
if !hasIndex(uint64(i)) {
|
||||||
kzgHashes = append(kzgHashes, primitives.ConvertKzgCommitmentToVersionedHash(commitment))
|
kzgHashes = append(kzgHashes, primitives.ConvertKzgCommitmentToVersionedHash(commitment))
|
||||||
|
kzgIndexes = append(kzgIndexes, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(kzgHashes) == 0 {
|
if len(kzgHashes) == 0 {
|
||||||
@@ -568,27 +570,21 @@ func (s *Service) ReconstructBlobSidecars(ctx context.Context, block interfaces.
|
|||||||
|
|
||||||
// Reconstruct verified blob sidecars
|
// Reconstruct verified blob sidecars
|
||||||
var verifiedBlobs []blocks.VerifiedROBlob
|
var verifiedBlobs []blocks.VerifiedROBlob
|
||||||
for i, blobIndex := 0, 0; i < len(kzgCommitments); i++ {
|
for i := 0; i < len(kzgHashes); i++ {
|
||||||
if hasIndex(uint64(i)) {
|
if blobs[i] == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
blob := blobs[i]
|
||||||
if blobIndex >= len(blobs) || blobs[blobIndex] == nil {
|
blobIndex := kzgIndexes[i]
|
||||||
blobIndex++
|
proof, err := blocks.MerkleProofKZGCommitment(blockBody, blobIndex)
|
||||||
continue
|
|
||||||
}
|
|
||||||
blob := blobs[blobIndex]
|
|
||||||
blobIndex++
|
|
||||||
|
|
||||||
proof, err := blocks.MerkleProofKZGCommitment(blockBody, i)
|
|
||||||
if err != nil {
|
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
|
continue
|
||||||
}
|
}
|
||||||
sidecar := ðpb.BlobSidecar{
|
sidecar := ðpb.BlobSidecar{
|
||||||
Index: uint64(i),
|
Index: uint64(blobIndex),
|
||||||
Blob: blob.Blob,
|
Blob: blob.Blob,
|
||||||
KzgCommitment: kzgCommitments[i],
|
KzgCommitment: kzgCommitments[blobIndex],
|
||||||
KzgProof: blob.KzgProof,
|
KzgProof: blob.KzgProof,
|
||||||
SignedBlockHeader: header,
|
SignedBlockHeader: header,
|
||||||
CommitmentInclusionProof: proof,
|
CommitmentInclusionProof: proof,
|
||||||
@@ -596,14 +592,14 @@ func (s *Service) ReconstructBlobSidecars(ctx context.Context, block interfaces.
|
|||||||
|
|
||||||
roBlob, err := blocks.NewROBlobWithRoot(sidecar, blockRoot)
|
roBlob, err := blocks.NewROBlobWithRoot(sidecar, blockRoot)
|
||||||
if err != nil {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
v := s.blobVerifier(roBlob, verification.ELMemPoolRequirements)
|
v := s.blobVerifier(roBlob, verification.ELMemPoolRequirements)
|
||||||
verifiedBlob, err := v.VerifiedROBlob()
|
verifiedBlob, err := v.VerifiedROBlob()
|
||||||
if err != nil {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2455,6 +2455,25 @@ func TestReconstructBlobSidecars(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 3, len(verifiedBlobs))
|
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 {
|
func createRandomKzgCommitments(t *testing.T, num int) [][]byte {
|
||||||
@@ -2467,12 +2486,16 @@ func createRandomKzgCommitments(t *testing.T, num int) [][]byte {
|
|||||||
return kzgCommitments
|
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) {
|
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
defer func() {
|
defer func() {
|
||||||
require.NoError(t, r.Body.Close())
|
require.NoError(t, r.Body.Close())
|
||||||
}()
|
}()
|
||||||
|
// Execute callback functions for each request.
|
||||||
|
for _, f := range callbackFuncs {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
blobs := make([]pb.BlobAndProofJson, numBlobs)
|
blobs := make([]pb.BlobAndProofJson, numBlobs)
|
||||||
for i := range blobs {
|
for i := range blobs {
|
||||||
|
|||||||
4
changelog/nisdas_fix_mutating_blob_mask.md
Normal file
4
changelog/nisdas_fix_mutating_blob_mask.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
### Fixed
|
||||||
|
|
||||||
|
- We change how we track blob indexes during their reconstruction from the EL to prevent
|
||||||
|
a mutating blob mask from causing invalid sidecars from being created.
|
||||||
Reference in New Issue
Block a user