Skip to content

Commit 173a1d2

Browse files
committed
Expedite removal of tx requests that are no longer needed
Whenever a transaction is added to the mempool or orphan pool, both its txid and wtxid are considered AlreadyHave, and thus will eventually be removed from m_txrequest. The same is true for hashes added to the reject filter, but note that sometimes only the wtxid is added (in which case only the wtxid can be removed from m_txrequest).
1 parent de11b0a commit 173a1d2

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

src/net_processing.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,8 @@ PeerManager::PeerManager(const CChainParams& chainparams, CConnman& connman, Ban
11851185

11861186
/**
11871187
* Evict orphan txn pool entries (EraseOrphanTx) based on a newly connected
1188-
* block. Also save the time of the last tip update.
1188+
* block, remember the recently confirmed transactions, and delete tracked
1189+
* announcements for them. Also save the time of the last tip update.
11891190
*/
11901191
void PeerManager::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
11911192
{
@@ -1229,6 +1230,13 @@ void PeerManager::BlockConnected(const std::shared_ptr<const CBlock>& pblock, co
12291230
}
12301231
}
12311232
}
1233+
{
1234+
LOCK(cs_main);
1235+
for (const auto& ptx : pblock->vtx) {
1236+
m_txrequest.ForgetTxHash(ptx->GetHash());
1237+
m_txrequest.ForgetTxHash(ptx->GetWitnessHash());
1238+
}
1239+
}
12321240
}
12331241

12341242
void PeerManager::BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex)
@@ -2942,6 +2950,10 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
29422950
if (!AlreadyHaveTx(GenTxid(/* is_wtxid=*/true, wtxid), m_mempool) &&
29432951
AcceptToMemoryPool(m_mempool, state, ptx, &lRemovedTxn, false /* bypass_limits */)) {
29442952
m_mempool.check(&::ChainstateActive().CoinsTip());
2953+
// As this version of the transaction was acceptable, we can forget about any
2954+
// requests for it.
2955+
m_txrequest.ForgetTxHash(tx.GetHash());
2956+
m_txrequest.ForgetTxHash(tx.GetWitnessHash());
29452957
RelayTransaction(tx.GetHash(), tx.GetWitnessHash(), m_connman);
29462958
for (unsigned int i = 0; i < tx.vout.size(); i++) {
29472959
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(txid, i));
@@ -3001,6 +3013,10 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
30013013
}
30023014
AddOrphanTx(ptx, pfrom.GetId());
30033015

3016+
// Once added to the orphan pool, a tx is considered AlreadyHave, and we shouldn't request it anymore.
3017+
m_txrequest.ForgetTxHash(tx.GetHash());
3018+
m_txrequest.ForgetTxHash(tx.GetWitnessHash());
3019+
30043020
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded (see CVE-2012-3789)
30053021
unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, gArgs.GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
30063022
unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
@@ -3017,6 +3033,8 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
30173033
// from any of our non-wtxidrelay peers.
30183034
recentRejects->insert(tx.GetHash());
30193035
recentRejects->insert(tx.GetWitnessHash());
3036+
m_txrequest.ForgetTxHash(tx.GetHash());
3037+
m_txrequest.ForgetTxHash(tx.GetWitnessHash());
30203038
}
30213039
} else {
30223040
if (state.GetResult() != TxValidationResult::TX_WITNESS_STRIPPED) {
@@ -3035,6 +3053,7 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
30353053
// if we start doing this too early.
30363054
assert(recentRejects);
30373055
recentRejects->insert(tx.GetWitnessHash());
3056+
m_txrequest.ForgetTxHash(tx.GetWitnessHash());
30383057
// If the transaction failed for TX_INPUTS_NOT_STANDARD,
30393058
// then we know that the witness was irrelevant to the policy
30403059
// failure, since this check depends only on the txid
@@ -3045,6 +3064,7 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
30453064
// parent-fetching by txid via the orphan-handling logic).
30463065
if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.GetWitnessHash() != tx.GetHash()) {
30473066
recentRejects->insert(tx.GetHash());
3067+
m_txrequest.ForgetTxHash(tx.GetHash());
30483068
}
30493069
if (RecursiveDynamicUsage(*ptx) < 100000) {
30503070
AddToCompactExtraTransactions(ptx);
@@ -4479,7 +4499,8 @@ bool PeerManager::SendMessages(CNode* pto)
44794499
}
44804500
m_txrequest.RequestedTx(pto->GetId(), gtxid.GetHash(), current_time + GETDATA_TX_INTERVAL);
44814501
} else {
4482-
// We have already seen this transaction, no need to download.
4502+
// We have already seen this transaction, no need to download. This is just a belt-and-suspenders, as
4503+
// this should already be called whenever a transaction becomes AlreadyHaveTx().
44834504
m_txrequest.ForgetTxHash(gtxid.GetHash());
44844505
}
44854506
}

0 commit comments

Comments
 (0)