@@ -490,7 +490,9 @@ std::shared_ptr<CWallet> CreateWallet(WalletContext& context, const std::string&
490
490
return wallet;
491
491
}
492
492
493
- std::shared_ptr<CWallet> RestoreWallet (WalletContext& context, const fs::path& backup_file, const std::string& wallet_name, std::optional<bool > load_on_start, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
493
+ // Re-creates wallet from the backup file by renaming and moving it into the wallet's directory.
494
+ // If 'load_after_restore=true', the wallet object will be fully initialized and appended to the context.
495
+ std::shared_ptr<CWallet> RestoreWallet (WalletContext& context, const fs::path& backup_file, const std::string& wallet_name, std::optional<bool > load_on_start, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings, bool load_after_restore)
494
496
{
495
497
DatabaseOptions options;
496
498
ReadDatabaseArgs (*context.args , options);
@@ -515,13 +517,17 @@ std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const fs::path& b
515
517
516
518
fs::copy_file (backup_file, wallet_file, fs::copy_options::none);
517
519
518
- wallet = LoadWallet (context, wallet_name, load_on_start, options, status, error, warnings);
520
+ if (load_after_restore) {
521
+ wallet = LoadWallet (context, wallet_name, load_on_start, options, status, error, warnings);
522
+ }
519
523
} catch (const std::exception& e) {
520
524
assert (!wallet);
521
525
if (!error.empty ()) error += Untranslated (" \n " );
522
526
error += Untranslated (strprintf (" Unexpected exception: %s" , e.what ()));
523
527
}
524
- if (!wallet) {
528
+
529
+ // Remove created wallet path only when loading fails
530
+ if (load_after_restore && !wallet) {
525
531
fs::remove_all (wallet_path);
526
532
}
527
533
@@ -4523,7 +4529,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4523
4529
}
4524
4530
if (!success) {
4525
4531
// Migration failed, cleanup
4526
- // Copy the backup to the actual wallet dir
4532
+ // Before deleting the wallet's directory, copy the backup file to the top-level wallets dir
4527
4533
fs::path temp_backup_location = fsbridge::AbsPathJoin (GetWalletDir (), backup_filename);
4528
4534
fs::copy_file (backup_path, temp_backup_location, fs::copy_options::none);
4529
4535
@@ -4560,17 +4566,24 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4560
4566
}
4561
4567
4562
4568
// Restore the backup
4563
- DatabaseStatus status;
4564
- std::vector<bilingual_str> warnings;
4565
- if (!RestoreWallet (context, temp_backup_location, wallet_name, /* load_on_start=*/ std::nullopt, status, error, warnings)) {
4566
- error += _ (" \n Unable to restore backup of wallet." );
4569
+ // Convert the backup file to the wallet db file by renaming it and moving it into the wallet's directory.
4570
+ // Reload it into memory if the wallet was previously loaded.
4571
+ bilingual_str restore_error;
4572
+ const auto & ptr_wallet = RestoreWallet (context, temp_backup_location, wallet_name, /* load_on_start=*/ std::nullopt, status, restore_error, warnings, /* load_after_restore=*/ was_loaded);
4573
+ if (!restore_error.empty ()) {
4574
+ error += restore_error + _ (" \n Unable to restore backup of wallet." );
4567
4575
return util::Error{error};
4568
4576
}
4569
4577
4570
- // Move the backup to the wallet dir
4578
+ // The wallet directory has been restored, but just in case, copy the previously created backup to the wallet dir
4571
4579
fs::copy_file (temp_backup_location, backup_path, fs::copy_options::none);
4572
4580
fs::remove (temp_backup_location);
4573
4581
4582
+ // Verify that there is no dangling wallet: when the wallet wasn't loaded before, expect null.
4583
+ // This check is performed after restoration to avoid an early error before saving the backup.
4584
+ bool wallet_reloaded = ptr_wallet != nullptr ;
4585
+ assert (was_loaded == wallet_reloaded);
4586
+
4574
4587
return util::Error{error};
4575
4588
}
4576
4589
return res;
0 commit comments