Skip to content

Commit b81a8a5

Browse files
committed
Merge #13667: wallet: Fix backupwallet for multiwallets
a1a998c 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
2 parents 37ab117 + a1a998c commit b81a8a5

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

src/wallet/db.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ bool BerkeleyDatabase::Backup(const std::string& strDest)
768768
env->mapFileUseCount.erase(strFile);
769769

770770
// Copy wallet file
771-
fs::path pathSrc = GetWalletDir() / strFile;
771+
fs::path pathSrc = env->Directory() / strFile;
772772
fs::path pathDest(strDest);
773773
if (fs::is_directory(pathDest))
774774
pathDest /= strFile;

test/functional/wallet_multiwallet.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ def run_test(self):
3030
wallet_dir = lambda *p: data_dir('wallets', *p)
3131
wallet = lambda name: node.get_wallet_rpc(name)
3232

33+
def wallet_file(name):
34+
if os.path.isdir(wallet_dir(name)):
35+
return wallet_dir(name, "wallet.dat")
36+
return wallet_dir(name)
37+
3338
# check wallet.dat is created
3439
self.stop_nodes()
3540
assert_equal(os.path.isfile(wallet_dir('wallet.dat')), True)
@@ -43,6 +48,12 @@ def run_test(self):
4348
# directory paths) can be loaded
4449
os.rename(wallet_dir("wallet.dat"), wallet_dir("w8"))
4550

51+
# create another dummy wallet for use in testing backups later
52+
self.start_node(0, [])
53+
self.stop_nodes()
54+
empty_wallet = os.path.join(self.options.tmpdir, 'empty.dat')
55+
os.rename(wallet_dir("wallet.dat"), empty_wallet)
56+
4657
# restart node with a mix of wallet names:
4758
# w1, w2, w3 - to verify new wallets created when non-existing paths specified
4859
# w - to verify wallet name matching works when one wallet path is prefix of another
@@ -59,10 +70,7 @@ def run_test(self):
5970
# check that all requested wallets were created
6071
self.stop_node(0)
6172
for wallet_name in wallet_names:
62-
if os.path.isdir(wallet_dir(wallet_name)):
63-
assert_equal(os.path.isfile(wallet_dir(wallet_name, "wallet.dat")), True)
64-
else:
65-
assert_equal(os.path.isfile(wallet_dir(wallet_name)), True)
73+
assert_equal(os.path.isfile(wallet_file(wallet_name)), True)
6674

6775
# should not initialize if wallet path can't be created
6876
exp_stderr = "boost::filesystem::create_directory: (The system cannot find the path specified|Not a directory):"
@@ -265,5 +273,25 @@ def run_test(self):
265273
assert_equal(self.nodes[0].listwallets(), ['w1'])
266274
assert_equal(w1.getwalletinfo()['walletname'], 'w1')
267275

276+
# Test backing up and restoring wallets
277+
self.log.info("Test wallet backup")
278+
self.restart_node(0, ['-nowallet'])
279+
for wallet_name in wallet_names:
280+
self.nodes[0].loadwallet(wallet_name)
281+
for wallet_name in wallet_names:
282+
rpc = self.nodes[0].get_wallet_rpc(wallet_name)
283+
addr = rpc.getnewaddress()
284+
backup = os.path.join(self.options.tmpdir, 'backup.dat')
285+
rpc.backupwallet(backup)
286+
self.nodes[0].unloadwallet(wallet_name)
287+
shutil.copyfile(empty_wallet, wallet_file(wallet_name))
288+
self.nodes[0].loadwallet(wallet_name)
289+
assert_equal(rpc.getaddressinfo(addr)['ismine'], False)
290+
self.nodes[0].unloadwallet(wallet_name)
291+
shutil.copyfile(backup, wallet_file(wallet_name))
292+
self.nodes[0].loadwallet(wallet_name)
293+
assert_equal(rpc.getaddressinfo(addr)['ismine'], True)
294+
295+
268296
if __name__ == '__main__':
269297
MultiWalletTest().main()

0 commit comments

Comments
 (0)