diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -3,3 +3,6 @@ This release includes the following features and fixes: + - Fixed a bug with Multiwallets that have their own directories (i.e. cases + such as `DATADIR/wallets/mywallet/wallet.dat`). Backups of these wallets + will now take each wallet's specific directory into account. diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -838,7 +838,7 @@ env->mapFileUseCount.erase(strFile); // Copy wallet file. - fs::path pathSrc = GetWalletDir() / strFile; + fs::path pathSrc = env->Directory() / strFile; fs::path pathDest(strDest); if (fs::is_directory(pathDest)) { pathDest /= strFile; 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 @@ -31,6 +31,11 @@ def wallet(name): return node.get_wallet_rpc(name) + def wallet_file(name): + if os.path.isdir(wallet_dir(name)): + return wallet_dir(name, "wallet.dat") + return wallet_dir(name) + # check wallet.dat is created self.stop_nodes() assert_equal(os.path.isfile(wallet_dir('wallet.dat')), True) @@ -44,6 +49,12 @@ # directory paths) can be loaded os.rename(wallet_dir("wallet.dat"), wallet_dir("w8")) + # create another dummy wallet for use in testing backups later + self.start_node(0, []) + self.stop_nodes() + empty_wallet = os.path.join(self.options.tmpdir, 'empty.dat') + os.rename(wallet_dir("wallet.dat"), empty_wallet) + # restart node with a mix of wallet names: # w1, w2, w3 - to verify new wallets created when non-existing paths specified # w - to verify wallet name matching works when one wallet path is prefix of another @@ -61,11 +72,7 @@ # check that all requested wallets were created self.stop_node(0) for wallet_name in wallet_names: - if os.path.isdir(wallet_dir(wallet_name)): - assert_equal(os.path.isfile( - wallet_dir(wallet_name, "wallet.dat")), True) - else: - assert_equal(os.path.isfile(wallet_dir(wallet_name)), True) + assert_equal(os.path.isfile(wallet_file(wallet_name)), True) # should not initialize if wallet path can't be created exp_stderr = "boost::filesystem::create_directory: (The system cannot find the path specified|Not a directory):" @@ -283,6 +290,25 @@ assert_equal(self.nodes[0].listwallets(), ['w1']) assert_equal(w1.getwalletinfo()['walletname'], 'w1') + # Test backing up and restoring wallets + self.log.info("Test wallet backup") + self.restart_node(0, ['-nowallet']) + for wallet_name in wallet_names: + self.nodes[0].loadwallet(wallet_name) + for wallet_name in wallet_names: + rpc = self.nodes[0].get_wallet_rpc(wallet_name) + addr = rpc.getnewaddress() + backup = os.path.join(self.options.tmpdir, 'backup.dat') + rpc.backupwallet(backup) + self.nodes[0].unloadwallet(wallet_name) + shutil.copyfile(empty_wallet, wallet_file(wallet_name)) + self.nodes[0].loadwallet(wallet_name) + assert_equal(rpc.getaddressinfo(addr)['ismine'], False) + self.nodes[0].unloadwallet(wallet_name) + shutil.copyfile(backup, wallet_file(wallet_name)) + self.nodes[0].loadwallet(wallet_name) + assert_equal(rpc.getaddressinfo(addr)['ismine'], True) + if __name__ == '__main__': MultiWalletTest().main()