@@ -128,6 +128,14 @@ def make_tx(wallet, utxo, feerate):
128
128
fee_rate = Decimal (feerate * 1000 ) / COIN ,
129
129
)
130
130
131
+ def check_fee_estimates_btw_modes (node , expected_conservative , expected_economical ):
132
+ fee_est_conservative = node .estimatesmartfee (1 , estimate_mode = "conservative" )['feerate' ]
133
+ fee_est_economical = node .estimatesmartfee (1 , estimate_mode = "economical" )['feerate' ]
134
+ fee_est_default = node .estimatesmartfee (1 )['feerate' ]
135
+ assert_equal (fee_est_conservative , expected_conservative )
136
+ assert_equal (fee_est_economical , expected_economical )
137
+ assert_equal (fee_est_default , expected_economical )
138
+
131
139
132
140
class EstimateFeeTest (BitcoinTestFramework ):
133
141
def set_test_params (self ):
@@ -382,6 +390,40 @@ def test_acceptstalefeeestimates_option(self):
382
390
self .start_node (0 ,extra_args = ["-acceptstalefeeestimates" ])
383
391
assert_equal (self .nodes [0 ].estimatesmartfee (1 )["feerate" ], fee_rate )
384
392
393
+ def clear_estimates (self ):
394
+ self .log .info ("Restarting node with fresh estimation" )
395
+ self .stop_node (0 )
396
+ fee_dat = self .nodes [0 ].chain_path / "fee_estimates.dat"
397
+ os .remove (fee_dat )
398
+ self .start_node (0 )
399
+ self .connect_nodes (0 , 1 )
400
+ self .connect_nodes (0 , 2 )
401
+ assert_equal (self .nodes [0 ].estimatesmartfee (1 )["errors" ], ["Insufficient data or no feerate found" ])
402
+
403
+ def broadcast_and_mine (self , broadcaster , miner , feerate , count ):
404
+ """Broadcast and mine some number of transactions with a specified fee rate."""
405
+ for _ in range (count ):
406
+ self .wallet .send_self_transfer (from_node = broadcaster , fee_rate = feerate )
407
+ self .sync_mempools ()
408
+ self .generate (miner , 1 )
409
+
410
+ def test_estimation_modes (self ):
411
+ low_feerate = Decimal ("0.001" )
412
+ high_feerate = Decimal ("0.005" )
413
+ tx_count = 24
414
+ # Broadcast and mine high fee transactions for the first 12 blocks.
415
+ for _ in range (12 ):
416
+ self .broadcast_and_mine (self .nodes [1 ], self .nodes [2 ], high_feerate , tx_count )
417
+ check_fee_estimates_btw_modes (self .nodes [0 ], high_feerate , high_feerate )
418
+
419
+ # We now track 12 blocks; short horizon stats will start decaying.
420
+ # Broadcast and mine low fee transactions for the next 4 blocks.
421
+ for _ in range (4 ):
422
+ self .broadcast_and_mine (self .nodes [1 ], self .nodes [2 ], low_feerate , tx_count )
423
+ # conservative mode will consider longer time horizons while economical mode does not
424
+ # Check the fee estimates for both modes after mining low fee transactions.
425
+ check_fee_estimates_btw_modes (self .nodes [0 ], high_feerate , low_feerate )
426
+
385
427
386
428
def run_test (self ):
387
429
self .log .info ("This test is time consuming, please be patient" )
@@ -420,17 +462,15 @@ def run_test(self):
420
462
self .log .info ("Test reading old fee_estimates.dat" )
421
463
self .test_old_fee_estimate_file ()
422
464
423
- self .log .info ("Restarting node with fresh estimation" )
424
- self .stop_node (0 )
425
- fee_dat = os .path .join (self .nodes [0 ].chain_path , "fee_estimates.dat" )
426
- os .remove (fee_dat )
427
- self .start_node (0 )
428
- self .connect_nodes (0 , 1 )
429
- self .connect_nodes (0 , 2 )
465
+ self .clear_estimates ()
430
466
431
467
self .log .info ("Testing estimates with RBF." )
432
468
self .sanity_check_rbf_estimates (self .confutxo + self .memutxo )
433
469
470
+ self .clear_estimates ()
471
+ self .log .info ("Test estimatesmartfee modes" )
472
+ self .test_estimation_modes ()
473
+
434
474
self .log .info ("Testing that fee estimation is disabled in blocksonly." )
435
475
self .restart_node (0 , ["-blocksonly" ])
436
476
assert_raises_rpc_error (
0 commit comments