mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
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).
This commit is contained in:
parent
de11b0a4ef
commit
173a1d2d3f
1 changed files with 23 additions and 2 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue