aboutsummaryrefslogtreecommitdiff
path: root/src/net_processing.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net_processing.cpp')
-rw-r--r--src/net_processing.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index ee50bc1805..14507aa920 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -1185,7 +1185,8 @@ PeerManager::PeerManager(const CChainParams& chainparams, CConnman& connman, Ban
/**
* Evict orphan txn pool entries (EraseOrphanTx) based on a newly connected
- * block. Also save the time of the last tip update.
+ * block, remember the recently confirmed transactions, and delete tracked
+ * announcements for them. Also save the time of the last tip update.
*/
void PeerManager::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
{
@@ -1229,6 +1230,13 @@ void PeerManager::BlockConnected(const std::shared_ptr<const CBlock>& pblock, co
}
}
}
+ {
+ LOCK(cs_main);
+ for (const auto& ptx : pblock->vtx) {
+ m_txrequest.ForgetTxHash(ptx->GetHash());
+ m_txrequest.ForgetTxHash(ptx->GetWitnessHash());
+ }
+ }
}
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
if (!AlreadyHaveTx(GenTxid(/* is_wtxid=*/true, wtxid), m_mempool) &&
AcceptToMemoryPool(m_mempool, state, ptx, &lRemovedTxn, false /* bypass_limits */)) {
m_mempool.check(&::ChainstateActive().CoinsTip());
+ // As this version of the transaction was acceptable, we can forget about any
+ // requests for it.
+ m_txrequest.ForgetTxHash(tx.GetHash());
+ m_txrequest.ForgetTxHash(tx.GetWitnessHash());
RelayTransaction(tx.GetHash(), tx.GetWitnessHash(), m_connman);
for (unsigned int i = 0; i < tx.vout.size(); i++) {
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(txid, i));
@@ -3001,6 +3013,10 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
}
AddOrphanTx(ptx, pfrom.GetId());
+ // Once added to the orphan pool, a tx is considered AlreadyHave, and we shouldn't request it anymore.
+ m_txrequest.ForgetTxHash(tx.GetHash());
+ m_txrequest.ForgetTxHash(tx.GetWitnessHash());
+
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded (see CVE-2012-3789)
unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, gArgs.GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
@@ -3017,6 +3033,8 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
// from any of our non-wtxidrelay peers.
recentRejects->insert(tx.GetHash());
recentRejects->insert(tx.GetWitnessHash());
+ m_txrequest.ForgetTxHash(tx.GetHash());
+ m_txrequest.ForgetTxHash(tx.GetWitnessHash());
}
} else {
if (state.GetResult() != TxValidationResult::TX_WITNESS_STRIPPED) {
@@ -3035,6 +3053,7 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
// if we start doing this too early.
assert(recentRejects);
recentRejects->insert(tx.GetWitnessHash());
+ m_txrequest.ForgetTxHash(tx.GetWitnessHash());
// If the transaction failed for TX_INPUTS_NOT_STANDARD,
// then we know that the witness was irrelevant to the policy
// failure, since this check depends only on the txid
@@ -3045,6 +3064,7 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
// parent-fetching by txid via the orphan-handling logic).
if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.GetWitnessHash() != tx.GetHash()) {
recentRejects->insert(tx.GetHash());
+ m_txrequest.ForgetTxHash(tx.GetHash());
}
if (RecursiveDynamicUsage(*ptx) < 100000) {
AddToCompactExtraTransactions(ptx);
@@ -4479,7 +4499,8 @@ bool PeerManager::SendMessages(CNode* pto)
}
m_txrequest.RequestedTx(pto->GetId(), gtxid.GetHash(), current_time + GETDATA_TX_INTERVAL);
} else {
- // We have already seen this transaction, no need to download.
+ // We have already seen this transaction, no need to download. This is just a belt-and-suspenders, as
+ // this should already be called whenever a transaction becomes AlreadyHaveTx().
m_txrequest.ForgetTxHash(gtxid.GetHash());
}
}