diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2012-11-30 17:10:07 -0800 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2012-11-30 17:10:07 -0800 |
commit | cd7fb7d1deece9da15d7750b3e05f729555a2cbe (patch) | |
tree | 6825effd685be37abf65c252e73c4263c67ed646 | |
parent | aaef016a07e66d555bdeba0697de2f9e313d78ae (diff) | |
parent | 231b399952fd620ee0f72b1947024dba9651630d (diff) |
Merge pull request #2033 from sipa/kickconflicts
Bugfix: remove conflicting transactions from memory pool
-rw-r--r-- | src/main.cpp | 28 | ||||
-rw-r--r-- | src/main.h | 3 |
2 files changed, 28 insertions, 3 deletions
diff --git a/src/main.cpp b/src/main.cpp index 5401d4ca17..944345abb2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -818,7 +818,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, CTransaction &tx) } -bool CTxMemPool::remove(CTransaction &tx) +bool CTxMemPool::remove(const CTransaction &tx, bool fRecursive) { // Remove transaction from memory pool { @@ -826,6 +826,13 @@ bool CTxMemPool::remove(CTransaction &tx) uint256 hash = tx.GetHash(); if (mapTx.count(hash)) { + if (fRecursive) { + for (unsigned int i = 0; i < tx.vout.size(); i++) { + std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(COutPoint(hash, i)); + if (it != mapNextTx.end()) + remove(*it->second.ptx, true); + } + } BOOST_FOREACH(const CTxIn& txin, tx.vin) mapNextTx.erase(txin.prevout); mapTx.erase(hash); @@ -835,6 +842,21 @@ bool CTxMemPool::remove(CTransaction &tx) return true; } +bool CTxMemPool::removeConflicts(const CTransaction &tx) +{ + // Remove transactions which depend on inputs of tx, recursively + LOCK(cs); + BOOST_FOREACH(const CTxIn &txin, tx.vin) { + std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout); + if (it != mapNextTx.end()) { + const CTransaction &txConflict = *it->second.ptx; + if (txConflict != tx) + remove(txConflict, true); + } + } + return true; +} + void CTxMemPool::clear() { LOCK(cs); @@ -1757,8 +1779,10 @@ bool SetBestChain(CBlockIndex* pindexNew) tx.AcceptToMemoryPool(false); // Delete redundant memory transactions that are in the connected branch - BOOST_FOREACH(CTransaction& tx, vDelete) + BOOST_FOREACH(CTransaction& tx, vDelete) { mempool.remove(tx); + mempool.removeConflicts(tx); + } // Update best block in wallet (so we can detect restored wallets) if (!fIsInitialDownload) diff --git a/src/main.h b/src/main.h index a5f60fe945..4bd4782ccb 100644 --- a/src/main.h +++ b/src/main.h @@ -1831,7 +1831,8 @@ public: bool accept(CTransaction &tx, bool fCheckInputs, bool* pfMissingInputs); bool addUnchecked(const uint256& hash, CTransaction &tx); - bool remove(CTransaction &tx); + bool remove(const CTransaction &tx, bool fRecursive = false); + bool removeConflicts(const CTransaction &tx); void clear(); void queryHashes(std::vector<uint256>& vtxid); void pruneSpent(const uint256& hash, CCoins &coins); |