mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-05 14:06:27 -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
|
* 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)
|
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)
|
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) &&
|
if (!AlreadyHaveTx(GenTxid(/* is_wtxid=*/true, wtxid), m_mempool) &&
|
||||||
AcceptToMemoryPool(m_mempool, state, ptx, &lRemovedTxn, false /* bypass_limits */)) {
|
AcceptToMemoryPool(m_mempool, state, ptx, &lRemovedTxn, false /* bypass_limits */)) {
|
||||||
m_mempool.check(&::ChainstateActive().CoinsTip());
|
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);
|
RelayTransaction(tx.GetHash(), tx.GetWitnessHash(), m_connman);
|
||||||
for (unsigned int i = 0; i < tx.vout.size(); i++) {
|
for (unsigned int i = 0; i < tx.vout.size(); i++) {
|
||||||
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(txid, 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());
|
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)
|
// 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 nMaxOrphanTx = (unsigned int)std::max((int64_t)0, gArgs.GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
|
||||||
unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
|
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.
|
// from any of our non-wtxidrelay peers.
|
||||||
recentRejects->insert(tx.GetHash());
|
recentRejects->insert(tx.GetHash());
|
||||||
recentRejects->insert(tx.GetWitnessHash());
|
recentRejects->insert(tx.GetWitnessHash());
|
||||||
|
m_txrequest.ForgetTxHash(tx.GetHash());
|
||||||
|
m_txrequest.ForgetTxHash(tx.GetWitnessHash());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (state.GetResult() != TxValidationResult::TX_WITNESS_STRIPPED) {
|
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.
|
// if we start doing this too early.
|
||||||
assert(recentRejects);
|
assert(recentRejects);
|
||||||
recentRejects->insert(tx.GetWitnessHash());
|
recentRejects->insert(tx.GetWitnessHash());
|
||||||
|
m_txrequest.ForgetTxHash(tx.GetWitnessHash());
|
||||||
// If the transaction failed for TX_INPUTS_NOT_STANDARD,
|
// If the transaction failed for TX_INPUTS_NOT_STANDARD,
|
||||||
// then we know that the witness was irrelevant to the policy
|
// then we know that the witness was irrelevant to the policy
|
||||||
// failure, since this check depends only on the txid
|
// 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).
|
// parent-fetching by txid via the orphan-handling logic).
|
||||||
if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.GetWitnessHash() != tx.GetHash()) {
|
if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.GetWitnessHash() != tx.GetHash()) {
|
||||||
recentRejects->insert(tx.GetHash());
|
recentRejects->insert(tx.GetHash());
|
||||||
|
m_txrequest.ForgetTxHash(tx.GetHash());
|
||||||
}
|
}
|
||||||
if (RecursiveDynamicUsage(*ptx) < 100000) {
|
if (RecursiveDynamicUsage(*ptx) < 100000) {
|
||||||
AddToCompactExtraTransactions(ptx);
|
AddToCompactExtraTransactions(ptx);
|
||||||
|
@ -4479,7 +4499,8 @@ bool PeerManager::SendMessages(CNode* pto)
|
||||||
}
|
}
|
||||||
m_txrequest.RequestedTx(pto->GetId(), gtxid.GetHash(), current_time + GETDATA_TX_INTERVAL);
|
m_txrequest.RequestedTx(pto->GetId(), gtxid.GetHash(), current_time + GETDATA_TX_INTERVAL);
|
||||||
} else {
|
} 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());
|
m_txrequest.ForgetTxHash(gtxid.GetHash());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue