@@ -36,6 +36,7 @@ import (
36
36
"github.com/ethereum/go-ethereum/core/state"
37
37
"github.com/ethereum/go-ethereum/core/txpool"
38
38
"github.com/ethereum/go-ethereum/core/types"
39
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
39
40
"github.com/ethereum/go-ethereum/event"
40
41
"github.com/ethereum/go-ethereum/log"
41
42
"github.com/ethereum/go-ethereum/metrics"
@@ -1299,32 +1300,86 @@ func (p *BlobPool) GetMetadata(hash common.Hash) *txpool.TxMetadata {
1299
1300
// GetBlobs returns a number of blobs and proofs for the given versioned hashes.
1300
1301
// This is a utility method for the engine API, enabling consensus clients to
1301
1302
// retrieve blobs from the pools directly instead of the network.
1302
- func (p * BlobPool ) GetBlobs (vhashes []common.Hash ) []* types.BlobTxSidecar {
1303
- sidecars := make ([]* types.BlobTxSidecar , len (vhashes ))
1304
- for idx , vhash := range vhashes {
1305
- // Retrieve the datastore item (in a short lock)
1306
- p .lock .RLock ()
1307
- id , exists := p .lookup .storeidOfBlob (vhash )
1308
- if ! exists {
1309
- p .lock .RUnlock ()
1303
+ func (p * BlobPool ) GetBlobs (vhashes []common.Hash , version byte ) ([]* kzg4844.Blob , []kzg4844.Commitment , [][]kzg4844.Proof , error ) {
1304
+ var (
1305
+ blobs = make ([]* kzg4844.Blob , len (vhashes ))
1306
+ commitments = make ([]kzg4844.Commitment , len (vhashes ))
1307
+ proofs = make ([][]kzg4844.Proof , len (vhashes ))
1308
+
1309
+ indices = make (map [common.Hash ][]int )
1310
+ filled = make (map [common.Hash ]struct {})
1311
+ )
1312
+ for i , h := range vhashes {
1313
+ indices [h ] = append (indices [h ], i )
1314
+ }
1315
+ for _ , vhash := range vhashes {
1316
+ // Skip duplicate vhash that was already resolved in a previous iteration
1317
+ if _ , ok := filled [vhash ]; ok {
1310
1318
continue
1311
1319
}
1312
- data , err := p .store .Get (id )
1320
+ // Retrieve the corresponding blob tx with the vhash
1321
+ p .lock .RLock ()
1322
+ txID , exists := p .lookup .storeidOfBlob (vhash )
1313
1323
p .lock .RUnlock ()
1314
-
1315
- // After releasing the lock, try to fill any blobs requested
1324
+ if ! exists {
1325
+ return nil , nil , nil , fmt .Errorf ("blob with vhash %x is not found" , vhash )
1326
+ }
1327
+ data , err := p .store .Get (txID )
1316
1328
if err != nil {
1317
- log .Error ("Tracked blob transaction missing from store" , "id" , id , "err" , err )
1318
- continue
1329
+ return nil , nil , nil , err
1319
1330
}
1320
- item := new (types.Transaction )
1321
- if err = rlp .DecodeBytes (data , item ); err != nil {
1322
- log .Error ("Blobs corrupted for traced transaction" , "id" , id , "err" , err )
1323
- continue
1331
+
1332
+ // Decode the blob transaction
1333
+ tx := new (types.Transaction )
1334
+ if err := rlp .DecodeBytes (data , tx ); err != nil {
1335
+ return nil , nil , nil , err
1336
+ }
1337
+ sidecar := tx .BlobTxSidecar ()
1338
+ if sidecar == nil {
1339
+ return nil , nil , nil , fmt .Errorf ("blob tx without sidecar %x" , tx .Hash ())
1340
+ }
1341
+ // Traverse the blobs in the transaction
1342
+ for i , hash := range tx .BlobHashes () {
1343
+ list , ok := indices [hash ]
1344
+ if ! ok {
1345
+ continue // non-interesting blob
1346
+ }
1347
+ var pf []kzg4844.Proof
1348
+ switch version {
1349
+ case types .BlobSidecarVersion0 :
1350
+ if sidecar .Version == types .BlobSidecarVersion0 {
1351
+ pf = []kzg4844.Proof {sidecar .Proofs [i ]}
1352
+ } else {
1353
+ proof , err := kzg4844 .ComputeBlobProof (& sidecar .Blobs [i ], sidecar .Commitments [i ])
1354
+ if err != nil {
1355
+ return nil , nil , nil , err
1356
+ }
1357
+ pf = []kzg4844.Proof {proof }
1358
+ }
1359
+ case types .BlobSidecarVersion1 :
1360
+ if sidecar .Version == types .BlobSidecarVersion0 {
1361
+ cellProofs , err := kzg4844 .ComputeCellProofs (& sidecar .Blobs [i ])
1362
+ if err != nil {
1363
+ return nil , nil , nil , err
1364
+ }
1365
+ pf = cellProofs
1366
+ } else {
1367
+ cellProofs , err := sidecar .CellProofsAt (i )
1368
+ if err != nil {
1369
+ return nil , nil , nil , err
1370
+ }
1371
+ pf = cellProofs
1372
+ }
1373
+ }
1374
+ for _ , index := range list {
1375
+ blobs [index ] = & sidecar .Blobs [i ]
1376
+ commitments [index ] = sidecar .Commitments [i ]
1377
+ proofs [index ] = pf
1378
+ }
1379
+ filled [hash ] = struct {}{}
1324
1380
}
1325
- sidecars [idx ] = item .BlobTxSidecar ()
1326
1381
}
1327
- return sidecars
1382
+ return blobs , commitments , proofs , nil
1328
1383
}
1329
1384
1330
1385
// AvailableBlobs returns the number of blobs that are available in the subpool.
0 commit comments