@@ -2923,7 +2923,7 @@ bool CWallet::EraseAddressReceiveRequest(WalletBatch& batch, const CTxDestinatio
2923
2923
return true ;
2924
2924
}
2925
2925
2926
- std::unique_ptr<WalletDatabase> MakeWalletDatabase (const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error_string )
2926
+ static util::Result<fs::path> GetWalletPath (const std::string& name)
2927
2927
{
2928
2928
// Do some checking on wallet path. It should be either a:
2929
2929
//
@@ -2936,15 +2936,24 @@ std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, cons
2936
2936
if (!(path_type == fs::file_type::not_found || path_type == fs::file_type::directory ||
2937
2937
(path_type == fs::file_type::symlink && fs::is_directory (wallet_path)) ||
2938
2938
(path_type == fs::file_type::regular && fs::PathFromString (name).filename () == fs::PathFromString (name)))) {
2939
- error_string = Untranslated (strprintf (
2939
+ return util::Error{ Untranslated (strprintf (
2940
2940
" Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
2941
2941
" database/log.?????????? files can be stored, a location where such a directory could be created, "
2942
2942
" or (for backwards compatibility) the name of an existing data file in -walletdir (%s)" ,
2943
- name, fs::quoted (fs::PathToString (GetWalletDir ()))));
2943
+ name, fs::quoted (fs::PathToString (GetWalletDir ()))))};
2944
+ }
2945
+ return wallet_path;
2946
+ }
2947
+
2948
+ std::unique_ptr<WalletDatabase> MakeWalletDatabase (const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error_string)
2949
+ {
2950
+ const auto & wallet_path = GetWalletPath (name);
2951
+ if (!wallet_path) {
2952
+ error_string = util::ErrorString (wallet_path);
2944
2953
status = DatabaseStatus::FAILED_BAD_PATH;
2945
2954
return nullptr ;
2946
2955
}
2947
- return MakeDatabase (wallet_path, options, status, error_string);
2956
+ return MakeDatabase (* wallet_path, options, status, error_string);
2948
2957
}
2949
2958
2950
2959
std::shared_ptr<CWallet> CWallet::Create (WalletContext& context, const std::string& name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings)
@@ -4346,11 +4355,24 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4346
4355
// If the wallet is still loaded, unload it so that nothing else tries to use it while we're changing it
4347
4356
bool was_loaded = false ;
4348
4357
if (auto wallet = GetWallet (context, wallet_name)) {
4358
+ if (wallet->IsWalletFlagSet (WALLET_FLAG_DESCRIPTORS)) {
4359
+ return util::Error{_ (" Error: This wallet is already a descriptor wallet" )};
4360
+ }
4361
+
4349
4362
if (!RemoveWallet (context, wallet, /* load_on_start=*/ std::nullopt, warnings)) {
4350
4363
return util::Error{_ (" Unable to unload the wallet before migrating" )};
4351
4364
}
4352
4365
UnloadWallet (std::move (wallet));
4353
4366
was_loaded = true ;
4367
+ } else {
4368
+ // Check if the wallet is BDB
4369
+ const auto & wallet_path = GetWalletPath (wallet_name);
4370
+ if (!wallet_path) {
4371
+ return util::Error{util::ErrorString (wallet_path)};
4372
+ }
4373
+ if (!IsBDBFile (BDBDataFile (*wallet_path))) {
4374
+ return util::Error{_ (" Error: This wallet is already a descriptor wallet" )};
4375
+ }
4354
4376
}
4355
4377
4356
4378
// Load the wallet but only in the context of this function.
@@ -4359,6 +4381,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4359
4381
empty_context.args = context.args ;
4360
4382
DatabaseOptions options;
4361
4383
options.require_existing = true ;
4384
+ options.require_format = DatabaseFormat::BERKELEY_RO;
4362
4385
DatabaseStatus status;
4363
4386
std::unique_ptr<WalletDatabase> database = MakeWalletDatabase (wallet_name, options, status, error);
4364
4387
if (!database) {
@@ -4373,6 +4396,8 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
4373
4396
4374
4397
// Helper to reload as normal for some of our exit scenarios
4375
4398
const auto & reload_wallet = [&](std::shared_ptr<CWallet>& to_reload) {
4399
+ // Reset options.require_format as wallets of any format may be reloaded.
4400
+ options.require_format = std::nullopt;
4376
4401
assert (to_reload.use_count () == 1 );
4377
4402
std::string name = to_reload->GetName ();
4378
4403
to_reload.reset ();
0 commit comments