Skip to content

Commit f734d7b

Browse files
committed
wallet: Move listdescriptors retrieving from RPC to CWallet
When listdescriptors retrieves the descriptors from the wallet, instead of having this logic in the RPC, move it into CWallet itself. This will enable other functions to get the descriptors in an exportable form.
1 parent f608d0f commit f734d7b

File tree

3 files changed

+47
-33
lines changed

3 files changed

+47
-33
lines changed

src/wallet/rpc/backup.cpp

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -500,40 +500,11 @@ RPCHelpMan listdescriptors()
500500
}
501501

502502
LOCK(wallet->cs_wallet);
503-
504-
const auto active_spk_mans = wallet->GetActiveScriptPubKeyMans();
505-
506-
struct WalletDescInfo {
507-
std::string descriptor;
508-
uint64_t creation_time;
509-
bool active;
510-
std::optional<bool> internal;
511-
std::optional<std::pair<int64_t,int64_t>> range;
512-
int64_t next_index;
513-
};
514-
515-
std::vector<WalletDescInfo> wallet_descriptors;
516-
for (const auto& spk_man : wallet->GetAllScriptPubKeyMans()) {
517-
const auto desc_spk_man = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_man);
518-
if (!desc_spk_man) {
519-
throw JSONRPCError(RPC_WALLET_ERROR, "Unexpected ScriptPubKey manager type.");
520-
}
521-
LOCK(desc_spk_man->cs_desc_man);
522-
const auto& wallet_descriptor = desc_spk_man->GetWalletDescriptor();
523-
std::string descriptor;
524-
if (!desc_spk_man->GetDescriptorString(descriptor, priv)) {
525-
throw JSONRPCError(RPC_WALLET_ERROR, "Can't get descriptor string.");
526-
}
527-
const bool is_range = wallet_descriptor.descriptor->IsRange();
528-
wallet_descriptors.push_back({
529-
descriptor,
530-
wallet_descriptor.creation_time,
531-
active_spk_mans.count(desc_spk_man) != 0,
532-
wallet->IsInternalScriptPubKeyMan(desc_spk_man),
533-
is_range ? std::optional(std::make_pair(wallet_descriptor.range_start, wallet_descriptor.range_end)) : std::nullopt,
534-
wallet_descriptor.next_index
535-
});
503+
util::Result<std::vector<WalletDescInfo>> exported = wallet->ExportDescriptors(priv);
504+
if (!exported) {
505+
throw JSONRPCError(RPC_WALLET_ERROR, util::ErrorString(exported).original);
536506
}
507+
std::vector<WalletDescInfo> wallet_descriptors = *exported;
537508

538509
std::sort(wallet_descriptors.begin(), wallet_descriptors.end(), [](const auto& a, const auto& b) {
539510
return a.descriptor < b.descriptor;

src/wallet/wallet.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4462,4 +4462,32 @@ std::optional<CKey> CWallet::GetKey(const CKeyID& keyid) const
44624462
}
44634463
return std::nullopt;
44644464
}
4465+
4466+
util::Result<std::vector<WalletDescInfo>> CWallet::ExportDescriptors(bool export_private) const
4467+
{
4468+
AssertLockHeld(cs_wallet);
4469+
std::vector<WalletDescInfo> wallet_descriptors;
4470+
for (const auto& spk_man : GetAllScriptPubKeyMans()) {
4471+
const auto desc_spk_man = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_man);
4472+
if (!desc_spk_man) {
4473+
return util::Error{_("Unexpected ScriptPubKey manager type.")};
4474+
}
4475+
LOCK(desc_spk_man->cs_desc_man);
4476+
const auto& wallet_descriptor = desc_spk_man->GetWalletDescriptor();
4477+
std::string descriptor;
4478+
if (!desc_spk_man->GetDescriptorString(descriptor, export_private)) {
4479+
return util::Error{_("Can't get descriptor string.")};
4480+
}
4481+
const bool is_range = wallet_descriptor.descriptor->IsRange();
4482+
wallet_descriptors.push_back({
4483+
descriptor,
4484+
wallet_descriptor.creation_time,
4485+
IsActiveScriptPubKeyMan(*desc_spk_man),
4486+
IsInternalScriptPubKeyMan(desc_spk_man),
4487+
is_range ? std::optional(std::make_pair(wallet_descriptor.range_start, wallet_descriptor.range_end)) : std::nullopt,
4488+
wallet_descriptor.next_index
4489+
});
4490+
}
4491+
return wallet_descriptors;
4492+
}
44654493
} // namespace wallet

src/wallet/wallet.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,18 @@ struct CRecipient
293293
bool fSubtractFeeFromAmount;
294294
};
295295

296+
// Struct containing all of the info from WalletDescriptor, except with the descriptor as a string,
297+
// and without its ID or cache.
298+
// Used when exporting descriptors from the wallet.
299+
struct WalletDescInfo {
300+
std::string descriptor;
301+
uint64_t creation_time;
302+
bool active;
303+
std::optional<bool> internal;
304+
std::optional<std::pair<int64_t,int64_t>> range;
305+
int64_t next_index;
306+
};
307+
296308
class WalletRescanReserver; //forward declarations for ScanForWalletTransactions/RescanFromTime
297309
/**
298310
* A CWallet maintains a set of transactions and balances, and provides the ability to create new transactions.
@@ -1055,6 +1067,9 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
10551067
//! Find the private key for the given key id from the wallet's descriptors, if available
10561068
//! Returns nullopt when no descriptor has the key or if the wallet is locked.
10571069
std::optional<CKey> GetKey(const CKeyID& keyid) const;
1070+
1071+
//! Export the descriptors from this wallet so that they can be imported elsewhere
1072+
util::Result<std::vector<WalletDescInfo>> ExportDescriptors(bool export_private) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
10581073
};
10591074

10601075
/**

0 commit comments

Comments
 (0)