v29.4-roots.2 · Commit 3: [PATCH 03/21] policy: restore conservative relay and network controls
test/functional/p2p_compactblocks_extratxs.py
Before: /dev/null · After: test/functional/p2p_compactblocks_extratxs.py
File metadata
new file mode 100755 index 0000000000000000000000000000000000000000..156c0785e9460c176b4e77e5d790ff5efb8fd8b0
Download original patch · Release notes
Diff rows 401–513 of 513. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.
test/functional/p2p_compactblocks_extratxs.py
ADDED
|
@@ -0,0 +1,513 @@ (continued)
|
|
|
401
|
+
test_count = 100
|
|
402
|
+
rejected_txs = self.populate_extra_pool(test_count, target_size=20000)
|
|
403
|
+
|
|
404
|
+
indices = list(range(test_count))
|
|
405
|
+
result = self.send_compact_block(rejected_txs, indices)
|
|
406
|
+
|
|
407
|
+
# Find the boundary - how many fit vs how many were evicted
|
|
408
|
+
num_evicted = len(result["missing_indices"])
|
|
409
|
+
num_fit = test_count - num_evicted
|
|
410
|
+
|
|
411
|
+
# Now restart and add exactly the number that fit
|
|
412
|
+
self.restart_node_with_limit(memory_mb=limit_mb)
|
|
413
|
+
rejected_txs = self.populate_extra_pool(num_fit, target_size=20000)
|
|
414
|
+
|
|
415
|
+
# Verify all fit
|
|
416
|
+
indices = list(range(num_fit))
|
|
417
|
+
result = self.send_compact_block(rejected_txs, indices)
|
|
418
|
+
assert result["missing_indices"] == [], f"Expected all {num_fit} transactions to fit at boundary"
|
|
419
|
+
|
|
420
|
+
# Add one more transaction - should evict exactly one
|
|
421
|
+
self.log.info("Adding one more transaction at the boundary...")
|
|
422
|
+
self.populate_extra_pool(1, target_size=20000)
|
|
423
|
+
|
|
424
|
+
# Check original transactions again
|
|
425
|
+
result2 = self.send_compact_block(rejected_txs, indices)
|
|
426
|
+
assert len(result2["missing_indices"]) == 1, "Expected exactly 1 eviction at boundary"
|
|
427
|
+
assert result2["missing_indices"] == [0], "Expected oldest transaction (0) to be evicted"
|
|
428
|
+
|
|
429
|
+
self.log.info("Size limit boundary behavior verified - one transaction evicted when limit exceeded")
|
|
430
|
+
|
|
431
|
+
def test_extratxnsize_small_limit(self):
|
|
432
|
+
"""Test extra transaction pool with very small size limit (0.1 MB)."""
|
|
433
|
+
self.log.info("Testing extra transaction pool with 0.1 MB size limit...")
|
|
434
|
+
|
|
435
|
+
limit_mb = 0.1
|
|
436
|
+
self.restart_node_with_limit(memory_mb=limit_mb)
|
|
437
|
+
|
|
438
|
+
test_count = 100
|
|
439
|
+
rejected_txs = self.populate_extra_pool(test_count, target_size=2000)
|
|
440
|
+
indices = list(range(test_count))
|
|
441
|
+
result = self.send_compact_block(rejected_txs, indices)
|
|
442
|
+
|
|
443
|
+
# Find the boundary - how many fit vs how many were evicted
|
|
444
|
+
num_evicted = len(result["missing_indices"])
|
|
445
|
+
num_fit = test_count - num_evicted
|
|
446
|
+
|
|
447
|
+
# fill exact capacity
|
|
448
|
+
self.restart_node_with_limit(memory_mb=limit_mb)
|
|
449
|
+
rejected_txs = self.populate_extra_pool(num_fit, target_size=2000)
|
|
450
|
+
|
|
451
|
+
indices = list(range(num_fit))
|
|
452
|
+
result = self.send_compact_block(rejected_txs, indices)
|
|
453
|
+
assert result["missing_indices"] == [], f"Expected all {num_fit} transactions to fit at boundary"
|
|
454
|
+
|
|
455
|
+
# Add one more transaction - should evict exactly one
|
|
456
|
+
self.log.info("Adding one more transaction at the boundary...")
|
|
457
|
+
self.populate_extra_pool(1, target_size=2000)
|
|
458
|
+
|
|
459
|
+
# Check original transactions again
|
|
460
|
+
result = self.send_compact_block(rejected_txs, indices)
|
|
461
|
+
assert len(result["missing_indices"]) == 1, "Expected exactly 1 eviction at boundary"
|
|
462
|
+
assert result["missing_indices"] == [0], "Expected oldest transaction (0) to be evicted"
|
|
463
|
+
|
|
464
|
+
self.log.info("Small size limit boundary behavior verified - one transaction evicted when limit exceeded")
|
|
465
|
+
|
|
466
|
+
def test_extratxnsize_large_transaction_exceeds_limit(self):
|
|
467
|
+
"""Test that a transaction larger than the entire size limit is rejected."""
|
|
468
|
+
self.log.info("Testing large transaction that exceeds size limit...")
|
|
469
|
+
|
|
470
|
+
limit_mb = 0.5 # 0.5 MB/500KB
|
|
471
|
+
self.restart_node_with_limit(memory_mb=limit_mb)
|
|
472
|
+
|
|
473
|
+
# Create a 600KB transaction (larger than 500KB limit)
|
|
474
|
+
# This should be rejected from mempool AND not stored in extra pool
|
|
475
|
+
rejected_txs = self.populate_extra_pool(1, target_size=600000) # 600 KB
|
|
476
|
+
|
|
477
|
+
# try block reconstruction
|
|
478
|
+
result = self.send_compact_block(rejected_txs, [0])
|
|
479
|
+
|
|
480
|
+
# Verify the transaction is NOT available (was not stored in extra pool)
|
|
481
|
+
assert len(result["missing_indices"]) == 1, "Large transaction should not be stored in extra pool"
|
|
482
|
+
|
|
483
|
+
def run_test(self):
|
|
484
|
+
self.wallet = MiniWallet(self.nodes[0])
|
|
485
|
+
|
|
486
|
+
# Setup the p2p connection
|
|
487
|
+
self.segwit_node = self.nodes[0].add_p2p_connection(TestP2PConn())
|
|
488
|
+
|
|
489
|
+
# Create UTXOs for testing
|
|
490
|
+
self.make_utxos()
|
|
491
|
+
|
|
492
|
+
# Ensure segwit is active
|
|
493
|
+
assert softfork_active(self.nodes[0], "segwit")
|
|
494
|
+
|
|
495
|
+
# Test policy rejection types first
|
|
496
|
+
self.test_policy_rejection_types()
|
|
497
|
+
|
|
498
|
+
# Extra Txn capacity tests
|
|
499
|
+
self.test_extratxnpool_disabled()
|
|
500
|
+
self.test_extratxnpool_capacity_and_wraparound()
|
|
501
|
+
self.test_single_extratxnpool_capacity()
|
|
502
|
+
self.test_extratxn_invalid_parameters()
|
|
503
|
+
|
|
504
|
+
# Extra Txn size tests
|
|
505
|
+
self.test_extratxnsize_zero_limit()
|
|
506
|
+
self.test_extratxnsize_eviction()
|
|
507
|
+
self.test_extratxnsize_boundary()
|
|
508
|
+
self.test_extratxnsize_small_limit()
|
|
509
|
+
self.test_extratxnsize_large_transaction_exceeds_limit()
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
if __name__ == '__main__':
|
|
513
|
+
CompactBlocksBlockReconstructionLimitTest(__file__).main()
|