diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py index 1b33724594cba..5128485ec06a1 100755 --- a/test/functional/feature_fee_estimation.py +++ b/test/functional/feature_fee_estimation.py @@ -99,8 +99,20 @@ def split_inputs(from_node, txins, txouts, initial_split=False): txouts.append({"txid": txid, "vout": 0, "amount": half_change}) txouts.append({"txid": txid, "vout": 1, "amount": rem_change}) +def check_raw_estimates(node, fees_seen): + """Call estimaterawfee and verify that the estimates meet certain invariants.""" -def check_estimates(node, fees_seen): + delta = 1.0e-6 # account for rounding error + for i in range(1, 26): + for _, e in node.estimaterawfee(i).items(): + feerate = float(e["feerate"]) + assert_greater_than(feerate, 0) + + if feerate + delta < min(fees_seen) or feerate - delta > max(fees_seen): + raise AssertionError("Estimated fee (%f) out of range (%f,%f)" + % (feerate, min(fees_seen), max(fees_seen))) + +def check_smart_estimates(node, fees_seen): """Call estimatesmartfee and verify that the estimates meet certain invariants.""" delta = 1.0e-6 # account for rounding error @@ -123,6 +135,9 @@ def check_estimates(node, fees_seen): else: assert_greater_than_or_equal(i + 1, e["blocks"]) +def check_estimates(node, fees_seen): + check_raw_estimates(node, fees_seen) + check_smart_estimates(node, fees_seen) class EstimateFeeTest(BitcoinTestFramework): def set_test_params(self): diff --git a/test/functional/rpc_estimatefee.py b/test/functional/rpc_estimatefee.py new file mode 100644 index 0000000000000..8bdecfc8cda4b --- /dev/null +++ b/test/functional/rpc_estimatefee.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test the estimatefee RPCs. + +Test the following RPCs: + - estimatesmartfee + - estimaterawfee +""" + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_raises_rpc_error + +class EstimateFeeTest(BitcoinTestFramework): + def set_test_params(self): + self.setup_clean_chain = False + self.num_nodes = 1 + + def run_test(self): + # missing required params + assert_raises_rpc_error(-1, "estimatesmartfee", self.nodes[0].estimatesmartfee) + assert_raises_rpc_error(-1, "estimaterawfee", self.nodes[0].estimaterawfee) + + # wrong type for conf_target + assert_raises_rpc_error(-3, "Expected type number, got string", self.nodes[0].estimatesmartfee, 'foo') + assert_raises_rpc_error(-3, "Expected type number, got string", self.nodes[0].estimaterawfee, 'foo') + + # wrong type for estimatesmartfee(estimate_mode) + assert_raises_rpc_error(-3, "Expected type string, got number", self.nodes[0].estimatesmartfee, 1, 1) + assert_raises_rpc_error(-8, "Invalid estimate_mode parameter", self.nodes[0].estimatesmartfee, 1, 'foo') + + # wrong type for estimaterawfee(threshold) + assert_raises_rpc_error(-3, "Expected type number, got string", self.nodes[0].estimaterawfee, 1, 'foo') + + # extra params + assert_raises_rpc_error(-1, "estimatesmartfee", self.nodes[0].estimatesmartfee, 1, 'ECONOMICAL', 1) + assert_raises_rpc_error(-1, "estimaterawfee", self.nodes[0].estimaterawfee, 1, 1, 1) + + # valid calls + self.nodes[0].estimatesmartfee(1) + # self.nodes[0].estimatesmartfee(1, None) + self.nodes[0].estimatesmartfee(1, 'ECONOMICAL') + + self.nodes[0].estimaterawfee(1) + self.nodes[0].estimaterawfee(1, None) + self.nodes[0].estimaterawfee(1, 1) + + +if __name__ == '__main__': + EstimateFeeTest().main() diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 7edb36c151434..9d87b5638c0da 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -196,6 +196,7 @@ 'wallet_fallbackfee.py', 'rpc_dumptxoutset.py', 'feature_minchainwork.py', + 'rpc_estimatefee.py', 'rpc_getblockstats.py', 'wallet_create_tx.py', 'p2p_fingerprint.py',