@@ -44,8 +44,8 @@ def run_test(self):
4444 assert_equal (node .getmempoolinfo ()['minrelaytxfee' ], Decimal ('0.00001000' ))
4545 assert_equal (node .getmempoolinfo ()['mempoolminfee' ], Decimal ('0.00001000' ))
4646
47- tx_batch_size = 25
48- num_of_batches = 3
47+ tx_batch_size = 1
48+ num_of_batches = 75
4949 # Generate UTXOs to flood the mempool
5050 # 1 to create a tx initially that will be evicted from the mempool later
5151 # 3 batches of multiple transactions with a fee rate much higher than the previous UTXO
@@ -119,7 +119,31 @@ def run_test(self):
119119
120120 # The node will broadcast each transaction, still abiding by its peer's fee filter
121121 peer .wait_for_broadcast ([tx ["tx" ].getwtxid () for tx in package_txns ])
122- self .generate (node , 1 )
122+
123+ self .log .info ("Check a package that passes mempoolminfee but is evicted immediately after submission" )
124+ mempoolmin_feerate = node .getmempoolinfo ()["mempoolminfee" ]
125+ current_mempool = node .getrawmempool (verbose = False )
126+ worst_feerate_btcvb = Decimal ("21000000" )
127+ for txid in current_mempool :
128+ entry = node .getmempoolentry (txid )
129+ worst_feerate_btcvb = min (worst_feerate_btcvb , entry ["fees" ]["descendant" ] / entry ["descendantsize" ])
130+ # Needs to be large enough to trigger eviction
131+ target_weight_each = 200000
132+ assert_greater_than (target_weight_each * 2 , node .getmempoolinfo ()["maxmempool" ] - node .getmempoolinfo ()["bytes" ])
133+ # Should be a true CPFP: parent's feerate is just below mempool min feerate
134+ parent_fee = (mempoolmin_feerate / 1000 ) * (target_weight_each // 4 ) - Decimal ("0.00001" )
135+ # Parent + child is above mempool minimum feerate
136+ child_fee = (worst_feerate_btcvb ) * (target_weight_each // 4 ) - Decimal ("0.00001" )
137+ # However, when eviction is triggered, these transactions should be at the bottom.
138+ # This assertion assumes parent and child are the same size.
139+ miniwallet .rescan_utxos ()
140+ tx_parent_just_below = miniwallet .create_self_transfer (fee = parent_fee , target_weight = target_weight_each )
141+ tx_child_just_above = miniwallet .create_self_transfer (utxo_to_spend = tx_parent_just_below ["new_utxo" ], fee = child_fee , target_weight = target_weight_each )
142+ # This package ranks below the lowest descendant package in the mempool
143+ assert_greater_than (worst_feerate_btcvb , (parent_fee + child_fee ) / (tx_parent_just_below ["tx" ].get_vsize () + tx_child_just_above ["tx" ].get_vsize ()))
144+ assert_greater_than (mempoolmin_feerate , (parent_fee ) / (tx_parent_just_below ["tx" ].get_vsize ()))
145+ assert_greater_than ((parent_fee + child_fee ) / (tx_parent_just_below ["tx" ].get_vsize () + tx_child_just_above ["tx" ].get_vsize ()), mempoolmin_feerate / 1000 )
146+ assert_raises_rpc_error (- 26 , "mempool full" , node .submitpackage , [tx_parent_just_below ["hex" ], tx_child_just_above ["hex" ]])
123147
124148 self .log .info ('Test passing a value below the minimum (5 MB) to -maxmempool throws an error' )
125149 self .stop_node (0 )
0 commit comments