diff options
| author | Pieter Wuille <[email protected]> | 2012-11-30 17:10:07 -0800 |
|---|---|---|
| committer | Pieter Wuille <[email protected]> | 2012-11-30 17:10:07 -0800 |
| commit | cd7fb7d1deece9da15d7750b3e05f729555a2cbe (patch) | |
| tree | 6825effd685be37abf65c252e73c4263c67ed646 /src/main.cpp | |
| parent | Merge pull request #2037 from luke-jr/printpriority (diff) | |
| parent | Bugfix: remove conflicting transactions from memory pool (diff) | |
| download | discoin-cd7fb7d1deece9da15d7750b3e05f729555a2cbe.tar.xz discoin-cd7fb7d1deece9da15d7750b3e05f729555a2cbe.zip | |
Merge pull request #2033 from sipa/kickconflicts
Bugfix: remove conflicting transactions from memory pool
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/src/main.cpp b/src/main.cpp index 5401d4ca1..944345abb 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) |