aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2018-08-07 13:27:21 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2018-08-07 13:31:54 +0200
commitb81a8a5ea90c397c3b48384500d176e83c3af537 (patch)
treeabe8d212b5acda4eb746992f1f9ea0bb29d43110
parent37ab117a87bac02a3341f4775e5448ea4793d2c8 (diff)
parenta1a998cf24c0cf1232e44ec8eaf2ad6875ab5153 (diff)
Merge #13667: wallet: Fix backupwallet for multiwallets
a1a998cf24c0cf1232e44ec8eaf2ad6875ab5153 wallet: Fix backupwallet for multiwallets (Daniel Kraft) Pull request description: `backupwallet` was broken for multiwallets in their own directories (i.e. something like `DATADIR/wallets/mywallet/wallet.dat`). In this case, the backup would use `DATADIR/wallets/wallet.dat` as source file and not take the specific wallet's directory into account. This led to either an error during the backup (if the wrong source file was not present) or would silently back up the wrong wallet; especially the latter behaviour can be quite bad for users. Tree-SHA512: 7efe2450ca047e40719fcc7cc211ed94699056020ac737cada7b59e8240298675960570c45079add424d0aab520437d5050d956acd695a9c2452dd4317b4d2c4
-rw-r--r--src/wallet/db.cpp2
-rwxr-xr-xtest/functional/wallet_multiwallet.py36
2 files changed, 33 insertions, 5 deletions
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index 01b8eacccb..00964b8cc8 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -768,7 +768,7 @@ bool BerkeleyDatabase::Backup(const std::string& strDest)
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
index fa5a2154a4..e2938dba3b 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -30,6 +30,11 @@ class MultiWalletTest(BitcoinTestFramework):
wallet_dir = lambda *p: data_dir('wallets', *p)
wallet = lambda name: 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)
@@ -43,6 +48,12 @@ class MultiWalletTest(BitcoinTestFramework):
# 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
@@ -59,10 +70,7 @@ class MultiWalletTest(BitcoinTestFramework):
# 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):"
@@ -265,5 +273,25 @@ class MultiWalletTest(BitcoinTestFramework):
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()