Skip to content

Commit 2ea3605

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 76dd4ed commit 2ea3605

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
@@ -503,40 +503,11 @@ RPCHelpMan listdescriptors()
503503
}
504504

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

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

src/wallet/wallet.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4469,4 +4469,32 @@ void CWallet::WriteBestBlock() const
44694469
batch.WriteBestBlock(loc);
44704470
}
44714471
}
4472+
4473+
util::Result<std::vector<WalletDescInfo>> CWallet::ExportDescriptors(bool export_private) const
4474+
{
4475+
AssertLockHeld(cs_wallet);
4476+
std::vector<WalletDescInfo> wallet_descriptors;
4477+
for (const auto& spk_man : GetAllScriptPubKeyMans()) {
4478+
const auto desc_spk_man = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_man);
4479+
if (!desc_spk_man) {
4480+
return util::Error{_("Unexpected ScriptPubKey manager type.")};
4481+
}
4482+
LOCK(desc_spk_man->cs_desc_man);
4483+
const auto& wallet_descriptor = desc_spk_man->GetWalletDescriptor();
4484+
std::string descriptor;
4485+
if (!desc_spk_man->GetDescriptorString(descriptor, export_private)) {
4486+
return util::Error{_("Can't get descriptor string.")};
4487+
}
4488+
const bool is_range = wallet_descriptor.descriptor->IsRange();
4489+
wallet_descriptors.push_back({
4490+
descriptor,
4491+
wallet_descriptor.creation_time,
4492+
IsActiveScriptPubKeyMan(*desc_spk_man),
4493+
IsInternalScriptPubKeyMan(desc_spk_man),
4494+
is_range ? std::optional(std::make_pair(wallet_descriptor.range_start, wallet_descriptor.range_end)) : std::nullopt,
4495+
wallet_descriptor.next_index
4496+
});
4497+
}
4498+
return wallet_descriptors;
4499+
}
44724500
} // namespace wallet

src/wallet/wallet.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,18 @@ struct CRecipient
303303
bool fSubtractFeeFromAmount;
304304
};
305305

306+
// Struct containing all of the info from WalletDescriptor, except with the descriptor as a string,
307+
// and without its ID or cache.
308+
// Used when exporting descriptors from the wallet.
309+
struct WalletDescInfo {
310+
std::string descriptor;
311+
uint64_t creation_time;
312+
bool active;
313+
std::optional<bool> internal;
314+
std::optional<std::pair<int64_t,int64_t>> range;
315+
int64_t next_index;
316+
};
317+
306318
class WalletRescanReserver; //forward declarations for ScanForWalletTransactions/RescanFromTime
307319
/**
308320
* A CWallet maintains a set of transactions and balances, and provides the ability to create new transactions.
@@ -1061,6 +1073,9 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
10611073
//! Find the private key for the given key id from the wallet's descriptors, if available
10621074
//! Returns nullopt when no descriptor has the key or if the wallet is locked.
10631075
std::optional<CKey> GetKey(const CKeyID& keyid) const;
1076+
1077+
//! Export the descriptors from this wallet so that they can be imported elsewhere
1078+
util::Result<std::vector<WalletDescInfo>> ExportDescriptors(bool export_private) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
10641079
};
10651080

10661081
/**

0 commit comments

Comments
 (0)