]>
Commit | Line | Data |
---|---|---|
171ca774 GA |
1 | #!/usr/bin/env python |
2 | ||
3 | # | |
4 | # Test fee estimation code | |
5 | # | |
6 | ||
e8097f7d | 7 | from test_framework import BitcoinTestFramework |
171ca774 GA |
8 | from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException |
9 | from util import * | |
10 | ||
e8097f7d | 11 | class EstimateFeeTest(BitcoinTestFramework): |
171ca774 | 12 | |
e8097f7d GA |
13 | def setup_network(self, test_dir): |
14 | nodes = [] | |
15 | nodes.append(start_node(0, test_dir, | |
171ca774 | 16 | ["-debug=mempool", "-debug=estimatefee"])) |
e8097f7d GA |
17 | # Node1 mines small-but-not-tiny blocks, and allows free transactions. |
18 | # NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes, | |
19 | # so blockmaxsize of 2,000 is really just 1,000 bytes (room enough for | |
20 | # 6 or 7 transactions) | |
21 | nodes.append(start_node(1, test_dir, | |
22 | ["-blockprioritysize=1500", "-blockmaxsize=2000", | |
23 | "-debug=mempool", "-debug=estimatefee"])) | |
24 | connect_nodes(nodes[1], 0) | |
25 | ||
26 | # Node2 is a stingy miner, that | |
27 | # produces very small blocks (room for only 3 or so transactions) | |
28 | node2args = [ "-blockprioritysize=0", "-blockmaxsize=1500", | |
29 | "-debug=mempool", "-debug=estimatefee"] | |
30 | nodes.append(start_node(2, test_dir, node2args)) | |
31 | connect_nodes(nodes[2], 0) | |
171ca774 | 32 | |
e8097f7d GA |
33 | sync_blocks(nodes) |
34 | return nodes | |
35 | ||
36 | ||
37 | def run_test(self, nodes): | |
38 | # Prime the memory pool with pairs of transactions | |
39 | # (high-priority, random fee and zero-priority, random fee) | |
40 | min_fee = Decimal("0.001") | |
41 | fees_per_kb = []; | |
42 | for i in range(12): | |
43 | (txid, txhex, fee) = random_zeropri_transaction(nodes, Decimal("1.1"), | |
44 | min_fee, min_fee, 20) | |
171ca774 GA |
45 | tx_kbytes = (len(txhex)/2)/1000.0 |
46 | fees_per_kb.append(float(fee)/tx_kbytes) | |
171ca774 | 47 | |
e8097f7d GA |
48 | # Mine blocks with node2 until the memory pool clears: |
49 | count_start = nodes[2].getblockcount() | |
50 | while len(nodes[2].getrawmempool()) > 0: | |
51 | nodes[2].setgenerate(True, 1) | |
52 | sync_blocks(nodes) | |
53 | ||
54 | all_estimates = [ nodes[0].estimatefee(i) for i in range(1,20) ] | |
55 | print("Fee estimates, super-stingy miner: "+str([str(e) for e in all_estimates])) | |
56 | ||
57 | # Estimates should be within the bounds of what transactions fees actually were: | |
58 | delta = 1.0e-6 # account for rounding error | |
59 | for e in filter(lambda x: x >= 0, all_estimates): | |
60 | if float(e)+delta < min(fees_per_kb) or float(e)-delta > max(fees_per_kb): | |
61 | raise AssertionError("Estimated fee (%f) out of range (%f,%f)"%(float(e), min_fee_kb, max_fee_kb)) | |
62 | ||
63 | # Generate transactions while mining 30 more blocks, this time with node1: | |
64 | for i in range(30): | |
65 | for j in range(random.randrange(6-4,6+4)): | |
66 | (txid, txhex, fee) = random_transaction(nodes, Decimal("1.1"), | |
67 | Decimal("0.0"), min_fee, 20) | |
68 | tx_kbytes = (len(txhex)/2)/1000.0 | |
69 | fees_per_kb.append(float(fee)/tx_kbytes) | |
70 | nodes[1].setgenerate(True, 1) | |
71 | sync_blocks(nodes) | |
72 | ||
73 | all_estimates = [ nodes[0].estimatefee(i) for i in range(1,20) ] | |
74 | print("Fee estimates, more generous miner: "+str([ str(e) for e in all_estimates])) | |
75 | for e in filter(lambda x: x >= 0, all_estimates): | |
76 | if float(e)+delta < min(fees_per_kb) or float(e)-delta > max(fees_per_kb): | |
77 | raise AssertionError("Estimated fee (%f) out of range (%f,%f)"%(float(e), min_fee_kb, max_fee_kb)) | |
78 | ||
79 | # Finish by mining a normal-sized block: | |
80 | while len(nodes[0].getrawmempool()) > 0: | |
81 | nodes[0].setgenerate(True, 1) | |
82 | sync_blocks(nodes) | |
83 | ||
84 | final_estimates = [ nodes[0].estimatefee(i) for i in range(1,20) ] | |
85 | print("Final fee estimates: "+str([ str(e) for e in final_estimates])) | |
171ca774 | 86 | |
171ca774 GA |
87 | |
88 | if __name__ == '__main__': | |
e8097f7d | 89 | EstimateFeeTest().main() |