Remove accidental stray semicolon
[bitcoinplatinum.git] / test / functional / blockchain.py
blob5bd3bc8f833a465b73306b53b38087de8378c9ff
1 #!/usr/bin/env python3
2 # Copyright (c) 2014-2016 The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 """Test RPCs related to blockchainstate.
7 Test the following RPCs:
8 - gettxoutsetinfo
9 - getdifficulty
10 - getbestblockhash
11 - getblockhash
12 - getblockheader
13 - getchaintxstats
14 - getnetworkhashps
15 - verifychain
17 Tests correspond to code in rpc/blockchain.cpp.
18 """
20 from decimal import Decimal
21 import http.client
22 import subprocess
24 from test_framework.test_framework import BitcoinTestFramework
25 from test_framework.util import (
26 assert_equal,
27 assert_raises,
28 assert_raises_jsonrpc,
29 assert_is_hex_string,
30 assert_is_hash_string,
33 class BlockchainTest(BitcoinTestFramework):
34 def set_test_params(self):
35 self.num_nodes = 1
36 self.extra_args = [['-stopatheight=207', '-prune=1']]
38 def run_test(self):
39 self._test_getblockchaininfo()
40 self._test_getchaintxstats()
41 self._test_gettxoutsetinfo()
42 self._test_getblockheader()
43 self._test_getdifficulty()
44 self._test_getnetworkhashps()
45 self._test_stopatheight()
46 assert self.nodes[0].verifychain(4, 0)
48 def _test_getblockchaininfo(self):
49 self.log.info("Test getblockchaininfo")
51 keys = [
52 'bestblockhash',
53 'bip9_softforks',
54 'blocks',
55 'chain',
56 'chainwork',
57 'difficulty',
58 'headers',
59 'mediantime',
60 'pruned',
61 'softforks',
62 'verificationprogress',
63 'warnings',
65 res = self.nodes[0].getblockchaininfo()
66 # result should have pruneheight and default keys if pruning is enabled
67 assert_equal(sorted(res.keys()), sorted(['pruneheight'] + keys))
68 # pruneheight should be greater or equal to 0
69 assert res['pruneheight'] >= 0
71 self.restart_node(0, ['-stopatheight=207'])
72 res = self.nodes[0].getblockchaininfo()
73 # should have exact keys
74 assert_equal(sorted(res.keys()), keys)
76 def _test_getchaintxstats(self):
77 chaintxstats = self.nodes[0].getchaintxstats(1)
78 # 200 txs plus genesis tx
79 assert_equal(chaintxstats['txcount'], 201)
80 # tx rate should be 1 per 10 minutes, or 1/600
81 # we have to round because of binary math
82 assert_equal(round(chaintxstats['txrate'] * 600, 10), Decimal(1))
84 b1 = self.nodes[0].getblock(self.nodes[0].getblockhash(1))
85 b200 = self.nodes[0].getblock(self.nodes[0].getblockhash(200))
86 time_diff = b200['mediantime'] - b1['mediantime']
88 chaintxstats = self.nodes[0].getchaintxstats()
89 assert_equal(chaintxstats['time'], b200['time'])
90 assert_equal(chaintxstats['txcount'], 201)
91 assert_equal(chaintxstats['window_block_count'], 199)
92 assert_equal(chaintxstats['window_tx_count'], 199)
93 assert_equal(chaintxstats['window_interval'], time_diff)
94 assert_equal(round(chaintxstats['txrate'] * time_diff, 10), Decimal(199))
96 chaintxstats = self.nodes[0].getchaintxstats(blockhash=b1['hash'])
97 assert_equal(chaintxstats['time'], b1['time'])
98 assert_equal(chaintxstats['txcount'], 2)
99 assert_equal(chaintxstats['window_block_count'], 0)
100 assert('window_tx_count' not in chaintxstats)
101 assert('window_interval' not in chaintxstats)
102 assert('txrate' not in chaintxstats)
104 assert_raises_jsonrpc(-8, "Invalid block count: should be between 0 and the block's height - 1", self.nodes[0].getchaintxstats, 201)
106 def _test_gettxoutsetinfo(self):
107 node = self.nodes[0]
108 res = node.gettxoutsetinfo()
110 assert_equal(res['total_amount'], Decimal('8725.00000000'))
111 assert_equal(res['transactions'], 200)
112 assert_equal(res['height'], 200)
113 assert_equal(res['txouts'], 200)
114 assert_equal(res['bogosize'], 17000),
115 assert_equal(res['bestblock'], node.getblockhash(200))
116 size = res['disk_size']
117 assert size > 6400
118 assert size < 64000
119 assert_equal(len(res['bestblock']), 64)
120 assert_equal(len(res['hash_serialized_2']), 64)
122 self.log.info("Test that gettxoutsetinfo() works for blockchain with just the genesis block")
123 b1hash = node.getblockhash(1)
124 node.invalidateblock(b1hash)
126 res2 = node.gettxoutsetinfo()
127 assert_equal(res2['transactions'], 0)
128 assert_equal(res2['total_amount'], Decimal('0'))
129 assert_equal(res2['height'], 0)
130 assert_equal(res2['txouts'], 0)
131 assert_equal(res2['bogosize'], 0),
132 assert_equal(res2['bestblock'], node.getblockhash(0))
133 assert_equal(len(res2['hash_serialized_2']), 64)
135 self.log.info("Test that gettxoutsetinfo() returns the same result after invalidate/reconsider block")
136 node.reconsiderblock(b1hash)
138 res3 = node.gettxoutsetinfo()
139 assert_equal(res['total_amount'], res3['total_amount'])
140 assert_equal(res['transactions'], res3['transactions'])
141 assert_equal(res['height'], res3['height'])
142 assert_equal(res['txouts'], res3['txouts'])
143 assert_equal(res['bogosize'], res3['bogosize'])
144 assert_equal(res['bestblock'], res3['bestblock'])
145 assert_equal(res['hash_serialized_2'], res3['hash_serialized_2'])
147 def _test_getblockheader(self):
148 node = self.nodes[0]
150 assert_raises_jsonrpc(-5, "Block not found",
151 node.getblockheader, "nonsense")
153 besthash = node.getbestblockhash()
154 secondbesthash = node.getblockhash(199)
155 header = node.getblockheader(besthash)
157 assert_equal(header['hash'], besthash)
158 assert_equal(header['height'], 200)
159 assert_equal(header['confirmations'], 1)
160 assert_equal(header['previousblockhash'], secondbesthash)
161 assert_is_hex_string(header['chainwork'])
162 assert_is_hash_string(header['hash'])
163 assert_is_hash_string(header['previousblockhash'])
164 assert_is_hash_string(header['merkleroot'])
165 assert_is_hash_string(header['bits'], length=None)
166 assert isinstance(header['time'], int)
167 assert isinstance(header['mediantime'], int)
168 assert isinstance(header['nonce'], int)
169 assert isinstance(header['version'], int)
170 assert isinstance(int(header['versionHex'], 16), int)
171 assert isinstance(header['difficulty'], Decimal)
173 def _test_getdifficulty(self):
174 difficulty = self.nodes[0].getdifficulty()
175 # 1 hash in 2 should be valid, so difficulty should be 1/2**31
176 # binary => decimal => binary math is why we do this check
177 assert abs(difficulty * 2**31 - 1) < 0.0001
179 def _test_getnetworkhashps(self):
180 hashes_per_second = self.nodes[0].getnetworkhashps()
181 # This should be 2 hashes every 10 minutes or 1/300
182 assert abs(hashes_per_second * 300 - 1) < 0.0001
184 def _test_stopatheight(self):
185 assert_equal(self.nodes[0].getblockcount(), 200)
186 self.nodes[0].generate(6)
187 assert_equal(self.nodes[0].getblockcount(), 206)
188 self.log.debug('Node should not stop at this height')
189 assert_raises(subprocess.TimeoutExpired, lambda: self.nodes[0].process.wait(timeout=3))
190 try:
191 self.nodes[0].generate(1)
192 except (ConnectionError, http.client.BadStatusLine):
193 pass # The node already shut down before response
194 self.log.debug('Node should stop at this height...')
195 self.nodes[0].wait_until_stopped()
196 self.start_node(0)
197 assert_equal(self.nodes[0].getblockcount(), 207)
200 if __name__ == '__main__':
201 BlockchainTest().main()