26
26
bulk_transaction ,
27
27
create_child_with_parents ,
28
28
make_chain ,
29
+ DEFAULT_FEE ,
29
30
)
30
31
31
32
class MempoolPackageLimitsTest (BitcoinTestFramework ):
@@ -50,6 +51,7 @@ def run_test(self):
50
51
51
52
self .test_chain_limits ()
52
53
self .test_desc_count_limits ()
54
+ self .test_desc_count_limits_2 ()
53
55
self .test_anc_count_limits ()
54
56
self .test_anc_count_limits_2 ()
55
57
self .test_anc_count_limits_bushy ()
@@ -177,6 +179,74 @@ def test_desc_count_limits(self):
177
179
node .generate (1 )
178
180
assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = package_hex )])
179
181
182
+ def test_desc_count_limits_2 (self ):
183
+ """Create a Package with 24 transaction in mempool and 2 transaction in package:
184
+ M1
185
+ ^ ^
186
+ M2 ^
187
+ . ^
188
+ . ^
189
+ . ^
190
+ M24 ^
191
+ ^
192
+ P1
193
+ ^
194
+ P2
195
+ P1 has M1 as a mempool ancestor, P2 has no in-mempool ancestors, but when
196
+ combined P2 has M1 as an ancestor and M1 exceeds descendant_limits(23 in-mempool
197
+ descendants + 2 in-package descendants, a total of 26 including itself).
198
+ """
199
+
200
+ node = self .nodes [0 ]
201
+ package_hex = []
202
+ # M1
203
+ first_coin_a = self .coins .pop ()
204
+ parent_value = (first_coin_a ["amount" ] - DEFAULT_FEE ) / 2 # Deduct reasonable fee and make 2 outputs
205
+ inputs = [{"txid" : first_coin_a ["txid" ], "vout" : 0 }]
206
+ outputs = [{self .address : parent_value }, {ADDRESS_BCRT1_P2WSH_OP_TRUE : parent_value }]
207
+ rawtx = node .createrawtransaction (inputs , outputs )
208
+
209
+ parent_signed = node .signrawtransactionwithkey (hexstring = rawtx , privkeys = self .privkeys )
210
+ assert parent_signed ["complete" ]
211
+ parent_tx = tx_from_hex (parent_signed ["hex" ])
212
+ parent_txid = parent_tx .rehash ()
213
+ node .sendrawtransaction (parent_signed ["hex" ])
214
+
215
+ # Chain M2...M24
216
+ spk = parent_tx .vout [0 ].scriptPubKey .hex ()
217
+ value = parent_value
218
+ txid = parent_txid
219
+ for i in range (23 ): # M2...M24
220
+ (tx , txhex , value , spk ) = make_chain (node , self .address , self .privkeys , txid , value , 0 , spk )
221
+ txid = tx .rehash ()
222
+ node .sendrawtransaction (txhex )
223
+
224
+ # P1
225
+ value_p1 = (parent_value - DEFAULT_FEE )
226
+ rawtx_p1 = node .createrawtransaction ([{"txid" : parent_txid , "vout" : 1 }], [{self .address : value_p1 }])
227
+ tx_child_p1 = tx_from_hex (rawtx_p1 )
228
+ tx_child_p1 .wit .vtxinwit = [CTxInWitness ()]
229
+ tx_child_p1 .wit .vtxinwit [0 ].scriptWitness .stack = [CScript ([OP_TRUE ])]
230
+ tx_child_p1_hex = tx_child_p1 .serialize ().hex ()
231
+ txid_child_p1 = tx_child_p1 .rehash ()
232
+ package_hex .append (tx_child_p1_hex )
233
+ tx_child_p1_spk = tx_child_p1 .vout [0 ].scriptPubKey .hex ()
234
+
235
+ # P2
236
+ (_ , tx_child_p2_hex , _ , _ ) = make_chain (node , self .address , self .privkeys , txid_child_p1 , value_p1 , 0 , tx_child_p1_spk )
237
+ package_hex .append (tx_child_p2_hex )
238
+
239
+ assert_equal (24 , node .getmempoolinfo ()["size" ])
240
+ assert_equal (2 , len (package_hex ))
241
+ testres = node .testmempoolaccept (rawtxs = package_hex )
242
+ assert_equal (len (testres ), len (package_hex ))
243
+ for txres in testres :
244
+ assert_equal (txres ["package-error" ], "package-mempool-limits" )
245
+
246
+ # Clear mempool and check that the package passes now
247
+ node .generate (1 )
248
+ assert all ([res ["allowed" ] for res in node .testmempoolaccept (rawtxs = package_hex )])
249
+
180
250
def test_anc_count_limits (self ):
181
251
"""Create a 'V' shaped chain with 24 transactions in the mempool and 3 in the package:
182
252
M1a M1b
0 commit comments