@@ -44,8 +44,8 @@ def run_test(self):
44
44
assert_equal (node .getmempoolinfo ()['minrelaytxfee' ], Decimal ('0.00001000' ))
45
45
assert_equal (node .getmempoolinfo ()['mempoolminfee' ], Decimal ('0.00001000' ))
46
46
47
- tx_batch_size = 25
48
- num_of_batches = 3
47
+ tx_batch_size = 1
48
+ num_of_batches = 75
49
49
# Generate UTXOs to flood the mempool
50
50
# 1 to create a tx initially that will be evicted from the mempool later
51
51
# 3 batches of multiple transactions with a fee rate much higher than the previous UTXO
@@ -119,7 +119,31 @@ def run_test(self):
119
119
120
120
# The node will broadcast each transaction, still abiding by its peer's fee filter
121
121
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" ]])
123
147
124
148
self .log .info ('Test passing a value below the minimum (5 MB) to -maxmempool throws an error' )
125
149
self .stop_node (0 )
0 commit comments