| 526 | } |
| 527 | |
| 528 | void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) |
| 529 | { |
| 530 | // Remove transactions spending a coinbase which are now immature and no-longer-final transactions |
| 531 | LOCK(cs); |
| 532 | list<CTransaction> transactionsToRemove; |
| 533 | for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { |
| 534 | const CTransaction& tx = it->GetTx(); |
| 535 | LockPoints lp = it->GetLockPoints(); |
| 536 | bool validLP = TestLockPointValidity(&lp); |
| 537 | if (!CheckFinalTx(tx, flags) || !CheckSequenceLocks(tx, flags, &lp, validLP)) { |
| 538 | // Note if CheckSequenceLocks fails the LockPoints may still be invalid |
| 539 | // So it's critical that we remove the tx and not depend on the LockPoints. |
| 540 | transactionsToRemove.push_back(tx); |
| 541 | } else if (it->GetSpendsCoinbase()) { |
| 542 | BOOST_FOREACH(const CTxIn& txin, tx.vin) { |
| 543 | indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); |
| 544 | if (it2 != mapTx.end()) |
| 545 | continue; |
| 546 | const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); |
| 547 | if (nCheckFrequency != 0) assert(coins); |
| 548 | if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { |
| 549 | transactionsToRemove.push_back(tx); |
| 550 | break; |
| 551 | } |
| 552 | } |
| 553 | } |
| 554 | if (!validLP) { |
| 555 | mapTx.modify(it, update_lock_points(lp)); |
| 556 | } |
| 557 | } |
| 558 | BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) { |
| 559 | list<CTransaction> removed; |
| 560 | removeRecursive(tx, removed); |
| 561 | } |
| 562 | } |
| 563 | |
| 564 | void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed) |
| 565 | { |
no test coverage detected