Uncache input txn in utxo cache if a tx is not accepted to mempool

This commit is contained in:
Matt Corallo 2015-10-22 15:50:33 -07:00
parent 97bf377bd1
commit bde953e281

View file

@ -835,8 +835,9 @@ std::string FormatStateMessage(const CValidationState &state)
state.GetRejectCode()); state.GetRejectCode());
} }
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee) bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee,
std::vector<uint256>& vHashTxnToUncache)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
if (pfMissingInputs) if (pfMissingInputs)
@ -917,13 +918,19 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
view.SetBackend(viewMemPool); view.SetBackend(viewMemPool);
// do we already have it? // do we already have it?
if (view.HaveCoins(hash)) bool fHadTxInCache = pcoinsTip->HaveCoinsInCache(hash);
if (view.HaveCoins(hash)) {
if (!fHadTxInCache)
vHashTxnToUncache.push_back(hash);
return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known"); return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known");
}
// do all inputs exist? // do all inputs exist?
// Note that this does not check for the presence of actual outputs (see the next check for that), // Note that this does not check for the presence of actual outputs (see the next check for that),
// and only helps with filling in pfMissingInputs (to determine missing vs spent). // and only helps with filling in pfMissingInputs (to determine missing vs spent).
BOOST_FOREACH(const CTxIn txin, tx.vin) { BOOST_FOREACH(const CTxIn txin, tx.vin) {
if (!pcoinsTip->HaveCoinsInCache(txin.prevout.hash))
vHashTxnToUncache.push_back(txin.prevout.hash);
if (!view.HaveCoins(txin.prevout.hash)) { if (!view.HaveCoins(txin.prevout.hash)) {
if (pfMissingInputs) if (pfMissingInputs)
*pfMissingInputs = true; *pfMissingInputs = true;
@ -1232,6 +1239,18 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
return true; return true;
} }
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee)
{
std::vector<uint256> vHashTxToUncache;
bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, fOverrideMempoolLimit, fRejectAbsurdFee, vHashTxToUncache);
if (!res) {
BOOST_FOREACH(const uint256& hashTx, vHashTxToUncache)
pcoinsTip->Uncache(hashTx);
}
return res;
}
/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow) bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow)
{ {