Skip to content

Commit 5ccec6f

Browse files
committed
core/txpool: refactor processing of pending transactions
core/txpool: make heads into smaller struct core/txpool miner: handle incoming txs in worker core/txpool: implement PendingHashes core/txpool: unexport types, use interface + minor tweaks core/txpool, miner: post-rebase fixup core/txpool, miner: add back handling of locals core/txpool, miner: move new types to pending.go core/txpool: testing core/txpool: make tests pass core/txpool, eth: fix up more tests core/txpool: fix pendingset empty-check core/txpool: add back sorting by time
1 parent aadcb88 commit 5ccec6f

15 files changed

+607
-518
lines changed

core/txpool/blobpool/blobpool.go

+67-24
Original file line numberDiff line numberDiff line change
@@ -1446,11 +1446,15 @@ func (p *BlobPool) drop() {
14461446
//
14471447
// The transactions can also be pre-filtered by the dynamic fee components to
14481448
// reduce allocations and load on downstream subsystems.
1449-
func (p *BlobPool) Pending(filter txpool.PendingFilter) map[common.Address][]*txpool.LazyTransaction {
1449+
func (p *BlobPool) Pending(filter txpool.PendingFilter) txpool.Pending {
14501450
// If only plain transactions are requested, this pool is unsuitable as it
14511451
// contains none, don't even bother.
14521452
if filter.OnlyPlainTxs {
1453-
return nil
1453+
return txpool.EmptyPending
1454+
}
1455+
if filter.OnlyLocals {
1456+
// There is no notion of local accounts in the blob pool.
1457+
return txpool.EmptyPending
14541458
}
14551459
// Track the amount of time waiting to retrieve the list of pending blob txs
14561460
// from the pool and the amount of time actually spent on assembling the data.
@@ -1466,19 +1470,31 @@ func (p *BlobPool) Pending(filter txpool.PendingFilter) map[common.Address][]*tx
14661470
pendtimeHist.Update(time.Since(execStart).Nanoseconds())
14671471
}()
14681472

1469-
pending := make(map[common.Address][]*txpool.LazyTransaction, len(p.index))
1473+
var (
1474+
baseFee = new(uint256.Int)
1475+
heads = make(txpool.TipList, 0, len(p.index))
1476+
tails = make(map[common.Address][]*txpool.LazyTransaction, len(p.index))
1477+
)
1478+
if filter.BaseFee != nil {
1479+
baseFee = filter.BaseFee
1480+
}
14701481
for addr, txs := range p.index {
1471-
lazies := make([]*txpool.LazyTransaction, 0, len(txs))
1472-
for _, tx := range txs {
1473-
// If transaction filtering was requested, discard badly priced ones
1474-
if filter.MinTip != nil && filter.BaseFee != nil {
1482+
var (
1483+
tail []*txpool.LazyTransaction
1484+
first = true
1485+
)
1486+
for i, tx := range txs {
1487+
var tip *uint256.Int
1488+
if filter.BaseFee != nil {
14751489
if tx.execFeeCap.Lt(filter.BaseFee) {
14761490
break // basefee too low, cannot be included, discard rest of txs from the account
14771491
}
1478-
tip := new(uint256.Int).Sub(tx.execFeeCap, filter.BaseFee)
1479-
if tip.Gt(tx.execTipCap) {
1480-
tip = tx.execTipCap
1481-
}
1492+
}
1493+
tip = new(uint256.Int).Sub(tx.execFeeCap, baseFee)
1494+
if tip.Gt(tx.execTipCap) {
1495+
tip = tx.execTipCap
1496+
}
1497+
if filter.MinTip != nil {
14821498
if tip.Lt(filter.MinTip) {
14831499
break // allowed or remaining tip too low, cannot be included, discard rest of txs from the account
14841500
}
@@ -1488,22 +1504,49 @@ func (p *BlobPool) Pending(filter txpool.PendingFilter) map[common.Address][]*tx
14881504
break // blobfee too low, cannot be included, discard rest of txs from the account
14891505
}
14901506
}
1491-
// Transaction was accepted according to the filter, append to the pending list
1492-
lazies = append(lazies, &txpool.LazyTransaction{
1493-
Pool: p,
1494-
Hash: tx.hash,
1495-
Time: execStart, // TODO(karalabe): Maybe save these and use that?
1496-
GasFeeCap: tx.execFeeCap,
1497-
GasTipCap: tx.execTipCap,
1498-
Gas: tx.execGas,
1499-
BlobGas: tx.blobGas,
1500-
})
1507+
// Transaction was accepted according to the filter, append to the pending set
1508+
lazyTx := &txpool.LazyTransaction{
1509+
Pool: p,
1510+
Hash: tx.hash,
1511+
Time: execStart,
1512+
Fees: *tip,
1513+
Gas: tx.execGas,
1514+
BlobGas: tx.blobGas,
1515+
}
1516+
if first {
1517+
first = false
1518+
tail = make([]*txpool.LazyTransaction, 0, len(txs)-i)
1519+
heads = append(heads, &txpool.TxTips{
1520+
From: addr,
1521+
Tips: lazyTx.Fees,
1522+
Time: lazyTx.Time.UnixNano(),
1523+
})
1524+
}
1525+
tail = append(tail, lazyTx)
1526+
}
1527+
if len(tail) > 0 {
1528+
tails[addr] = tail
15011529
}
1502-
if len(lazies) > 0 {
1503-
pending[addr] = lazies
1530+
}
1531+
return txpool.NewPendingSet(heads, tails)
1532+
}
1533+
1534+
// PendingHashes retrieves the hashes of all currently processable transactions.
1535+
// The returned list is grouped by origin account and sorted by nonce
1536+
func (p *BlobPool) PendingHashes(filter txpool.PendingFilter) []common.Hash {
1537+
if filter.OnlyPlainTxs || filter.OnlyLocals {
1538+
return nil
1539+
}
1540+
p.lock.RLock()
1541+
defer p.lock.RUnlock()
1542+
1543+
var hashes = make([]common.Hash, 0, len(p.index))
1544+
for _, txs := range p.index {
1545+
for _, tx := range txs {
1546+
hashes = append(hashes, tx.hash)
15041547
}
15051548
}
1506-
return pending
1549+
return hashes
15071550
}
15081551

15091552
// updateStorageMetrics retrieves a bunch of stats from the data store and pushes

core/txpool/blobpool/blobpool_test.go

+12-5
Original file line numberDiff line numberDiff line change
@@ -1356,15 +1356,22 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) {
13561356
// Benchmark assembling the pending
13571357
b.ResetTimer()
13581358
b.ReportAllocs()
1359-
1359+
var p txpool.Pending
13601360
for i := 0; i < b.N; i++ {
1361-
p := pool.Pending(txpool.PendingFilter{
1361+
p = pool.Pending(txpool.PendingFilter{
13621362
MinTip: uint256.NewInt(1),
13631363
BaseFee: chain.basefee,
13641364
BlobFee: chain.blobfee,
13651365
})
1366-
if len(p) != int(capacity) {
1367-
b.Fatalf("have %d want %d", len(p), capacity)
1368-
}
1366+
}
1367+
b.StopTimer()
1368+
1369+
count := 0
1370+
for ltx, _ := p.Peek(); ltx != nil; ltx, _ = p.Peek() {
1371+
p.Shift()
1372+
count++
1373+
}
1374+
if count != int(capacity) {
1375+
b.Fatalf("have %d want %d", count, capacity)
13691376
}
13701377
}

core/txpool/legacypool/legacypool.go

+77-35
Original file line numberDiff line numberDiff line change
@@ -522,57 +522,99 @@ func (pool *LegacyPool) ContentFrom(addr common.Address) ([]*types.Transaction,
522522
//
523523
// The transactions can also be pre-filtered by the dynamic fee components to
524524
// reduce allocations and load on downstream subsystems.
525-
func (pool *LegacyPool) Pending(filter txpool.PendingFilter) map[common.Address][]*txpool.LazyTransaction {
525+
func (pool *LegacyPool) Pending(filter txpool.PendingFilter) txpool.Pending {
526526
// If only blob transactions are requested, this pool is unsuitable as it
527527
// contains none, don't even bother.
528528
if filter.OnlyBlobTxs {
529-
return nil
529+
return txpool.EmptyPending
530530
}
531531
pool.mu.Lock()
532532
defer pool.mu.Unlock()
533533

534-
// Convert the new uint256.Int types to the old big.Int ones used by the legacy pool
535534
var (
536-
minTipBig *big.Int
537-
baseFeeBig *big.Int
535+
baseFee = new(uint256.Int)
536+
minTip = new(uint256.Int)
537+
heads = make(txpool.TipList, 0, len(pool.pending))
538+
tails = make(map[common.Address][]*txpool.LazyTransaction, len(pool.pending))
538539
)
539540
if filter.MinTip != nil {
540-
minTipBig = filter.MinTip.ToBig()
541-
}
542-
if filter.BaseFee != nil {
543-
baseFeeBig = filter.BaseFee.ToBig()
541+
minTip = filter.MinTip
544542
}
545-
pending := make(map[common.Address][]*txpool.LazyTransaction, len(pool.pending))
543+
baseFeeBig := baseFee.ToBig()
546544
for addr, list := range pool.pending {
547-
txs := list.Flatten()
548-
549-
// If the miner requests tip enforcement, cap the lists now
550-
if minTipBig != nil && !pool.locals.contains(addr) {
551-
for i, tx := range txs {
552-
if tx.EffectiveGasTipIntCmp(minTipBig, baseFeeBig) < 0 {
553-
txs = txs[:i]
554-
break
555-
}
556-
}
545+
if filter.NoLocals && pool.locals.contains(addr) {
546+
continue
557547
}
558-
if len(txs) > 0 {
559-
lazies := make([]*txpool.LazyTransaction, len(txs))
560-
for i := 0; i < len(txs); i++ {
561-
lazies[i] = &txpool.LazyTransaction{
562-
Pool: pool,
563-
Hash: txs[i].Hash(),
564-
Tx: txs[i],
565-
Time: txs[i].Time(),
566-
GasFeeCap: uint256.MustFromBig(txs[i].GasFeeCap()),
567-
GasTipCap: uint256.MustFromBig(txs[i].GasTipCap()),
568-
Gas: txs[i].Gas(),
569-
BlobGas: txs[i].BlobGas(),
570-
}
548+
if filter.OnlyLocals && !pool.locals.contains(addr) {
549+
continue
550+
}
551+
var (
552+
tail []*txpool.LazyTransaction
553+
first = true
554+
txs = list.Flatten()
555+
)
556+
for i, tx := range txs {
557+
if tx.GasFeeCapIntCmp(baseFeeBig) < 0 {
558+
break // basefee too low, cannot be included, discard rest of txs from the account
559+
}
560+
gasTipCap := uint256.MustFromBig(tx.GasTipCap())
561+
gasFeeCap := uint256.MustFromBig(tx.GasFeeCap())
562+
tip := new(uint256.Int).Sub(gasFeeCap, baseFee)
563+
if tip.Gt(gasTipCap) {
564+
tip = gasTipCap
571565
}
572-
pending[addr] = lazies
566+
if tip.Lt(minTip) {
567+
break // allowed or remaining tip too low, cannot be included, discard rest of txs from the account
568+
}
569+
lazyTx := &txpool.LazyTransaction{
570+
Pool: pool,
571+
Hash: txs[i].Hash(),
572+
Tx: txs[i],
573+
Time: txs[i].Time(),
574+
Fees: *tip,
575+
Gas: txs[i].Gas(),
576+
BlobGas: txs[i].BlobGas(),
577+
}
578+
if first {
579+
first = false
580+
tail = make([]*txpool.LazyTransaction, 0, len(txs)-i)
581+
heads = append(heads, &txpool.TxTips{
582+
From: addr,
583+
Tips: lazyTx.Fees,
584+
Time: lazyTx.Time.UnixNano(),
585+
})
586+
}
587+
tail = append(tail, lazyTx)
588+
}
589+
if len(tail) > 0 {
590+
tails[addr] = tail
591+
}
592+
}
593+
return txpool.NewPendingSet(heads, tails)
594+
}
595+
596+
// PendingHashes retrieves the hashes of all currently processable transactions.
597+
// The returned list is grouped by origin account and sorted by nonce
598+
func (pool *LegacyPool) PendingHashes(filter txpool.PendingFilter) []common.Hash {
599+
if filter.OnlyBlobTxs {
600+
return nil
601+
}
602+
pool.mu.Lock()
603+
defer pool.mu.Unlock()
604+
605+
var hashes = make([]common.Hash, 0, len(pool.pending))
606+
for addr, list := range pool.pending {
607+
if filter.NoLocals && pool.locals.contains(addr) {
608+
continue
609+
}
610+
if filter.OnlyLocals && !pool.locals.contains(addr) {
611+
continue
612+
}
613+
for _, tx := range list.Flatten() {
614+
hashes = append(hashes, tx.Hash())
573615
}
574616
}
575-
return pending
617+
return hashes
576618
}
577619

578620
// Locals retrieves the accounts currently considered local by the pool.

0 commit comments

Comments
 (0)