Suggestion for a few more within-block test cases, if you’re interested (can also just open a followup, have some other test ideas as well)
0diff --git a/test/functional/mempool_truc.py b/test/functional/mempool_truc.py
1index 098631b5c41..58c69f07819 100755
2--- a/test/functional/mempool_truc.py
3+++ b/test/functional/mempool_truc.py
4@@ -167,34 +167,76 @@ class MempoolTRUC(BitcoinTestFramework):
5 self.log.info("Test that, during a reorg, TRUC rules are not enforced")
6 self.check_mempool([])
7
8+ # TRUC violations across the block + mempool
9 # Testing 2<-3 versions allowed
10 tx_v2_block = self.wallet.create_self_transfer(version=2)
11-
12 # Testing 3<-2 versions allowed
13 tx_v3_block = self.wallet.create_self_transfer(version=3)
14-
15 # Testing overly-large child size
16- tx_v3_block2 = self.wallet.create_self_transfer(version=3)
17+ tx_v3_large_parent = self.wallet.create_self_transfer(version=3)
18+
19+ # TRUC violations within the block
20+ # 2<-3 versions
21+ tx_v2_parent = self.wallet.create_self_transfer(version=2)
22+ tx_v3_child = self.wallet.create_self_transfer(utxo_to_spend=tx_v2_parent["new_utxo"], version=3)
23+ # 3<-2 versions
24+ tx_v3_parent = self.wallet.create_self_transfer(version=3)
25+ tx_v2_child = self.wallet.create_self_transfer(utxo_to_spend=tx_v3_parent["new_utxo"], version=2)
26
27 # Also create a linear chain of 3 TRUC transactions that will be directly mined, followed by one v2 in-mempool after block is made
28 tx_chain_1 = self.wallet.create_self_transfer(version=3)
29 tx_chain_2 = self.wallet.create_self_transfer(utxo_to_spend=tx_chain_1["new_utxo"], version=3)
30 tx_chain_3 = self.wallet.create_self_transfer(utxo_to_spend=tx_chain_2["new_utxo"], version=3)
31
32- tx_to_mine = [tx_v3_block["hex"], tx_v2_block["hex"], tx_v3_block2["hex"], tx_chain_1["hex"], tx_chain_2["hex"], tx_chain_3["hex"]]
33+ # 1-parent-2-child group of TRUC transactions that will be directly mined.
34+ tx_1p2c_parent = self.wallet.create_self_transfer_multi(num_outputs=2, version=3)
35+ tx_1p2c_child1 = self.wallet.create_self_transfer(utxo_to_spend=tx_1p2c_parent["new_utxos"][0], version=3)
36+ tx_1p2c_child2 = self.wallet.create_self_transfer(utxo_to_spend=tx_1p2c_parent["new_utxos"][1], version=3)
37+
38+ # 2-parent-1-child group of TRUC transactions that will be directly mined.
39+ tx_2p1c_parent1 = self.wallet.create_self_transfer(version=3)
40+ tx_2p1c_parent2 = self.wallet.create_self_transfer(version=3)
41+ tx_2p1c_child = self.wallet.create_self_transfer_multi(utxos_to_spend=[tx_2p1c_parent1["new_utxo"], tx_2p1c_parent2["new_utxo"]], version=3)
42+
43+ tx_to_mine = [
44+ tx_v3_block["hex"], tx_v2_block["hex"], tx_v3_large_parent["hex"],
45+ tx_v2_parent["hex"], tx_v3_child["hex"],
46+ tx_v3_parent["hex"], tx_v2_child["hex"],
47+ tx_chain_1["hex"], tx_chain_2["hex"], tx_chain_3["hex"],
48+ tx_1p2c_parent["hex"], tx_1p2c_child1["hex"], tx_1p2c_child2["hex"],
49+ tx_2p1c_parent1["hex"], tx_2p1c_parent2["hex"], tx_2p1c_child["hex"]
50+ ]
51 block = self.generateblock(node, output="raw(42)", transactions=tx_to_mine)
52
53 self.check_mempool([])
54 tx_v2_from_v3 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v3_block["new_utxo"], version=2)
55 tx_v3_from_v2 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v2_block["new_utxo"], version=3)
56- tx_v3_child_large = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v3_block2["new_utxo"], target_vsize=1250, version=3)
57- assert_greater_than(node.getmempoolentry(tx_v3_child_large["txid"])["vsize"], TRUC_CHILD_MAX_VSIZE)
58+ tx_v3_large_child = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v3_large_parent["new_utxo"], target_vsize=1250, version=3)
59+ assert_greater_than(node.getmempoolentry(tx_v3_large_child["txid"])["vsize"], TRUC_CHILD_MAX_VSIZE)
60+
61 tx_chain_4 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_chain_3["new_utxo"], version=2)
62- self.check_mempool([tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"], tx_chain_4["txid"]])
63+ self.check_mempool([tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_large_child["txid"], tx_chain_4["txid"]])
64
65 # Reorg should have all block transactions re-accepted, ignoring TRUC enforcement
66 node.invalidateblock(block["hash"])
67- self.check_mempool([tx_v3_block["txid"], tx_v2_block["txid"], tx_v3_block2["txid"], tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"], tx_chain_1["txid"], tx_chain_2["txid"], tx_chain_3["txid"], tx_chain_4["txid"]])
68+ self.check_mempool([
69+ # 3<-2 block + mempool
70+ tx_v3_block["txid"], tx_v2_from_v3["txid"],
71+ # 2<-3 block + mempool
72+ tx_v2_block["txid"], tx_v3_from_v2["txid"],
73+ # oversized child block + mempool
74+ tx_v3_large_parent["txid"], tx_v3_large_child["txid"],
75+ # 2<-3 within the block
76+ tx_v2_parent["txid"], tx_v3_child["txid"],
77+ # 3<-2 within the block
78+ tx_v3_parent["txid"], tx_v2_child["txid"],
79+ # chain of 3 in block + 1 in mempool
80+ tx_chain_1["txid"], tx_chain_2["txid"], tx_chain_3["txid"], tx_chain_4["txid"],
81+ # 1-parent-2-child in block
82+ tx_1p2c_parent["txid"], tx_1p2c_child1["txid"], tx_1p2c_child2["txid"],
83+ # 2-parent-1-child in block
84+ tx_2p1c_parent1["txid"], tx_2p1c_parent2["txid"], tx_2p1c_child["txid"],
85+ ]) [@cleanup](/bitcoin-bitcoin/contributor/cleanup/)(extra_args=["-limitdescendantsize=10"])
86 def test_nondefault_package_limits(self):