Skip to content

Commit 067365d

Browse files
glozowsipa
andcommitted
[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 <[email protected]>
1 parent 1a41e79 commit 067365d

File tree

4 files changed

+617
-341
lines changed

4 files changed

+617
-341
lines changed

src/node/txdownloadman_impl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ bool TxDownloadManagerImpl::AddTxAnnouncement(NodeId peer, const GenTxid& gtxid,
188188

189189
if (MaybeAddOrphanResolutionCandidate(unique_parents, *wtxid, peer, now)) {
190190
m_orphanage->AddAnnouncer(orphan_tx->GetWitnessHash(), peer);
191+
m_orphanage->LimitOrphans(m_opts.m_rng);
191192
}
192193

193194
// 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
420421
m_txrequest.ForgetTxHash(tx.GetWitnessHash());
421422

422423
// DoS prevention: do not allow m_orphanage to grow unbounded (see CVE-2012-3789)
423-
// Note that, if the orphanage reaches capacity, it's possible that we immediately evict
424-
// the transaction we just added.
425424
m_orphanage->LimitOrphans(m_opts.m_rng);
426425
} else {
427426
unique_parents.clear();

0 commit comments

Comments
 (0)