Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/txpool/legacypool: add overflowpool for txs #2660

Merged
merged 59 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
dfb046e
txpool: incomplete pool2 and pool3
emailtovamos Jul 16, 2024
e30248b
pool: optimise sending in reorg
emailtovamos Jul 29, 2024
f80ac01
pool: add static info and simplify transfer
emailtovamos Aug 1, 2024
8655d30
pool: remove comments, use queue not pool23
emailtovamos Aug 1, 2024
4538e92
pool: remove unused function
emailtovamos Aug 1, 2024
4369e3d
pool: refactor and bugfix
emailtovamos Aug 1, 2024
d0d6a27
pool: buffer test and size logic
emailtovamos Aug 2, 2024
5faf413
pool: add discarded ones to pool3 by default.
emailtovamos Aug 2, 2024
5bb78b3
pool: minor refactor
emailtovamos Aug 20, 2024
6b4e16b
pool: make slots config
emailtovamos Aug 21, 2024
d03f7e5
pool: initialise pool3 slots
emailtovamos Aug 21, 2024
94a60a9
pool: add underpriced to pool2 or 3
emailtovamos Aug 23, 2024
ed2d1d7
pool: enqueue in pool2 & drop properly
emailtovamos Aug 25, 2024
6daecfb
pool: bugfix:always drop drop and pool2 size
emailtovamos Aug 27, 2024
9d7298f
pool: TestDualHeapEviction passing partly
emailtovamos Aug 27, 2024
a1a25e9
pool: TestDualHeapEviction fully pass
emailtovamos Aug 27, 2024
253d9a5
pool: some cleanups
emailtovamos Aug 27, 2024
0692a99
pool: fix the TestTransactionFutureAttack test
emailtovamos Aug 28, 2024
40dcfcd
pool: cleanup debug logs
emailtovamos Aug 28, 2024
6673f3e
pool: fix TestUnderpricingDynamicFee based on new pool
emailtovamos Aug 28, 2024
ebd8f59
pool: fix all old tests
emailtovamos Aug 28, 2024
bdb4cc2
pool: lint
emailtovamos Aug 29, 2024
e45e7eb
pool: include static in flatten
emailtovamos Aug 29, 2024
069eaf2
pool: proper use of AsyncSendPooledTransactionHashes
emailtovamos Aug 29, 2024
70ece93
pool: flags for pool2 and 3 capacity
emailtovamos Aug 29, 2024
e7d0a16
pool: fix test as now by default pool2 and pool3 aren't empty
emailtovamos Aug 30, 2024
16a2a53
Merge remote-tracking branch 'origin/develop' into txpool-new
emailtovamos Sep 2, 2024
0f8a1b5
pool: test for transfer
emailtovamos Sep 3, 2024
76d157d
pool: set transfer time in config
emailtovamos Sep 3, 2024
aeec0c7
pool: remove unused criticalpathpool
emailtovamos Sep 3, 2024
53042e1
buffer: make private
emailtovamos Sep 3, 2024
8e6833c
pool: bug fix and test fix
emailtovamos Sep 3, 2024
5f398db
pool: pool2 can have 0 size
emailtovamos Sep 3, 2024
706a24e
pool: lint fix
emailtovamos Sep 4, 2024
0e61543
test: requestPromoteExecutables after every enqueue for testing
emailtovamos Sep 6, 2024
0a5dbef
pool: queued goes to 0 locally after this change
emailtovamos Sep 6, 2024
248bb6b
pool: fastcache, interface, metrics modify
emailtovamos Sep 11, 2024
cf10c5c
eth: send to some peers of pool2, not just static
emailtovamos Sep 11, 2024
b818cb7
pool: transfer on block import and simplify it
emailtovamos Sep 12, 2024
774e314
pool: truly discard underpriced, Transfer after lock is over
emailtovamos Sep 18, 2024
629af6d
pool: else ifs instead of ifs
emailtovamos Sep 18, 2024
3e3c56b
pool: address minor issues
emailtovamos Sep 19, 2024
0957562
pool: heap map as pool3
emailtovamos Sep 25, 2024
846e55b
pool: remove pool2 from legacypool
emailtovamos Sep 25, 2024
6a6e09c
pool: remove pool2 related code
emailtovamos Sep 26, 2024
355dee9
pool: edit tests and remove remaining pool2 logic
emailtovamos Sep 26, 2024
1ad40cd
pool: add back removed logic
emailtovamos Sep 26, 2024
d5b10e0
pool: remove fastcache which is no longer required
emailtovamos Sep 26, 2024
4e69ac4
pool: remove event and debug logs
emailtovamos Sep 26, 2024
31c9465
pool: remove old buffer for pool3
emailtovamos Sep 26, 2024
a8959fe
pool: minor refactors
emailtovamos Sep 26, 2024
9c72c02
pool: preallocate pool3
emailtovamos Sep 26, 2024
5d44ba9
pool: remove sequence, more sturdy, maxsize
emailtovamos Oct 1, 2024
7a929d6
pool: refactor to overflow pool
emailtovamos Oct 14, 2024
8170d99
Merge branch 'develop' into txpool-new
emailtovamos Oct 14, 2024
0e67514
pool: remove debug logs
emailtovamos Oct 14, 2024
f41bb13
pool: refactoring, addressing comments
emailtovamos Oct 15, 2024
0dd0bd7
pool: remove extra new lines
emailtovamos Oct 15, 2024
60bdc25
pool: fail fast, disable by default, no interface
emailtovamos Oct 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ var (
utils.TxPoolGlobalSlotsFlag,
utils.TxPoolAccountQueueFlag,
utils.TxPoolGlobalQueueFlag,
utils.TxPoolOverflowPoolSlotsFlag,
utils.TxPoolLifetimeFlag,
utils.TxPoolReannounceTimeFlag,
utils.BlobPoolDataDirFlag,
Expand Down
30 changes: 20 additions & 10 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,12 @@ var (
Value: ethconfig.Defaults.TxPool.GlobalQueue,
Category: flags.TxPoolCategory,
}
TxPoolOverflowPoolSlotsFlag = &cli.Uint64Flag{
Name: "txpool.overflowpoolslots",
Usage: "Maximum number of transaction slots in overflow pool",
Value: ethconfig.Defaults.TxPool.OverflowPoolSlots,
Category: flags.TxPoolCategory,
}
TxPoolLifetimeFlag = &cli.DurationFlag{
Name: "txpool.lifetime",
Usage: "Maximum amount of time non-executable transaction are queued",
Expand Down Expand Up @@ -1789,6 +1795,9 @@ func setTxPool(ctx *cli.Context, cfg *legacypool.Config) {
if ctx.IsSet(TxPoolGlobalQueueFlag.Name) {
cfg.GlobalQueue = ctx.Uint64(TxPoolGlobalQueueFlag.Name)
}
if ctx.IsSet(TxPoolOverflowPoolSlotsFlag.Name) {
cfg.OverflowPoolSlots = ctx.Uint64(TxPoolOverflowPoolSlotsFlag.Name)
}
if ctx.IsSet(TxPoolLifetimeFlag.Name) {
cfg.Lifetime = ctx.Duration(TxPoolLifetimeFlag.Name)
}
Expand Down Expand Up @@ -2310,16 +2319,17 @@ func EnableNodeInfo(poolConfig *legacypool.Config, nodeInfo *p2p.NodeInfo) Setup
return func() {
// register node info into metrics
metrics.NewRegisteredLabel("node-info", nil).Mark(map[string]interface{}{
"Enode": nodeInfo.Enode,
"ENR": nodeInfo.ENR,
"ID": nodeInfo.ID,
"PriceLimit": poolConfig.PriceLimit,
"PriceBump": poolConfig.PriceBump,
"AccountSlots": poolConfig.AccountSlots,
"GlobalSlots": poolConfig.GlobalSlots,
"AccountQueue": poolConfig.AccountQueue,
"GlobalQueue": poolConfig.GlobalQueue,
"Lifetime": poolConfig.Lifetime,
"Enode": nodeInfo.Enode,
"ENR": nodeInfo.ENR,
"ID": nodeInfo.ID,
"PriceLimit": poolConfig.PriceLimit,
"PriceBump": poolConfig.PriceBump,
"AccountSlots": poolConfig.AccountSlots,
"GlobalSlots": poolConfig.GlobalSlots,
"AccountQueue": poolConfig.AccountQueue,
"GlobalQueue": poolConfig.GlobalQueue,
"OverflowPoolSlots": poolConfig.OverflowPoolSlots,
"Lifetime": poolConfig.Lifetime,
})
}
}
Expand Down
171 changes: 171 additions & 0 deletions core/txpool/legacypool/heap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package legacypool

import (
"container/heap"
"fmt"
"sync"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)

// txHeapItem implements the Interface interface (https://pkg.go.dev/container/heap#Interface) of heap so that it can be heapified
type txHeapItem struct {
tx *types.Transaction
timestamp int64 // Unix timestamp (nanoseconds) of when the transaction was added
index int
}

type txHeap []*txHeapItem

func (h txHeap) Len() int { return len(h) }
func (h txHeap) Less(i, j int) bool {
return h[i].timestamp < h[j].timestamp
}
func (h txHeap) Swap(i, j int) {
if i < 0 || j < 0 || i >= len(h) || j >= len(h) {
return // Silently fail if indices are out of bounds
}
h[i], h[j] = h[j], h[i]
if h[i] != nil {
h[i].index = i
}
if h[j] != nil {
h[j].index = j
}
}

func (h *txHeap) Push(x interface{}) {
item, ok := x.(*txHeapItem)
if !ok {
return
}
n := len(*h)
item.index = n
*h = append(*h, item)
}

func (h *txHeap) Pop() interface{} {
old := *h
n := len(old)
if n == 0 {
return nil // Return nil if the heap is empty
}
item := old[n-1]
old[n-1] = nil // avoid memory leak
*h = old[0 : n-1]
if item != nil {
item.index = -1 // for safety
}
return item
}

type TxOverflowPoolHeap struct {
buddh0 marked this conversation as resolved.
Show resolved Hide resolved
txHeap txHeap
index map[common.Hash]*txHeapItem
mu sync.RWMutex
maxSize uint64
totalSize int
}

func NewTxOverflowPoolHeap(estimatedMaxSize uint64) *TxOverflowPoolHeap {
return &TxOverflowPoolHeap{
txHeap: make(txHeap, 0, estimatedMaxSize),
index: make(map[common.Hash]*txHeapItem, estimatedMaxSize),
maxSize: estimatedMaxSize,
}
}

func (tp *TxOverflowPoolHeap) Add(tx *types.Transaction) {
tp.mu.Lock()
defer tp.mu.Unlock()

if _, exists := tp.index[tx.Hash()]; exists {
// Transaction already in pool, ignore
return
}

if uint64(len(tp.txHeap)) >= tp.maxSize {
// Remove the oldest transaction to make space
oldestItem, ok := heap.Pop(&tp.txHeap).(*txHeapItem)
if !ok || oldestItem == nil {
return
}
delete(tp.index, oldestItem.tx.Hash())
tp.totalSize -= numSlots(oldestItem.tx)
OverflowPoolGauge.Dec(1)
}

item := &txHeapItem{
tx: tx,
timestamp: time.Now().UnixNano(),
}
heap.Push(&tp.txHeap, item)
tp.index[tx.Hash()] = item
tp.totalSize += numSlots(tx)
OverflowPoolGauge.Inc(1)
}

func (tp *TxOverflowPoolHeap) Get(hash common.Hash) (*types.Transaction, bool) {
tp.mu.RLock()
defer tp.mu.RUnlock()
if item, ok := tp.index[hash]; ok {
return item.tx, true
}
return nil, false
}

func (tp *TxOverflowPoolHeap) Remove(hash common.Hash) {
tp.mu.Lock()
defer tp.mu.Unlock()
if item, ok := tp.index[hash]; ok {
heap.Remove(&tp.txHeap, item.index)
delete(tp.index, hash)
tp.totalSize -= numSlots(item.tx)
OverflowPoolGauge.Dec(1)
}
}

func (tp *TxOverflowPoolHeap) Flush(n int) []*types.Transaction {
tp.mu.Lock()
defer tp.mu.Unlock()
if n > tp.txHeap.Len() {
n = tp.txHeap.Len()
}
txs := make([]*types.Transaction, n)
for i := 0; i < n; i++ {
item, ok := heap.Pop(&tp.txHeap).(*txHeapItem)
if !ok || item == nil {
continue
}
txs[i] = item.tx
delete(tp.index, item.tx.Hash())
tp.totalSize -= numSlots(item.tx)
}

OverflowPoolGauge.Dec(int64(n))
return txs
}

func (tp *TxOverflowPoolHeap) Len() int {
tp.mu.RLock()
defer tp.mu.RUnlock()
return tp.txHeap.Len()
}

func (tp *TxOverflowPoolHeap) Size() int {
tp.mu.RLock()
defer tp.mu.RUnlock()
return tp.totalSize
}

func (tp *TxOverflowPoolHeap) PrintTxStats() {
tp.mu.RLock()
defer tp.mu.RUnlock()
for _, item := range tp.txHeap {
tx := item.tx
fmt.Printf("Hash: %s, Timestamp: %d, GasFeeCap: %s, GasTipCap: %s\n",
tx.Hash().String(), item.timestamp, tx.GasFeeCap().String(), tx.GasTipCap().String())
}
}
Loading
Loading