8
8
import logging
9
9
import optparse
10
10
import os
11
- import sys
12
11
import shutil
12
+ import subprocess
13
+ import sys
13
14
import tempfile
14
15
import time
15
16
16
17
from .util import (
17
- initialize_chain ,
18
- start_nodes ,
18
+ PortSeed ,
19
+ MAX_NODES ,
20
+ bitcoind_processes ,
21
+ check_json_precision ,
19
22
connect_nodes_bi ,
23
+ disable_mocktime ,
20
24
disconnect_nodes ,
25
+ enable_coverage ,
26
+ enable_mocktime ,
27
+ get_mocktime ,
28
+ get_rpc_proxy ,
29
+ initialize_datadir ,
30
+ log_filename ,
31
+ p2p_port ,
32
+ rpc_url ,
33
+ set_node_times ,
34
+ start_nodes ,
35
+ stop_node ,
36
+ stop_nodes ,
21
37
sync_blocks ,
22
38
sync_mempools ,
23
- stop_nodes ,
24
- stop_node ,
25
- enable_coverage ,
26
- check_json_precision ,
27
- initialize_chain_clean ,
28
- PortSeed ,
39
+ wait_for_bitcoind_start ,
29
40
)
30
41
from .authproxy import JSONRPCException
31
42
@@ -49,9 +60,9 @@ def add_options(self, parser):
49
60
def setup_chain (self ):
50
61
self .log .info ("Initializing test directory " + self .options .tmpdir )
51
62
if self .setup_clean_chain :
52
- initialize_chain_clean (self .options .tmpdir , self .num_nodes )
63
+ self . _initialize_chain_clean (self .options .tmpdir , self .num_nodes )
53
64
else :
54
- initialize_chain (self .options .tmpdir , self .num_nodes , self .options .cachedir )
65
+ self . _initialize_chain (self .options .tmpdir , self .num_nodes , self .options .cachedir )
55
66
56
67
def stop_node (self , num_node ):
57
68
stop_node (self .nodes [num_node ], num_node )
@@ -216,6 +227,87 @@ def _start_logging(self):
216
227
rpc_handler .setLevel (logging .DEBUG )
217
228
rpc_logger .addHandler (rpc_handler )
218
229
230
+ def _initialize_chain (self , test_dir , num_nodes , cachedir ):
231
+ """Initialize a pre-mined blockchain for use by the test.
232
+
233
+ Create a cache of a 200-block-long chain (with wallet) for MAX_NODES
234
+ Afterward, create num_nodes copies from the cache."""
235
+
236
+ assert num_nodes <= MAX_NODES
237
+ create_cache = False
238
+ for i in range (MAX_NODES ):
239
+ if not os .path .isdir (os .path .join (cachedir , 'node' + str (i ))):
240
+ create_cache = True
241
+ break
242
+
243
+ if create_cache :
244
+ self .log .debug ("Creating data directories from cached datadir" )
245
+
246
+ # find and delete old cache directories if any exist
247
+ for i in range (MAX_NODES ):
248
+ if os .path .isdir (os .path .join (cachedir , "node" + str (i ))):
249
+ shutil .rmtree (os .path .join (cachedir , "node" + str (i )))
250
+
251
+ # Create cache directories, run bitcoinds:
252
+ for i in range (MAX_NODES ):
253
+ datadir = initialize_datadir (cachedir , i )
254
+ args = [os .getenv ("BITCOIND" , "bitcoind" ), "-server" , "-keypool=1" , "-datadir=" + datadir , "-discover=0" ]
255
+ if i > 0 :
256
+ args .append ("-connect=127.0.0.1:" + str (p2p_port (0 )))
257
+ bitcoind_processes [i ] = subprocess .Popen (args )
258
+ self .log .debug ("initialize_chain: bitcoind started, waiting for RPC to come up" )
259
+ wait_for_bitcoind_start (bitcoind_processes [i ], rpc_url (i ), i )
260
+ self .log .debug ("initialize_chain: RPC successfully started" )
261
+
262
+ rpcs = []
263
+ for i in range (MAX_NODES ):
264
+ try :
265
+ rpcs .append (get_rpc_proxy (rpc_url (i ), i ))
266
+ except :
267
+ self .log .exception ("Error connecting to node %d" % i )
268
+ sys .exit (1 )
269
+
270
+ # Create a 200-block-long chain; each of the 4 first nodes
271
+ # gets 25 mature blocks and 25 immature.
272
+ # Note: To preserve compatibility with older versions of
273
+ # initialize_chain, only 4 nodes will generate coins.
274
+ #
275
+ # blocks are created with timestamps 10 minutes apart
276
+ # starting from 2010 minutes in the past
277
+ enable_mocktime ()
278
+ block_time = get_mocktime () - (201 * 10 * 60 )
279
+ for i in range (2 ):
280
+ for peer in range (4 ):
281
+ for j in range (25 ):
282
+ set_node_times (rpcs , block_time )
283
+ rpcs [peer ].generate (1 )
284
+ block_time += 10 * 60
285
+ # Must sync before next peer starts generating blocks
286
+ sync_blocks (rpcs )
287
+
288
+ # Shut them down, and clean up cache directories:
289
+ stop_nodes (rpcs )
290
+ disable_mocktime ()
291
+ for i in range (MAX_NODES ):
292
+ os .remove (log_filename (cachedir , i , "debug.log" ))
293
+ os .remove (log_filename (cachedir , i , "db.log" ))
294
+ os .remove (log_filename (cachedir , i , "peers.dat" ))
295
+ os .remove (log_filename (cachedir , i , "fee_estimates.dat" ))
296
+
297
+ for i in range (num_nodes ):
298
+ from_dir = os .path .join (cachedir , "node" + str (i ))
299
+ to_dir = os .path .join (test_dir , "node" + str (i ))
300
+ shutil .copytree (from_dir , to_dir )
301
+ initialize_datadir (test_dir , i ) # Overwrite port/rpcport in bitcoin.conf
302
+
303
+ def _initialize_chain_clean (self , test_dir , num_nodes ):
304
+ """Initialize empty blockchain for use by the test.
305
+
306
+ Create an empty blockchain and num_nodes wallets.
307
+ Useful if a test case wants complete control over initialization."""
308
+ for i in range (num_nodes ):
309
+ initialize_datadir (test_dir , i )
310
+
219
311
# Test framework for doing p2p comparison testing, which sets up some bitcoind
220
312
# binaries:
221
313
# 1 binary: test binary
0 commit comments