@@ -177,98 +177,6 @@ def test_mid_package_eviction_success(self):
177
177
evicted_feerate_btc_per_kvb = entry ["fees" ]["modified" ] / (Decimal (entry ["vsize" ]) / 1000 )
178
178
assert_greater_than (evicted_feerate_btc_per_kvb , max_parent_feerate )
179
179
180
- def test_mid_package_eviction (self ):
181
- node = self .nodes [0 ]
182
- self .log .info ("Check a package where each parent passes the current mempoolminfee but would cause eviction before package submission terminates" )
183
-
184
- self .restart_node (0 , extra_args = self .extra_args [0 ])
185
-
186
- # Restarting the node resets mempool minimum feerate
187
- assert_equal (node .getmempoolinfo ()['minrelaytxfee' ], Decimal ('0.00001000' ))
188
- assert_equal (node .getmempoolinfo ()['mempoolminfee' ], Decimal ('0.00001000' ))
189
-
190
- fill_mempool (self , node )
191
- current_info = node .getmempoolinfo ()
192
- mempoolmin_feerate = current_info ["mempoolminfee" ]
193
-
194
- package_hex = []
195
- # UTXOs to be spent by the ultimate child transaction
196
- parent_utxos = []
197
-
198
- evicted_vsize = 2000
199
- # Mempool transaction which is evicted due to being at the "bottom" of the mempool when the
200
- # mempool overflows and evicts by descendant score. It's important that the eviction doesn't
201
- # happen in the middle of package evaluation, as it can invalidate the coins cache.
202
- mempool_evicted_tx = self .wallet .send_self_transfer (
203
- from_node = node ,
204
- fee_rate = mempoolmin_feerate ,
205
- target_vsize = evicted_vsize ,
206
- confirmed_only = True
207
- )
208
- # Already in mempool when package is submitted.
209
- assert mempool_evicted_tx ["txid" ] in node .getrawmempool ()
210
-
211
- # This parent spends the above mempool transaction that exists when its inputs are first
212
- # looked up, but disappears later. It is rejected for being too low fee (but eligible for
213
- # reconsideration), and its inputs are cached. When the mempool transaction is evicted, its
214
- # coin is no longer available, but the cache could still contains the tx.
215
- cpfp_parent = self .wallet .create_self_transfer (
216
- utxo_to_spend = mempool_evicted_tx ["new_utxo" ],
217
- fee_rate = mempoolmin_feerate - Decimal ('0.00001' ),
218
- confirmed_only = True )
219
- package_hex .append (cpfp_parent ["hex" ])
220
- parent_utxos .append (cpfp_parent ["new_utxo" ])
221
- assert_equal (node .testmempoolaccept ([cpfp_parent ["hex" ]])[0 ]["reject-reason" ], "mempool min fee not met" )
222
-
223
- self .wallet .rescan_utxos ()
224
-
225
- # Series of parents that don't need CPFP and are submitted individually. Each one is large and
226
- # high feerate, which means they should trigger eviction but not be evicted.
227
- parent_vsize = 25000
228
- num_big_parents = 3
229
- # Need to be large enough to trigger eviction
230
- # (note that the mempool usage of a tx is about three times its vsize)
231
- assert_greater_than (parent_vsize * num_big_parents * 3 , current_info ["maxmempool" ] - current_info ["bytes" ])
232
- parent_feerate = 100 * mempoolmin_feerate
233
-
234
- big_parent_txids = []
235
- for i in range (num_big_parents ):
236
- parent = self .wallet .create_self_transfer (fee_rate = parent_feerate , target_vsize = parent_vsize , confirmed_only = True )
237
- parent_utxos .append (parent ["new_utxo" ])
238
- package_hex .append (parent ["hex" ])
239
- big_parent_txids .append (parent ["txid" ])
240
- # There is room for each of these transactions independently
241
- assert node .testmempoolaccept ([parent ["hex" ]])[0 ]["allowed" ]
242
-
243
- # Create a child spending everything, bumping cpfp_parent just above mempool minimum
244
- # feerate. It's important not to bump too much as otherwise mempool_evicted_tx would not be
245
- # evicted, making this test much less meaningful.
246
- approx_child_vsize = self .wallet .create_self_transfer_multi (utxos_to_spend = parent_utxos )["tx" ].get_vsize ()
247
- cpfp_fee = (mempoolmin_feerate / 1000 ) * (cpfp_parent ["tx" ].get_vsize () + approx_child_vsize ) - cpfp_parent ["fee" ]
248
- # Specific number of satoshis to fit within a small window. The parent_cpfp + child package needs to be
249
- # - When there is mid-package eviction, high enough feerate to meet the new mempoolminfee
250
- # - When there is no mid-package eviction, low enough feerate to be evicted immediately after submission.
251
- magic_satoshis = 1200
252
- cpfp_satoshis = int (cpfp_fee * COIN ) + magic_satoshis
253
-
254
- child = self .wallet .create_self_transfer_multi (utxos_to_spend = parent_utxos , fee_per_output = cpfp_satoshis )
255
- package_hex .append (child ["hex" ])
256
-
257
- # Package should be submitted, temporarily exceeding maxmempool, and then evicted.
258
- with node .assert_debug_log (expected_msgs = ["rolling minimum fee bumped" ]):
259
- assert_equal (node .submitpackage (package_hex )["package_msg" ], "transaction failed" )
260
-
261
- # Maximum size must never be exceeded.
262
- assert_greater_than (node .getmempoolinfo ()["maxmempool" ], node .getmempoolinfo ()["bytes" ])
263
-
264
- # Evicted transaction and its descendants must not be in mempool.
265
- resulting_mempool_txids = node .getrawmempool ()
266
- assert mempool_evicted_tx ["txid" ] not in resulting_mempool_txids
267
- assert cpfp_parent ["txid" ] not in resulting_mempool_txids
268
- assert child ["txid" ] not in resulting_mempool_txids
269
- for txid in big_parent_txids :
270
- assert txid in resulting_mempool_txids
271
-
272
180
def test_mid_package_replacement (self ):
273
181
node = self .nodes [0 ]
274
182
self .log .info ("Check a package where an early tx depends on a later-replaced mempool tx" )
@@ -433,7 +341,6 @@ def run_test(self):
433
341
434
342
self .test_mid_package_eviction_success ()
435
343
self .test_mid_package_replacement ()
436
- self .test_mid_package_eviction ()
437
344
self .test_rbf_carveout_disallowed ()
438
345
439
346
0 commit comments