move initialize_chain() and initialize_chain_clean() to be methods of BitcoinTestFramework

This commit is contained in:
John Newbery 2017-03-23 16:49:02 -04:00
parent dc8fc0c73b
commit b111324acd
2 changed files with 103 additions and 92 deletions

View File

@ -8,24 +8,35 @@ from collections import deque
import logging import logging
import optparse import optparse
import os import os
import sys
import shutil import shutil
import subprocess
import sys
import tempfile import tempfile
import time import time
from .util import ( from .util import (
initialize_chain, PortSeed,
start_nodes, MAX_NODES,
bitcoind_processes,
check_json_precision,
connect_nodes_bi, connect_nodes_bi,
disable_mocktime,
disconnect_nodes, disconnect_nodes,
enable_coverage,
enable_mocktime,
get_mocktime,
get_rpc_proxy,
initialize_datadir,
log_filename,
p2p_port,
rpc_url,
set_node_times,
start_nodes,
stop_node,
stop_nodes,
sync_blocks, sync_blocks,
sync_mempools, sync_mempools,
stop_nodes, wait_for_bitcoind_start,
stop_node,
enable_coverage,
check_json_precision,
initialize_chain_clean,
PortSeed,
) )
from .authproxy import JSONRPCException from .authproxy import JSONRPCException
@ -49,9 +60,9 @@ class BitcoinTestFramework(object):
def setup_chain(self): def setup_chain(self):
self.log.info("Initializing test directory "+self.options.tmpdir) self.log.info("Initializing test directory "+self.options.tmpdir)
if self.setup_clean_chain: if self.setup_clean_chain:
initialize_chain_clean(self.options.tmpdir, self.num_nodes) self._initialize_chain_clean(self.options.tmpdir, self.num_nodes)
else: else:
initialize_chain(self.options.tmpdir, self.num_nodes, self.options.cachedir) self._initialize_chain(self.options.tmpdir, self.num_nodes, self.options.cachedir)
def stop_node(self, num_node): def stop_node(self, num_node):
stop_node(self.nodes[num_node], num_node) stop_node(self.nodes[num_node], num_node)
@ -216,6 +227,87 @@ class BitcoinTestFramework(object):
rpc_handler.setLevel(logging.DEBUG) rpc_handler.setLevel(logging.DEBUG)
rpc_logger.addHandler(rpc_handler) rpc_logger.addHandler(rpc_handler)
def _initialize_chain(self, test_dir, num_nodes, cachedir):
"""Initialize a pre-mined blockchain for use by the test.
Create a cache of a 200-block-long chain (with wallet) for MAX_NODES
Afterward, create num_nodes copies from the cache."""
assert num_nodes <= MAX_NODES
create_cache = False
for i in range(MAX_NODES):
if not os.path.isdir(os.path.join(cachedir, 'node' + str(i))):
create_cache = True
break
if create_cache:
self.log.debug("Creating data directories from cached datadir")
# find and delete old cache directories if any exist
for i in range(MAX_NODES):
if os.path.isdir(os.path.join(cachedir, "node" + str(i))):
shutil.rmtree(os.path.join(cachedir, "node" + str(i)))
# Create cache directories, run bitcoinds:
for i in range(MAX_NODES):
datadir = initialize_datadir(cachedir, i)
args = [os.getenv("BITCOIND", "bitcoind"), "-server", "-keypool=1", "-datadir=" + datadir, "-discover=0"]
if i > 0:
args.append("-connect=127.0.0.1:" + str(p2p_port(0)))
bitcoind_processes[i] = subprocess.Popen(args)
self.log.debug("initialize_chain: bitcoind started, waiting for RPC to come up")
wait_for_bitcoind_start(bitcoind_processes[i], rpc_url(i), i)
self.log.debug("initialize_chain: RPC successfully started")
rpcs = []
for i in range(MAX_NODES):
try:
rpcs.append(get_rpc_proxy(rpc_url(i), i))
except:
self.log.exception("Error connecting to node %d" % i)
sys.exit(1)
# Create a 200-block-long chain; each of the 4 first nodes
# gets 25 mature blocks and 25 immature.
# Note: To preserve compatibility with older versions of
# initialize_chain, only 4 nodes will generate coins.
#
# blocks are created with timestamps 10 minutes apart
# starting from 2010 minutes in the past
enable_mocktime()
block_time = get_mocktime() - (201 * 10 * 60)
for i in range(2):
for peer in range(4):
for j in range(25):
set_node_times(rpcs, block_time)
rpcs[peer].generate(1)
block_time += 10 * 60
# Must sync before next peer starts generating blocks
sync_blocks(rpcs)
# Shut them down, and clean up cache directories:
stop_nodes(rpcs)
disable_mocktime()
for i in range(MAX_NODES):
os.remove(log_filename(cachedir, i, "debug.log"))
os.remove(log_filename(cachedir, i, "db.log"))
os.remove(log_filename(cachedir, i, "peers.dat"))
os.remove(log_filename(cachedir, i, "fee_estimates.dat"))
for i in range(num_nodes):
from_dir = os.path.join(cachedir, "node" + str(i))
to_dir = os.path.join(test_dir, "node" + str(i))
shutil.copytree(from_dir, to_dir)
initialize_datadir(test_dir, i) # Overwrite port/rpcport in bitcoin.conf
def _initialize_chain_clean(self, test_dir, num_nodes):
"""Initialize empty blockchain for use by the test.
Create an empty blockchain and num_nodes wallets.
Useful if a test case wants complete control over initialization."""
for i in range(num_nodes):
initialize_datadir(test_dir, i)
# Test framework for doing p2p comparison testing, which sets up some bitcoind # Test framework for doing p2p comparison testing, which sets up some bitcoind
# binaries: # binaries:
# 1 binary: test binary # 1 binary: test binary

