mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
core/txpool, eth: remove GetCells
This commit is contained in:
parent
6bbcbe6a65
commit
b2c50675ca
7 changed files with 121 additions and 77 deletions
|
|
@ -1671,6 +1671,17 @@ func (p *BlobPool) GetBlobs(vhashes []common.Hash, version byte) ([]*kzg4844.Blo
|
|||
return blobs, commitments, proofs, nil
|
||||
}
|
||||
|
||||
// GetBlobHashes returns the blob versioned hashes for a given transaction hash.
|
||||
func (p *BlobPool) GetBlobHashes(txHash common.Hash) []common.Hash {
|
||||
p.lock.RLock()
|
||||
defer p.lock.RUnlock()
|
||||
vhashes, ok := p.lookup.blobHashesOfTx(txHash)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return vhashes
|
||||
}
|
||||
|
||||
// GetBlobCells returns cells for the given versioned blob hashes,
|
||||
// filtered by the requested cell indices(mask).
|
||||
// Each entry in the result corresponds to one vhash. Nil entries mean the blob
|
||||
|
|
@ -2436,38 +2447,3 @@ func (p *BlobPool) GetCustody(hash common.Hash) *types.CustodyBitmap {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCells returns the cells matching the given custody bitmap for a transaction.
|
||||
func (p *BlobPool) GetCells(hash common.Hash, mask types.CustodyBitmap) ([]kzg4844.Cell, error) {
|
||||
p.lock.RLock()
|
||||
defer p.lock.RUnlock()
|
||||
id, ok := p.lookup.storeidOfTx(hash)
|
||||
if !ok {
|
||||
return nil, errors.New("requested cells don't exist")
|
||||
}
|
||||
data, err := p.store.Get(id)
|
||||
if err != nil {
|
||||
return nil, errors.New("tracked blob transaction missing from store")
|
||||
}
|
||||
// Decode the blob transaction
|
||||
var pooledTx PooledBlobTx
|
||||
if err := rlp.DecodeBytes(data, &pooledTx); err != nil {
|
||||
return nil, errors.New("blobs corrupted for traced transaction")
|
||||
}
|
||||
tx := pooledTx.Transaction
|
||||
sidecar := pooledTx.Sidecar
|
||||
// Return cells in blob-major order: [blob0_cell0, blob0_cell1, ..., blob1_cell0, ...]
|
||||
cellsPerBlob := sidecar.Custody.OneCount()
|
||||
cells := make([]kzg4844.Cell, 0, mask.OneCount()*len(tx.BlobHashes()))
|
||||
for blobIdx := 0; blobIdx < len(tx.BlobHashes()); blobIdx++ {
|
||||
for cellIdx, custodyIdx := range sidecar.Custody.Indices() {
|
||||
if mask.IsSet(custodyIdx) {
|
||||
cells = append(cells, sidecar.Cells[blobIdx*cellsPerBlob+cellIdx])
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(cells) != mask.OneCount()*len(tx.BlobHashes()) {
|
||||
return nil, fmt.Errorf("not enough cells: tx %s, needed %d, have %d", tx.Hash(), len(tx.BlobHashes())*mask.OneCount(), len(cells))
|
||||
}
|
||||
return cells, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2227,33 +2227,32 @@ func TestGetCells(t *testing.T) {
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cells, err := pool.GetCells(tt.hash, tt.mask)
|
||||
|
||||
if err != nil && !tt.shouldFail {
|
||||
t.Errorf("expected to success, got %v", err)
|
||||
vhashes := pool.GetBlobHashes(tt.hash)
|
||||
if tt.shouldFail {
|
||||
if vhashes != nil {
|
||||
t.Errorf("expected nil vhashes for non-existent tx")
|
||||
}
|
||||
return
|
||||
}
|
||||
if err == nil && tt.shouldFail {
|
||||
t.Errorf("expected to fail, got %v", err)
|
||||
if vhashes == nil {
|
||||
t.Fatalf("expected vhashes, got nil")
|
||||
}
|
||||
|
||||
if len(cells) != tt.expectedLen {
|
||||
t.Errorf("expected %d cells, got %d", tt.expectedLen, len(cells))
|
||||
blobCells, _, err := pool.GetBlobCells(vhashes, tt.mask)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if tt.expectedLen > 0 && tt.expectedLen%3 == 0 {
|
||||
blobCount := 3
|
||||
cellsPerBlob := tt.expectedLen / blobCount
|
||||
|
||||
for blobIdx := 0; blobIdx < blobCount; blobIdx++ {
|
||||
startIdx := blobIdx * cellsPerBlob
|
||||
endIdx := startIdx + cellsPerBlob
|
||||
|
||||
if endIdx > len(cells) {
|
||||
t.Errorf("blob %d: expected cells up to index %d, but only have %d cells",
|
||||
blobIdx, endIdx-1, len(cells))
|
||||
// Count total non-nil cells across all blobs
|
||||
totalCells := 0
|
||||
for _, bc := range blobCells {
|
||||
for _, c := range bc {
|
||||
if c != nil {
|
||||
totalCells++
|
||||
}
|
||||
}
|
||||
}
|
||||
if totalCells != tt.expectedLen {
|
||||
t.Errorf("expected %d cells, got %d", tt.expectedLen, totalCells)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ type txMetadata struct {
|
|||
size uint64 // the RLP encoded size of transaction (blobs are included)
|
||||
sizeWithoutBlob uint64 // the RLP encoded size without blob data (for ETH/72 announcements)
|
||||
custody types.CustodyBitmap
|
||||
vhashes []common.Hash // blob versioned hashes for the transaction
|
||||
}
|
||||
|
||||
// lookup maps blob versioned hashes to transaction hashes that include them,
|
||||
|
|
@ -59,6 +60,15 @@ func (l *lookup) storeidOfTx(txhash common.Hash) (uint64, bool) {
|
|||
return meta.id, true
|
||||
}
|
||||
|
||||
// blobHashesOfTx returns the blob versioned hashes for a transaction.
|
||||
func (l *lookup) blobHashesOfTx(txhash common.Hash) ([]common.Hash, bool) {
|
||||
meta, ok := l.txIndex[txhash]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return meta.vhashes, true
|
||||
}
|
||||
|
||||
// storeidOfBlob returns the datastore storage item id of a blob.
|
||||
func (l *lookup) storeidOfBlob(vhash common.Hash) (uint64, bool) {
|
||||
// If the blob is unknown, return a miss
|
||||
|
|
@ -98,6 +108,7 @@ func (l *lookup) track(tx *blobTxMeta) {
|
|||
size: tx.size,
|
||||
sizeWithoutBlob: tx.sizeWithoutBlob,
|
||||
custody: *tx.custody,
|
||||
vhashes: tx.vhashes,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@ type txPool interface {
|
|||
// support cell-based blob data availability.
|
||||
type blobPool interface {
|
||||
Has(hash common.Hash) bool
|
||||
GetCells(hash common.Hash, mask types.CustodyBitmap) ([]kzg4844.Cell, error)
|
||||
GetBlobHashes(hash common.Hash) []common.Hash
|
||||
GetBlobCells(vhashes []common.Hash, mask types.CustodyBitmap) ([][]*kzg4844.Cell, [][]*kzg4844.Proof, error)
|
||||
HasPayload(hash common.Hash) bool
|
||||
GetCustody(hash common.Hash) *types.CustodyBitmap
|
||||
AddPooledTx(pooledTx *blobpool.PooledBlobTx) error
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package eth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"maps"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
|
|
@ -181,28 +180,59 @@ func (p *testTxPool) Pending(filter txpool.PendingFilter) (map[common.Address][]
|
|||
func (p *testTxPool) SubscribeTransactions(ch chan<- core.NewTxsEvent, reorgs bool) event.Subscription {
|
||||
return p.txFeed.Subscribe(ch)
|
||||
}
|
||||
func (p *testTxPool) GetCells(hash common.Hash, mask types.CustodyBitmap) ([]kzg4844.Cell, error) {
|
||||
func (p *testTxPool) GetBlobHashes(hash common.Hash) []common.Hash {
|
||||
p.lock.RLock()
|
||||
defer p.lock.RUnlock()
|
||||
|
||||
_, exists := p.txPool[hash]
|
||||
tx, exists := p.txPool[hash]
|
||||
if !exists {
|
||||
return nil, errors.New("Requested tx does not exist")
|
||||
return nil
|
||||
}
|
||||
return tx.BlobHashes()
|
||||
}
|
||||
|
||||
var cells []kzg4844.Cell
|
||||
func (p *testTxPool) GetBlobCells(vhashes []common.Hash, mask types.CustodyBitmap) ([][]*kzg4844.Cell, [][]*kzg4844.Proof, error) {
|
||||
p.lock.RLock()
|
||||
defer p.lock.RUnlock()
|
||||
|
||||
if cells, exists = p.cellPool[hash]; !exists {
|
||||
return nil, errors.New("Requested cells do not exist")
|
||||
}
|
||||
requestedIndices := mask.Indices()
|
||||
cells := make([][]*kzg4844.Cell, len(vhashes))
|
||||
proofs := make([][]*kzg4844.Proof, len(vhashes))
|
||||
|
||||
result := make([]kzg4844.Cell, 0, mask.OneCount())
|
||||
for _, idx := range mask.Indices() {
|
||||
if int(idx) < len(cells) {
|
||||
result = append(result, cells[idx])
|
||||
for i, vhash := range vhashes {
|
||||
// Find the tx containing this versioned hash
|
||||
var foundTx *types.Transaction
|
||||
var blobIdx int
|
||||
for _, tx := range p.txPool {
|
||||
for j, bh := range tx.BlobHashes() {
|
||||
if bh == vhash {
|
||||
foundTx = tx
|
||||
blobIdx = j
|
||||
break
|
||||
}
|
||||
}
|
||||
if foundTx != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if foundTx == nil {
|
||||
continue
|
||||
}
|
||||
txCells, ok := p.cellPool[foundTx.Hash()]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
_ = blobIdx // cells in the mock are stored flat by cell index
|
||||
blobCells := make([]*kzg4844.Cell, len(requestedIndices))
|
||||
for j, idx := range requestedIndices {
|
||||
if int(idx) < len(txCells) {
|
||||
cell := txCells[idx]
|
||||
blobCells[j] = &cell
|
||||
}
|
||||
}
|
||||
cells[i] = blobCells
|
||||
}
|
||||
return result, nil
|
||||
return cells, proofs, nil
|
||||
}
|
||||
|
||||
func (p *testTxPool) GetCustody(hash common.Hash) *types.CustodyBitmap {
|
||||
|
|
|
|||
|
|
@ -89,8 +89,10 @@ type Backend interface {
|
|||
|
||||
// BlobPool defines the methods needed by the protocol handler to serve cell requests.
|
||||
type BlobPool interface {
|
||||
// GetCells retrieves cells for a given transaction hash filtered by the custody bitmap.
|
||||
GetCells(hash common.Hash, mask types.CustodyBitmap) ([]kzg4844.Cell, error)
|
||||
// GetBlobHashes returns the blob versioned hashes for a given transaction hash.
|
||||
GetBlobHashes(hash common.Hash) []common.Hash
|
||||
// GetBlobCells retrieves cells and proofs for given versioned blob hashes filtered by the custody bitmap.
|
||||
GetBlobCells(vhashes []common.Hash, mask types.CustodyBitmap) ([][]*kzg4844.Cell, [][]*kzg4844.Proof, error)
|
||||
// GetCustody returns the custody bitmap for a given transaction hash.
|
||||
GetCustody(hash common.Hash) *types.CustodyBitmap
|
||||
// Has returns whether the blob pool contains a transaction with the given hash.
|
||||
|
|
|
|||
|
|
@ -623,14 +623,39 @@ func answerGetCells(backend Backend, query GetCellsRequest) ([]common.Hash, [][]
|
|||
if cellCounts >= maxCells {
|
||||
break
|
||||
}
|
||||
cell, _ := backend.BlobPool().GetCells(hash, query.Mask)
|
||||
if len(cell) == 0 {
|
||||
// skip this tx
|
||||
// Look up the blob versioned hashes for this transaction
|
||||
vhashes := backend.BlobPool().GetBlobHashes(hash)
|
||||
if len(vhashes) == 0 {
|
||||
continue
|
||||
}
|
||||
blobCells, _, _ := backend.BlobPool().GetBlobCells(vhashes, query.Mask)
|
||||
|
||||
// Flatten per-blob cells into a single slice. If any blob has a nil
|
||||
// entry (unavailable cell), skip the entire transaction.
|
||||
var flat []kzg4844.Cell
|
||||
skip := false
|
||||
for _, bc := range blobCells {
|
||||
if bc == nil {
|
||||
skip = true
|
||||
break
|
||||
}
|
||||
for _, c := range bc {
|
||||
if c == nil {
|
||||
skip = true
|
||||
break
|
||||
}
|
||||
flat = append(flat, *c)
|
||||
}
|
||||
if skip {
|
||||
break
|
||||
}
|
||||
}
|
||||
if skip || len(flat) == 0 {
|
||||
continue
|
||||
}
|
||||
hashes = append(hashes, hash)
|
||||
cells = append(cells, cell)
|
||||
cellCounts += len(cell)
|
||||
cells = append(cells, flat)
|
||||
cellCounts += len(flat)
|
||||
}
|
||||
return hashes, cells, query.Mask
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue