Browse Source

Fix removal of time-locked transactions during reorg

pull/4/head
Matt Corallo 9 years ago
committed by Jack Grigg
parent
commit
f5b35d2305
No known key found for this signature in database GPG Key ID: 665DBCD284F7DAFF
  1. 2
      src/main.cpp
  2. 25
      src/txmempool.cpp
  3. 2
      src/txmempool.h

2
src/main.cpp

@ -2457,7 +2457,7 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
// in which case we don't want to evict from the mempool yet!
mempool.removeWithAnchor(anchorBeforeDisconnect);
}
mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight);
mempool.removeForReorg(pcoinsTip, pindexDelete->nHeight);
mempool.check(pcoinsTip);
}

25
src/txmempool.cpp

@ -11,6 +11,7 @@
#include "main.h"
#include "policy/fees.h"
#include "streams.h"
#include "timedata.h"
#include "util.h"
#include "utilmoneystr.h"
#include "version.h"
@ -167,22 +168,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
LOCK(cs);
list<CTransaction> transactionsToRemove;
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
const CTransaction& tx = it->GetTx();
BOOST_FOREACH(const CTxIn& txin, tx.vin) {
indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
if (it2 != mapTx.end())
continue;
const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
if (nCheckFrequency != 0) assert(coins);
if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) {
transactionsToRemove.push_back(tx);
break;
if (!IsFinalTx(tx, nMemPoolHeight, GetAdjustedTime())) {
transactionsToRemove.push_back(tx);
} else {
BOOST_FOREACH(const CTxIn& txin, tx.vin) {
indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
if (it2 != mapTx.end())
continue;
const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash);
if (nCheckFrequency != 0) assert(coins);
if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) {
transactionsToRemove.push_back(tx);
break;
}
}
}
}

2
src/txmempool.h

@ -160,7 +160,7 @@ public:
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true);
void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false);
void removeWithAnchor(const uint256 &invalidRoot);
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 removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
std::list<CTransaction>& conflicts, bool fCurrentEstimate = true);

Loading…
Cancel
Save