View File

@ -226,87 +226,6 @@ def wait_for_bitcoind_start(process, url, i):
raise # unknown JSON RPC exception raise # unknown JSON RPC exception
time.sleep(0.25) time.sleep(0.25)
def initialize_chain(test_dir, num_nodes, cachedir):
"""
Create a cache of a 200-block-long chain (with wallet) for MAX_NODES
Afterward, create num_nodes copies from the cache
"""
assert num_nodes <= MAX_NODES
create_cache = False
for i in range(MAX_NODES):
if not os.path.isdir(os.path.join(cachedir, 'node'+str(i))):
create_cache = True
break
if create_cache:
logger.debug("Creating data directories from cached datadir")
#find and delete old cache directories if any exist
for i in range(MAX_NODES):
if os.path.isdir(os.path.join(cachedir,"node"+str(i))):
shutil.rmtree(os.path.join(cachedir,"node"+str(i)))
# Create cache directories, run bitcoinds:
for i in range(MAX_NODES):
datadir=initialize_datadir(cachedir, i)
args = [ os.getenv("BITCOIND", "bitcoind"), "-server", "-keypool=1", "-datadir="+datadir, "-discover=0" ]
if i > 0:
args.append("-connect=127.0.0.1:"+str(p2p_port(0)))
bitcoind_processes[i] = subprocess.Popen(args)
logger.debug("initialize_chain: bitcoind started, waiting for RPC to come up")
wait_for_bitcoind_start(bitcoind_processes[i], rpc_url(i), i)
logger.debug("initialize_chain: RPC successfully started")
rpcs = []
for i in range(MAX_NODES):
try:
rpcs.append(get_rpc_proxy(rpc_url(i), i))
except:
sys.stderr.write("Error connecting to "+url+"\n")
sys.exit(1)
# Create a 200-block-long chain; each of the 4 first nodes
# gets 25 mature blocks and 25 immature.
# Note: To preserve compatibility with older versions of
# initialize_chain, only 4 nodes will generate coins.
#
# blocks are created with timestamps 10 minutes apart
# starting from 2010 minutes in the past
enable_mocktime()
block_time = get_mocktime() - (201 * 10 * 60)
for i in range(2):
for peer in range(4):
for j in range(25):
set_node_times(rpcs, block_time)
rpcs[peer].generate(1)
block_time += 10*60
# Must sync before next peer starts generating blocks
sync_blocks(rpcs)
# Shut them down, and clean up cache directories:
stop_nodes(rpcs)
disable_mocktime()
for i in range(MAX_NODES):
os.remove(log_filename(cachedir, i, "debug.log"))
os.remove(log_filename(cachedir, i, "db.log"))
os.remove(log_filename(cachedir, i, "peers.dat"))
os.remove(log_filename(cachedir, i, "fee_estimates.dat"))
for i in range(num_nodes):
from_dir = os.path.join(cachedir, "node"+str(i))
to_dir = os.path.join(test_dir, "node"+str(i))
shutil.copytree(from_dir, to_dir)
initialize_datadir(test_dir, i) # Overwrite port/rpcport in bitcoin.conf
def initialize_chain_clean(test_dir, num_nodes):
"""
Create an empty blockchain and num_nodes wallets.
Useful if a test case wants complete control over initialization.
"""
for i in range(num_nodes):
datadir=initialize_datadir(test_dir, i)
def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None, stderr=None): def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None, stderr=None):
""" """