@@ -490,7 +490,9 @@ std::shared_ptr<CWallet> CreateWallet(WalletContext& context, const std::string&
490490 return wallet;
491491}
492492
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)
494496{
495497 DatabaseOptions options;
496498 ReadDatabaseArgs (*context.args , options);
@@ -515,13 +517,17 @@ std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const fs::path& b
515517
516518 fs::copy_file (backup_file, wallet_file, fs::copy_options::none);
517519
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+ }
519523 } catch (const std::exception& e) {
520524 assert (!wallet);
521525 if (!error.empty ()) error += Untranslated (" \n " );
522526 error += Untranslated (strprintf (" Unexpected exception: %s" , e.what ()));
523527 }
524- if (!wallet) {
528+
529+ // Remove created wallet path only when loading fails
530+ if (load_after_restore && !wallet) {
525531 fs::remove_all (wallet_path);
526532 }
527533
@@ -4523,7 +4529,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
45234529 }
45244530 if (!success) {
45254531 // 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
45274533 fs::path temp_backup_location = fsbridge::AbsPathJoin (GetWalletDir (), backup_filename);
45284534 fs::copy_file (backup_path, temp_backup_location, fs::copy_options::none);
45294535
@@ -4560,17 +4566,24 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
45604566 }
45614567
45624568 // 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." );
45674575 return util::Error{error};
45684576 }
45694577
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
45714579 fs::copy_file (temp_backup_location, backup_path, fs::copy_options::none);
45724580 fs::remove (temp_backup_location);
45734581
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+
45744587 return util::Error{error};
45754588 }
45764589 return res;
0 commit comments