clear address reservations inside subpools, with explanation for why it's not done at the TxPool level.

pull/30534/head
Jared Wasinger 1 month ago
parent 3665ebeecd
commit a67a0b4756
  1. 17
      core/txpool/blobpool/blobpool.go
  2. 22
      core/txpool/legacypool/legacypool.go

@ -1669,6 +1669,23 @@ func (p *BlobPool) Clear() {
log.Warn("failed to delete blob tx from backing store", "err", err) log.Warn("failed to delete blob tx from backing store", "err", err)
} }
} }
// unreserve each tracked account. Ideally, we could just clear the
// reservation map in the parent txpool context. However, if we clear in
// parent context, to avoid exposing the subpool lock, we have to lock the
// reservations and then lock each subpool.
//
// This creates the potential for a deadlock situation:
//
// * TxPool.Clear locks the reservations
// * a new transaction is received which locks the subpool mutex
// * TxPool.Clear attempts to lock subpool mutex
//
// The transaction addition may attempt to reserve the sender addr which
// can't happen until Clear releases the reservation lock. Clear cannot
// acquire the subpool lock until the transaction addition is completed.
for acct, _ := range p.index {
p.reserve(acct, false)
}
p.lookup = make(map[common.Hash]uint64) p.lookup = make(map[common.Hash]uint64)
p.index = make(map[common.Address][]*blobTxMeta) p.index = make(map[common.Address][]*blobTxMeta)
p.spent = make(map[common.Address]*uint256.Int) p.spent = make(map[common.Address]*uint256.Int)

@ -1961,6 +1961,28 @@ func (p *LegacyPool) Clear() {
p.mu.Lock() p.mu.Lock()
defer p.mu.Unlock() defer p.mu.Unlock()
// unreserve each tracked account. Ideally, we could just clear the
// reservation map in the parent txpool context. However, if we clear in
// parent context, to avoid exposing the subpool lock, we have to lock the
// reservations and then lock each subpool.
//
// This creates the potential for a deadlock situation:
//
// * TxPool.Clear locks the reservations
// * a new transaction is received which locks the subpool mutex
// * TxPool.Clear attempts to lock subpool mutex
//
// The transaction addition may attempt to reserve the sender addr which
// can't happen until Clear releases the reservation lock. Clear cannot
// acquire the subpool lock until the transaction addition is completed.
for _, tx := range p.all.remotes {
senderAddr, _ := types.Sender(p.signer, tx)
p.reserve(senderAddr, false)
}
for localSender, _ := range p.locals.accounts {
p.reserve(localSender, false)
}
p.all = newLookup() p.all = newLookup()
p.priced = newPricedList(p.all) p.priced = newPricedList(p.all)
p.pending = make(map[common.Address]*list) p.pending = make(map[common.Address]*list)

Loading…
Cancel
Save