@@ -4213,11 +4213,13 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4213
4213
std::vector<bilingual_str> warnings;
4214
4214
4215
4215
// If the wallet is still loaded, unload it so that nothing else tries to use it while we're changing it
4216
+ bool was_loaded = false ;
4216
4217
if (auto wallet = GetWallet (context, wallet_name)) {
4217
4218
if (!RemoveWallet (context, wallet, /* load_on_start=*/ std::nullopt, warnings)) {
4218
4219
return util::Error{_ (" Unable to unload the wallet before migrating" )};
4219
4220
}
4220
4221
UnloadWallet (std::move (wallet));
4222
+ was_loaded = true ;
4221
4223
}
4222
4224
4223
4225
// Load the wallet but only in the context of this function.
@@ -4238,8 +4240,20 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4238
4240
return util::Error{Untranslated (" Wallet loading failed." ) + Untranslated (" " ) + error};
4239
4241
}
4240
4242
4243
+ // Helper to reload as normal for some of our exit scenarios
4244
+ const auto & reload_wallet = [&](std::shared_ptr<CWallet>& to_reload) {
4245
+ assert (to_reload.use_count () == 1 );
4246
+ std::string name = to_reload->GetName ();
4247
+ to_reload.reset ();
4248
+ to_reload = LoadWallet (context, name, /* load_on_start=*/ std::nullopt, options, status, error, warnings);
4249
+ return to_reload != nullptr ;
4250
+ };
4251
+
4241
4252
// Before anything else, check if there is something to migrate.
4242
4253
if (local_wallet->IsWalletFlagSet (WALLET_FLAG_DESCRIPTORS)) {
4254
+ if (was_loaded) {
4255
+ reload_wallet (local_wallet);
4256
+ }
4243
4257
return util::Error{_ (" Error: This wallet is already a descriptor wallet" )};
4244
4258
}
4245
4259
@@ -4248,27 +4262,33 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4248
4262
fs::path backup_filename = fs::PathFromString (strprintf (" %s-%d.legacy.bak" , wallet_name, GetTime ()));
4249
4263
fs::path backup_path = this_wallet_dir / backup_filename;
4250
4264
if (!local_wallet->BackupWallet (fs::PathToString (backup_path))) {
4265
+ if (was_loaded) {
4266
+ reload_wallet (local_wallet);
4267
+ }
4251
4268
return util::Error{_ (" Error: Unable to make a backup of your wallet" )};
4252
4269
}
4253
4270
res.backup_path = backup_path;
4254
4271
4255
4272
bool success = false ;
4256
- {
4257
- LOCK (local_wallet->cs_wallet );
4258
4273
4259
- // Unlock the wallet if needed
4260
- if (local_wallet->IsLocked () && !local_wallet->Unlock (passphrase)) {
4261
- if (passphrase.find (' \0 ' ) == std::string::npos) {
4262
- return util::Error{Untranslated (" Error: Wallet decryption failed, the wallet passphrase was not provided or was incorrect." )};
4263
- } else {
4264
- return util::Error{Untranslated (" Error: Wallet decryption failed, the wallet passphrase entered was incorrect. "
4265
- " The passphrase contains a null character (ie - a zero byte). "
4266
- " If this passphrase was set with a version of this software prior to 25.0, "
4267
- " please try again with only the characters up to — but not including — "
4268
- " the first null character." )};
4269
- }
4274
+ // Unlock the wallet if needed
4275
+ if (local_wallet->IsLocked () && !local_wallet->Unlock (passphrase)) {
4276
+ if (was_loaded) {
4277
+ reload_wallet (local_wallet);
4278
+ }
4279
+ if (passphrase.find (' \0 ' ) == std::string::npos) {
4280
+ return util::Error{Untranslated (" Error: Wallet decryption failed, the wallet passphrase was not provided or was incorrect." )};
4281
+ } else {
4282
+ return util::Error{Untranslated (" Error: Wallet decryption failed, the wallet passphrase entered was incorrect. "
4283
+ " The passphrase contains a null character (ie - a zero byte). "
4284
+ " If this passphrase was set with a version of this software prior to 25.0, "
4285
+ " please try again with only the characters up to — but not including — "
4286
+ " the first null character." )};
4270
4287
}
4288
+ }
4271
4289
4290
+ {
4291
+ LOCK (local_wallet->cs_wallet );
4272
4292
// First change to using SQLite
4273
4293
if (!local_wallet->MigrateToSQLite (error)) return util::Error{error};
4274
4294
@@ -4286,24 +4306,19 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4286
4306
std::set<fs::path> wallet_dirs;
4287
4307
if (success) {
4288
4308
// Migration successful, unload all wallets locally, then reload them.
4289
- const auto & reload_wallet = [&](std::shared_ptr<CWallet>& to_reload) {
4290
- assert (to_reload.use_count () == 1 );
4291
- std::string name = to_reload->GetName ();
4292
- wallet_dirs.insert (fs::PathFromString (to_reload->GetDatabase ().Filename ()).parent_path ());
4293
- to_reload.reset ();
4294
- to_reload = LoadWallet (context, name, /* load_on_start=*/ std::nullopt, options, status, error, warnings);
4295
- return to_reload != nullptr ;
4296
- };
4297
4309
// Reload the main wallet
4310
+ wallet_dirs.insert (fs::PathFromString (local_wallet->GetDatabase ().Filename ()).parent_path ());
4298
4311
success = reload_wallet (local_wallet);
4299
4312
res.wallet = local_wallet;
4300
4313
res.wallet_name = wallet_name;
4301
4314
if (success && res.watchonly_wallet ) {
4302
4315
// Reload watchonly
4316
+ wallet_dirs.insert (fs::PathFromString (res.watchonly_wallet ->GetDatabase ().Filename ()).parent_path ());
4303
4317
success = reload_wallet (res.watchonly_wallet );
4304
4318
}
4305
4319
if (success && res.solvables_wallet ) {
4306
4320
// Reload solvables
4321
+ wallet_dirs.insert (fs::PathFromString (res.solvables_wallet ->GetDatabase ().Filename ()).parent_path ());
4307
4322
success = reload_wallet (res.solvables_wallet );
4308
4323
}
4309
4324
}
0 commit comments