@@ -2923,7 +2923,7 @@ bool CWallet::EraseAddressReceiveRequest(WalletBatch& batch, const CTxDestinatio
29232923 return true ;
29242924}
29252925
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)
29272927{
29282928 // Do some checking on wallet path. It should be either a:
29292929 //
@@ -2936,15 +2936,24 @@ std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, cons
29362936 if (!(path_type == fs::file_type::not_found || path_type == fs::file_type::directory ||
29372937 (path_type == fs::file_type::symlink && fs::is_directory (wallet_path)) ||
29382938 (path_type == fs::file_type::regular && fs::PathFromString (name).filename () == fs::PathFromString (name)))) {
2939- error_string = Untranslated (strprintf (
2939+ return util::Error{ Untranslated (strprintf (
29402940 " Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
29412941 " database/log.?????????? files can be stored, a location where such a directory could be created, "
29422942 " 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);
29442953 status = DatabaseStatus::FAILED_BAD_PATH;
29452954 return nullptr ;
29462955 }
2947- return MakeDatabase (wallet_path, options, status, error_string);
2956+ return MakeDatabase (* wallet_path, options, status, error_string);
29482957}
29492958
29502959std::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
43464355 // If the wallet is still loaded, unload it so that nothing else tries to use it while we're changing it
43474356 bool was_loaded = false ;
43484357 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+
43494362 if (!RemoveWallet (context, wallet, /* load_on_start=*/ std::nullopt , warnings)) {
43504363 return util::Error{_ (" Unable to unload the wallet before migrating" )};
43514364 }
43524365 UnloadWallet (std::move (wallet));
43534366 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+ }
43544376 }
43554377
43564378 // Load the wallet but only in the context of this function.
@@ -4359,6 +4381,7 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
43594381 empty_context.args = context.args ;
43604382 DatabaseOptions options;
43614383 options.require_existing = true ;
4384+ options.require_format = DatabaseFormat::BERKELEY_RO;
43624385 DatabaseStatus status;
43634386 std::unique_ptr<WalletDatabase> database = MakeWalletDatabase (wallet_name, options, status, error);
43644387 if (!database) {
@@ -4373,6 +4396,8 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
43734396
43744397 // Helper to reload as normal for some of our exit scenarios
43754398 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 ;
43764401 assert (to_reload.use_count () == 1 );
43774402 std::string name = to_reload->GetName ();
43784403 to_reload.reset ();
0 commit comments