| 498 | } |
| 499 | |
| 500 | void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) |
| 501 | { |
| 502 | // Remove transactions spending a coinbase which are now immature and no-longer-final transactions |
| 503 | LOCK(cs); |
| 504 | setEntries txToRemove; |
| 505 | for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { |
| 506 | const CTransaction& tx = it->GetTx(); |
| 507 | LockPoints lp = it->GetLockPoints(); |
| 508 | bool validLP = TestLockPointValidity(&lp); |
| 509 | if (!CheckFinalTx(tx, flags) || !CheckSequenceLocks(tx, flags, &lp, validLP)) { |
| 510 | // Note if CheckSequenceLocks fails the LockPoints may still be invalid |
| 511 | // So it's critical that we remove the tx and not depend on the LockPoints. |
| 512 | txToRemove.insert(it); |
| 513 | } else if (it->GetSpendsCoinbase()) { |
| 514 | for (const CTxIn& txin : tx.vin) { |
| 515 | indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); |
| 516 | if (it2 != mapTx.end()) |
| 517 | continue; |
| 518 | const Coin &coin = pcoins->AccessCoin(txin.prevout); |
| 519 | if (nCheckFrequency != 0) assert(!coin.IsSpent()); |
| 520 | if (coin.IsSpent() || (coin.IsCoinBase() && ((signed long)nMemPoolHeight) - coin.nHeight < COINBASE_MATURITY)) { |
| 521 | txToRemove.insert(it); |
| 522 | break; |
| 523 | } |
| 524 | } |
| 525 | } |
| 526 | if (!validLP) { |
| 527 | mapTx.modify(it, update_lock_points(lp)); |
| 528 | } |
| 529 | } |
| 530 | setEntries setAllRemoves; |
| 531 | for (txiter it : txToRemove) { |
| 532 | CalculateDescendants(it, setAllRemoves); |
| 533 | } |
| 534 | RemoveStaged(setAllRemoves, false, MemPoolRemovalReason::REORG); |
| 535 | } |
| 536 | |
| 537 | void CTxMemPool::removeConflicts(const CTransaction &tx) |
| 538 | { |
no test coverage detected