From 9f94de5bb54ff683bd4d3a7723617b34a4706bb6 Mon Sep 17 00:00:00 2001 From: furszy Date: Thu, 8 May 2025 11:54:47 -0400 Subject: [PATCH] wallet: init, don't error out when loading legacy wallets Instead of failing during initialization when encountering a legacy wallet, skip loading the wallet and notify the user accordingly. This allows users to access migration functionalities without needing to manually remove the wallet from settings.json or resort to using the bitcoin-wallet utility. This means that GUI users will be able to use the migration button, and bitcoin-cli users will be able to call the migratewallet RPC directly after init. --- src/wallet/db.h | 1 + src/wallet/load.cpp | 13 +++++++++++-- src/wallet/rpc/util.cpp | 1 + src/wallet/walletdb.cpp | 4 ++-- test/functional/wallet_backwards_compatibility.py | 2 +- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/wallet/db.h b/src/wallet/db.h index 7870dcc4b22..f494a71552f 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -184,6 +184,7 @@ enum class DatabaseStatus { SUCCESS, FAILED_BAD_PATH, FAILED_BAD_FORMAT, + FAILED_LEGACY_DISABLED, FAILED_ALREADY_LOADED, FAILED_ALREADY_EXISTS, FAILED_NOT_FOUND, diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp index 3fdad7d6fb1..fbcc5c3aed4 100644 --- a/src/wallet/load.cpp +++ b/src/wallet/load.cpp @@ -99,6 +99,10 @@ bool VerifyWallets(WalletContext& context) if (!MakeWalletDatabase(wallet_file, options, status, error_string)) { if (status == DatabaseStatus::FAILED_NOT_FOUND) { chain.initWarning(Untranslated(strprintf("Skipping -wallet path that doesn't exist. %s", error_string.original))); + } else if (status == DatabaseStatus::FAILED_LEGACY_DISABLED) { + // Skipping legacy wallets as they will not be loaded. + // This will be properly communicated to the user during the loading process. + continue; } else { chain.initError(error_string); return false; @@ -132,8 +136,13 @@ bool LoadWallets(WalletContext& context) bilingual_str error; std::vector warnings; std::unique_ptr database = MakeWalletDatabase(name, options, status, error); - if (!database && status == DatabaseStatus::FAILED_NOT_FOUND) { - continue; + if (!database) { + if (status == DatabaseStatus::FAILED_NOT_FOUND) continue; + if (status == DatabaseStatus::FAILED_LEGACY_DISABLED) { + // Inform user that legacy wallet is not loaded and suggest upgrade options + chain.initWarning(error); + continue; + } } chain.initMessage(_("Loading wallet…")); std::shared_ptr pwallet = database ? CWallet::Create(context, name, std::move(database), options.create_flags, error, warnings) : nullptr; diff --git a/src/wallet/rpc/util.cpp b/src/wallet/rpc/util.cpp index 219378cfd44..a840a657f5f 100644 --- a/src/wallet/rpc/util.cpp +++ b/src/wallet/rpc/util.cpp @@ -123,6 +123,7 @@ void HandleWalletError(const std::shared_ptr wallet, DatabaseStatus& st switch (status) { case DatabaseStatus::FAILED_NOT_FOUND: case DatabaseStatus::FAILED_BAD_FORMAT: + case DatabaseStatus::FAILED_LEGACY_DISABLED: code = RPC_WALLET_NOT_FOUND; break; case DatabaseStatus::FAILED_ALREADY_LOADED: diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index b06787a5b36..12e92cb43e0 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1383,8 +1383,8 @@ std::unique_ptr MakeDatabase(const fs::path& path, const Databas // BERKELEY_RO can only be opened if require_format was set, which only occurs in migration. if (format && format == DatabaseFormat::BERKELEY_RO && (!options.require_format || options.require_format != DatabaseFormat::BERKELEY_RO)) { - error = Untranslated(strprintf("Failed to open database path '%s'. The wallet appears to be a Legacy wallet, please use the wallet migration tool (migratewallet RPC).", fs::PathToString(path))); - status = DatabaseStatus::FAILED_BAD_FORMAT; + error = Untranslated(strprintf("Failed to open database path '%s'. The wallet appears to be a Legacy wallet, please use the wallet migration tool (migratewallet RPC or the GUI option).", fs::PathToString(path))); + status = DatabaseStatus::FAILED_LEGACY_DISABLED; return nullptr; } diff --git a/test/functional/wallet_backwards_compatibility.py b/test/functional/wallet_backwards_compatibility.py index 62d28abcb3c..bb34003e9c4 100755 --- a/test/functional/wallet_backwards_compatibility.py +++ b/test/functional/wallet_backwards_compatibility.py @@ -378,7 +378,7 @@ class BackwardsCompatibilityTest(BitcoinTestFramework): # Restore the wallet to master # Legacy wallets are no longer supported. Trying to load these should result in an error - assert_raises_rpc_error(-18, "The wallet appears to be a Legacy wallet, please use the wallet migration tool (migratewallet RPC)", node_master.restorewallet, wallet_name, backup_path) + assert_raises_rpc_error(-18, "The wallet appears to be a Legacy wallet, please use the wallet migration tool (migratewallet RPC or the GUI option)", node_master.restorewallet, wallet_name, backup_path) self.test_v22_inactivehdchain_path()