| 267 | } |
| 268 | |
| 269 | void CTxMemPool::removeRecursive(const CTransaction &origTx, |
| 270 | MemPoolRemovalReason reason) { |
| 271 | // Remove transaction from memory pool. |
| 272 | AssertLockHeld(cs); |
| 273 | setEntries txToRemove; |
| 274 | txiter origit = mapTx.find(origTx.GetId()); |
| 275 | if (origit != mapTx.end()) { |
| 276 | txToRemove.insert(origit); |
| 277 | } else { |
| 278 | // When recursively removing but origTx isn't in the mempool be sure to |
| 279 | // remove any children that are in the pool. This can happen during |
| 280 | // chain re-orgs if origTx isn't re-accepted into the mempool for any |
| 281 | // reason. |
| 282 | auto it = mapNextTx.lower_bound(COutPoint(origTx.GetId(), 0)); |
| 283 | while (it != mapNextTx.end() && |
| 284 | it->first->GetTxId() == origTx.GetId()) { |
| 285 | txiter nextit = mapTx.find(it->second->GetId()); |
| 286 | assert(nextit != mapTx.end()); |
| 287 | txToRemove.insert(nextit); |
| 288 | ++it; |
| 289 | } |
| 290 | } |
| 291 | |
| 292 | setEntries setAllRemoves; |
| 293 | for (txiter it : txToRemove) { |
| 294 | CalculateDescendants(it, setAllRemoves); |
| 295 | } |
| 296 | |
| 297 | RemoveStaged(setAllRemoves, reason); |
| 298 | } |
| 299 | |
| 300 | void CTxMemPool::removeConflicts(const CTransaction &tx) { |
| 301 | // Remove transactions which depend on inputs of tx, recursively |