Skip to content

Commit 723d12c

Browse files
committed
Remove txn which are invalidated by coinbase maturity during reorg
1 parent 868d041 commit 723d12c

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

src/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,6 +1895,7 @@ bool static DisconnectTip(CValidationState &state) {
18951895
if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
18961896
mempool.remove(tx, removed, true);
18971897
}
1898+
mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight);
18981899
mempool.check(pcoinsTip);
18991900
// Update chainActive and related variables.
19001901
UpdateTip(pindexDelete->pprev);

src/txmempool.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "txmempool.h"
77

88
#include "clientversion.h"
9+
#include "main.h" // for COINBASE_MATURITY
910
#include "streams.h"
1011
#include "util.h"
1112
#include "utilmoneystr.h"
@@ -453,6 +454,31 @@ void CTxMemPool::remove(const CTransaction &tx, std::list<CTransaction>& removed
453454
}
454455
}
455456

457+
void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight)
458+
{
459+
// Remove transactions spending a coinbase which are now immature
460+
LOCK(cs);
461+
list<CTransaction> transactionsToRemove;
462+
for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
463+
const CTransaction& tx = it->second.GetTx();
464+
BOOST_FOREACH(const CTxIn& txin, tx.vin) {
465+
std::map<uint256, CTxMemPoolEntry>::const_iterator it2 = mapTx.find(txin.prevout.hash);
466+
if (it2 != mapTx.end())
467+
continue;
468+
const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
469+
if (fSanityCheck) assert(coins);
470+
if (!coins || (coins->IsCoinBase() && nMemPoolHeight - coins->nHeight < COINBASE_MATURITY)) {
471+
transactionsToRemove.push_back(tx);
472+
break;
473+
}
474+
}
475+
}
476+
BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) {
477+
list<CTransaction> removed;
478+
remove(tx, removed, true);
479+
}
480+
}
481+
456482
void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed)
457483
{
458484
// Remove transactions which depend on inputs of tx, recursively

src/txmempool.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class CTxMemPool
113113

114114
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry);
115115
void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false);
116+
void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight);
116117
void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed);
117118
void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
118119
std::list<CTransaction>& conflicts);

0 commit comments

Comments
 (0)