mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 13:46:43 +00:00
make sure the index can be reheaped when call filter method again
This commit is contained in:
parent
b369a855fb
commit
640d0079d5
1 changed files with 9 additions and 24 deletions
|
|
@ -18,6 +18,7 @@ package legacypool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/heap"
|
"container/heap"
|
||||||
|
"maps"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"slices"
|
"slices"
|
||||||
|
|
@ -113,23 +114,12 @@ func (m *SortedMap) Forward(threshold uint64) types.Transactions {
|
||||||
// If you want to do several consecutive filterings, it's therefore better to first
|
// If you want to do several consecutive filterings, it's therefore better to first
|
||||||
// do a .filter(func1) followed by .Filter(func2) or reheap()
|
// do a .filter(func1) followed by .Filter(func2) or reheap()
|
||||||
func (m *SortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions {
|
func (m *SortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions {
|
||||||
removed := m.filter(filter)
|
return m.filter(filter)
|
||||||
// If transactions were removed, the heap and cache are ruined
|
|
||||||
if len(removed) > 0 {
|
|
||||||
m.reheap()
|
|
||||||
}
|
|
||||||
return removed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SortedMap) reheap() {
|
func (m *SortedMap) reheap() {
|
||||||
*m.index = make([]uint64, 0, len(m.items))
|
*m.index = slices.Collect(maps.Keys(m.items))
|
||||||
for nonce := range m.items {
|
|
||||||
*m.index = append(*m.index, nonce)
|
|
||||||
}
|
|
||||||
heap.Init(m.index)
|
heap.Init(m.index)
|
||||||
m.cacheMu.Lock()
|
|
||||||
m.cache = nil
|
|
||||||
m.cacheMu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter is identical to Filter, but **does not** regenerate the heap. This method
|
// filter is identical to Filter, but **does not** regenerate the heap. This method
|
||||||
|
|
@ -148,6 +138,8 @@ func (m *SortedMap) filter(filter func(*types.Transaction) bool) types.Transacti
|
||||||
m.cacheMu.Lock()
|
m.cacheMu.Lock()
|
||||||
m.cache = nil
|
m.cache = nil
|
||||||
m.cacheMu.Unlock()
|
m.cacheMu.Unlock()
|
||||||
|
// If transactions were removed, the heap and cache are ruined
|
||||||
|
m.reheap()
|
||||||
}
|
}
|
||||||
return removed
|
return removed
|
||||||
}
|
}
|
||||||
|
|
@ -238,10 +230,7 @@ func (m *SortedMap) flatten() types.Transactions {
|
||||||
defer m.cacheMu.Unlock()
|
defer m.cacheMu.Unlock()
|
||||||
// If the sorting was not cached yet, create and cache it
|
// If the sorting was not cached yet, create and cache it
|
||||||
if m.cache == nil {
|
if m.cache == nil {
|
||||||
m.cache = make(types.Transactions, 0, len(m.items))
|
m.cache = slices.Collect(maps.Values(m.items))
|
||||||
for _, tx := range m.items {
|
|
||||||
m.cache = append(m.cache, tx)
|
|
||||||
}
|
|
||||||
sort.Sort(types.TxByNonce(m.cache))
|
sort.Sort(types.TxByNonce(m.cache))
|
||||||
}
|
}
|
||||||
return m.cache
|
return m.cache
|
||||||
|
|
@ -251,11 +240,8 @@ func (m *SortedMap) flatten() types.Transactions {
|
||||||
// sorted internal representation. The result of the sorting is cached in case
|
// sorted internal representation. The result of the sorting is cached in case
|
||||||
// it's requested again before any modifications are made to the contents.
|
// it's requested again before any modifications are made to the contents.
|
||||||
func (m *SortedMap) Flatten() types.Transactions {
|
func (m *SortedMap) Flatten() types.Transactions {
|
||||||
cache := m.flatten()
|
|
||||||
// Copy the cache to prevent accidental modification
|
// Copy the cache to prevent accidental modification
|
||||||
txs := make(types.Transactions, len(cache))
|
return slices.Clone(m.flatten())
|
||||||
copy(txs, cache)
|
|
||||||
return txs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LastElement returns the last element of a flattened list, thus, the
|
// LastElement returns the last element of a flattened list, thus, the
|
||||||
|
|
@ -367,11 +353,11 @@ func (l *list) Filter(costLimit *uint256.Int, gasLimit uint64) (types.Transactio
|
||||||
if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit {
|
if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
l.costcap = new(uint256.Int).Set(costLimit) // Lower the caps to the thresholds
|
l.costcap.Set(costLimit) // Lower the caps to the thresholds
|
||||||
l.gascap = gasLimit
|
l.gascap = gasLimit
|
||||||
|
|
||||||
// Filter out all the transactions above the account's funds
|
// Filter out all the transactions above the account's funds
|
||||||
removed := l.txs.Filter(func(tx *types.Transaction) bool {
|
removed := l.txs.filter(func(tx *types.Transaction) bool {
|
||||||
return tx.Gas() > gasLimit || tx.Cost().Cmp(costLimit.ToBig()) > 0
|
return tx.Gas() > gasLimit || tx.Cost().Cmp(costLimit.ToBig()) > 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -392,7 +378,6 @@ func (l *list) Filter(costLimit *uint256.Int, gasLimit uint64) (types.Transactio
|
||||||
// Reset total cost
|
// Reset total cost
|
||||||
l.subTotalCost(removed)
|
l.subTotalCost(removed)
|
||||||
l.subTotalCost(invalids)
|
l.subTotalCost(invalids)
|
||||||
l.txs.reheap()
|
|
||||||
return removed, invalids
|
return removed, invalids
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue