mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-18 19:40:40 +01:00
[p2p] overhaul TxOrphanage with smarter limits
This is largely a reimplementation using boost::multi_index_container. All the same public methods are available. It has an index by outpoint, per-peer tracking, peer worksets, etc. A few differences: - Limits have changed: instead of a global limit of 100 unique orphans, we have a maximum number of announcements (which can include duplicate orphans) and a global memory limit which scales with the number of peers. - The maximum announcements limit is 100 to match the original limit, but this is actually a stricter limit because the announcement count is not de-duplicated. - Eviction strategy: when global limits are reached, a per-peer limit comes into play. While limits are exceeded, we choose the peer whose “DoS score” (max usage / limit ratio for announcements and memory limits) is highest and evict announcements by entry time, sorting non-reconsiderable ones before reconsiderable ones. Since announcements are unique by (wtxid, peer), as long as 1 announcement remains for a transaction, it remains in the orphanage. - This eviction strategy means no peer can influence the eviction of another peer’s orphans. - Also, since global limits are a multiple of per-peer limits, as long as a peer does not exceed its limits, its orphans are protected from eviction. - Orphans no longer expire, since older announcements are generally removed before newer ones. - GetChildrenFromSamePeer returns the transactions from newest to oldest. Co-authored-by: Pieter Wuille <pieter@wuille.net>
This commit is contained in:
@@ -188,6 +188,7 @@ bool TxDownloadManagerImpl::AddTxAnnouncement(NodeId peer, const GenTxid& gtxid,
|
||||
|
||||
if (MaybeAddOrphanResolutionCandidate(unique_parents, *wtxid, peer, now)) {
|
||||
m_orphanage->AddAnnouncer(orphan_tx->GetWitnessHash(), peer);
|
||||
m_orphanage->LimitOrphans(m_opts.m_rng);
|
||||
}
|
||||
|
||||
// Return even if the peer isn't an orphan resolution candidate. This would be caught by AlreadyHaveTx.
|
||||
@@ -420,8 +421,6 @@ node::RejectedTxTodo TxDownloadManagerImpl::MempoolRejectedTx(const CTransaction
|
||||
m_txrequest.ForgetTxHash(tx.GetWitnessHash());
|
||||
|
||||
// DoS prevention: do not allow m_orphanage to grow unbounded (see CVE-2012-3789)
|
||||
// Note that, if the orphanage reaches capacity, it's possible that we immediately evict
|
||||
// the transaction we just added.
|
||||
m_orphanage->LimitOrphans(m_opts.m_rng);
|
||||
} else {
|
||||
unique_parents.clear();
|
||||
|
||||
Reference in New Issue
Block a user