Remove txn which are invalidated by coinbase maturity during reorg
This commit is contained in:
parent
868d041622
commit
723d12c098
3 changed files with 28 additions and 0 deletions
|
@ -1895,6 +1895,7 @@ bool static DisconnectTip(CValidationState &state) {
|
||||||
if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
|
if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL))
|
||||||
mempool.remove(tx, removed, true);
|
mempool.remove(tx, removed, true);
|
||||||
}
|
}
|
||||||
|
mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight);
|
||||||
mempool.check(pcoinsTip);
|
mempool.check(pcoinsTip);
|
||||||
// Update chainActive and related variables.
|
// Update chainActive and related variables.
|
||||||
UpdateTip(pindexDelete->pprev);
|
UpdateTip(pindexDelete->pprev);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "txmempool.h"
|
#include "txmempool.h"
|
||||||
|
|
||||||
#include "clientversion.h"
|
#include "clientversion.h"
|
||||||
|
#include "main.h" // for COINBASE_MATURITY
|
||||||
#include "streams.h"
|
#include "streams.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utilmoneystr.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)
|
void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed)
|
||||||
{
|
{
|
||||||
// Remove transactions which depend on inputs of tx, recursively
|
// Remove transactions which depend on inputs of tx, recursively
|
||||||
|
|
|
@ -113,6 +113,7 @@ public:
|
||||||
|
|
||||||
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry);
|
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry);
|
||||||
void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false);
|
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 removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed);
|
||||||
void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
|
void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
|
||||||
std::list<CTransaction>& conflicts);
|
std::list<CTransaction>& conflicts);
|
||||||
|
|
Loading…
Add table
Reference in a new issue