@@ -1185,7 +1185,8 @@ PeerManager::PeerManager(const CChainParams& chainparams, CConnman& connman, Ban
1185
1185
1186
1186
/* *
1187
1187
* 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.
1189
1190
*/
1190
1191
void PeerManager::BlockConnected (const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
1191
1192
{
@@ -1229,6 +1230,13 @@ void PeerManager::BlockConnected(const std::shared_ptr<const CBlock>& pblock, co
1229
1230
}
1230
1231
}
1231
1232
}
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
+ }
1232
1240
}
1233
1241
1234
1242
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
2942
2950
if (!AlreadyHaveTx (GenTxid (/* is_wtxid=*/ true , wtxid), m_mempool) &&
2943
2951
AcceptToMemoryPool (m_mempool, state, ptx, &lRemovedTxn, false /* bypass_limits */ )) {
2944
2952
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 ());
2945
2957
RelayTransaction (tx.GetHash (), tx.GetWitnessHash (), m_connman);
2946
2958
for (unsigned int i = 0 ; i < tx.vout .size (); i++) {
2947
2959
auto it_by_prev = mapOrphanTransactionsByPrev.find (COutPoint (txid, i));
@@ -3001,6 +3013,10 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
3001
3013
}
3002
3014
AddOrphanTx (ptx, pfrom.GetId ());
3003
3015
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
+
3004
3020
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded (see CVE-2012-3789)
3005
3021
unsigned int nMaxOrphanTx = (unsigned int )std::max ((int64_t )0 , gArgs .GetArg (" -maxorphantx" , DEFAULT_MAX_ORPHAN_TRANSACTIONS));
3006
3022
unsigned int nEvicted = LimitOrphanTxSize (nMaxOrphanTx);
@@ -3017,6 +3033,8 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
3017
3033
// from any of our non-wtxidrelay peers.
3018
3034
recentRejects->insert (tx.GetHash ());
3019
3035
recentRejects->insert (tx.GetWitnessHash ());
3036
+ m_txrequest.ForgetTxHash (tx.GetHash ());
3037
+ m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
3020
3038
}
3021
3039
} else {
3022
3040
if (state.GetResult () != TxValidationResult::TX_WITNESS_STRIPPED) {
@@ -3035,6 +3053,7 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
3035
3053
// if we start doing this too early.
3036
3054
assert (recentRejects);
3037
3055
recentRejects->insert (tx.GetWitnessHash ());
3056
+ m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
3038
3057
// If the transaction failed for TX_INPUTS_NOT_STANDARD,
3039
3058
// then we know that the witness was irrelevant to the policy
3040
3059
// failure, since this check depends only on the txid
@@ -3045,6 +3064,7 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
3045
3064
// parent-fetching by txid via the orphan-handling logic).
3046
3065
if (state.GetResult () == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.GetWitnessHash () != tx.GetHash ()) {
3047
3066
recentRejects->insert (tx.GetHash ());
3067
+ m_txrequest.ForgetTxHash (tx.GetHash ());
3048
3068
}
3049
3069
if (RecursiveDynamicUsage (*ptx) < 100000 ) {
3050
3070
AddToCompactExtraTransactions (ptx);
@@ -4479,7 +4499,8 @@ bool PeerManager::SendMessages(CNode* pto)
4479
4499
}
4480
4500
m_txrequest.RequestedTx (pto->GetId (), gtxid.GetHash (), current_time + GETDATA_TX_INTERVAL);
4481
4501
} 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().
4483
4504
m_txrequest.ForgetTxHash (gtxid.GetHash ());
4484
4505
}
4485
4506
}
0 commit comments