mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 07:39:08 +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:
@@ -170,27 +170,6 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
||||
expected_num_orphans -= 2;
|
||||
BOOST_CHECK(orphanage->Size() == expected_num_orphans);
|
||||
}
|
||||
|
||||
// Test LimitOrphanTxSize() function, nothing should timeout:
|
||||
FastRandomContext rng{/*fDeterministic=*/true};
|
||||
orphanage->LimitOrphans(rng);
|
||||
BOOST_CHECK_EQUAL(orphanage->Size(), expected_num_orphans);
|
||||
|
||||
// Add one more orphan, check timeout logic
|
||||
auto timeout_tx = MakeTransactionSpending(/*outpoints=*/{}, rng);
|
||||
orphanage->AddTx(timeout_tx, 0);
|
||||
expected_num_orphans += 1;
|
||||
BOOST_CHECK_EQUAL(orphanage->Size(), expected_num_orphans);
|
||||
|
||||
// One second shy of expiration
|
||||
SetMockTime(now + node::ORPHAN_TX_EXPIRE_TIME - 1s);
|
||||
orphanage->LimitOrphans(rng);
|
||||
BOOST_CHECK_EQUAL(orphanage->Size(), expected_num_orphans);
|
||||
|
||||
// Jump one more second, orphan should be timed out on limiting
|
||||
SetMockTime(now + node::ORPHAN_TX_EXPIRE_TIME);
|
||||
orphanage->LimitOrphans(rng);
|
||||
BOOST_CHECK_EQUAL(orphanage->Size(), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(same_txid_diff_witness)
|
||||
|
||||
Reference in New Issue
Block a user