Fix removal of time-locked transactions during reorg

This commit is contained in:
Matt Corallo 2015-08-26 18:58:17 -07:00 committed by Suhas Daftuar
parent 0c9959a308
commit 9b060e5cfb
3 changed files with 17 additions and 12 deletions

View File

@ -2350,7 +2350,7 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons
// UpdateTransactionsFromBlock finds descendants of any transactions in this // UpdateTransactionsFromBlock finds descendants of any transactions in this
// block that were added back and cleans up the mempool state. // block that were added back and cleans up the mempool state.
mempool.UpdateTransactionsFromBlock(vHashUpdate); mempool.UpdateTransactionsFromBlock(vHashUpdate);
mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight); mempool.removeForReorg(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);

View File

@ -11,6 +11,7 @@
#include "main.h" #include "main.h"
#include "policy/fees.h" #include "policy/fees.h"
#include "streams.h" #include "streams.h"
#include "timedata.h"
#include "util.h" #include "util.h"
#include "utilmoneystr.h" #include "utilmoneystr.h"
#include "utiltime.h" #include "utiltime.h"
@ -478,22 +479,26 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list<CTransaction>& rem
} }
} }
void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight) void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight)
{ {
// Remove transactions spending a coinbase which are now immature // Remove transactions spending a coinbase which are now immature
LOCK(cs); LOCK(cs);
list<CTransaction> transactionsToRemove; list<CTransaction> transactionsToRemove;
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
const CTransaction& tx = it->GetTx(); const CTransaction& tx = it->GetTx();
BOOST_FOREACH(const CTxIn& txin, tx.vin) { if (!IsFinalTx(tx, nMemPoolHeight, GetAdjustedTime())) {
indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); transactionsToRemove.push_back(tx);
if (it2 != mapTx.end()) } else {
continue; BOOST_FOREACH(const CTxIn& txin, tx.vin) {
const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
if (nCheckFrequency != 0) assert(coins); if (it2 != mapTx.end())
if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { continue;
transactionsToRemove.push_back(tx); const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
break; if (nCheckFrequency != 0) assert(coins);
if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) {
transactionsToRemove.push_back(tx);
break;
}
} }
} }
} }

View File

@ -376,7 +376,7 @@ public:
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true); bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true);
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 removeForReorg(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, bool fCurrentEstimate = true); std::list<CTransaction>& conflicts, bool fCurrentEstimate = true);