From 55215d780b97b7ef9a5908b8d0cdefef404b77d9 Mon Sep 17 00:00:00 2001 From: andyzhang2023 Date: Sat, 17 Aug 2024 21:48:44 +0800 Subject: [PATCH] improve price list reheap in txpool --- core/txpool/legacypool/legacypool.go | 12 ++++++++++-- core/txpool/legacypool/legacypool_test.go | 1 + core/txpool/legacypool/list.go | 6 +++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index a539253fa3..dcc4802fa2 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -840,6 +840,16 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e } // If the transaction pool is full, discard underpriced transactions if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue { + currHead := pool.currentHead.Load() + if currHead != nil && currHead.BaseFee != nil && pool.priced.NeedReheap(currHead) { + if pool.chainconfig.IsLondon(new(big.Int).Add(currHead.Number, big.NewInt(1))) { + baseFee := eip1559.CalcBaseFee(pool.chainconfig, currHead, currHead.Time+1) + pool.priced.SetBaseFee(baseFee) + } + pool.priced.Reheap() + pool.priced.currHead = currHead + } + // If the new transaction is underpriced, don't accept it if !isLocal && pool.priced.Underpriced(tx) { log.Trace("Discarding underpriced transaction", "hash", hash, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap()) @@ -1451,8 +1461,6 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest, if pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) { pendingBaseFee = eip1559.CalcBaseFee(pool.chainconfig, reset.newHead, reset.newHead.Time+1) pool.priced.SetBaseFee(pendingBaseFee) - } else { - pool.priced.Reheap() } } // Update all accounts to the latest known pending nonce diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index df25aff5e5..6b900ed2c0 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -2073,6 +2073,7 @@ func TestDualHeapEviction(t *testing.T) { add(false) for baseFee = 0; baseFee <= 1000; baseFee += 100 { pool.priced.SetBaseFee(big.NewInt(int64(baseFee))) + pool.priced.Reheap() add(true) check(highCap, "fee cap") add(false) diff --git a/core/txpool/legacypool/list.go b/core/txpool/legacypool/list.go index 5aee83bb37..6b823a4a73 100644 --- a/core/txpool/legacypool/list.go +++ b/core/txpool/legacypool/list.go @@ -549,6 +549,7 @@ func (h *priceHeap) Pop() interface{} { // better candidates for inclusion while in other cases (at the top of the baseFee peak) // the floating heap is better. When baseFee is decreasing they behave similarly. type pricedList struct { + currHead *types.Header // Current block header for effective tip calculation // Number of stale price points to (re-heap trigger). stales atomic.Int64 @@ -667,6 +668,10 @@ func (l *pricedList) Discard(slots int, force bool) (types.Transactions, bool) { return drop, true } +func (l *pricedList) NeedReheap(currHead *types.Header) bool { + return l.currHead == nil || currHead == nil || currHead.Hash().Cmp(l.currHead.Hash()) != 0 +} + // Reheap forcibly rebuilds the heap based on the current remote transaction set. func (l *pricedList) Reheap() { l.reheapMu.Lock() @@ -698,5 +703,4 @@ func (l *pricedList) Reheap() { // necessary to call right before SetBaseFee when processing a new block. func (l *pricedList) SetBaseFee(baseFee *big.Int) { l.urgent.baseFee = baseFee - l.Reheap() }