Skip to content

Commit dbfa345

Browse files
committed
wallet: Allow MigrateLegacyToDescriptor to take a wallet name
An overload of MigrateLegacyToDescriptor is added which takes the wallet name. The original that took a wallet pointer is still available, it just gets the name, closes the wallet, and calls the new overload.
1 parent 7753efc commit dbfa345

File tree

3 files changed

+32
-26
lines changed

3 files changed

+32
-26
lines changed

src/wallet/rpc/wallet.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -738,16 +738,20 @@ static RPCHelpMan migratewallet()
738738
},
739739
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
740740
{
741-
std::shared_ptr<CWallet> wallet = GetWalletForJSONRPCRequest(request);
742-
if (!wallet) return NullUniValue;
741+
std::string wallet_name;
742+
{
743+
std::shared_ptr<CWallet> wallet = GetWalletForJSONRPCRequest(request);
744+
if (!wallet) return NullUniValue;
743745

744-
if (wallet->IsCrypted()) {
745-
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: migratewallet on encrypted wallets is currently unsupported.");
746+
if (wallet->IsCrypted()) {
747+
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: migratewallet on encrypted wallets is currently unsupported.");
748+
}
749+
wallet_name = wallet->GetName();
746750
}
747751

748752
WalletContext& context = EnsureWalletContext(request.context);
749753

750-
util::Result<MigrationResult> res = MigrateLegacyToDescriptor(std::move(wallet), context);
754+
util::Result<MigrationResult> res = MigrateLegacyToDescriptor(wallet_name, context);
751755
if (!res) {
752756
throw JSONRPCError(RPC_WALLET_ERROR, util::ErrorString(res).original);
753757
}

src/wallet/wallet.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4165,32 +4165,19 @@ bool DoMigration(CWallet& wallet, WalletContext& context, bilingual_str& error,
41654165
return true;
41664166
}
41674167

4168-
util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>&& wallet, WalletContext& context)
4168+
util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& wallet_name, WalletContext& context)
41694169
{
4170-
// Before anything else, check if there is something to migrate.
4171-
if (!wallet->GetLegacyScriptPubKeyMan()) {
4172-
return util::Error{_("Error: This wallet is already a descriptor wallet")};
4173-
}
4174-
41754170
MigrationResult res;
41764171
bilingual_str error;
41774172
std::vector<bilingual_str> warnings;
41784173

4179-
// Make a backup of the DB
4180-
std::string wallet_name = wallet->GetName();
4181-
fs::path this_wallet_dir = fs::absolute(fs::PathFromString(wallet->GetDatabase().Filename())).parent_path();
4182-
fs::path backup_filename = fs::PathFromString(strprintf("%s-%d.legacy.bak", wallet_name, GetTime()));
4183-
fs::path backup_path = this_wallet_dir / backup_filename;
4184-
if (!wallet->BackupWallet(fs::PathToString(backup_path))) {
4185-
return util::Error{_("Error: Unable to make a backup of your wallet")};
4186-
}
4187-
res.backup_path = backup_path;
4188-
4189-
// Unload the wallet so that nothing else tries to use it while we're changing it
4190-
if (!RemoveWallet(context, wallet, /*load_on_start=*/std::nullopt, warnings)) {
4191-
return util::Error{_("Unable to unload the wallet before migrating")};
4174+
// If the wallet is still loaded, unload it so that nothing else tries to use it while we're changing it
4175+
if (auto wallet = GetWallet(context, wallet_name)) {
4176+
if (!RemoveWallet(context, wallet, /*load_on_start=*/std::nullopt, warnings)) {
4177+
return util::Error{_("Unable to unload the wallet before migrating")};
4178+
}
4179+
UnloadWallet(std::move(wallet));
41924180
}
4193-
UnloadWallet(std::move(wallet));
41944181

41954182
// Load the wallet but only in the context of this function.
41964183
// No signals should be connected nor should anything else be aware of this wallet
@@ -4204,11 +4191,26 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>
42044191
return util::Error{Untranslated("Wallet file verification failed.") + Untranslated(" ") + error};
42054192
}
42064193

4194+
// Make the local wallet
42074195
std::shared_ptr<CWallet> local_wallet = CWallet::Create(empty_context, wallet_name, std::move(database), options.create_flags, error, warnings);
42084196
if (!local_wallet) {
42094197
return util::Error{Untranslated("Wallet loading failed.") + Untranslated(" ") + error};
42104198
}
42114199

4200+
// Before anything else, check if there is something to migrate.
4201+
if (!local_wallet->GetLegacyScriptPubKeyMan()) {
4202+
return util::Error{_("Error: This wallet is already a descriptor wallet")};
4203+
}
4204+
4205+
// Make a backup of the DB
4206+
fs::path this_wallet_dir = fs::absolute(fs::PathFromString(local_wallet->GetDatabase().Filename())).parent_path();
4207+
fs::path backup_filename = fs::PathFromString(strprintf("%s-%d.legacy.bak", wallet_name, GetTime()));
4208+
fs::path backup_path = this_wallet_dir / backup_filename;
4209+
if (!local_wallet->BackupWallet(fs::PathToString(backup_path))) {
4210+
return util::Error{_("Error: Unable to make a backup of your wallet")};
4211+
}
4212+
res.backup_path = backup_path;
4213+
42124214
bool success = false;
42134215
{
42144216
LOCK(local_wallet->cs_wallet);

src/wallet/wallet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ struct MigrationResult {
10071007
};
10081008

10091009
//! Do all steps to migrate a legacy wallet to a descriptor wallet
1010-
util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>&& wallet, WalletContext& context);
1010+
util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& wallet_name, WalletContext& context);
10111011
} // namespace wallet
10121012

10131013
#endif // BITCOIN_WALLET_WALLET_H

0 commit comments

Comments
 (0)