mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
fix: Check L1DataFee in txpool promoteExecutables and demoteUnexecutables (#948)
fix: Check L1DataFee in txpool promoteExecutables and demoteUnexecutables (#627) * Check L1DataFee in txpool promoteExecutables * bump version * implement L1 data fee in demoteUnexecutables as well * Update core/tx_list.go * Update core/tx_pool.go * feat: consider l1 data fee in txpool costcap (#681) * feat(txpool): consider l1 data fee in costcap * fix CI * simplify logic * remove one db read op * bump version --------- Co-authored-by: vyzo <vyzo@hackzen.org> Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com> Co-authored-by: Péter Garamvölgyi <peter@scroll.io> Co-authored-by: georgehao <haohongfan@gmail.com>
This commit is contained in:
parent
15e380d0dd
commit
58ed1a2a3b
2 changed files with 56 additions and 2 deletions
|
|
@ -1500,8 +1500,10 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
|
|||
pool.all.Remove(hash)
|
||||
}
|
||||
log.Trace("Removed old queued transactions", "count", len(forwards))
|
||||
|
||||
// Drop all transactions that are too costly (low balance or out of gas)
|
||||
drops, _ := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
|
||||
costLimit := pool.currentState.GetBalance(addr)
|
||||
drops, _ := list.FilterF(costLimit, gasLimit, pool.executableTxFilter(costLimit, gasLimit))
|
||||
for _, tx := range drops {
|
||||
hash := tx.Hash()
|
||||
pool.all.Remove(hash)
|
||||
|
|
@ -1549,6 +1551,26 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
|
|||
return promoted
|
||||
}
|
||||
|
||||
func (pool *LegacyPool) executableTxFilter(costLimit *big.Int, gasLimit uint64) func(tx *types.Transaction) bool {
|
||||
return func(tx *types.Transaction) bool {
|
||||
if tx.Gas() > gasLimit || tx.Cost().Cmp(costLimit) > 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
if pool.chainconfig.Scroll.FeeVaultEnabled() {
|
||||
// recheck L1 data fee, as the oracle price may have changed
|
||||
l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState, pool.chainconfig, pool.currentHead.Load().Number)
|
||||
if err != nil {
|
||||
log.Error("Failed to calculate L1 data fee", "err", err, "tx", tx)
|
||||
return false
|
||||
}
|
||||
return costLimit.Cmp(new(big.Int).Add(tx.Cost(), l1DataFee)) < 0
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// truncatePending removes transactions from the pending queue if the pool is above the
|
||||
// pending limit. The algorithm tries to reduce transaction counts by an approximately
|
||||
// equal number for all for accounts with many pending transactions.
|
||||
|
|
@ -1702,7 +1724,8 @@ func (pool *LegacyPool) demoteUnexecutables() {
|
|||
log.Trace("Removed old pending transaction", "hash", hash)
|
||||
}
|
||||
// Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later
|
||||
drops, invalids := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
|
||||
costLimit := pool.currentState.GetBalance(addr)
|
||||
drops, invalids := list.FilterF(costLimit, gasLimit, pool.executableTxFilter(costLimit, gasLimit))
|
||||
for _, tx := range drops {
|
||||
hash := tx.Hash()
|
||||
log.Trace("Removed unpayable pending transaction", "hash", hash)
|
||||
|
|
|
|||
|
|
@ -404,6 +404,37 @@ func (l *list) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions,
|
|||
return removed, invalids
|
||||
}
|
||||
|
||||
// FilterF removes all transactions from the list that satisfy a predicate.
|
||||
// Every removed transaction is returned for any post-removal maintenance.
|
||||
// Strict-mode invalidated transactions are also returned.
|
||||
func (l *list) FilterF(costLimit *big.Int, gasLimit uint64, f func(tx *types.Transaction) bool) (types.Transactions, types.Transactions) {
|
||||
// If all transactions are below the threshold, short circuit
|
||||
if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit {
|
||||
return nil, nil
|
||||
}
|
||||
l.costcap = new(big.Int).Set(costLimit) // Lower the caps to the thresholds
|
||||
l.gascap = gasLimit
|
||||
|
||||
removed := l.txs.Filter(f)
|
||||
|
||||
if len(removed) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var invalids types.Transactions
|
||||
// If the list was strict, filter anything above the lowest nonce
|
||||
if l.strict {
|
||||
lowest := uint64(math.MaxUint64)
|
||||
for _, tx := range removed {
|
||||
if nonce := tx.Nonce(); lowest > nonce {
|
||||
lowest = nonce
|
||||
}
|
||||
}
|
||||
invalids = l.txs.filter(func(tx *types.Transaction) bool { return tx.Nonce() > lowest })
|
||||
}
|
||||
l.txs.reheap()
|
||||
return removed, invalids
|
||||
}
|
||||
|
||||
// Cap places a hard limit on the number of items, returning all transactions
|
||||
// exceeding that limit.
|
||||
func (l *list) Cap(threshold int) types.Transactions {
|
||||
|
|
|
|||
Loading…
Reference in a new issue