mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
clear address reservations inside subpools, with explanation for why it's not done at the TxPool level.
This commit is contained in:
parent
5842b1db62
commit
8d241f0475
2 changed files with 39 additions and 0 deletions
|
|
@ -1729,6 +1729,23 @@ func (p *BlobPool) Clear() {
|
|||
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.index = make(map[common.Address][]*blobTxMeta)
|
||||
p.spent = make(map[common.Address]*uint256.Int)
|
||||
|
|
|
|||
|
|
@ -1968,6 +1968,28 @@ func (p *LegacyPool) Clear() {
|
|||
p.mu.Lock()
|
||||
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.priced = newPricedList(p.all)
|
||||
p.pending = make(map[common.Address]*list)
|
||||
|
|
|
|||
Loading…
Reference in a new issue