diff options
author | Matt Corallo <git@bluematt.me> | 2014-11-11 20:57:54 -0800 |
---|---|---|
committer | Matt Corallo <git@bluematt.me> | 2014-12-08 14:05:42 -0800 |
commit | 723d12c098456e7682e641076e76468a9fb0cec0 (patch) | |
tree | f50a3c3ee4baa4e0507dc1befda01ed03784d8af | |
parent | 868d041622e2f589ab4535c30ce683534b6d4f71 (diff) |
Remove txn which are invalidated by coinbase maturity during reorg
-rw-r--r-- | src/main.cpp | 1 | ||||
-rw-r--r-- | src/txmempool.cpp | 26 | ||||
-rw-r--r-- | src/txmempool.h | 1 |
3 files changed, 28 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp index 3a2c167e80..9e1c41ada7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1895,6 +1895,7 @@ bool static DisconnectTip(CValidationState &state) { if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) mempool.remove(tx, removed, true); } + mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight); mempool.check(pcoinsTip); // Update chainActive and related variables. UpdateTip(pindexDelete->pprev); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index e13f1cc350..ff04a8ad9a 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -6,6 +6,7 @@ #include "txmempool.h" #include "clientversion.h" +#include "main.h" // for COINBASE_MATURITY #include "streams.h" #include "util.h" #include "utilmoneystr.h" @@ -453,6 +454,31 @@ void CTxMemPool::remove(const CTransaction &tx, std::list<CTransaction>& removed } } +void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight) +{ + // Remove transactions spending a coinbase which are now immature + LOCK(cs); + list<CTransaction> transactionsToRemove; + for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { + const CTransaction& tx = it->second.GetTx(); + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash); + if (it2 != mapTx.end()) + continue; + const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); + if (fSanityCheck) assert(coins); + if (!coins || (coins->IsCoinBase() && nMemPoolHeight - coins->nHeight < COINBASE_MATURITY)) { + transactionsToRemove.push_back(tx); + break; + } + } + } + BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) { + list<CTransaction> removed; + remove(tx, removed, true); + } +} + void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed) { // Remove transactions which depend on inputs of tx, recursively diff --git a/src/txmempool.h b/src/txmempool.h index d00bdd0616..f671352b58 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -113,6 +113,7 @@ public: bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry); void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false); + void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight); void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed); void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight, std::list<CTransaction>& conflicts); |