@@ -4172,18 +4172,10 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4172
4172
std::vector<bilingual_str> warnings;
4173
4173
bilingual_str error;
4174
4174
4175
- // If the wallet is still loaded, unload it so that nothing else tries to use it while we're changing it
4176
- bool was_loaded = false ;
4175
+ // The only kind of wallets that could be loaded are descriptor ones, which don't need to be migrated.
4177
4176
if (auto wallet = GetWallet (context, wallet_name)) {
4178
- if (wallet->IsWalletFlagSet (WALLET_FLAG_DESCRIPTORS)) {
4179
- return util::Error{_ (" Error: This wallet is already a descriptor wallet" )};
4180
- }
4181
-
4182
- if (!RemoveWallet (context, wallet, /* load_on_start=*/ std::nullopt, warnings)) {
4183
- return util::Error{_ (" Unable to unload the wallet before migrating" )};
4184
- }
4185
- WaitForDeleteWallet (std::move (wallet));
4186
- was_loaded = true ;
4177
+ assert (wallet->IsWalletFlagSet (WALLET_FLAG_DESCRIPTORS));
4178
+ return util::Error{_ (" Error: This wallet is already a descriptor wallet" )};
4187
4179
} else {
4188
4180
// Check if the wallet is BDB
4189
4181
const auto & wallet_path = GetWalletPath (wallet_name);
@@ -4217,10 +4209,10 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4217
4209
return util::Error{Untranslated (" Wallet loading failed." ) + Untranslated (" " ) + error};
4218
4210
}
4219
4211
4220
- return MigrateLegacyToDescriptor (std::move (local_wallet), passphrase, context, was_loaded );
4212
+ return MigrateLegacyToDescriptor (std::move (local_wallet), passphrase, context);
4221
4213
}
4222
4214
4223
- util::Result<MigrationResult> MigrateLegacyToDescriptor (std::shared_ptr<CWallet> local_wallet, const SecureString& passphrase, WalletContext& context, bool was_loaded )
4215
+ util::Result<MigrationResult> MigrateLegacyToDescriptor (std::shared_ptr<CWallet> local_wallet, const SecureString& passphrase, WalletContext& context)
4224
4216
{
4225
4217
MigrationResult res;
4226
4218
bilingual_str error;
@@ -4232,20 +4224,8 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
4232
4224
4233
4225
const std::string wallet_name = local_wallet->GetName ();
4234
4226
4235
- // Helper to reload as normal for some of our exit scenarios
4236
- const auto & reload_wallet = [&](std::shared_ptr<CWallet>& to_reload) {
4237
- assert (to_reload.use_count () == 1 );
4238
- std::string name = to_reload->GetName ();
4239
- to_reload.reset ();
4240
- to_reload = LoadWallet (context, name, /* load_on_start=*/ std::nullopt, options, status, error, warnings);
4241
- return to_reload != nullptr ;
4242
- };
4243
-
4244
4227
// Before anything else, check if there is something to migrate.
4245
4228
if (local_wallet->IsWalletFlagSet (WALLET_FLAG_DESCRIPTORS)) {
4246
- if (was_loaded) {
4247
- reload_wallet (local_wallet);
4248
- }
4249
4229
return util::Error{_ (" Error: This wallet is already a descriptor wallet" )};
4250
4230
}
4251
4231
@@ -4254,9 +4234,6 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
4254
4234
fs::path backup_filename = fs::PathFromString (strprintf (" %s_%d.legacy.bak" , (wallet_name.empty () ? " default_wallet" : wallet_name), GetTime ()));
4255
4235
fs::path backup_path = this_wallet_dir / backup_filename;
4256
4236
if (!local_wallet->BackupWallet (fs::PathToString (backup_path))) {
4257
- if (was_loaded) {
4258
- reload_wallet (local_wallet);
4259
- }
4260
4237
return util::Error{_ (" Error: Unable to make a backup of your wallet" )};
4261
4238
}
4262
4239
res.backup_path = backup_path;
@@ -4265,9 +4242,6 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
4265
4242
4266
4243
// Unlock the wallet if needed
4267
4244
if (local_wallet->IsLocked () && !local_wallet->Unlock (passphrase)) {
4268
- if (was_loaded) {
4269
- reload_wallet (local_wallet);
4270
- }
4271
4245
if (passphrase.find (' \0 ' ) == std::string::npos) {
4272
4246
return util::Error{Untranslated (" Error: Wallet decryption failed, the wallet passphrase was not provided or was incorrect." )};
4273
4247
} else {
@@ -4304,10 +4278,10 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
4304
4278
}
4305
4279
}
4306
4280
4307
- // In case of reloading failure, we need to remember the wallet dirs to remove
4308
- // Set is used as it may be populated with the same wallet directory paths multiple times,
4309
- // both before and after reloading . This ensures the set is complete even if one of the wallets
4310
- // fails to reload .
4281
+ // In case of loading failure, we need to remember the wallet dirs to remove.
4282
+ // A `set` is used as it may be populated with the same wallet directory paths multiple times,
4283
+ // both before and after loading . This ensures the set is complete even if one of the wallets
4284
+ // fails to load .
4311
4285
std::set<fs::path> wallet_dirs;
4312
4286
if (success) {
4313
4287
Assume (!res.wallet ); // We will set it here.
@@ -4319,15 +4293,17 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
4319
4293
for (const auto & path_to_remove : paths_to_remove) fs::remove_all (path_to_remove);
4320
4294
}
4321
4295
4322
- // Migration successful, unload all wallets locally, then reload them.
4323
- // Note: We use a pointer to the shared_ptr to avoid increasing its reference count,
4324
- // as 'reload_wallet' expects to be the sole owner (use_count == 1).
4296
+ // Migration successful, load all the migrated wallets.
4325
4297
for (std::shared_ptr<CWallet>* wallet_ptr : {&local_wallet, &res.watchonly_wallet , &res.solvables_wallet }) {
4326
4298
if (success && *wallet_ptr) {
4327
4299
std::shared_ptr<CWallet>& wallet = *wallet_ptr;
4328
- // Save db path and reload wallet
4300
+ // Save db path and load wallet
4329
4301
wallet_dirs.insert (fs::PathFromString (wallet->GetDatabase ().Filename ()).parent_path ());
4330
- success = reload_wallet (wallet);
4302
+ assert (wallet.use_count () == 1 );
4303
+ std::string wallet_name = wallet->GetName ();
4304
+ wallet.reset ();
4305
+ wallet = LoadWallet (context, wallet_name, /* load_on_start=*/ std::nullopt, options, status, error, warnings);
4306
+ success = (wallet != nullptr );
4331
4307
4332
4308
// When no wallet is set, set the main wallet.
4333
4309
if (!res.wallet ) {
@@ -4377,23 +4353,19 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
4377
4353
4378
4354
// Restore the backup
4379
4355
// Convert the backup file to the wallet db file by renaming it and moving it into the wallet's directory.
4380
- // Reload it into memory if the wallet was previously loaded.
4381
4356
bilingual_str restore_error;
4382
- 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 );
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 );
4383
4358
if (!restore_error.empty ()) {
4384
4359
error += restore_error + _ (" \n Unable to restore backup of wallet." );
4385
4360
return util::Error{error};
4386
4361
}
4362
+ // Verify that the legacy wallet is not loaded after restoring from the backup.
4363
+ assert (!ptr_wallet);
4387
4364
4388
4365
// The wallet directory has been restored, but just in case, copy the previously created backup to the wallet dir
4389
4366
fs::copy_file (temp_backup_location, backup_path, fs::copy_options::none);
4390
4367
fs::remove (temp_backup_location);
4391
4368
4392
- // Verify that there is no dangling wallet: when the wallet wasn't loaded before, expect null.
4393
- // This check is performed after restoration to avoid an early error before saving the backup.
4394
- bool wallet_reloaded = ptr_wallet != nullptr ;
4395
- assert (was_loaded == wallet_reloaded);
4396
-
4397
4369
return util::Error{error};
4398
4370
}
4399
4371
return res;
0 commit comments