88
99from test_framework .blocktools import COINBASE_MATURITY
1010from test_framework .test_framework import BitcoinTestFramework
11- from test_framework .messages import (
12- COIN ,
13- )
1411from test_framework .util import (
1512 assert_equal ,
1613)
1714from test_framework .wallet import MiniWallet
1815
16+ # Decorator to
17+ # 1) check that mempool is empty at the start of a subtest
18+ # 2) run the subtest, which may submit some transaction(s) to the mempool and
19+ # create a list of hex transactions
20+ # 3) testmempoolaccept the package hex and check that it fails with the error
21+ # "package-mempool-limits" for each tx
22+ # 4) after mining a block, clearing the pre-submitted transactions from mempool,
23+ # check that submitting the created package succeeds
24+ def check_package_limits (func ):
25+ def func_wrapper (self , * args , ** kwargs ):
26+ node = self .nodes [0 ]
27+ assert_equal (0 , node .getmempoolinfo ()["size" ])
28+ package_hex = func (self , * args , ** kwargs )
29+ testres_error_expected = node .testmempoolaccept (rawtxs = package_hex )
30+ assert_equal (len (testres_error_expected ), len (package_hex ))
31+ for txres in testres_error_expected :
32+ assert_equal (txres ["package-error" ], "package-mempool-limits" )
33+
34+ # Clear mempool and check that the package passes now
35+ self .generate (node , 1 )
36+ assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = package_hex )])
37+
38+ return func_wrapper
39+
40+
1941class MempoolPackageLimitsTest (BitcoinTestFramework ):
2042 def set_test_params (self ):
2143 self .num_nodes = 1
@@ -39,9 +61,9 @@ def run_test(self):
3961 self .test_anc_size_limits ()
4062 self .test_desc_size_limits ()
4163
64+ @check_package_limits
4265 def test_chain_limits_helper (self , mempool_count , package_count ):
4366 node = self .nodes [0 ]
44- assert_equal (0 , node .getmempoolinfo ()["size" ])
4567 chain_hex = []
4668
4769 chaintip_utxo = self .wallet .send_self_transfer_chain (from_node = node , chain_length = mempool_count )[- 1 ]["new_utxo" ]
@@ -50,13 +72,7 @@ def test_chain_limits_helper(self, mempool_count, package_count):
5072 tx = self .wallet .create_self_transfer (utxo_to_spend = chaintip_utxo )
5173 chaintip_utxo = tx ["new_utxo" ]
5274 chain_hex .append (tx ["hex" ])
53- testres_too_long = node .testmempoolaccept (rawtxs = chain_hex )
54- for txres in testres_too_long :
55- assert_equal (txres ["package-error" ], "package-mempool-limits" )
56-
57- # Clear mempool and check that the package passes now
58- self .generate (node , 1 )
59- assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = chain_hex )])
75+ return chain_hex
6076
6177 def test_chain_limits (self ):
6278 """Create chains from mempool and package transactions that are longer than 25,
@@ -75,6 +91,7 @@ def test_chain_limits(self):
7591 # 13 transactions in the mempool and 13 in the package.
7692 self .test_chain_limits_helper (13 , 13 )
7793
94+ @check_package_limits
7895 def test_desc_count_limits (self ):
7996 """Create an 'A' shaped package with 24 transactions in the mempool and 2 in the package:
8097 M1
@@ -92,7 +109,6 @@ def test_desc_count_limits(self):
92109 package transactions).
93110 """
94111 node = self .nodes [0 ]
95- assert_equal (0 , node .getmempoolinfo ()["size" ])
96112 self .log .info ("Check that in-mempool and in-package descendants are calculated properly in packages" )
97113 # Top parent in mempool, M1
98114 m1_utxos = self .wallet .send_self_transfer_multi (from_node = node , num_outputs = 2 )['new_utxos' ]
@@ -112,14 +128,9 @@ def test_desc_count_limits(self):
112128
113129 assert_equal (24 , node .getmempoolinfo ()["size" ])
114130 assert_equal (2 , len (package_hex ))
115- testres_too_long = node .testmempoolaccept (rawtxs = package_hex )
116- for txres in testres_too_long :
117- assert_equal (txres ["package-error" ], "package-mempool-limits" )
118-
119- # Clear mempool and check that the package passes now
120- self .generate (node , 1 )
121- assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = package_hex )])
131+ return package_hex
122132
133+ @check_package_limits
123134 def test_desc_count_limits_2 (self ):
124135 """Create a Package with 24 transaction in mempool and 2 transaction in package:
125136 M1
@@ -156,15 +167,9 @@ def test_desc_count_limits_2(self):
156167
157168 assert_equal (24 , node .getmempoolinfo ()["size" ])
158169 assert_equal (2 , len (package_hex ))
159- testres = node .testmempoolaccept (rawtxs = package_hex )
160- assert_equal (len (testres ), len (package_hex ))
161- for txres in testres :
162- assert_equal (txres ["package-error" ], "package-mempool-limits" )
163-
164- # Clear mempool and check that the package passes now
165- self .generate (node , 1 )
166- assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = package_hex )])
170+ return package_hex
167171
172+ @check_package_limits
168173 def test_anc_count_limits (self ):
169174 """Create a 'V' shaped chain with 24 transactions in the mempool and 3 in the package:
170175 M1a M1b
@@ -182,7 +187,6 @@ def test_anc_count_limits(self):
182187 and in-package ancestors are all considered together.
183188 """
184189 node = self .nodes [0 ]
185- assert_equal (0 , node .getmempoolinfo ()["size" ])
186190 package_hex = []
187191 pc_parent_utxos = []
188192
@@ -202,14 +206,9 @@ def test_anc_count_limits(self):
202206
203207 assert_equal (24 , node .getmempoolinfo ()["size" ])
204208 assert_equal (3 , len (package_hex ))
205- testres_too_long = node .testmempoolaccept (rawtxs = package_hex )
206- for txres in testres_too_long :
207- assert_equal (txres ["package-error" ], "package-mempool-limits" )
208-
209- # Clear mempool and check that the package passes now
210- self .generate (node , 1 )
211- assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = package_hex )])
209+ return package_hex
212210
211+ @check_package_limits
213212 def test_anc_count_limits_2 (self ):
214213 """Create a 'Y' shaped chain with 24 transactions in the mempool and 2 in the package:
215214 M1a M1b
@@ -227,7 +226,6 @@ def test_anc_count_limits_2(self):
227226 and in-package ancestors are all considered together.
228227 """
229228 node = self .nodes [0 ]
230- assert_equal (0 , node .getmempoolinfo ()["size" ])
231229 pc_parent_utxos = []
232230
233231 self .log .info ("Check that in-mempool and in-package ancestors are calculated properly in packages" )
@@ -244,14 +242,9 @@ def test_anc_count_limits_2(self):
244242 pd_tx = self .wallet .create_self_transfer (utxo_to_spend = pc_tx ["new_utxos" ][0 ])
245243
246244 assert_equal (24 , node .getmempoolinfo ()["size" ])
247- testres_too_long = node .testmempoolaccept (rawtxs = [pc_tx ["hex" ], pd_tx ["hex" ]])
248- for txres in testres_too_long :
249- assert_equal (txres ["package-error" ], "package-mempool-limits" )
250-
251- # Clear mempool and check that the package passes now
252- self .generate (node , 1 )
253- assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = [pc_tx ["hex" ], pd_tx ["hex" ]])])
245+ return [pc_tx ["hex" ], pd_tx ["hex" ]]
254246
247+ @check_package_limits
255248 def test_anc_count_limits_bushy (self ):
256249 """Create a tree with 20 transactions in the mempool and 6 in the package:
257250 M1...M4 M5...M8 M9...M12 M13...M16 M17...M20
@@ -264,7 +257,6 @@ def test_anc_count_limits_bushy(self):
264257 combined, PC has 25 in-mempool and in-package parents.
265258 """
266259 node = self .nodes [0 ]
267- assert_equal (0 , node .getmempoolinfo ()["size" ])
268260 package_hex = []
269261 pc_parent_utxos = []
270262 for _ in range (5 ): # Make package transactions P0 ... P4
@@ -281,14 +273,9 @@ def test_anc_count_limits_bushy(self):
281273
282274 assert_equal (20 , node .getmempoolinfo ()["size" ])
283275 assert_equal (6 , len (package_hex ))
284- testres = node .testmempoolaccept (rawtxs = package_hex )
285- for txres in testres :
286- assert_equal (txres ["package-error" ], "package-mempool-limits" )
287-
288- # Clear mempool and check that the package passes now
289- self .generate (node , 1 )
290- assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = package_hex )])
276+ return package_hex
291277
278+ @check_package_limits
292279 def test_anc_size_limits (self ):
293280 """Test Case with 2 independent transactions in the mempool and a parent + child in the
294281 package, where the package parent is the child of both mempool transactions (30KvB each):
@@ -302,10 +289,9 @@ def test_anc_size_limits(self):
302289 """
303290 node = self .nodes [0 ]
304291 parent_utxos = []
305- assert_equal (0 , node .getmempoolinfo ()["size" ])
306- parents_tx = []
307- target_weight = 1000 * 30 # 30KvB
308- high_fee = Decimal ("0.003" ) # 10 sats/vB
292+ target_vsize = 30_000
293+ high_fee = 10 * target_vsize # 10 sats/vB
294+ target_weight = target_vsize
309295 fee_rate = Decimal ("0.01" )
310296 self .log .info ("Check that in-mempool and in-package ancestor size limits are calculated properly in packages" )
311297 # Mempool transactions A and B
@@ -315,22 +301,17 @@ def test_anc_size_limits(self):
315301 parent_utxos .append (bulked_tx ["new_utxo" ])
316302
317303 # Package transaction C
318- pc_tx = self .wallet .create_self_transfer_multi (utxos_to_spend = parent_utxos , fee_per_output = int ( high_fee * COIN ) , target_weight = target_weight )
304+ pc_tx = self .wallet .create_self_transfer_multi (utxos_to_spend = parent_utxos , fee_per_output = high_fee , target_weight = target_weight )
319305
320306 # Package transaction D
321307 pd_tx = self .wallet .create_self_transfer (utxo_to_spend = pc_tx ["new_utxos" ][0 ], target_weight = target_weight , fee_rate = fee_rate )
322308
323309 assert_equal (2 , node .getmempoolinfo ()["size" ])
324- testres_too_heavy = node .testmempoolaccept (rawtxs = [pc_tx ["hex" ], pd_tx ["hex" ]])
325- for txres in testres_too_heavy :
326- assert_equal (txres ["package-error" ], "package-mempool-limits" )
327-
328- # Clear mempool and check that the package passes now
329- self .generate (node , 1 )
330- assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = [pc_tx ["hex" ], pd_tx ["hex" ]])])
310+ return [pc_tx ["hex" ], pd_tx ["hex" ]]
331311
312+ @check_package_limits
332313 def test_desc_size_limits (self ):
333- """Create 3 mempool transactions and 2 package transactions (25KvB each):
314+ """Create 3 mempool transactions and 2 package transactions (21KvB each):
334315 Ma
335316 ^ ^
336317 Mb Mc
@@ -340,12 +321,12 @@ def test_desc_size_limits(self):
340321 and in-package descendants are all considered together.
341322 """
342323 node = self .nodes [0 ]
343- assert_equal ( 0 , node . getmempoolinfo ()[ "size" ])
344- target_weight = 21 * 1000
345- high_fee = Decimal ( "0.0021" ) # 10 sats/vB
324+ target_vsize = 21_000
325+ high_fee = 10 * target_vsize # 10 sats/vB
326+ target_weight = target_vsize
346327 self .log .info ("Check that in-mempool and in-package descendant sizes are calculated properly in packages" )
347328 # Top parent in mempool, Ma
348- ma_tx = self .wallet .create_self_transfer_multi (num_outputs = 2 , fee_per_output = int ( high_fee / 2 * COIN ) , target_weight = target_weight )
329+ ma_tx = self .wallet .create_self_transfer_multi (num_outputs = 2 , fee_per_output = high_fee // 2 , target_weight = target_weight )
349330 self .wallet .sendrawtransaction (from_node = node , tx_hex = ma_tx ["hex" ])
350331
351332 package_hex = []
@@ -360,13 +341,8 @@ def test_desc_size_limits(self):
360341
361342 assert_equal (3 , node .getmempoolinfo ()["size" ])
362343 assert_equal (2 , len (package_hex ))
363- testres_too_heavy = node .testmempoolaccept (rawtxs = package_hex )
364- for txres in testres_too_heavy :
365- assert_equal (txres ["package-error" ], "package-mempool-limits" )
344+ return package_hex
366345
367- # Clear mempool and check that the package passes now
368- self .generate (node , 1 )
369- assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = package_hex )])
370346
371347if __name__ == "__main__" :
372348 MempoolPackageLimitsTest ().main ()
0 commit comments