Skip to content

Conversation

@MarcoPolo
Copy link

@MarcoPolo MarcoPolo commented Dec 12, 2025

This is used by cell-level dissemination (aka partial messages) to give the CL all blobs the EL knows about and let CL communicate efficiently about any other missing blobs. In other words, partial responses from the EL is useful now.

See the related (closed) PR: ethereum/execution-apis#674 and the new PR: ethereum/execution-apis#719

@raulk
Copy link
Member

raulk commented Dec 13, 2025

Previous version of this PR: #32170

@raulk
Copy link
Member

raulk commented Dec 13, 2025

This one includes metrics accounting, so it seems like an improvement over the old one.

@MariusVanDerWijden
Copy link
Member

How do you feel about:

diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go
index 109581e240..2be050f084 100644
--- a/eth/catalyst/api.go
+++ b/eth/catalyst/api.go
@@ -571,51 +571,19 @@ func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProo
 	if api.config().LatestFork(head.Time) < forks.Osaka {
 		return nil, unsupportedForkErr("engine_getBlobsV2 is not available before Osaka fork")
 	}
-	if len(hashes) > 128 {
-		return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes)))
-	}
-	available := api.eth.BlobTxPool().AvailableBlobs(hashes)
-	getBlobsRequestedCounter.Inc(int64(len(hashes)))
-	getBlobsAvailableCounter.Inc(int64(available))
-
-	// Optimization: check first if all blobs are available, if not, return empty response
-	if available != len(hashes) {
-		getBlobsV2RequestMiss.Inc(1)
-		return nil, nil
-	}
-
-	blobs, _, proofs, err := api.eth.BlobTxPool().GetBlobs(hashes, types.BlobSidecarVersion1, false)
-	if err != nil {
-		return nil, engine.InvalidParams.With(err)
-	}
-
-	// To comply with API spec, check again that we really got all data needed
-	for _, blob := range blobs {
-		if blob == nil {
-			getBlobsV2RequestMiss.Inc(1)
-			return nil, nil
-		}
-	}
-	getBlobsV2RequestHit.Inc(1)
-
-	res := make([]*engine.BlobAndProofV2, len(hashes))
-	for i := 0; i < len(blobs); i++ {
-		var cellProofs []hexutil.Bytes
-		for _, proof := range proofs[i] {
-			cellProofs = append(cellProofs, proof[:])
-		}
-		res[i] = &engine.BlobAndProofV2{
-			Blob:       blobs[i][:],
-			CellProofs: cellProofs,
-		}
-	}
-	return res, nil
+	return api.getBlobs(hashes, false)
 }
 
 // GetBlobsV3 returns a set of blobs from the transaction pool. Same as
 // GetBlobsV2, except will return partial responses in case there is a missing
 // blob.
 func (api *ConsensusAPI) GetBlobsV3(hashes []common.Hash) ([]*engine.BlobAndProofV2, error) {
+	return api.getBlobs(hashes, true)
+}
+
+// getBlobs returns all available blobs.
+// if allowPartials is not set, either all or no blobs are returned.
+func (api *ConsensusAPI) getBlobs(hashes []common.Hash, allowPartials bool) ([]*engine.BlobAndProofV2, error) {
 	if len(hashes) > 128 {
 		return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes)))
 	}
@@ -631,10 +599,14 @@ func (api *ConsensusAPI) GetBlobsV3(hashes []common.Hash) ([]*engine.BlobAndProo
 	res := make([]*engine.BlobAndProofV2, len(hashes))
 	for i := range blobs {
 		if blobs[i] == nil {
-			getBlobsV3RequestMiss.Inc(1)
-			continue
+			if allowPartials {
+				getBlobsV3RequestMiss.Inc(1)
+				continue
+			} else {
+				getBlobsV2RequestMiss.Inc(1)
+				return nil, nil
+			}
 		}
-		getBlobsV3RequestHit.Inc(1)
 		var cellProofs []hexutil.Bytes
 		for _, proof := range proofs[i] {
 			cellProofs = append(cellProofs, proof[:])
@@ -644,6 +616,11 @@ func (api *ConsensusAPI) GetBlobsV3(hashes []common.Hash) ([]*engine.BlobAndProo
 			CellProofs: cellProofs,
 		}
 	}
+	if allowPartials {
+		getBlobsV3RequestHit.Inc(int64(len(blobs)))
+	} else {
+		getBlobsV2RequestHit.Inc(1)
+	}
 	return res, nil
 }
 

@MarcoPolo
Copy link
Author

@MariusVanDerWijden done. Updated in the latest version of the commit git range-diff c75be1f61a18...5cbe6bd60c4d

@MarcoPolo MarcoPolo marked this pull request as ready for review December 17, 2025 19:06
Copy link
Member

@MariusVanDerWijden MariusVanDerWijden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants