Skip to content

Commit f6ee59b

Browse files
committed
wallet: migration: Make backup in walletdir
1 parent e22c359 commit f6ee59b

File tree

2 files changed

+18
-15
lines changed

2 files changed

+18
-15
lines changed

src/wallet/wallet.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4230,9 +4230,8 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
42304230
}
42314231

42324232
// Make a backup of the DB
4233-
fs::path this_wallet_dir = fs::absolute(fs::PathFromString(local_wallet->GetDatabase().Filename())).parent_path();
42344233
fs::path backup_filename = fs::PathFromString(strprintf("%s_%d.legacy.bak", (wallet_name.empty() ? "default_wallet" : wallet_name), GetTime()));
4235-
fs::path backup_path = this_wallet_dir / backup_filename;
4234+
fs::path backup_path = fsbridge::AbsPathJoin(GetWalletDir(), backup_filename);
42364235
if (!local_wallet->BackupWallet(fs::PathToString(backup_path))) {
42374236
return util::Error{_("Error: Unable to make a backup of your wallet")};
42384237
}
@@ -4314,11 +4313,6 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
43144313
}
43154314
}
43164315
if (!success) {
4317-
// Migration failed, cleanup
4318-
// Before deleting the wallet's directory, copy the backup file to the top-level wallets dir
4319-
fs::path temp_backup_location = fsbridge::AbsPathJoin(GetWalletDir(), backup_filename);
4320-
fs::copy_file(backup_path, temp_backup_location, fs::copy_options::none);
4321-
43224316
// Make list of wallets to cleanup
43234317
std::vector<std::shared_ptr<CWallet>> created_wallets;
43244318
if (local_wallet) created_wallets.push_back(std::move(local_wallet));
@@ -4354,18 +4348,14 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
43544348
// Restore the backup
43554349
// Convert the backup file to the wallet db file by renaming it and moving it into the wallet's directory.
43564350
bilingual_str restore_error;
4357-
const auto& ptr_wallet = RestoreWallet(context, temp_backup_location, wallet_name, /*load_on_start=*/std::nullopt, status, restore_error, warnings, /*load_after_restore=*/false);
4351+
const auto& ptr_wallet = RestoreWallet(context, backup_path, wallet_name, /*load_on_start=*/std::nullopt, status, restore_error, warnings, /*load_after_restore=*/false);
43584352
if (!restore_error.empty()) {
43594353
error += restore_error + _("\nUnable to restore backup of wallet.");
43604354
return util::Error{error};
43614355
}
43624356
// Verify that the legacy wallet is not loaded after restoring from the backup.
43634357
assert(!ptr_wallet);
43644358

4365-
// The wallet directory has been restored, but just in case, copy the previously created backup to the wallet dir
4366-
fs::copy_file(temp_backup_location, backup_path, fs::copy_options::none);
4367-
fs::remove(temp_backup_location);
4368-
43694359
return util::Error{error};
43704360
}
43714361
return res;

test/functional/wallet_migration.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,17 +118,30 @@ def migrate_and_get_rpc(self, wallet_name, **kwargs):
118118
for w in wallets["wallets"]:
119119
if w["name"] == wallet_name:
120120
assert_equal(w["warnings"], ["This wallet is a legacy wallet and will need to be migrated with migratewallet before it can be loaded"])
121+
122+
# Mock time so that we can check the backup filename.
123+
mocked_time = int(time.time())
124+
self.master_node.setmocktime(mocked_time)
121125
# Migrate, checking that rescan does not occur
122126
with self.master_node.assert_debug_log(expected_msgs=[], unexpected_msgs=["Rescanning"]):
123127
migrate_info = self.master_node.migratewallet(wallet_name=wallet_name, **kwargs)
128+
self.master_node.setmocktime(0)
124129
# Update wallet name in case the initial wallet was completely migrated to a watch-only wallet
125130
# (in which case the wallet name would be suffixed by the 'watchonly' term)
126-
wallet_name = migrate_info['wallet_name']
127-
wallet = self.master_node.get_wallet_rpc(wallet_name)
131+
migrated_wallet_name = migrate_info['wallet_name']
132+
wallet = self.master_node.get_wallet_rpc(migrated_wallet_name)
128133
assert_equal(wallet.getwalletinfo()["descriptors"], True)
129-
self.assert_is_sqlite(wallet_name)
134+
self.assert_is_sqlite(migrated_wallet_name)
130135
# Always verify the backup path exist after migration
131136
assert os.path.exists(migrate_info['backup_path'])
137+
if wallet_name == "":
138+
backup_prefix = "default_wallet"
139+
else:
140+
backup_prefix = os.path.basename(os.path.realpath(self.old_node.wallets_path / wallet_name))
141+
142+
expected_backup_path = self.master_node.wallets_path / f"{backup_prefix}_{mocked_time}.legacy.bak"
143+
assert_equal(str(expected_backup_path), migrate_info['backup_path'])
144+
132145
return migrate_info, wallet
133146

134147
def test_basic(self):

0 commit comments

Comments
 (0)