Skip to content

Commit 25bf86a

Browse files
committed
[test]: ensure estimatesmartfee default mode is economical
1 parent 41a2545 commit 25bf86a

File tree

1 file changed

+47
-7
lines changed

1 file changed

+47
-7
lines changed

test/functional/feature_fee_estimation.py

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ def make_tx(wallet, utxo, feerate):
128128
fee_rate=Decimal(feerate * 1000) / COIN,
129129
)
130130

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+
131139

132140
class EstimateFeeTest(BitcoinTestFramework):
133141
def set_test_params(self):
@@ -382,6 +390,40 @@ def test_acceptstalefeeestimates_option(self):
382390
self.start_node(0,extra_args=["-acceptstalefeeestimates"])
383391
assert_equal(self.nodes[0].estimatesmartfee(1)["feerate"], fee_rate)
384392

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+
385427

386428
def run_test(self):
387429
self.log.info("This test is time consuming, please be patient")
@@ -420,17 +462,15 @@ def run_test(self):
420462
self.log.info("Test reading old fee_estimates.dat")
421463
self.test_old_fee_estimate_file()
422464

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()
430466

431467
self.log.info("Testing estimates with RBF.")
432468
self.sanity_check_rbf_estimates(self.confutxo + self.memutxo)
433469

470+
self.clear_estimates()
471+
self.log.info("Test estimatesmartfee modes")
472+
self.test_estimation_modes()
473+
434474
self.log.info("Testing that fee estimation is disabled in blocksonly.")
435475
self.restart_node(0, ["-blocksonly"])
436476
assert_raises_rpc_error(

0 commit comments

Comments
 (0)