Skip to content

Commit eb11ebb

Browse files
committed
core/txpool/blobpool: improve GetBlobs
1 parent 80a763e commit eb11ebb

File tree

3 files changed

+296
-129
lines changed

3 files changed

+296
-129
lines changed

core/txpool/blobpool/blobpool.go

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)