aboutsummaryrefslogtreecommitdiff
path: root/src/txmempool.cpp
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2015-03-25 13:13:09 -0400
committerWladimir J. van der Laan <laanwj@gmail.com>2015-04-06 11:38:43 +0200
commit1c62e8409998f0358f2fca522678704824e332c1 (patch)
treea97745d53f7d078ced94f5f5522431af33c1c80f /src/txmempool.cpp
parent149c1d890ddc6dd0f108436704ac88bbed9ab12c (diff)
downloadbitcoin-1c62e8409998f0358f2fca522678704824e332c1.tar.xz
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 (adapted for 0.10). Rebased-From: ad9e86dca11dce023d827d342e966f3806c39d27 Github-Pull: #5945
Diffstat (limited to 'src/txmempool.cpp')
-rw-r--r--src/txmempool.cpp12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index dcdf5653fe..db598a1dfa 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();