spkm: Remove DescriptorSPKM constructor that doesn't take a descriptor

Instead of creating a DescriptorSPKM that doesn't have a descriptor,
only to then generate the descriptor, combine SetupDescriptorGeneration
into the GenerateNewSingleSig factory function, and within that
function, generate the descriptor first before constructing the new
DescriptorSPKM.
This commit is contained in:
Ava Chow
2026-06-02 14:10:54 -07:00
parent 770ff64bd7
commit 9fc7b2618b
4 changed files with 35 additions and 56 deletions

View File

@@ -28,17 +28,16 @@ std::unique_ptr<ExternalSignerScriptPubKeyMan> ExternalSignerScriptPubKeyMan::Lo
std::unique_ptr<ExternalSignerScriptPubKeyMan> ExternalSignerScriptPubKeyMan::CreateNew(WalletStorage& storage, WalletBatch& batch, int64_t keypool_size, std::unique_ptr<Descriptor> desc)
{
auto spkm = std::unique_ptr<ExternalSignerScriptPubKeyMan>(new ExternalSignerScriptPubKeyMan(storage, keypool_size));
LOCK(spkm->cs_desc_man);
assert(storage.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
assert(storage.IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER));
int64_t creation_time = GetTime();
// Make the descriptor
WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
spkm->m_wallet_descriptor = w_desc;
auto spkm = std::unique_ptr<ExternalSignerScriptPubKeyMan>(new ExternalSignerScriptPubKeyMan(storage, w_desc, keypool_size));
LOCK(spkm->cs_desc_man);
assert(storage.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
assert(storage.IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER));
// Store the descriptor
if (!batch.WriteDescriptor(spkm->GetID(), spkm->m_wallet_descriptor)) {

View File

@@ -16,14 +16,7 @@ namespace wallet {
class ExternalSignerScriptPubKeyMan : public DescriptorScriptPubKeyMan
{
private:
//! Create an ExternalSPKM from existing wallet data
ExternalSignerScriptPubKeyMan(WalletStorage& storage, WalletDescriptor& descriptor, int64_t keypool_size, const KeyMap& keys, const CryptedKeyMap& ckeys)
: DescriptorScriptPubKeyMan(storage, descriptor, keypool_size, keys, ckeys)
{}
ExternalSignerScriptPubKeyMan(WalletStorage& storage, int64_t keypool_size)
: DescriptorScriptPubKeyMan(storage, keypool_size)
{}
using DescriptorScriptPubKeyMan::DescriptorScriptPubKeyMan;
public:
static std::unique_ptr<ExternalSignerScriptPubKeyMan> LoadFromStorage(WalletStorage& storage, WalletDescriptor& descriptor, int64_t keypool_size, const KeyMap& keys, const CryptedKeyMap& ckeys);

View File

@@ -866,8 +866,30 @@ std::unique_ptr<DescriptorScriptPubKeyMan> DescriptorScriptPubKeyMan::LoadFromSt
std::unique_ptr<DescriptorScriptPubKeyMan> DescriptorScriptPubKeyMan::GenerateNewSingleSig(WalletStorage& storage, WalletBatch& batch, int64_t keypool_size, const CExtKey& master_key, OutputType addr_type, bool internal)
{
auto spkm = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(storage, keypool_size));
spkm->SetupDescriptorGeneration(batch, master_key, addr_type, internal);
WalletDescriptor desc = GenerateWalletDescriptor(master_key.Neuter(), addr_type, internal);
auto spkm = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(storage, desc, keypool_size));
LOCK(spkm->cs_desc_man);
Assert(spkm->m_storage.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
// Store the master private key, and descriptor
if (!spkm->AddDescriptorKeyWithDB(batch, master_key.key, master_key.key.GetPubKey())) {
throw std::runtime_error(std::string(__func__) + ": writing descriptor master private key failed");
}
if (!batch.WriteDescriptor(spkm->GetID(), spkm->m_wallet_descriptor)) {
throw std::runtime_error(std::string(__func__) + ": writing descriptor failed");
}
// Set m_decryption_thoroughly_checked for encrypted wallets
if (spkm->m_storage.HasEncryptionKeys()) {
spkm->m_decryption_thoroughly_checked = true;
}
// TopUp
spkm->TopUpWithDB(batch);
spkm->m_storage.UnsetBlankWalletFlag(batch);
return spkm;
}
@@ -1214,33 +1236,6 @@ bool DescriptorScriptPubKeyMan::AddDescriptorKeyWithDB(WalletBatch& batch, const
}
}
void DescriptorScriptPubKeyMan::SetupDescriptorGeneration(WalletBatch& batch, const CExtKey& master_key, OutputType addr_type, bool internal)
{
LOCK(cs_desc_man);
Assert(m_storage.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
Assert(!m_wallet_descriptor.descriptor);
m_wallet_descriptor = GenerateWalletDescriptor(master_key.Neuter(), addr_type, internal);
// Store the master private key, and descriptor
if (!AddDescriptorKeyWithDB(batch, master_key.key, master_key.key.GetPubKey())) {
throw std::runtime_error(std::string(__func__) + ": writing descriptor master private key failed");
}
if (!batch.WriteDescriptor(GetID(), m_wallet_descriptor)) {
throw std::runtime_error(std::string(__func__) + ": writing descriptor failed");
}
// Set m_decryption_thoroughly_checked for encrypted wallets
if (m_storage.HasEncryptionKeys()) {
m_decryption_thoroughly_checked = true;
}
// TopUp
TopUpWithDB(batch);
m_storage.UnsetBlankWalletFlag(batch);
}
bool DescriptorScriptPubKeyMan::IsHDEnabled() const
{
LOCK(cs_desc_man);

View File

@@ -301,13 +301,6 @@ private:
*/
mutable std::map<uint256, MuSig2SecNonce> m_musig2_secnonces;
//! Create a new DescriptorScriptPubKeyMan from an existing descriptor (i.e. from an import)
DescriptorScriptPubKeyMan(WalletStorage& storage, WalletDescriptor& descriptor, int64_t keypool_size)
: ScriptPubKeyMan(storage),
m_keypool_size(keypool_size),
m_wallet_descriptor(descriptor)
{}
bool AddDescriptorKeyWithDB(WalletBatch& batch, const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
KeyMap GetKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
@@ -324,16 +317,15 @@ private:
void AddDescriptorKey(const CKey& key, const CPubKey &pubkey);
void UpdateWithSigningProvider(WalletBatch& batch, const FlatSigningProvider& signing_provider) EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man);
//! Setup descriptors based on the given CExtKey
void SetupDescriptorGeneration(WalletBatch& batch, const CExtKey& master_key, OutputType addr_type, bool internal);
protected:
//! Create a DescriptorScriptPubKeyMan from existing data (i.e. during loading)
DescriptorScriptPubKeyMan(WalletStorage& storage, WalletDescriptor& descriptor, int64_t keypool_size, const KeyMap& keys, const CryptedKeyMap& ckeys);
DescriptorScriptPubKeyMan(WalletStorage& storage, int64_t keypool_size)
//! Create a new DescriptorScriptPubKeyMan from a descriptor (e.g. from an import, newly generated)
DescriptorScriptPubKeyMan(WalletStorage& storage, WalletDescriptor& descriptor, int64_t keypool_size)
: ScriptPubKeyMan(storage),
m_keypool_size(keypool_size)
m_keypool_size(keypool_size),
m_wallet_descriptor(descriptor)
{}
WalletDescriptor m_wallet_descriptor GUARDED_BY(cs_desc_man);