diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -13,6 +13,7 @@ self.setup_clean_chain = True self.num_nodes = 1 self.supports_cli = False + self.wallet_names = [] def test_config_file_parser(self): # Assume node is stopped diff --git a/test/functional/feature_dbcrash.py b/test/functional/feature_dbcrash.py --- a/test/functional/feature_dbcrash.py +++ b/test/functional/feature_dbcrash.py @@ -56,7 +56,7 @@ # long-running test self.base_args = ["-limitdescendantsize=0", "-maxmempool=0", "-rpcservertimeout=900", "-dbbatchsize=200000", - "-wallet=", "-noparkdeepreorg"] + "-noparkdeepreorg"] # Set different crash ratios and cache sizes. Note that not all of # -dbcache goes to the in-memory coins cache. @@ -68,7 +68,7 @@ # and non-standard txs (e.g. txs with "dust" outputs) self.node3_args = [ "-blockmaxsize={}".format(DEFAULT_MAX_BLOCK_SIZE), - "-acceptnonstdtxn", "-wallet="] + "-acceptnonstdtxn"] self.extra_args = [self.node0_args, self.node1_args, self.node2_args, self.node3_args] diff --git a/test/functional/feature_filelock.py b/test/functional/feature_filelock.py --- a/test/functional/feature_filelock.py +++ b/test/functional/feature_filelock.py @@ -16,7 +16,7 @@ def setup_network(self): self.add_nodes(self.num_nodes, extra_args=None) - self.nodes[0].start(['-wallet=']) + self.nodes[0].start() self.nodes[0].wait_for_rpc_connection() def run_test(self): @@ -31,6 +31,7 @@ '-datadir={}'.format(self.nodes[0].datadir), '-noserver'], expected_msg=expected_msg) if self.is_wallet_compiled(): + self.nodes[0].createwallet(self.default_wallet_name) wallet_dir = os.path.join(datadir, 'wallets') self.log.info( "Check that we can't start a second bitcoind instance using the same wallet") diff --git a/test/functional/feature_notifications.py b/test/functional/feature_notifications.py --- a/test/functional/feature_notifications.py +++ b/test/functional/feature_notifications.py @@ -52,8 +52,8 @@ "-blocknotify=echo > {}".format(os.path.join(self.blocknotify_dir, '%s'))], ["-blockversion=211", "-rescan", - "-wallet={}".format(self.wallet), "-walletnotify=echo > {}".format(os.path.join(self.walletnotify_dir, notify_outputname('%w', '%s')))]] + self.wallet_names = [self.default_wallet_name, self.wallet] super().setup_network() def run_test(self): diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py --- a/test/functional/feature_pruning.py +++ b/test/functional/feature_pruning.py @@ -88,19 +88,18 @@ # Create nodes 0 and 1 to mine. # Create node 2 to test pruning. self.full_node_default_args = ["-maxreceivebuffer=20000", "-blockmaxsize=999000", - "-checkblocks=5", "-noparkdeepreorg", "-maxreorgdepth=-1", - "-wallet="] + "-checkblocks=5", "-noparkdeepreorg", "-maxreorgdepth=-1"] # Create nodes 3 and 4 to test manual pruning (they will be re-started with manual pruning later) # Create nodes 5 to test wallet in prune mode, but do not connect self.extra_args = [self.full_node_default_args, self.full_node_default_args, - ["-wallet=", "-maxreceivebuffer=20000", "-prune=550", + ["-maxreceivebuffer=20000", "-prune=550", "-noparkdeepreorg", "-maxreorgdepth=-1"], - ["-wallet=", "-maxreceivebuffer=20000", "-blockmaxsize=999000", + ["-maxreceivebuffer=20000", "-blockmaxsize=999000", "-noparkdeepreorg", "-maxreorgdepth=-1"], - ["-wallet=", "-maxreceivebuffer=20000", "-blockmaxsize=999000", + ["-maxreceivebuffer=20000", "-blockmaxsize=999000", "-noparkdeepreorg", "-maxreorgdepth=-1"], - ["-wallet=", "-prune=550"]] + ["-prune=550"]] self.rpc_timeout = 120 def skip_test_if_missing_module(self): @@ -122,11 +121,7 @@ def setup_nodes(self): self.add_nodes(self.num_nodes, self.extra_args) self.start_nodes() - for n in self.nodes: - n.importprivkey( - privkey=n.get_deterministic_priv_key().key, - label='coinbase', - rescan=False) + self.import_deterministic_coinbase_privkeys() def create_big_chain(self): # Start by creating some coinbases we can spend later diff --git a/test/functional/feature_settings.py b/test/functional/feature_settings.py --- a/test/functional/feature_settings.py +++ b/test/functional/feature_settings.py @@ -16,6 +16,7 @@ def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 1 + self.wallet_names = [] def run_test(self): node, = self.nodes diff --git a/test/functional/rpc_getdescriptorinfo.py b/test/functional/rpc_getdescriptorinfo.py --- a/test/functional/rpc_getdescriptorinfo.py +++ b/test/functional/rpc_getdescriptorinfo.py @@ -14,6 +14,7 @@ def set_test_params(self): self.num_nodes = 1 self.extra_args = [["-disablewallet"]] + self.wallet_names = [] def test_desc(self, desc, isrange, issolvable, hasprivatekeys): info = self.nodes[0].getdescriptorinfo(desc) diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -109,11 +109,15 @@ self.rpc_timeout = 60 self.supports_cli = True self.bind_to_localhost_only = True + self.parse_args() self.default_wallet_name = "" self.wallet_data_filename = "wallet.dat" - # We run parse_args before set_test_params for tests who need to - # know the parser options during setup. - self.parse_args() + # Optional list of wallet names that can be set in set_test_params to + # create and import keys to. If unset, default is len(nodes) * + # [default_wallet_name]. If wallet names are None, wallet creation is + # skipped. If list is truncated, wallet creation is skipped and keys + # are not imported. + self.wallet_names = None self.set_test_params() if self.options.timeout_factor == 0: self.options.timeout_factor = 99999 @@ -383,27 +387,12 @@ def setup_nodes(self): """Override this method to customize test node setup""" extra_args = [[]] * self.num_nodes - wallets = [[]] * self.num_nodes if hasattr(self, "extra_args"): extra_args = self.extra_args - wallets = [[x for x in eargs if x.startswith('-wallet=')] - for eargs in extra_args] - extra_args = [x + ['-nowallet'] for x in extra_args] self.add_nodes(self.num_nodes, extra_args) self.start_nodes() - for i, n in enumerate(self.nodes): - n.extra_args.pop() - if '-wallet=0' in n.extra_args or '-nowallet' in n.extra_args or '-disablewallet' in n.extra_args or not self.is_wallet_compiled(): - continue - if '-wallet=' not in wallets[i] and not any( - [x.startswith('-wallet=') for x in wallets[i]]): - wallets[i].append('-wallet=') - for w in wallets[i]: - wallet_name = w.split('=', 1)[1] - n.createwallet( - wallet_name=wallet_name, - descriptors=self.options.descriptors) - self.import_deterministic_coinbase_privkeys() + if self.is_wallet_compiled(): + self.import_deterministic_coinbase_privkeys() if not self.setup_clean_chain: for n in self.nodes: assert_equal(n.getblockchaininfo()["blocks"], 199) @@ -419,13 +408,17 @@ assert_equal(chain_info["initialblockdownload"], False) def import_deterministic_coinbase_privkeys(self): - for n in self.nodes: - try: - n.getwalletinfo() - except JSONRPCException as e: - assert str(e).startswith('Method not found') - continue - + wallet_names = ( + [self.default_wallet_name] * len(self.nodes) + if self.wallet_names is None else self.wallet_names + ) + assert len(wallet_names) <= len(self.nodes) + for wallet_name, n in zip(wallet_names, self.nodes): + if wallet_name is not None: + n.createwallet( + wallet_name=wallet_name, + descriptors=self.options.descriptors, + load_on_startup=True) n.importprivkey( privkey=n.get_deterministic_priv_key().key, label='coinbase') diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py --- a/test/functional/tool_wallet.py +++ b/test/functional/tool_wallet.py @@ -88,7 +88,7 @@ "wallets") self.assert_raises_tool_error( f'Error initializing wallet database environment "{locked_dir}"!', - '-wallet=wallet.dat', + '-wallet=' + self.default_wallet_name, 'info', ) path = os.path.join(self.options.tmpdir, "node0", "regtest", @@ -123,7 +123,10 @@ Transactions: 0 Address Book: 1 ''') - self.assert_tool_output(out, '-wallet=wallet.dat', 'info') + self.assert_tool_output( + out, + '-wallet=' + self.default_wallet_name, + 'info') timestamp_after = self.wallet_timestamp() self.log.debug( 'Wallet file timestamp after calling info: {}'.format(timestamp_after)) @@ -167,7 +170,10 @@ Transactions: 1 Address Book: 1 ''') - self.assert_tool_output(out, '-wallet=wallet.dat', 'info') + self.assert_tool_output( + out, + '-wallet=' + self.default_wallet_name, + 'info') shasum_after = self.wallet_shasum() timestamp_after = self.wallet_timestamp() self.log.debug( @@ -209,7 +215,7 @@ def test_getwalletinfo_on_different_wallet(self): self.log.info('Starting node with arg -wallet=foo') - self.start_node(0, ['-wallet=foo']) + self.start_node(0, ['-nowallet', '-wallet=foo']) self.log.info( 'Calling getwalletinfo on a different wallet ("foo"), testing output') diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py --- a/test/functional/wallet_backup.py +++ b/test/functional/wallet_backup.py @@ -50,10 +50,10 @@ # nodes 1, 2,3 are spenders, let's give them a keypool=100 # whitelist all peers to speed up tx relay / mempool sync self.extra_args = [ - ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet="], - ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet="], - ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet="], - ["-whitelist=noban@127.0.0.1", "-wallet="], + ["-whitelist=noban@127.0.0.1", "-keypool=100"], + ["-whitelist=noban@127.0.0.1", "-keypool=100"], + ["-whitelist=noban@127.0.0.1", "-keypool=100"], + ["-whitelist=noban@127.0.0.1"], ] self.rpc_timeout = 120 diff --git a/test/functional/wallet_disable.py b/test/functional/wallet_disable.py --- a/test/functional/wallet_disable.py +++ b/test/functional/wallet_disable.py @@ -17,6 +17,7 @@ self.setup_clean_chain = True self.num_nodes = 1 self.extra_args = [["-disablewallet"]] + self.wallet_names = [] def run_test(self): # Make sure wallet is really disabled diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py --- a/test/functional/wallet_import_rescan.py +++ b/test/functional/wallet_import_rescan.py @@ -152,7 +152,7 @@ self.skip_if_no_wallet() def setup_network(self): - self.extra_args = [["-wallet="] for _ in range(self.num_nodes)] + self.extra_args = [[] for _ in range(self.num_nodes)] for i, import_node in enumerate(IMPORT_NODES, 2): if import_node.prune: self.extra_args[i] += ["-prune=1"] @@ -160,11 +160,8 @@ self.add_nodes(self.num_nodes, extra_args=self.extra_args) # Import keys with pruning disabled - self.start_nodes(extra_args=[["-wallet="]] * self.num_nodes) - for n in self.nodes: - n.importprivkey( - privkey=n.get_deterministic_priv_key().key, - label='coinbase') + self.start_nodes(extra_args=[[]] * self.num_nodes) + self.import_deterministic_coinbase_privkeys() self.stop_nodes() self.start_nodes() diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -43,7 +43,6 @@ def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 - self.extra_args = [["-wallet="], ["-wallet="]] def skip_test_if_missing_module(self): self.skip_if_no_wallet() @@ -93,7 +92,8 @@ wallet_dir("w8")) # create another dummy wallet for use in testing backups later - self.start_node(0, ["-wallet=" + self.default_wallet_name]) + self.start_node( + 0, ["-nowallet", "-wallet=" + self.default_wallet_name]) self.stop_nodes() empty_wallet = os.path.join(self.options.tmpdir, 'empty.dat') os.rename(wallet_dir(self.default_wallet_name, self.wallet_data_filename), @@ -112,7 +112,8 @@ 'w7_symlink', 'w8', self.default_wallet_name] if os.name == 'nt': wallet_names.remove('w7_symlink') - extra_args = ['-wallet={}'.format(n) for n in wallet_names] + extra_args = ['-nowallet'] + \ + ['-wallet={}'.format(n) for n in wallet_names] self.start_node(0, extra_args) assert_equal( sorted(map(lambda w: w['name'], @@ -130,7 +131,7 @@ # should not initialize if wallet path can't be created exp_stderr = "boost::filesystem::create_directory:" self.nodes[0].assert_start_raises_init_error( - ['-wallet=wallet.dat/bad'], exp_stderr, match=ErrorMatch.PARTIAL_REGEX) + ['-wallet=w8/bad'], exp_stderr, match=ErrorMatch.PARTIAL_REGEX) self.nodes[0].assert_start_raises_init_error( ['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" does not exist') @@ -167,7 +168,7 @@ # if wallets/ doesn't exist, datadir should be the default wallet dir wallet_dir2 = data_dir('walletdir') os.rename(wallet_dir(), wallet_dir2) - self.start_node(0, ['-wallet=w4', '-wallet=w5']) + self.start_node(0, ['-nowallet', '-wallet=w4', '-wallet=w5']) assert_equal(set(node.listwallets()), {"w4", "w5"}) w5 = wallet("w5") node.generatetoaddress(nblocks=1, address=w5.getnewaddress()) @@ -175,7 +176,7 @@ # now if wallets/ exists again, but the rootdir is specified as the # walletdir, w4 and w5 should still be loaded os.rename(wallet_dir2, wallet_dir()) - self.restart_node(0, ['-wallet=w4', '-wallet=w5', + self.restart_node(0, ['-nowallet', '-wallet=w4', '-wallet=w5', '-walletdir=' + data_dir()]) assert_equal(set(node.listwallets()), {"w4", "w5"}) w5 = wallet("w5") @@ -185,8 +186,7 @@ competing_wallet_dir = os.path.join( self.options.tmpdir, 'competing_walletdir') os.mkdir(competing_wallet_dir) - self.restart_node( - 0, ['-walletdir=' + competing_wallet_dir, '-wallet=']) + self.restart_node(0, ['-walletdir=' + competing_wallet_dir]) exp_stderr = r"Error: Error initializing wallet database environment \"\S+competing_walletdir\"!" self.nodes[1].assert_start_raises_init_error( ['-walletdir=' + competing_wallet_dir], exp_stderr, match=ErrorMatch.PARTIAL_REGEX)