@@ -25,7 +25,6 @@ import (
2525 "math/big"
2626 "os"
2727 "path/filepath"
28- "slices"
2928 "sort"
3029 "sync"
3130 "time"
@@ -37,6 +36,7 @@ import (
3736 "github.com/ethereum/go-ethereum/core/state"
3837 "github.com/ethereum/go-ethereum/core/txpool"
3938 "github.com/ethereum/go-ethereum/core/types"
39+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
4040 "github.com/ethereum/go-ethereum/event"
4141 "github.com/ethereum/go-ethereum/log"
4242 "github.com/ethereum/go-ethereum/metrics"
@@ -1300,46 +1300,86 @@ func (p *BlobPool) GetMetadata(hash common.Hash) *txpool.TxMetadata {
13001300// GetBlobs returns a number of blobs and proofs for the given versioned hashes.
13011301// This is a utility method for the engine API, enabling consensus clients to
13021302// retrieve blobs from the pools directly instead of the network.
1303- func (p * BlobPool ) GetBlobs (vhashes []common.Hash ) []* types.BlobTxSidecar {
1304- sidecars := make ([]* types.BlobTxSidecar , len (vhashes ))
1305- for idx , vhash := range vhashes {
1306- if sidecars [idx ] != nil {
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 {
13071318 continue
13081319 }
1309- // Retrieve the datastore item (in a short lock)
1320+ // Retrieve the corresponding blob tx with the vhash
13101321 p .lock .RLock ()
1311- id , exists := p .lookup .storeidOfBlob (vhash )
1322+ txID , exists := p .lookup .storeidOfBlob (vhash )
1323+ p .lock .RUnlock ()
13121324 if ! exists {
1313- p .lock .RUnlock ()
1314- continue
1325+ return nil , nil , nil , fmt .Errorf ("blob with vhash %x is not found" , vhash )
13151326 }
1316- data , err := p .store .Get (id )
1317- p .lock .RUnlock ()
1318-
1319- // After releasing the lock, try to fill any blobs requested
1327+ data , err := p .store .Get (txID )
13201328 if err != nil {
1321- log .Error ("Tracked blob transaction missing from store" , "id" , id , "err" , err )
1322- continue
1329+ return nil , nil , nil , err
13231330 }
1324- item := new (types.Transaction )
1325- if err = rlp .DecodeBytes (data , item ); err != nil {
1326- log .Error ("Blobs corrupted for traced transaction" , "id" , id , "err" , err )
1327- continue
1328- }
1329- sidecars [idx ] = item .BlobTxSidecar ()
13301331
1331- // If multi blobs in the same transaction, fill the other sidecars.
1332- hashes := item .BlobHashes ()
1333- for i , vHash := range vhashes {
1334- if sidecars [i ] != nil {
1335- continue
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+ }
13361373 }
1337- if slices .Index (hashes , vHash ) != - 1 {
1338- sidecars [i ] = item .BlobTxSidecar ()
1374+ for _ , index := range list {
1375+ blobs [index ] = & sidecar .Blobs [i ]
1376+ commitments [index ] = sidecar .Commitments [i ]
1377+ proofs [index ] = pf
13391378 }
1379+ filled [hash ] = struct {}{}
13401380 }
13411381 }
1342- return sidecars
1382+ return blobs , commitments , proofs , nil
13431383}
13441384
13451385// AvailableBlobs returns the number of blobs that are available in the subpool.
0 commit comments