66
77Test the following RPCs:
88 - getblockchaininfo
9+ - getchaintxstats
910 - gettxoutsetinfo
10- - getdifficulty
11- - getbestblockhash
12- - getblockhash
1311 - getblockheader
14- - getchaintxstats
12+ - getdifficulty
1513 - getnetworkhashps
14+ - waitforblockheight
15+ - getblock
16+ - getblockhash
17+ - getbestblockhash
1618 - verifychain
1719
1820Tests correspond to code in rpc/blockchain.cpp.
4951from test_framework .wallet import MiniWallet
5052
5153
54+ HEIGHT = 200 # blocks mined
55+ TIME_RANGE_STEP = 600 # ten-minute steps
56+ TIME_RANGE_MTP = TIME_GENESIS_BLOCK + (HEIGHT - 6 ) * TIME_RANGE_STEP
57+ TIME_RANGE_END = TIME_GENESIS_BLOCK + HEIGHT * TIME_RANGE_STEP
58+
59+
5260class BlockchainTest (BitcoinTestFramework ):
5361 def set_test_params (self ):
5462 self .setup_clean_chain = True
@@ -71,12 +79,11 @@ def run_test(self):
7179 assert self .nodes [0 ].verifychain (4 , 0 )
7280
7381 def mine_chain (self ):
74- self .log .info ('Create some old blocks' )
75- for t in range (TIME_GENESIS_BLOCK , TIME_GENESIS_BLOCK + 200 * 600 , 600 ):
76- # ten-minute steps from genesis block time
82+ self .log .info (f"Generate { HEIGHT } blocks after the genesis block in ten-minute steps" )
83+ for t in range (TIME_GENESIS_BLOCK , TIME_RANGE_END , TIME_RANGE_STEP ):
7784 self .nodes [0 ].setmocktime (t )
7885 self .nodes [0 ].generatetoaddress (1 , ADDRESS_BCRT1_P2WSH_OP_TRUE )
79- assert_equal (self .nodes [0 ].getblockchaininfo ()['blocks' ], 200 )
86+ assert_equal (self .nodes [0 ].getblockchaininfo ()['blocks' ], HEIGHT )
8087
8188 def _test_getblockchaininfo (self ):
8289 self .log .info ("Test getblockchaininfo" )
@@ -99,7 +106,8 @@ def _test_getblockchaininfo(self):
99106 ]
100107 res = self .nodes [0 ].getblockchaininfo ()
101108
102- assert isinstance (res ['time' ], int )
109+ assert_equal (res ['time' ], TIME_RANGE_END - TIME_RANGE_STEP )
110+ assert_equal (res ['mediantime' ], TIME_RANGE_MTP )
103111
104112 # result should have these additional pruning keys if manual pruning is enabled
105113 assert_equal (sorted (res .keys ()), sorted (['pruneheight' , 'automatic_pruning' ] + keys ))
@@ -148,8 +156,8 @@ def _test_getblockchaininfo(self):
148156 'statistics' : {
149157 'period' : 144 ,
150158 'threshold' : 108 ,
151- 'elapsed' : 57 ,
152- 'count' : 57 ,
159+ 'elapsed' : HEIGHT - 143 ,
160+ 'count' : HEIGHT - 143 ,
153161 'possible' : True ,
154162 },
155163 'min_activation_height' : 0 ,
@@ -186,33 +194,33 @@ def _test_getchaintxstats(self):
186194 assert_raises_rpc_error (- 8 , "blockhash must be of length 64 (not 1, for '0')" , self .nodes [0 ].getchaintxstats , blockhash = '0' )
187195 assert_raises_rpc_error (- 8 , "blockhash must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')" , self .nodes [0 ].getchaintxstats , blockhash = 'ZZZ0000000000000000000000000000000000000000000000000000000000000' )
188196 assert_raises_rpc_error (- 5 , "Block not found" , self .nodes [0 ].getchaintxstats , blockhash = '0000000000000000000000000000000000000000000000000000000000000000' )
189- blockhash = self .nodes [0 ].getblockhash (200 )
197+ blockhash = self .nodes [0 ].getblockhash (HEIGHT )
190198 self .nodes [0 ].invalidateblock (blockhash )
191199 assert_raises_rpc_error (- 8 , "Block is not in main chain" , self .nodes [0 ].getchaintxstats , blockhash = blockhash )
192200 self .nodes [0 ].reconsiderblock (blockhash )
193201
194202 chaintxstats = self .nodes [0 ].getchaintxstats (nblocks = 1 )
195203 # 200 txs plus genesis tx
196- assert_equal (chaintxstats ['txcount' ], 201 )
204+ assert_equal (chaintxstats ['txcount' ], HEIGHT + 1 )
197205 # tx rate should be 1 per 10 minutes, or 1/600
198206 # we have to round because of binary math
199- assert_equal (round (chaintxstats ['txrate' ] * 600 , 10 ), Decimal (1 ))
207+ assert_equal (round (chaintxstats ['txrate' ] * TIME_RANGE_STEP , 10 ), Decimal (1 ))
200208
201209 b1_hash = self .nodes [0 ].getblockhash (1 )
202210 b1 = self .nodes [0 ].getblock (b1_hash )
203- b200_hash = self .nodes [0 ].getblockhash (200 )
211+ b200_hash = self .nodes [0 ].getblockhash (HEIGHT )
204212 b200 = self .nodes [0 ].getblock (b200_hash )
205213 time_diff = b200 ['mediantime' ] - b1 ['mediantime' ]
206214
207215 chaintxstats = self .nodes [0 ].getchaintxstats ()
208216 assert_equal (chaintxstats ['time' ], b200 ['time' ])
209- assert_equal (chaintxstats ['txcount' ], 201 )
217+ assert_equal (chaintxstats ['txcount' ], HEIGHT + 1 )
210218 assert_equal (chaintxstats ['window_final_block_hash' ], b200_hash )
211- assert_equal (chaintxstats ['window_final_block_height' ], 200 )
212- assert_equal (chaintxstats ['window_block_count' ], 199 )
213- assert_equal (chaintxstats ['window_tx_count' ], 199 )
219+ assert_equal (chaintxstats ['window_final_block_height' ], HEIGHT )
220+ assert_equal (chaintxstats ['window_block_count' ], HEIGHT - 1 )
221+ assert_equal (chaintxstats ['window_tx_count' ], HEIGHT - 1 )
214222 assert_equal (chaintxstats ['window_interval' ], time_diff )
215- assert_equal (round (chaintxstats ['txrate' ] * time_diff , 10 ), Decimal (199 ))
223+ assert_equal (round (chaintxstats ['txrate' ] * time_diff , 10 ), Decimal (HEIGHT - 1 ))
216224
217225 chaintxstats = self .nodes [0 ].getchaintxstats (blockhash = b1_hash )
218226 assert_equal (chaintxstats ['time' ], b1 ['time' ])
@@ -229,18 +237,18 @@ def _test_gettxoutsetinfo(self):
229237 res = node .gettxoutsetinfo ()
230238
231239 assert_equal (res ['total_amount' ], Decimal ('8725.00000000' ))
232- assert_equal (res ['transactions' ], 200 )
233- assert_equal (res ['height' ], 200 )
234- assert_equal (res ['txouts' ], 200 )
240+ assert_equal (res ['transactions' ], HEIGHT )
241+ assert_equal (res ['height' ], HEIGHT )
242+ assert_equal (res ['txouts' ], HEIGHT )
235243 assert_equal (res ['bogosize' ], 16800 ),
236- assert_equal (res ['bestblock' ], node .getblockhash (200 ))
244+ assert_equal (res ['bestblock' ], node .getblockhash (HEIGHT ))
237245 size = res ['disk_size' ]
238246 assert size > 6400
239247 assert size < 64000
240248 assert_equal (len (res ['bestblock' ]), 64 )
241249 assert_equal (len (res ['hash_serialized_2' ]), 64 )
242250
243- self .log .info ("Test that gettxoutsetinfo() works for blockchain with just the genesis block" )
251+ self .log .info ("Test gettxoutsetinfo works for blockchain with just the genesis block" )
244252 b1hash = node .getblockhash (1 )
245253 node .invalidateblock (b1hash )
246254
@@ -253,7 +261,7 @@ def _test_gettxoutsetinfo(self):
253261 assert_equal (res2 ['bestblock' ], node .getblockhash (0 ))
254262 assert_equal (len (res2 ['hash_serialized_2' ]), 64 )
255263
256- self .log .info ("Test that gettxoutsetinfo() returns the same result after invalidate/reconsider block" )
264+ self .log .info ("Test gettxoutsetinfo returns the same result after invalidate/reconsider block" )
257265 node .reconsiderblock (b1hash )
258266
259267 res3 = node .gettxoutsetinfo ()
@@ -262,7 +270,7 @@ def _test_gettxoutsetinfo(self):
262270 del res ['disk_size' ], res3 ['disk_size' ]
263271 assert_equal (res , res3 )
264272
265- self .log .info ("Test hash_type option for gettxoutsetinfo() " )
273+ self .log .info ("Test gettxoutsetinfo hash_type option" )
266274 # Adding hash_type 'hash_serialized_2', which is the default, should
267275 # not change the result.
268276 res4 = node .gettxoutsetinfo (hash_type = 'hash_serialized_2' )
@@ -286,18 +294,19 @@ def _test_gettxoutsetinfo(self):
286294 assert_raises_rpc_error (- 8 , "foohash is not a valid hash_type" , node .gettxoutsetinfo , "foohash" )
287295
288296 def _test_getblockheader (self ):
297+ self .log .info ("Test getblockheader" )
289298 node = self .nodes [0 ]
290299
291300 assert_raises_rpc_error (- 8 , "hash must be of length 64 (not 8, for 'nonsense')" , node .getblockheader , "nonsense" )
292301 assert_raises_rpc_error (- 8 , "hash must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')" , node .getblockheader , "ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844" )
293302 assert_raises_rpc_error (- 5 , "Block not found" , node .getblockheader , "0cf7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844" )
294303
295304 besthash = node .getbestblockhash ()
296- secondbesthash = node .getblockhash (199 )
305+ secondbesthash = node .getblockhash (HEIGHT - 1 )
297306 header = node .getblockheader (blockhash = besthash )
298307
299308 assert_equal (header ['hash' ], besthash )
300- assert_equal (header ['height' ], 200 )
309+ assert_equal (header ['height' ], HEIGHT )
301310 assert_equal (header ['confirmations' ], 1 )
302311 assert_equal (header ['previousblockhash' ], secondbesthash )
303312 assert_is_hex_string (header ['chainwork' ])
@@ -307,7 +316,7 @@ def _test_getblockheader(self):
307316 assert_is_hash_string (header ['merkleroot' ])
308317 assert_is_hash_string (header ['bits' ], length = None )
309318 assert isinstance (header ['time' ], int )
310- assert isinstance (header ['mediantime' ], int )
319+ assert_equal (header ['mediantime' ], TIME_RANGE_MTP )
311320 assert isinstance (header ['nonce' ], int )
312321 assert isinstance (header ['version' ], int )
313322 assert isinstance (int (header ['versionHex' ], 16 ), int )
@@ -325,20 +334,23 @@ def _test_getblockheader(self):
325334 assert 'nextblockhash' not in node .getblockheader (node .getbestblockhash ())
326335
327336 def _test_getdifficulty (self ):
337+ self .log .info ("Test getdifficulty" )
328338 difficulty = self .nodes [0 ].getdifficulty ()
329339 # 1 hash in 2 should be valid, so difficulty should be 1/2**31
330340 # binary => decimal => binary math is why we do this check
331341 assert abs (difficulty * 2 ** 31 - 1 ) < 0.0001
332342
333343 def _test_getnetworkhashps (self ):
344+ self .log .info ("Test getnetworkhashps" )
334345 hashes_per_second = self .nodes [0 ].getnetworkhashps ()
335346 # This should be 2 hashes every 10 minutes or 1/300
336347 assert abs (hashes_per_second * 300 - 1 ) < 0.0001
337348
338349 def _test_stopatheight (self ):
339- assert_equal (self .nodes [0 ].getblockcount (), 200 )
350+ self .log .info ("Test stopping at height" )
351+ assert_equal (self .nodes [0 ].getblockcount (), HEIGHT )
340352 self .nodes [0 ].generatetoaddress (6 , ADDRESS_BCRT1_P2WSH_OP_TRUE )
341- assert_equal (self .nodes [0 ].getblockcount (), 206 )
353+ assert_equal (self .nodes [0 ].getblockcount (), HEIGHT + 6 )
342354 self .log .debug ('Node should not stop at this height' )
343355 assert_raises (subprocess .TimeoutExpired , lambda : self .nodes [0 ].process .wait (timeout = 3 ))
344356 try :
@@ -348,7 +360,7 @@ def _test_stopatheight(self):
348360 self .log .debug ('Node should stop at this height...' )
349361 self .nodes [0 ].wait_until_stopped ()
350362 self .start_node (0 )
351- assert_equal (self .nodes [0 ].getblockcount (), 207 )
363+ assert_equal (self .nodes [0 ].getblockcount (), HEIGHT + 7 )
352364
353365 def _test_waitforblockheight (self ):
354366 self .log .info ("Test waitforblockheight" )
@@ -400,20 +412,20 @@ def _test_getblock(self):
400412 miniwallet .send_self_transfer (fee_rate = fee_per_kb , from_node = node )
401413 blockhash = node .generate (1 )[0 ]
402414
403- self .log .info ("Test that getblock with verbosity 1 doesn't include fee" )
415+ self .log .info ("Test getblock with verbosity 1 doesn't include fee" )
404416 block = node .getblock (blockhash , 1 )
405417 assert 'fee' not in block ['tx' ][1 ]
406418
407- self .log .info ('Test that getblock with verbosity 2 includes expected fee' )
419+ self .log .info ('Test getblock with verbosity 2 includes expected fee' )
408420 block = node .getblock (blockhash , 2 )
409421 tx = block ['tx' ][1 ]
410422 assert 'fee' in tx
411423 assert_equal (tx ['fee' ], tx ['vsize' ] * fee_per_byte )
412424
413- self .log .info ("Test that getblock with verbosity 2 still works with pruned Undo data" )
425+ self .log .info ("Test getblock with verbosity 2 still works with pruned Undo data" )
414426 datadir = get_datadir_path (self .options .tmpdir , 0 )
415427
416- self .log .info ("Test that getblock with invalid verbosity type returns proper error message" )
428+ self .log .info ("Test getblock with invalid verbosity type returns proper error message" )
417429 assert_raises_rpc_error (- 1 , "JSON value is not an integer as expected" , node .getblock , blockhash , "2" )
418430
419431 def move_block_file (old , new ):
0 commit comments