@@ -25,7 +25,7 @@ class PruneTest(BitcoinTestFramework):
2525 def __init__ (self ):
2626 super ().__init__ ()
2727 self .setup_clean_chain = True
28- self .num_nodes = 5
28+ self .num_nodes = 6
2929
3030 # Cache for utxos, as the listunspent may take a long time later in the test
3131 self .utxo_cache_0 = []
@@ -43,12 +43,12 @@ def setup_network(self):
4343 self .nodes .append (start_node (2 , self .options .tmpdir , ["-debug" ,"-maxreceivebuffer=20000" ,"-prune=550" ], timewait = 900 ))
4444 self .prunedir = self .options .tmpdir + "/node2/regtest/blocks/"
4545
46- # Create node 3 to test manual pruning (it will be re-started with manual pruning later)
46+ # Create nodes 3 and 4 to test manual pruning (they will be re-started with manual pruning later)
4747 self .nodes .append (start_node (3 , self .options .tmpdir , ["-debug=0" ,"-maxreceivebuffer=20000" ,"-blockmaxsize=999000" ], timewait = 900 ))
48- self .manualdir = self .options .tmpdir + "/node3/regtest/blocks/"
48+ self .nodes . append ( start_node ( 4 , self .options .tmpdir , [ "-debug=0" , "-maxreceivebuffer=20000" , "-blockmaxsize=999000" ], timewait = 900 ))
4949
50- # Create node 4 to test wallet in prune mode, but do not connect
51- self .nodes .append (start_node (4 , self .options .tmpdir , ["-debug=0" , "-prune=550" ]))
50+ # Create nodes 5 to test wallet in prune mode, but do not connect
51+ self .nodes .append (start_node (5 , self .options .tmpdir , ["-debug=0" , "-prune=550" ]))
5252
5353 # Determine default relay fee
5454 self .relayfee = self .nodes [0 ].getnetworkinfo ()["relayfee" ]
@@ -57,7 +57,8 @@ def setup_network(self):
5757 connect_nodes (self .nodes [1 ], 2 )
5858 connect_nodes (self .nodes [2 ], 0 )
5959 connect_nodes (self .nodes [0 ], 3 )
60- sync_blocks (self .nodes [0 :4 ])
60+ connect_nodes (self .nodes [0 ], 4 )
61+ sync_blocks (self .nodes [0 :5 ])
6162
6263 def create_big_chain (self ):
6364 # Start by creating some coinbases we can spend later
@@ -68,7 +69,7 @@ def create_big_chain(self):
6869 for i in range (645 ):
6970 mine_large_block (self .nodes [0 ], self .utxo_cache_0 )
7071
71- sync_blocks (self .nodes [0 :4 ])
72+ sync_blocks (self .nodes [0 :5 ])
7273
7374 def test_height_min (self ):
7475 if not os .path .isfile (self .prunedir + "blk00000.dat" ):
@@ -223,68 +224,78 @@ def reorg_back(self):
223224 # Verify we can now have the data for a block previously pruned
224225 assert (self .nodes [2 ].getblock (self .forkhash )["height" ] == self .forkheight )
225226
226- def manual_test (self ):
227- # at this point, node3 has 995 blocks and has not yet run in prune mode
228- self .nodes [3 ] = start_node (3 , self .options .tmpdir , ["-debug=0" ], timewait = 900 )
229- assert_raises_message (JSONRPCException , "not in prune mode" , self .nodes [3 ].pruneblockchain , 500 )
230- stop_node (self .nodes [3 ],3 )
227+ def manual_test (self , node_number , use_timestamp ):
228+ # at this point, node has 995 blocks and has not yet run in prune mode
229+ node = self .nodes [node_number ] = start_node (node_number , self .options .tmpdir , ["-debug=0" ], timewait = 900 )
230+ assert_equal (node .getblockcount (), 995 )
231+ assert_raises_message (JSONRPCException , "not in prune mode" , node .pruneblockchain , 500 )
232+ stop_node (node , node_number )
231233
232234 # now re-start in manual pruning mode
233- self .nodes [3 ] = start_node (3 , self .options .tmpdir , ["-debug=0" ,"-prune=1" ], timewait = 900 )
234- assert_equal (self .nodes [3 ].getblockcount (), 995 )
235+ node = self .nodes [node_number ] = start_node (node_number , self .options .tmpdir , ["-debug=0" ,"-prune=1" ], timewait = 900 )
236+ assert_equal (node .getblockcount (), 995 )
237+
238+ def height (index ):
239+ if use_timestamp :
240+ return node .getblockheader (node .getblockhash (index ))["time" ]
241+ else :
242+ return index
243+
244+ def has_block (index ):
245+ return os .path .isfile (self .options .tmpdir + "/node{}/regtest/blocks/blk{:05}.dat" .format (node_number , index ))
235246
236247 # should not prune because chain tip of node 3 (995) < PruneAfterHeight (1000)
237- assert_raises_message (JSONRPCException , "Blockchain is too short for pruning" , self . nodes [ 3 ]. pruneblockchain , 500 )
248+ assert_raises_message (JSONRPCException , "Blockchain is too short for pruning" , node . pruneblockchain , height ( 500 ) )
238249
239250 # mine 6 blocks so we are at height 1001 (i.e., above PruneAfterHeight)
240- self . nodes [ 3 ] .generate (6 )
251+ node .generate (6 )
241252
242253 # negative and zero inputs should raise an exception
243254 try :
244- self . nodes [ 3 ] .pruneblockchain (- 10 )
255+ node .pruneblockchain (- 10 )
245256 raise AssertionError ("pruneblockchain(-10) should have failed." )
246257 except :
247258 pass
248259
249260 try :
250- self . nodes [ 3 ] .pruneblockchain (0 )
261+ node .pruneblockchain (0 )
251262 raise AssertionError ("pruneblockchain(0) should have failed." )
252263 except :
253264 pass
254265
255266 # height=100 too low to prune first block file so this is a no-op
256- self . nodes [ 3 ]. pruneblockchain (100 )
257- if not os . path . isfile ( self . manualdir + "blk00000.dat" ):
267+ node . pruneblockchain (height ( 100 ) )
268+ if not has_block ( 0 ):
258269 raise AssertionError ("blk00000.dat is missing when should still be there" )
259270
260271 # height=500 should prune first file
261- self . nodes [ 3 ]. pruneblockchain (500 )
262- if os . path . isfile ( self . manualdir + "blk00000.dat" ):
272+ node . pruneblockchain (height ( 500 ) )
273+ if has_block ( 0 ):
263274 raise AssertionError ("blk00000.dat is still there, should be pruned by now" )
264- if not os . path . isfile ( self . manualdir + "blk00001.dat" ):
275+ if not has_block ( 1 ):
265276 raise AssertionError ("blk00001.dat is missing when should still be there" )
266277
267278 # height=650 should prune second file
268- self . nodes [ 3 ]. pruneblockchain (650 )
269- if os . path . isfile ( self . manualdir + "blk00001.dat" ):
279+ node . pruneblockchain (height ( 650 ) )
280+ if has_block ( 1 ):
270281 raise AssertionError ("blk00001.dat is still there, should be pruned by now" )
271282
272283 # height=1000 should not prune anything more, because tip-288 is in blk00002.dat.
273- self . nodes [ 3 ]. pruneblockchain (1000 )
274- if not os . path . isfile ( self . manualdir + "blk00002.dat" ):
284+ node . pruneblockchain (height ( 1000 ) )
285+ if not has_block ( 2 ):
275286 raise AssertionError ("blk00002.dat is still there, should be pruned by now" )
276287
277288 # advance the tip so blk00002.dat and blk00003.dat can be pruned (the last 288 blocks should now be in blk00004.dat)
278- self . nodes [ 3 ] .generate (288 )
279- self . nodes [ 3 ]. pruneblockchain (1000 )
280- if os . path . isfile ( self . manualdir + "blk00002.dat" ):
289+ node .generate (288 )
290+ node . pruneblockchain (height ( 1000 ) )
291+ if has_block ( 2 ):
281292 raise AssertionError ("blk00002.dat is still there, should be pruned by now" )
282- if os . path . isfile ( self . manualdir + "blk00003.dat" ):
293+ if has_block ( 3 ):
283294 raise AssertionError ("blk00003.dat is still there, should be pruned by now" )
284295
285296 # stop node, start back up with auto-prune at 550MB, make sure still runs
286- stop_node (self . nodes [ 3 ], 3 )
287- self .nodes [3 ] = start_node (3 , self .options .tmpdir , ["-debug=0" ,"-prune=550" ], timewait = 900 )
297+ stop_node (node , node_number )
298+ self .nodes [node_number ] = start_node (node_number , self .options .tmpdir , ["-debug=0" ,"-prune=550" ], timewait = 900 )
288299
289300 print ("Success" )
290301
@@ -300,16 +311,16 @@ def wallet_test(self):
300311
301312 # check that wallet loads loads successfully when restarting a pruned node after IBD.
302313 # this was reported to fail in #7494.
303- print ("Syncing node 4 to test wallet" )
304- connect_nodes (self .nodes [0 ], 4 )
305- nds = [self .nodes [0 ], self .nodes [4 ]]
314+ print ("Syncing node 5 to test wallet" )
315+ connect_nodes (self .nodes [0 ], 5 )
316+ nds = [self .nodes [0 ], self .nodes [5 ]]
306317 sync_blocks (nds )
307318 try :
308- stop_node (self .nodes [4 ], 4 ) #stop and start to trigger rescan
309- start_node (4 , self .options .tmpdir , ["-debug=1" ,"-prune=550" ])
319+ stop_node (self .nodes [5 ], 5 ) #stop and start to trigger rescan
320+ start_node (5 , self .options .tmpdir , ["-debug=1" ,"-prune=550" ])
310321 print ("Success" )
311322 except Exception as detail :
312- raise AssertionError ("Wallet test: unable to re-start node4 " )
323+ raise AssertionError ("Wallet test: unable to re-start node5 " )
313324
314325 def run_test (self ):
315326 print ("Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)" )
@@ -326,6 +337,7 @@ def run_test(self):
326337
327338 # stop manual-pruning node with 995 blocks
328339 stop_node (self .nodes [3 ],3 )
340+ stop_node (self .nodes [4 ],4 )
329341
330342 print ("Check that we haven't started pruning yet because we're below PruneAfterHeight" )
331343 self .test_height_min ()
@@ -409,8 +421,11 @@ def run_test(self):
409421 #
410422 # N1 doesn't change because 1033 on main chain (*) is invalid
411423
412- print ("Test manual pruning" )
413- self .manual_test ()
424+ print ("Test manual pruning with block indices" )
425+ self .manual_test (3 , use_timestamp = False )
426+
427+ print ("Test manual pruning with timestamps" )
428+ self .manual_test (4 , use_timestamp = True )
414429
415430 print ("Test wallet re-scan" )
416431 self .wallet_test ()
0 commit comments