Skip to content

Commit

Permalink
Fix removal of time-locked transactions during reorg
Browse files Browse the repository at this point in the history
coming from btc@9b060e5cfb0d185b553b21ae19d390f81e83bd4d
  • Loading branch information
furszy committed Jul 3, 2020
1 parent de74ab3 commit 8ad82ca
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2677,7 +2677,7 @@ bool static DisconnectTip(CValidationState& state)
// UpdateTransactionsFromBlock finds descendants of any transactions in this
// block that were added back and cleans up the mempool state.
mempool.UpdateTransactionsFromBlock(vHashUpdate);
mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight);
mempool.removeForReorg(pcoinsTip, pindexDelete->nHeight);
mempool.check(pcoinsTip);
// Update chainActive and related variables.
UpdateTip(pindexDelete->pprev);
Expand Down
27 changes: 16 additions & 11 deletions src/txmempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "main.h"
#include "policy/fees.h"
#include "streams.h"
#include "timedata.h"
#include "consensus/tx_verify.h"
#include "util.h"
#include "utilmoneystr.h"
#include "utiltime.h"
Expand Down Expand Up @@ -458,23 +460,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);
std::list<CTransaction> transactionsToRemove;
for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
const CTransaction& tx = it->GetTx();
for (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() || coins->IsCoinStake()) && ((signed long)nMemPoolHeight) - coins->nHeight < (unsigned)Params().GetConsensus().nCoinbaseMaturity)) {
transactionsToRemove.push_back(tx);
break;
if (!IsFinalTx(tx, nMemPoolHeight, GetAdjustedTime())) {
transactionsToRemove.push_back(tx);
} else {
for (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() || coins->IsCoinStake()) && ((signed long)nMemPoolHeight) - coins->nHeight < (unsigned)Params().GetConsensus().nCoinbaseMaturity)) {
transactionsToRemove.push_back(tx);
break;
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/txmempool.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ class CTxMemPool
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry& entry, 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 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);
void clear();
Expand Down

0 comments on commit 8ad82ca

Please sign in to comment.