mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-17 19:10:40 +01:00
wallet: migration: Make backup in walletdir
This commit is contained in:
@@ -4230,9 +4230,8 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
|
||||
}
|
||||
|
||||
// Make a backup of the DB
|
||||
fs::path this_wallet_dir = fs::absolute(fs::PathFromString(local_wallet->GetDatabase().Filename())).parent_path();
|
||||
fs::path backup_filename = fs::PathFromString(strprintf("%s_%d.legacy.bak", (wallet_name.empty() ? "default_wallet" : wallet_name), GetTime()));
|
||||
fs::path backup_path = this_wallet_dir / backup_filename;
|
||||
fs::path backup_path = fsbridge::AbsPathJoin(GetWalletDir(), backup_filename);
|
||||
if (!local_wallet->BackupWallet(fs::PathToString(backup_path))) {
|
||||
return util::Error{_("Error: Unable to make a backup of your wallet")};
|
||||
}
|
||||
@@ -4314,11 +4313,6 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
// Migration failed, cleanup
|
||||
// Before deleting the wallet's directory, copy the backup file to the top-level wallets dir
|
||||
fs::path temp_backup_location = fsbridge::AbsPathJoin(GetWalletDir(), backup_filename);
|
||||
fs::copy_file(backup_path, temp_backup_location, fs::copy_options::none);
|
||||
|
||||
// Make list of wallets to cleanup
|
||||
std::vector<std::shared_ptr<CWallet>> created_wallets;
|
||||
if (local_wallet) created_wallets.push_back(std::move(local_wallet));
|
||||
@@ -4354,7 +4348,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
|
||||
// Restore the backup
|
||||
// Convert the backup file to the wallet db file by renaming it and moving it into the wallet's directory.
|
||||
bilingual_str restore_error;
|
||||
const auto& ptr_wallet = RestoreWallet(context, temp_backup_location, wallet_name, /*load_on_start=*/std::nullopt, status, restore_error, warnings, /*load_after_restore=*/false);
|
||||
const auto& ptr_wallet = RestoreWallet(context, backup_path, wallet_name, /*load_on_start=*/std::nullopt, status, restore_error, warnings, /*load_after_restore=*/false);
|
||||
if (!restore_error.empty()) {
|
||||
error += restore_error + _("\nUnable to restore backup of wallet.");
|
||||
return util::Error{error};
|
||||
@@ -4362,10 +4356,6 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
|
||||
// Verify that the legacy wallet is not loaded after restoring from the backup.
|
||||
assert(!ptr_wallet);
|
||||
|
||||
// The wallet directory has been restored, but just in case, copy the previously created backup to the wallet dir
|
||||
fs::copy_file(temp_backup_location, backup_path, fs::copy_options::none);
|
||||
fs::remove(temp_backup_location);
|
||||
|
||||
return util::Error{error};
|
||||
}
|
||||
return res;
|
||||
|
||||
@@ -118,17 +118,30 @@ class WalletMigrationTest(BitcoinTestFramework):
|
||||
for w in wallets["wallets"]:
|
||||
if w["name"] == wallet_name:
|
||||
assert_equal(w["warnings"], ["This wallet is a legacy wallet and will need to be migrated with migratewallet before it can be loaded"])
|
||||
|
||||
# Mock time so that we can check the backup filename.
|
||||
mocked_time = int(time.time())
|
||||
self.master_node.setmocktime(mocked_time)
|
||||
# Migrate, checking that rescan does not occur
|
||||
with self.master_node.assert_debug_log(expected_msgs=[], unexpected_msgs=["Rescanning"]):
|
||||
migrate_info = self.master_node.migratewallet(wallet_name=wallet_name, **kwargs)
|
||||
self.master_node.setmocktime(0)
|
||||
# Update wallet name in case the initial wallet was completely migrated to a watch-only wallet
|
||||
# (in which case the wallet name would be suffixed by the 'watchonly' term)
|
||||
wallet_name = migrate_info['wallet_name']
|
||||
wallet = self.master_node.get_wallet_rpc(wallet_name)
|
||||
migrated_wallet_name = migrate_info['wallet_name']
|
||||
wallet = self.master_node.get_wallet_rpc(migrated_wallet_name)
|
||||
assert_equal(wallet.getwalletinfo()["descriptors"], True)
|
||||
self.assert_is_sqlite(wallet_name)
|
||||
self.assert_is_sqlite(migrated_wallet_name)
|
||||
# Always verify the backup path exist after migration
|
||||
assert os.path.exists(migrate_info['backup_path'])
|
||||
if wallet_name == "":
|
||||
backup_prefix = "default_wallet"
|
||||
else:
|
||||
backup_prefix = os.path.basename(os.path.realpath(self.old_node.wallets_path / wallet_name))
|
||||
|
||||
expected_backup_path = self.master_node.wallets_path / f"{backup_prefix}_{mocked_time}.legacy.bak"
|
||||
assert_equal(str(expected_backup_path), migrate_info['backup_path'])
|
||||
|
||||
return migrate_info, wallet
|
||||
|
||||
def test_basic(self):
|
||||
|
||||
Reference in New Issue
Block a user