diff options
| author | Gavin Andresen <[email protected]> | 2015-03-25 13:13:09 -0400 |
|---|---|---|
| committer | Gavin Andresen <[email protected]> | 2015-03-26 11:58:19 -0400 |
| commit | ad9e86dca11dce023d827d342e966f3806c39d27 (patch) | |
| tree | 0d7d145efb3df126bc9efb408c81cd0f09430b37 /src/txmempool.cpp | |
| parent | Fix --disable-wallet build after merge of #5681 (diff) | |
| download | discoin-ad9e86dca11dce023d827d342e966f3806c39d27.tar.xz discoin-ad9e86dca11dce023d827d342e966f3806c39d27.zip | |
Keep mempool consistent during block-reorgs
This fixes a subtle bug involving block re-orgs and non-standard transactions.
Start with a block containing a non-standard transaction, and
one or more transactions spending it in the memory pool.
Then re-org away from that block to another chain that does
not contain the non-standard transaction.
Result before this fix: the dependent transactions get stuck
in the mempool without their parent, putting the mempool
in an inconsistent state.
Tested with a new unit test.
Diffstat (limited to 'src/txmempool.cpp')
| -rw-r--r-- | src/txmempool.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 0d5066032..85ea3f77b 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -444,6 +444,18 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem LOCK(cs); std::deque<uint256> txToRemove; txToRemove.push_back(origTx.GetHash()); + if (fRecursive && !mapTx.count(origTx.GetHash())) { + // If recursively removing but origTx isn't in the mempool + // be sure to remove any children that are in the pool. This can + // happen during chain re-orgs if origTx isn't re-accepted into + // the mempool for any reason. + for (unsigned int i = 0; i < origTx.vout.size(); i++) { + std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(origTx.GetHash(), i)); + if (it == mapNextTx.end()) + continue; + txToRemove.push_back(it->second.ptx->GetHash()); + } + } while (!txToRemove.empty()) { uint256 hash = txToRemove.front(); |