Skip to content

Commit ea29c43

Browse files
committed
[p2p] bump DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE to 3,000
For the default number of peers (125), allows each to relay a default descendant package (up to 25-1=24 can be missing inputs) of small (9 inputs or fewer) transactions out of order. This limit also gives acceptable bounds for worst case LimitOrphans iterations. Functional tests aren't changed to check for larger cap because it would make the runtime too long. Also deletes the now-unused DEFAULT_MAX_ORPHAN_TRANSACTIONS.
1 parent 24afee8 commit ea29c43

File tree

5 files changed

+10
-60
lines changed

5 files changed

+10
-60
lines changed

src/node/txorphanage.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ namespace node {
2020
static constexpr int64_t DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER{404'000};
2121
/** Default value for TxOrphanage::m_max_global_latency_score. Helps limit the maximum latency for operations like
2222
* EraseForBlock and LimitOrphans. */
23-
static constexpr unsigned int DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE{100};
24-
/** Default maximum number of orphan transactions kept in memory */
25-
static const uint32_t DEFAULT_MAX_ORPHAN_TRANSACTIONS{100};
23+
static constexpr unsigned int DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE{3000};
2624

2725
/** A class to track orphan transactions (failed on TX_MISSING_INPUTS)
2826
* Since we cannot distinguish orphans from bad transactions with non-existent inputs, we heavily limit the amount of

src/test/fuzz/txdownloadman.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,9 @@ FUZZ_TARGET(txdownloadman, .init = initialize)
277277
// peer without tracking anything (this is only for the txdownload_impl target).
278278
static bool HasRelayPermissions(NodeId peer) { return peer == 0; }
279279

280-
static void CheckInvariants(const node::TxDownloadManagerImpl& txdownload_impl, size_t max_orphan_count)
280+
static void CheckInvariants(const node::TxDownloadManagerImpl& txdownload_impl)
281281
{
282-
// Orphanage usage should never exceed what is allowed
283-
Assert(txdownload_impl.m_orphanage->Size() <= max_orphan_count);
284282
txdownload_impl.m_orphanage->SanityCheck();
285-
286283
// We should never have more than the maximum in-flight requests out for a peer.
287284
for (NodeId peer = 0; peer < NUM_PEERS; ++peer) {
288285
if (!HasRelayPermissions(peer)) {
@@ -301,7 +298,6 @@ FUZZ_TARGET(txdownloadman_impl, .init = initialize)
301298
// Initialize a TxDownloadManagerImpl
302299
bilingual_str error;
303300
CTxMemPool pool{MemPoolOptionsForTest(g_setup->m_node), error};
304-
const auto max_orphan_count = node::DEFAULT_MAX_ORPHAN_TRANSACTIONS;
305301
FastRandomContext det_rand{true};
306302
node::TxDownloadManagerImpl txdownload_impl{node::TxDownloadOptions{pool, det_rand, true}};
307303

@@ -434,7 +430,7 @@ FUZZ_TARGET(txdownloadman_impl, .init = initialize)
434430
if (fuzzed_data_provider.ConsumeBool()) time_skip *= -1;
435431
time += time_skip;
436432
}
437-
CheckInvariants(txdownload_impl, max_orphan_count);
433+
CheckInvariants(txdownload_impl);
438434
// Disconnect everybody, check that all data structures are empty.
439435
for (NodeId nodeid = 0; nodeid < NUM_PEERS; ++nodeid) {
440436
txdownload_impl.DisconnectedPeer(nodeid);

src/test/fuzz/txorphan.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
5252

5353
std::vector<CTransactionRef> tx_history;
5454

55-
LIMITED_WHILE(outpoints.size() < 200'000 && fuzzed_data_provider.ConsumeBool(), 10 * node::DEFAULT_MAX_ORPHAN_TRANSACTIONS)
55+
LIMITED_WHILE(outpoints.size() < 200'000 && fuzzed_data_provider.ConsumeBool(), 1000)
5656
{
5757
// construct transaction
5858
const CTransactionRef tx = [&] {
@@ -100,7 +100,7 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
100100
}
101101

102102
// trigger orphanage functions
103-
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10 * node::DEFAULT_MAX_ORPHAN_TRANSACTIONS)
103+
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 1000)
104104
{
105105
NodeId peer_id = fuzzed_data_provider.ConsumeIntegral<NodeId>();
106106
const auto total_bytes_start{orphanage->TotalOrphanUsage()};
@@ -220,7 +220,6 @@ FUZZ_TARGET(txorphan, .init = initialize_orphanage)
220220
// test mocktime and expiry
221221
SetMockTime(ConsumeTime(fuzzed_data_provider));
222222
orphanage->LimitOrphans();
223-
Assert(orphanage->Size() <= node::DEFAULT_MAX_ORPHAN_TRANSACTIONS);
224223
});
225224

226225
}

test/functional/p2p_invalid_tx.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,14 @@ def run_test(self):
143143
self.wait_until(lambda: 1 == len(node.getpeerinfo()), timeout=12) # p2ps[1] is no longer connected
144144
assert_equal(expected_mempool, set(node.getrawmempool()))
145145

146-
self.log.info('Test orphan pool overflow')
146+
self.log.info('Test orphanage can store more than 100 transactions')
147147
orphan_tx_pool = [CTransaction() for _ in range(101)]
148148
for i in range(len(orphan_tx_pool)):
149149
orphan_tx_pool[i].vin.append(CTxIn(outpoint=COutPoint(i, 333)))
150150
orphan_tx_pool[i].vout.append(CTxOut(nValue=11 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
151151

152-
with node.assert_debug_log(['orphanage overflow, removed 1 tx']):
153-
node.p2ps[0].send_txs_and_test(orphan_tx_pool, node, success=False)
152+
node.p2ps[0].send_txs_and_test(orphan_tx_pool, node, success=False)
153+
self.wait_until(lambda: len(node.getorphantxs()) >= 101)
154154

155155
self.log.info('Test orphan with rejected parents')
156156
rejected_parent = CTransaction()
@@ -160,8 +160,8 @@ def run_test(self):
160160
node.p2ps[0].send_txs_and_test([rejected_parent], node, success=False)
161161

162162
self.log.info('Test that a peer disconnection causes erase its transactions from the orphan pool')
163-
with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=26']):
164-
self.reconnect_p2p(num_connections=1)
163+
self.reconnect_p2p(num_connections=1)
164+
self.wait_until(lambda: len(node.getorphantxs()) == 0)
165165

166166
self.log.info('Test that a transaction in the orphan pool is included in a new tip block causes erase this transaction from the orphan pool')
167167
tx_withhold_until_block_A = CTransaction()

test/functional/p2p_orphan_handling.py

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@
4343
# for one peer and y seconds for another, use specific values instead.
4444
TXREQUEST_TIME_SKIP = NONPREF_PEER_TX_DELAY + TXID_RELAY_DELAY + OVERLOADED_PEER_TX_DELAY + 1
4545

46-
DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100
47-
4846
def cleanup(func):
4947
# Time to fastfoward (using setmocktime) in between subtests to ensure they do not interfere with
5048
# one another, in seconds. Equal to 12 hours, which is enough to expire anything that may exist
@@ -593,46 +591,6 @@ def test_orphan_txid_inv(self):
593591
assert_equal(node.getmempoolentry(tx_child["txid"])["wtxid"], tx_child["wtxid"])
594592
self.wait_until(lambda: len(node.getorphantxs()) == 0)
595593

596-
@cleanup
597-
def test_max_orphan_amount(self):
598-
self.log.info("Check that we never exceed our storage limits for orphans")
599-
600-
node = self.nodes[0]
601-
self.generate(self.wallet, 1)
602-
peer_1 = node.add_p2p_connection(P2PInterface())
603-
604-
self.log.info("Check that orphanage is empty on start of test")
605-
assert len(node.getorphantxs()) == 0
606-
607-
self.log.info("Filling up orphanage with " + str(DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "(DEFAULT_MAX_ORPHAN_TRANSACTIONS) orphans")
608-
orphans = []
609-
parent_orphans = []
610-
for _ in range(DEFAULT_MAX_ORPHAN_TRANSACTIONS):
611-
tx_parent_1 = self.wallet.create_self_transfer()
612-
tx_child_1 = self.wallet.create_self_transfer(utxo_to_spend=tx_parent_1["new_utxo"])
613-
parent_orphans.append(tx_parent_1["tx"])
614-
orphans.append(tx_child_1["tx"])
615-
peer_1.send_without_ping(msg_tx(tx_child_1["tx"]))
616-
617-
peer_1.sync_with_ping()
618-
orphanage = node.getorphantxs()
619-
self.wait_until(lambda: len(node.getorphantxs()) == DEFAULT_MAX_ORPHAN_TRANSACTIONS)
620-
621-
for orphan in orphans:
622-
assert tx_in_orphanage(node, orphan)
623-
624-
self.log.info("Check that we do not add more than the max orphan amount")
625-
tx_parent_1 = self.wallet.create_self_transfer()
626-
tx_child_1 = self.wallet.create_self_transfer(utxo_to_spend=tx_parent_1["new_utxo"])
627-
peer_1.send_and_ping(msg_tx(tx_child_1["tx"]))
628-
parent_orphans.append(tx_parent_1["tx"])
629-
orphanage = node.getorphantxs()
630-
assert_equal(len(orphanage), DEFAULT_MAX_ORPHAN_TRANSACTIONS)
631-
632-
self.log.info("Clearing the orphanage")
633-
for index, parent_orphan in enumerate(parent_orphans):
634-
peer_1.send_and_ping(msg_tx(parent_orphan))
635-
self.wait_until(lambda: len(node.getorphantxs()) == 0)
636594

637595
@cleanup
638596
def test_orphan_handling_prefer_outbound(self):
@@ -820,7 +778,6 @@ def run_test(self):
820778
self.test_same_txid_orphan()
821779
self.test_same_txid_orphan_of_orphan()
822780
self.test_orphan_txid_inv()
823-
self.test_max_orphan_amount()
824781
self.test_orphan_handling_prefer_outbound()
825782
self.test_announcers_before_and_after()
826783
self.test_parents_change()

0 commit comments

Comments
 (0)