Merge #16042: test: Bump MAX_NODES to 12

fa47330397 test: Speed up cache creation (MarcoFalke)
fa6ad7a5ec test: Bump MAX_NODES to 12 (MarcoFalke)

Pull request description:

  When testing a combination of settings that affect the datadir (e.g. prune, blockfilter, ...) we may need a lot of datadirs.
  Bump the maximum number of nodes proactively from 8 to 12, so that caches get populated with 12 node dirs, as opposed to 8.

  Also, add an assert that the list of deterministic keys is exactly the number of max nodes (and not more than that.

  Also, create the cache faster.

ACKs for commit fa4733:
  laanwj:
    utACK fa473303972b7dad600d949dc9b303d8136cb7e7

Tree-SHA512: 9803c765ed52d344102f5a3bce57b05d88a7429dcb05ed66ed6c881fda8d87c2834d02d21b95fe9f39c0efe3b8527e13cf94f006588cde22e8c2cd50b2d517a6
This commit is contained in:
MarcoFalke 2019-05-24 07:00:54 -04:00 committed by UdjinM6
parent 5524c42b8c
commit 9e41907692
No known key found for this signature in database
GPG Key ID: 83592BD1400D58D9
2 changed files with 54 additions and 49 deletions

View File

@ -559,37 +559,29 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
rpc_handler.setLevel(logging.DEBUG) rpc_handler.setLevel(logging.DEBUG)
rpc_logger.addHandler(rpc_handler) rpc_logger.addHandler(rpc_handler)
def _initialize_chain(self, extra_args=None): def _initialize_chain(self):
"""Initialize a pre-mined blockchain for use by the test. """Initialize a pre-mined blockchain for use by the test.
Create a cache of a 199-block-long chain (with wallet) for MAX_NODES Create a cache of a 199-block-long chain
Afterward, create num_nodes copies from the cache.""" Afterward, create num_nodes copies from the cache."""
CACHE_NODE_ID = 0 # Use node 0 to create the cache for all other nodes
cache_node_dir = get_datadir_path(self.options.cachedir, CACHE_NODE_ID)
assert self.num_nodes <= MAX_NODES assert self.num_nodes <= MAX_NODES
create_cache = False
for i in range(MAX_NODES):
if not os.path.isdir(get_datadir_path(self.options.cachedir, i)):
create_cache = True
break
if create_cache: if not os.path.isdir(cache_node_dir):
self.log.debug("Creating data directories from cached datadir") self.log.debug("Creating cache directory {}".format(cache_node_dir))
# find and delete old cache directories if any exist initialize_datadir(self.options.cachedir, CACHE_NODE_ID, self.chain)
for i in range(MAX_NODES): self.nodes.append(
if os.path.isdir(get_datadir_path(self.options.cachedir, i)): TestNode(
shutil.rmtree(get_datadir_path(self.options.cachedir, i)) CACHE_NODE_ID,
cache_node_dir,
# Create cache directories, run dashds: chain=self.chain,
self.set_genesis_mocktime() extra_conf=["bind=127.0.0.1"],
for i in range(MAX_NODES): extra_args=['-disablewallet', "-mocktime=%d" % TIME_GENESIS_BLOCK],
datadir = initialize_datadir(self.options.cachedir, i, self.chain) extra_args_from_options=self.extra_args_from_options,
args = [self.options.bitcoind, "-datadir=" + datadir, "-mocktime="+str(TIME_GENESIS_BLOCK), '-disablewallet'] rpchost=None,
if i > 0:
args.append("-connect=127.0.0.1:" + str(p2p_port(0)))
if extra_args is not None:
args.extend(extra_args)
self.nodes.append(TestNode(i, get_datadir_path(self.options.cachedir, i), chain=self.chain, extra_conf=["bind=127.0.0.1"], extra_args=[], extra_args_from_options=self.extra_args_from_options, rpchost=None,
timewait=self.rpc_timeout, timewait=self.rpc_timeout,
bitcoind=self.options.bitcoind, bitcoind=self.options.bitcoind,
bitcoin_cli=self.options.bitcoincli, bitcoin_cli=self.options.bitcoincli,
@ -597,12 +589,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
coverage_dir=None, coverage_dir=None,
cwd=self.options.tmpdir, cwd=self.options.tmpdir,
)) ))
self.nodes[i].args = args self.start_node(CACHE_NODE_ID)
self.start_node(i)
# Wait for RPC connections to be ready # Wait for RPC connections to be ready
for node in self.nodes: self.nodes[CACHE_NODE_ID].wait_for_rpc_connection()
node.wait_for_rpc_connection()
# Create a 199-block-long chain; each of the 4 first nodes # Create a 199-block-long chain; each of the 4 first nodes
# gets 25 mature blocks and 25 immature. # gets 25 mature blocks and 25 immature.
@ -613,30 +603,31 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.set_genesis_mocktime() self.set_genesis_mocktime()
for i in range(8): for i in range(8):
self.bump_mocktime((25 if i != 7 else 24) * 156) self.bump_mocktime((25 if i != 7 else 24) * 156)
self.nodes[0].generatetoaddress(25 if i != 7 else 24, self.nodes[i % 4].get_deterministic_priv_key().address) self.nodes[CACHE_NODE_ID].generatetoaddress(
sync_blocks(self.nodes) nblocks=25 if i != 7 else 24,
for n in self.nodes: address=TestNode.PRIV_KEYS[i % 4].address,
assert_equal(n.getblockchaininfo()["blocks"], 199) )
# Shut them down, and clean up cache directories: assert_equal(self.nodes[CACHE_NODE_ID].getblockchaininfo()["blocks"], 199)
# Shut it down, and clean up cache directories:
self.stop_nodes() self.stop_nodes()
self.nodes = [] self.nodes = []
self.disable_mocktime() self.disable_mocktime()
def cache_path(n, *paths): def cache_path(*paths):
chain = get_chain_folder(get_datadir_path(self.options.cachedir, n), self.chain) chain = get_chain_folder(cache_node_dir, self.chain)
return os.path.join(get_datadir_path(self.options.cachedir, n), chain, *paths) return os.path.join(cache_node_dir, chain, *paths)
for i in range(MAX_NODES): os.rmdir(cache_path('wallets')) # Remove empty wallets dir
os.rmdir(cache_path(i, 'wallets')) # Remove empty wallets dir for entry in os.listdir(cache_path()):
for entry in os.listdir(cache_path(i)): if entry not in ['chainstate', 'blocks', 'indexes', 'evodb', 'llmq']: # Keep some folders
if entry not in ['chainstate', 'blocks', 'indexes', 'evodb', 'llmq', 'backups']: os.remove(cache_path(entry))
os.remove(cache_path(i, entry))
for i in range(self.num_nodes): for i in range(self.num_nodes):
from_dir = get_datadir_path(self.options.cachedir, i) self.log.debug("Copy cache directory {} to node {}".format(cache_node_dir, i))
to_dir = get_datadir_path(self.options.tmpdir, i) to_dir = get_datadir_path(self.options.tmpdir, i)
shutil.copytree(from_dir, to_dir) shutil.copytree(cache_node_dir, to_dir)
initialize_datadir(self.options.tmpdir, i, self.chain) # Overwrite port/rpcport in dash.conf initialize_datadir(self.options.tmpdir, i, self.chain) # Overwrite port/rpcport in dash.conf
def _initialize_chain_clean(self): def _initialize_chain_clean(self):

View File

@ -23,6 +23,7 @@ import collections
from .authproxy import JSONRPCException from .authproxy import JSONRPCException
from .util import ( from .util import (
MAX_NODES,
append_config, append_config,
delete_cookie_file, delete_cookie_file,
get_rpc_proxy, get_rpc_proxy,
@ -131,10 +132,8 @@ class TestNode():
self.p2ps = [] self.p2ps = []
def get_deterministic_priv_key(self): AddressKeyPair = collections.namedtuple('AddressKeyPair', ['address', 'key'])
"""Return a deterministic priv key in base58, that only depends on the node's index""" PRIV_KEYS = [
AddressKeyPair = collections.namedtuple('AddressKeyPair', ['address', 'key'])
PRIV_KEYS = [
# address , privkey # address , privkey
AddressKeyPair('yYdShjQSptFKitYLksFEUSwHe4hnbar5rf', 'cMfbiEsnG5b8Gwm6vEgfWvZLuXZNC4zsN2y7Es3An9xHRWRjmwgR'), AddressKeyPair('yYdShjQSptFKitYLksFEUSwHe4hnbar5rf', 'cMfbiEsnG5b8Gwm6vEgfWvZLuXZNC4zsN2y7Es3An9xHRWRjmwgR'),
AddressKeyPair('yfTFJgvq65UZsb9RBbpdYAAzsJoCGXqH2w', 'cStuFACUD1N6JjKQxNLUQ443qJUtSzLitKKEkA8x6utxTPZTLUtA'), AddressKeyPair('yfTFJgvq65UZsb9RBbpdYAAzsJoCGXqH2w', 'cStuFACUD1N6JjKQxNLUQ443qJUtSzLitKKEkA8x6utxTPZTLUtA'),
@ -145,8 +144,23 @@ class TestNode():
AddressKeyPair('yfy21e12jn3A3uDicNehCq486o9fMwJKMc', 'cMuko9rLDbtxCFWuBSrFgBDRSMxsLWKpJKScRGNuWKbhuQsnsjKT'), AddressKeyPair('yfy21e12jn3A3uDicNehCq486o9fMwJKMc', 'cMuko9rLDbtxCFWuBSrFgBDRSMxsLWKpJKScRGNuWKbhuQsnsjKT'),
AddressKeyPair('yURgENB3b2YRMWnbhKF7iGs3KoaVRVXsJr', 'cQhdjTMh57MaHCDk9FsWGPtftRMBUuhaYAtouWnetcewmBuSrLSM'), AddressKeyPair('yURgENB3b2YRMWnbhKF7iGs3KoaVRVXsJr', 'cQhdjTMh57MaHCDk9FsWGPtftRMBUuhaYAtouWnetcewmBuSrLSM'),
AddressKeyPair('yYC9AxBEUs3ZZxfcQvj2LUF5PVxxtqaEs7', 'cQFueiiP13mfytV3Svoe4o4Ux79fRJvwuSgHapXsnBwrHod57EeL'), AddressKeyPair('yYC9AxBEUs3ZZxfcQvj2LUF5PVxxtqaEs7', 'cQFueiiP13mfytV3Svoe4o4Ux79fRJvwuSgHapXsnBwrHod57EeL'),
] AddressKeyPair('yVs9jXGyLWLLFbpESnoppk7F8DtXcuCCTf', 'cN55daf1HotwBAgAKWVgDcoppmUNDtQSfb7XLutTLeAgVc3u8hik'),
return PRIV_KEYS[self.index] AddressKeyPair('yV3eqNNshZJ4Pv6NCyYsbdJb1ERFFygFqf', 'cT7qK7g1wkYEMvKowd2ZrX1E5f6JQ7TM246UfqbCiyF7kZhorpX3'),
AddressKeyPair('yfE8gZCiFW9Uqu21v3JGibr3WVSPQWmY8n', 'cPiRWE8KMjTRxH1MWkPerhfoHFn5iHPWVK5aPqjW8NxmdwenFinJ'),
AddressKeyPair('yLLVXzya7GzmVkjQzsCG4iDpqYJyJFDSEV', 'cVLCocFyWxzyCwEknkWvDeWneTBsh9Jf3u4yiJCYjcy3gt8Jw1cM'),
AddressKeyPair('yLNNR3HeJxgR669oRePksYmCqHuPUG79mF', 'cQawC3oUgoToGDJBw1Ub2PpDmf44kVtcaVaTcHyzXMRKGwdn9UYW'),
AddressKeyPair('yLPKVwRTXME7Q3JfKAPJ4FHEaGdWgJuhpj', 'cVcFaWTbkCUZPFTHfDs8iHurPWns5QXc5rqcfkPMHUdmv17o8UYB'),
AddressKeyPair('yLPUundzTpvjU8KYVyM4Zmnr4REf3FFvhZ', 'cRVeRmRaYuEYP9HbCZFsf1ifYYZ4KQD9rttRoTNb9wjPzhvRwqMb'),
AddressKeyPair('yLRhHqau58AS1ALtnaowv1Pyztxi1Q6fXG', 'cNYFW52pJswYbfPR9fpiRpWHEQygg5tyMih2ASPsgMgPy9SUSSEV'),
AddressKeyPair('yLRwHeMkXwYrkDzC4q12vej243AyTeWiPm', 'cRqfZ3dAp8BJUcGhSv7ueCXNGbki1bpcXEKk5dEJN344H52GuHQY'),
AddressKeyPair('yLTMCXJhG1mpaWhbHcsr7zUt9wDWuQSPSk', 'cVWGbeCT5QcVGVTL5NuiLs9JfL8HFDb9PN5Gq2xudw6ZsDFeDy1V'),
AddressKeyPair('yLU9vxiAWUdiKKxn6EazLDFq9WXrK2T7RP', 'cVCzrzfxMhUMxV34UhTmdmntAqHvosAuNo2KUZsiHZSKLm73g35o'),
]
def get_deterministic_priv_key(self):
"""Return a deterministic priv key in base58, that only depends on the node's index"""
assert len(self.PRIV_KEYS) == MAX_NODES
return self.PRIV_KEYS[self.index]
def _node_msg(self, msg: str) -> str: def _node_msg(self, msg: str) -> str:
"""Return a modified msg that identifies this node by its index as a debugging aid.""" """Return a modified msg that identifies this node by its index as a debugging aid."""