-
Notifications
You must be signed in to change notification settings - Fork 20.9k
miner, core/txpool: refactor processing of pending
transactions
#29025
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
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -522,57 +522,95 @@ func (pool *LegacyPool) ContentFrom(addr common.Address) ([]*types.Transaction, | |
// | ||
// The transactions can also be pre-filtered by the dynamic fee components to | ||
// reduce allocations and load on downstream subsystems. | ||
func (pool *LegacyPool) Pending(filter txpool.PendingFilter) map[common.Address][]*txpool.LazyTransaction { | ||
func (pool *LegacyPool) Pending(filter txpool.PendingFilter) txpool.Pending { | ||
// If only blob transactions are requested, this pool is unsuitable as it | ||
// contains none, don't even bother. | ||
if filter.OnlyBlobTxs { | ||
return nil | ||
return txpool.EmptyPending | ||
} | ||
pool.mu.Lock() | ||
defer pool.mu.Unlock() | ||
|
||
// Convert the new uint256.Int types to the old big.Int ones used by the legacy pool | ||
var ( | ||
minTipBig *big.Int | ||
baseFeeBig *big.Int | ||
baseFee = new(uint256.Int) | ||
minTip = new(uint256.Int) | ||
heads = make(txpool.TipList, 0, len(pool.pending)) | ||
tails = make(map[common.Address][]*txpool.LazyTransaction, len(pool.pending)) | ||
) | ||
if filter.MinTip != nil { | ||
minTipBig = filter.MinTip.ToBig() | ||
} | ||
if filter.BaseFee != nil { | ||
baseFeeBig = filter.BaseFee.ToBig() | ||
minTip = filter.MinTip | ||
} | ||
pending := make(map[common.Address][]*txpool.LazyTransaction, len(pool.pending)) | ||
baseFeeBig := baseFee.ToBig() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like you dropped the |
||
for addr, list := range pool.pending { | ||
txs := list.Flatten() | ||
|
||
// If the miner requests tip enforcement, cap the lists now | ||
if minTipBig != nil && !pool.locals.contains(addr) { | ||
for i, tx := range txs { | ||
if tx.EffectiveGasTipIntCmp(minTipBig, baseFeeBig) < 0 { | ||
txs = txs[:i] | ||
break | ||
} | ||
} | ||
if filter.NoLocals && pool.locals.contains(addr) { | ||
continue | ||
} | ||
if len(txs) > 0 { | ||
lazies := make([]*txpool.LazyTransaction, len(txs)) | ||
for i := 0; i < len(txs); i++ { | ||
lazies[i] = &txpool.LazyTransaction{ | ||
Pool: pool, | ||
Hash: txs[i].Hash(), | ||
Tx: txs[i], | ||
Time: txs[i].Time(), | ||
GasFeeCap: uint256.MustFromBig(txs[i].GasFeeCap()), | ||
GasTipCap: uint256.MustFromBig(txs[i].GasTipCap()), | ||
Gas: txs[i].Gas(), | ||
BlobGas: txs[i].BlobGas(), | ||
} | ||
if filter.OnlyLocals && !pool.locals.contains(addr) { | ||
continue | ||
} | ||
var ( | ||
tail []*txpool.LazyTransaction | ||
txs = list.Flatten() | ||
) | ||
for i, tx := range txs { | ||
if tx.GasFeeCapIntCmp(baseFeeBig) < 0 { | ||
break // basefee too low, cannot be included, discard rest of txs from the account | ||
} | ||
gasTipCap := uint256.MustFromBig(tx.GasTipCap()) | ||
gasFeeCap := uint256.MustFromBig(tx.GasFeeCap()) | ||
tip := new(uint256.Int).Sub(gasFeeCap, baseFee) | ||
if tip.Gt(gasTipCap) { | ||
tip = gasTipCap | ||
} | ||
if tip.Lt(minTip) { | ||
break // allowed or remaining tip too low, cannot be included, discard rest of txs from the account | ||
} | ||
lazyTx := &txpool.LazyTransaction{ | ||
Pool: pool, | ||
Hash: txs[i].Hash(), | ||
Tx: txs[i], | ||
Time: txs[i].Time(), | ||
Fees: *tip, | ||
Gas: txs[i].Gas(), | ||
BlobGas: txs[i].BlobGas(), | ||
} | ||
if len(tail) == 0 { | ||
tail = make([]*txpool.LazyTransaction, 0, len(txs)-i) | ||
heads = append(heads, &txpool.TxTips{ | ||
From: addr, | ||
Tips: lazyTx.Fees, | ||
Time: lazyTx.Time.UnixNano(), | ||
}) | ||
} | ||
pending[addr] = lazies | ||
tail = append(tail, lazyTx) | ||
} | ||
if len(tail) > 0 { | ||
tails[addr] = tail | ||
} | ||
} | ||
return txpool.NewPendingSet(heads, tails) | ||
} | ||
|
||
// PendingHashes retrieves the hashes of all currently processable transactions. | ||
// The returned list is grouped by origin account and sorted by nonce | ||
func (pool *LegacyPool) PendingHashes(filter txpool.PendingFilter) []common.Hash { | ||
holiman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if filter.OnlyBlobTxs { | ||
return nil | ||
} | ||
pool.mu.Lock() | ||
defer pool.mu.Unlock() | ||
|
||
var hashes = make([]common.Hash, 0, len(pool.pending)) | ||
for addr, list := range pool.pending { | ||
if filter.NoLocals && pool.locals.contains(addr) { | ||
continue | ||
} | ||
if filter.OnlyLocals && !pool.locals.contains(addr) { | ||
continue | ||
} | ||
hashes = list.AppendHashes(hashes) | ||
} | ||
return pending | ||
return hashes | ||
} | ||
|
||
// Locals retrieves the accounts currently considered local by the pool. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -258,6 +258,25 @@ func (m *sortedMap) Flatten() types.Transactions { | |
return txs | ||
} | ||
|
||
// AppendHashes uses the flattened slice of transactions and appends the hashes | ||
// to the destination slice. | ||
func (m *sortedMap) AppendHashes(dst []common.Hash) []common.Hash { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added this function. It serves as backend for |
||
m.cacheMu.Lock() | ||
defer m.cacheMu.Unlock() | ||
// If the sorting was not cached yet, create and cache it | ||
if m.cache == nil { | ||
m.cache = make(types.Transactions, 0, len(m.items)) | ||
for _, tx := range m.items { | ||
m.cache = append(m.cache, tx) | ||
} | ||
sort.Sort(types.TxByNonce(m.cache)) | ||
} | ||
for _, tx := range m.items { | ||
dst = append(dst, tx.Hash()) | ||
} | ||
return dst | ||
} | ||
|
||
// LastElement returns the last element of a flattened list, thus, the | ||
// transaction with the highest nonce | ||
func (m *sortedMap) LastElement() *types.Transaction { | ||
|
@@ -453,6 +472,12 @@ func (l *list) Flatten() types.Transactions { | |
return l.txs.Flatten() | ||
} | ||
|
||
// AppendHashes flattens a nonce-sorted slice of transcations, and appends | ||
// the hashes to dst. The destination slice might be reallocated, and is returned. | ||
func (l *list) AppendHashes(dst []common.Hash) []common.Hash { | ||
return l.txs.AppendHashes(dst) | ||
} | ||
|
||
// LastElement returns the last element of a flattened list, thus, the | ||
// transaction with the highest nonce | ||
func (l *list) LastElement() *types.Transaction { | ||
|
Uh oh!
There was an error while loading. Please reload this page.