Repository: bitcoin/bitcoin
File: test/functional/p2p_orphan_handling.py (Python)

Code before:
            honest_peer.send_and_ping(msg_tx(tx_child["tx"]))

        # 5. After first parent request times out, the node sends another one for the missing parent
        # of the real orphan child.
        node.bumpmocktime(GETDATA_TX_INTERVAL)
        honest_peer.wait_for_getdata([parent_txid_int])
        honest_peer.send_and_ping(msg_tx(tx_parent["tx"]))

        # 6. After parent is accepted, orphans should be reconsidered.
        # The real child should be accepted and the fake one rejected. This may happen in either
        # order since the message-processing is randomized. If tx_orphan_bad_wit is validated first,
        # its consensus error leads to disconnection of bad_peer. If tx_child is validated first,
        # tx_orphan_bad_wit is rejected for txn-same-nonwitness-data-in-mempool (no punishment).
        node_mempool = node.getrawmempool()
        assert tx_parent["txid"] in node_mempool
        assert tx_child["txid"] in node_mempool
        assert_equal(node.getmempoolentry(tx_child["txid"])["wtxid"], tx_child["wtxid"])


    def run_test(self):
        self.nodes[0].setmocktime(int(time.time()))
        self.wallet_nonsegwit = MiniWallet(self.nodes[0], mode=MiniWalletMode.RAW_P2PK)
        self.generate(self.wallet_nonsegwit, 10)
        self.wallet = MiniWallet(self.nodes[0])
        self.generate(self.wallet, 160)
        self.test_arrival_timing_orphan()
        self.test_orphan_rejected_parents_exceptions()
        self.test_orphan_multiple_parents()
        self.test_orphans_overlapping_parents()
        self.test_orphan_of_orphan()
        self.test_orphan_inherit_rejection()
        self.test_same_txid_orphan()
        self.test_same_txid_orphan_of_orphan()
        self.test_orphan_txid_inv()


if __name__ == '__main__':
    OrphanHandlingTest(__file__).main()


Review comment (suggestion):
Generating 160 blocks might be overkill. The following generates one and moves `node = self.nodes[0]` to just under the opening log (to match other functions).

```diff
diff --git a/test/functional/p2p_orphan_handling.py b/test/functional/p2p_orphan_handling.py
index 0a88b4c9587..5276814a087 100755
--- a/test/functional/p2p_orphan_handling.py
+++ b/test/functional/p2p_orphan_handling.py
@@ -572,9 +572,9 @@ class OrphanHandlingTest(BitcoinTestFramework):
     @cleanup
     def test_max_orphan_amount(self):
         self.log.info("Check that we never exceed our storage limits for orphans")
-
-        self.generate(self.wallet, 160)
         node = self.nodes[0]
+
+        self.generate(self.wallet, 1)
         peer_1 = node.add_p2p_connection(P2PInterface())
 
         self.log.info("Check that orphanage is empty on start of test")
```

Code after:
        node.bumpmocktime(TXREQUEST_TIME_SKIP)
        honest_peer.wait_for_getdata([child_txid_int])
        with node.assert_debug_log(["stored orphan tx"]):
            honest_peer.send_and_ping(msg_tx(tx_child["tx"]))

        # 5. After first parent request times out, the node sends another one for the missing parent
        # of the real orphan child.
        node.bumpmocktime(GETDATA_TX_INTERVAL)
        honest_peer.wait_for_getdata([parent_txid_int])
        honest_peer.send_and_ping(msg_tx(tx_parent["tx"]))

        # 6. After parent is accepted, orphans should be reconsidered.
        # The real child should be accepted and the fake one rejected. This may happen in either
        # order since the message-processing is randomized. If tx_orphan_bad_wit is validated first,
        # its consensus error leads to disconnection of bad_peer. If tx_child is validated first,
        # tx_orphan_bad_wit is rejected for txn-same-nonwitness-data-in-mempool (no punishment).
        node_mempool = node.getrawmempool()
        assert tx_parent["txid"] in node_mempool
        assert tx_child["txid"] in node_mempool
        assert_equal(node.getmempoolentry(tx_child["txid"])["wtxid"], tx_child["wtxid"])

    @cleanup
    def test_max_orphan_amount(self):
        self.log.info("Check that we never exceed our storage limits for orphans")

        node = self.nodes[0]
        self.generate(self.wallet, 1)
        peer_1 = node.add_p2p_connection(P2PInterface())

        self.log.info("Check that orphanage is empty on start of test")
        assert len(node.getorphantxs()) == 0

        self.log.info("Filling up orphanage with " + str(DEFAULT_MAX_ORPHAN_TRANSACTIONS) + "(DEFAULT_MAX_ORPHAN_TRANSACTIONS) orphans")
        orphans = []
        parent_orphans = []
        for _ in range(DEFAULT_MAX_ORPHAN_TRANSACTIONS):
            tx_parent_1 = self.wallet.create_self_transfer()
            tx_child_1 = self.wallet.create_self_transfer(utxo_to_spend=tx_parent_1["new_utxo"])
            parent_orphans.append(tx_parent_1["tx"])
            orphans.append(tx_child_1["tx"])
            peer_1.send_message(msg_tx(tx_child_1["tx"]))

        peer_1.sync_with_ping()
        orphanage = node.getorphantxs()
        assert_equal(len(orphanage), DEFAULT_MAX_ORPHAN_TRANSACTIONS)

        for orphan in orphans:
            assert tx_in_orphanage(node, orphan)

        self.log.info("Check that we do not add more than the max orphan amount")
        tx_parent_1 = self.wallet.create_self_transfer()