Skip to content

Commit 48baa51

Browse files
committed
Uncache input txn in utxo cache if a tx is not accepted to mempool
>>> backports bitcoin/bitcoin@bde953e
1 parent c7070de commit 48baa51

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

src/main.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -842,8 +842,9 @@ std::string FormatStateMessage(const CValidationState &state)
842842
state.GetRejectCode());
843843
}
844844

845-
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransaction& tx, bool fLimitFree,
846-
bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectInsaneFee, bool ignoreFees)
845+
bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
846+
bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, bool ignoreFees,
847+
std::vector<uint256>& vHashTxnToUncache)
847848
{
848849
AssertLockHeld(cs_main);
849850
if (pfMissingInputs)
@@ -927,13 +928,19 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa
927928
view.SetBackend(viewMemPool);
928929

929930
// do we already have it?
930-
if (view.HaveCoins(hash))
931+
bool fHadTxInCache = pcoinsTip->HaveCoinsInCache(hash);
932+
if (view.HaveCoins(hash)) {
933+
if (!fHadTxInCache)
934+
vHashTxnToUncache.push_back(hash);
931935
return state.Invalid(false, REJECT_ALREADY_KNOWN, "txn-already-known");
936+
}
932937

933938
// do all inputs exist?
934939
// Note that this does not check for the presence of actual outputs (see the next check for that),
935940
// only helps filling in pfMissingInputs (to determine missing vs spent).
936941
for (const CTxIn& txin : tx.vin) {
942+
if (!pcoinsTip->HaveCoinsInCache(txin.prevout.hash))
943+
vHashTxnToUncache.push_back(txin.prevout.hash);
937944
if (!view.HaveCoins(txin.prevout.hash)) {
938945
if (pfMissingInputs)
939946
*pfMissingInputs = true;
@@ -1038,7 +1045,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa
10381045
}
10391046
}
10401047

1041-
if (fRejectInsaneFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
1048+
if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000)
10421049
return state.Invalid(false,
10431050
REJECT_HIGHFEE, "absurdly-high-fee",
10441051
strprintf("%d > %d", nFees, ::minRelayTxFee.GetFee(nSize) * 10000));
@@ -1112,6 +1119,18 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState& state, const CTransa
11121119
return true;
11131120
}
11141121

1122+
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,
1123+
bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee, bool fIgnoreFees)
1124+
{
1125+
std::vector<uint256> vHashTxToUncache;
1126+
bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, fOverrideMempoolLimit, fRejectAbsurdFee, fIgnoreFees, vHashTxToUncache);
1127+
if (!res) {
1128+
for (const uint256& hashTx: vHashTxToUncache)
1129+
pcoinsTip->Uncache(hashTx);
1130+
}
1131+
return res;
1132+
}
1133+
11151134
bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransaction& tx, bool fLimitFree, bool* pfMissingInputs, bool fRejectInsaneFee, bool isDSTX)
11161135
{
11171136
AssertLockHeld(cs_main);

0 commit comments

Comments
 (0)