aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wallet/rpc/wallet.cpp14
-rw-r--r--src/wallet/wallet.cpp17
-rw-r--r--src/wallet/wallet.h2
3 files changed, 23 insertions, 10 deletions
diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp
index 2773a7ed59..e8743cd2f6 100644
--- a/src/wallet/rpc/wallet.cpp
+++ b/src/wallet/rpc/wallet.cpp
@@ -713,6 +713,7 @@ static RPCHelpMan migratewallet()
HELP_REQUIRING_PASSPHRASE,
{
{"wallet_name", RPCArg::Type::STR, RPCArg::DefaultHint{"the wallet name from the RPC endpoint"}, "The name of the wallet to migrate. If provided both here and in the RPC endpoint, the two must be identical."},
+ {"passphrase", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The wallet passphrase"},
},
RPCResult{
RPCResult::Type::OBJ, "", "",
@@ -741,15 +742,14 @@ static RPCHelpMan migratewallet()
wallet_name = request.params[0].get_str();
}
- WalletContext& context = EnsureWalletContext(request.context);
- {
- std::shared_ptr<CWallet> wallet = GetWallet(context, wallet_name);
- if (wallet && wallet->IsCrypted()) {
- throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: migratewallet on encrypted wallets is currently unsupported.");
- }
+ SecureString wallet_pass;
+ wallet_pass.reserve(100);
+ if (!request.params[1].isNull()) {
+ wallet_pass = std::string_view{request.params[1].get_str()};
}
- util::Result<MigrationResult> res = MigrateLegacyToDescriptor(wallet_name, context);
+ WalletContext& context = EnsureWalletContext(request.context);
+ util::Result<MigrationResult> res = MigrateLegacyToDescriptor(wallet_name, wallet_pass, context);
if (!res) {
throw JSONRPCError(RPC_WALLET_ERROR, util::ErrorString(res).original);
}
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index e5f730f71b..b957055c0f 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -3767,7 +3767,7 @@ std::optional<MigrationData> CWallet::GetDescriptorsForLegacy(bilingual_str& err
std::optional<MigrationData> res = legacy_spkm->MigrateToDescriptor();
if (res == std::nullopt) {
- error = _("Error: Unable to produce descriptors for this legacy wallet. Make sure the wallet is unlocked first");
+ error = _("Error: Unable to produce descriptors for this legacy wallet. Make sure to provide the wallet's passphrase if it is encrypted.");
return std::nullopt;
}
return res;
@@ -4057,7 +4057,7 @@ bool DoMigration(CWallet& wallet, WalletContext& context, bilingual_str& error,
return true;
}
-util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& wallet_name, WalletContext& context)
+util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& wallet_name, const SecureString& passphrase, WalletContext& context)
{
MigrationResult res;
bilingual_str error;
@@ -4107,6 +4107,19 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
{
LOCK(local_wallet->cs_wallet);
+ // Unlock the wallet if needed
+ if (local_wallet->IsLocked() && !local_wallet->Unlock(passphrase)) {
+ if (passphrase.find('\0') == std::string::npos) {
+ return util::Error{Untranslated("Error: Wallet decryption failed, the wallet passphrase was not provided or was incorrect.")};
+ } else {
+ return util::Error{Untranslated("Error: Wallet decryption failed, the wallet passphrase entered was incorrect. "
+ "The passphrase contains a null character (ie - a zero byte). "
+ "If this passphrase was set with a version of this software prior to 25.0, "
+ "please try again with only the characters up to — but not including — "
+ "the first null character.")};
+ }
+ }
+
// First change to using SQLite
if (!local_wallet->MigrateToSQLite(error)) return util::Error{error};
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 405e531500..637e9e6d41 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -1006,7 +1006,7 @@ struct MigrationResult {
};
//! Do all steps to migrate a legacy wallet to a descriptor wallet
-util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& wallet_name, WalletContext& context);
+util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& wallet_name, const SecureString& passphrase, WalletContext& context);
} // namespace wallet
#endif // BITCOIN_WALLET_WALLET_H