Skip to content

Commit 63b9efa

Browse files
author
MarcoFalke
committed
Merge #16042: test: Bump MAX_NODES to 12
fa47330 test: Speed up cache creation (MarcoFalke) fa6ad7a 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 fa47330 Tree-SHA512: 9803c765ed52d344102f5a3bce57b05d88a7429dcb05ed66ed6c881fda8d87c2834d02d21b95fe9f39c0efe3b8527e13cf94f006588cde22e8c2cd50b2d517a6
2 parents 854ffca + fa47330 commit 63b9efa

File tree

3 files changed

+42
-51
lines changed

3 files changed

+42
-51
lines changed

test/functional/test_framework/test_framework.py

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
disconnect_nodes,
3030
get_datadir_path,
3131
initialize_datadir,
32-
p2p_port,
3332
sync_blocks,
3433
sync_mempools,
3534
)
@@ -468,48 +467,34 @@ def _start_logging(self):
468467
def _initialize_chain(self):
469468
"""Initialize a pre-mined blockchain for use by the test.
470469
471-
Create a cache of a 199-block-long chain (with wallet) for MAX_NODES
470+
Create a cache of a 199-block-long chain
472471
Afterward, create num_nodes copies from the cache."""
473472

473+
CACHE_NODE_ID = 0 # Use node 0 to create the cache for all other nodes
474+
cache_node_dir = get_datadir_path(self.options.cachedir, CACHE_NODE_ID)
474475
assert self.num_nodes <= MAX_NODES
475-
create_cache = False
476-
for i in range(MAX_NODES):
477-
if not os.path.isdir(get_datadir_path(self.options.cachedir, i)):
478-
create_cache = True
479-
break
480-
481-
if create_cache:
482-
self.log.debug("Creating data directories from cached datadir")
483-
484-
# find and delete old cache directories if any exist
485-
for i in range(MAX_NODES):
486-
if os.path.isdir(get_datadir_path(self.options.cachedir, i)):
487-
shutil.rmtree(get_datadir_path(self.options.cachedir, i))
488-
489-
# Create cache directories, run bitcoinds:
490-
for i in range(MAX_NODES):
491-
datadir = initialize_datadir(self.options.cachedir, i)
492-
args = [self.options.bitcoind, "-datadir=" + datadir, '-disablewallet']
493-
if i > 0:
494-
args.append("-connect=127.0.0.1:" + str(p2p_port(0)))
495-
self.nodes.append(TestNode(
496-
i,
497-
get_datadir_path(self.options.cachedir, i),
476+
477+
if not os.path.isdir(cache_node_dir):
478+
self.log.debug("Creating cache directory {}".format(cache_node_dir))
479+
480+
initialize_datadir(self.options.cachedir, CACHE_NODE_ID)
481+
self.nodes.append(
482+
TestNode(
483+
CACHE_NODE_ID,
484+
cache_node_dir,
498485
extra_conf=["bind=127.0.0.1"],
499-
extra_args=[],
486+
extra_args=['-disablewallet'],
500487
rpchost=None,
501488
timewait=self.rpc_timeout,
502489
bitcoind=self.options.bitcoind,
503490
bitcoin_cli=self.options.bitcoincli,
504491
coverage_dir=None,
505492
cwd=self.options.tmpdir,
506493
))
507-
self.nodes[i].args = args
508-
self.start_node(i)
494+
self.start_node(CACHE_NODE_ID)
509495

510496
# Wait for RPC connections to be ready
511-
for node in self.nodes:
512-
node.wait_for_rpc_connection()
497+
self.nodes[CACHE_NODE_ID].wait_for_rpc_connection()
513498

514499
# Create a 199-block-long chain; each of the 4 first nodes
515500
# gets 25 mature blocks and 25 immature.
@@ -518,29 +503,29 @@ def _initialize_chain(self):
518503
# This is needed so that we are out of IBD when the test starts,
519504
# see the tip age check in IsInitialBlockDownload().
520505
for i in range(8):
521-
self.nodes[0].generatetoaddress(25 if i != 7 else 24, self.nodes[i % 4].get_deterministic_priv_key().address)
522-
self.sync_blocks()
506+
self.nodes[CACHE_NODE_ID].generatetoaddress(
507+
nblocks=25 if i != 7 else 24,
508+
address=TestNode.PRIV_KEYS[i % 4].address,
509+
)
523510

524-
for n in self.nodes:
525-
assert_equal(n.getblockchaininfo()["blocks"], 199)
511+
assert_equal(self.nodes[CACHE_NODE_ID].getblockchaininfo()["blocks"], 199)
526512

527-
# Shut them down, and clean up cache directories:
513+
# Shut it down, and clean up cache directories:
528514
self.stop_nodes()
529515
self.nodes = []
530516

531-
def cache_path(n, *paths):
532-
return os.path.join(get_datadir_path(self.options.cachedir, n), "regtest", *paths)
517+
def cache_path(*paths):
518+
return os.path.join(cache_node_dir, "regtest", *paths)
533519

534-
for i in range(MAX_NODES):
535-
os.rmdir(cache_path(i, 'wallets')) # Remove empty wallets dir
536-
for entry in os.listdir(cache_path(i)):
537-
if entry not in ['chainstate', 'blocks']:
538-
os.remove(cache_path(i, entry))
520+
os.rmdir(cache_path('wallets')) # Remove empty wallets dir
521+
for entry in os.listdir(cache_path()):
522+
if entry not in ['chainstate', 'blocks']: # Only keep chainstate and blocks folder
523+
os.remove(cache_path(entry))
539524

540525
for i in range(self.num_nodes):
541-
from_dir = get_datadir_path(self.options.cachedir, i)
526+
self.log.debug("Copy cache directory {} to node {}".format(cache_node_dir, i))
542527
to_dir = get_datadir_path(self.options.tmpdir, i)
543-
shutil.copytree(from_dir, to_dir)
528+
shutil.copytree(cache_node_dir, to_dir)
544529
initialize_datadir(self.options.tmpdir, i) # Overwrite port/rpcport in bitcoin.conf
545530

546531
def _initialize_chain_clean(self):

test/functional/test_framework/test_node.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from .authproxy import JSONRPCException
2525
from .util import (
26+
MAX_NODES,
2627
append_config,
2728
delete_cookie_file,
2829
get_rpc_proxy,
@@ -110,10 +111,8 @@ def __init__(self, i, datadir, *, rpchost, timewait, bitcoind, bitcoin_cli, cove
110111

111112
self.p2ps = []
112113

113-
def get_deterministic_priv_key(self):
114-
"""Return a deterministic priv key in base58, that only depends on the node's index"""
115-
AddressKeyPair = collections.namedtuple('AddressKeyPair', ['address', 'key'])
116-
PRIV_KEYS = [
114+
AddressKeyPair = collections.namedtuple('AddressKeyPair', ['address', 'key'])
115+
PRIV_KEYS = [
117116
# address , privkey
118117
AddressKeyPair('mjTkW3DjgyZck4KbiRusZsqTgaYTxdSz6z', 'cVpF924EspNh8KjYsfhgY96mmxvT6DgdWiTYMtMjuM74hJaU5psW'),
119118
AddressKeyPair('msX6jQXvxiNhx3Q62PKeLPrhrqZQdSimTg', 'cUxsWyKyZ9MAQTaAhUQWJmBbSvHMwSmuv59KgxQV7oZQU3PXN3KE'),
@@ -124,8 +123,15 @@ def get_deterministic_priv_key(self):
124123
AddressKeyPair('myzuPxRwsf3vvGzEuzPfK9Nf2RfwauwYe6', 'cQMpDLJwA8DBe9NcQbdoSb1BhmFxVjWD5gRyrLZCtpuF9Zi3a9RK'),
125124
AddressKeyPair('mumwTaMtbxEPUswmLBBN3vM9oGRtGBrys8', 'cSXmRKXVcoouhNNVpcNKFfxsTsToY5pvB9DVsFksF1ENunTzRKsy'),
126125
AddressKeyPair('mpV7aGShMkJCZgbW7F6iZgrvuPHjZjH9qg', 'cSoXt6tm3pqy43UMabY6eUTmR3eSUYFtB2iNQDGgb3VUnRsQys2k'),
127-
]
128-
return PRIV_KEYS[self.index]
126+
AddressKeyPair('mq4fBNdckGtvY2mijd9am7DRsbRB4KjUkf', 'cN55daf1HotwBAgAKWVgDcoppmUNDtQSfb7XLutTLeAgVc3u8hik'),
127+
AddressKeyPair('mpFAHDjX7KregM3rVotdXzQmkbwtbQEnZ6', 'cT7qK7g1wkYEMvKowd2ZrX1E5f6JQ7TM246UfqbCiyF7kZhorpX3'),
128+
AddressKeyPair('mzRe8QZMfGi58KyWCse2exxEFry2sfF2Y7', 'cPiRWE8KMjTRxH1MWkPerhfoHFn5iHPWVK5aPqjW8NxmdwenFinJ'),
129+
]
130+
131+
def get_deterministic_priv_key(self):
132+
"""Return a deterministic priv key in base58, that only depends on the node's index"""
133+
assert len(self.PRIV_KEYS) == MAX_NODES
134+
return self.PRIV_KEYS[self.index]
129135

130136
def get_mem_rss_kilobytes(self):
131137
"""Get the memory usage (RSS) per `ps`.

test/functional/test_framework/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf'), lock=N
228228
############################################
229229

230230
# The maximum number of nodes a single test can spawn
231-
MAX_NODES = 8
231+
MAX_NODES = 12
232232
# Don't assign rpc or p2p ports lower than this
233233
PORT_MIN = 11000
234234
# The number of ports to "reserve" for p2p and rpc, each

0 commit comments

Comments
 (0)