From 493656763f73e5ef1cfb979a513c12983dca99dd Mon Sep 17 00:00:00 2001 From: Ava Chow Date: Mon, 18 Mar 2024 16:16:48 -0400 Subject: [PATCH] desc spkm: Return SigningProvider only if we have the privkey If we know about a pubkey that's in our descriptor, but we don't have the private key, don't return a SigningProvider for that pubkey. This is specifically an issue for Taproot outputs that use the H point as the resulting PSBTs may end up containing irrelevant information because the H point was detected as a pubkey each unrelated descriptor knew about. --- src/script/signingprovider.cpp | 5 +++++ src/script/signingprovider.h | 1 + src/wallet/scriptpubkeyman.cpp | 6 +++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/script/signingprovider.cpp b/src/script/signingprovider.cpp index baabd4d5b5cc8..597b1a1544bcc 100644 --- a/src/script/signingprovider.cpp +++ b/src/script/signingprovider.cpp @@ -62,6 +62,11 @@ bool FlatSigningProvider::GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) if (ret) info = std::move(out.second); return ret; } +bool FlatSigningProvider::HaveKey(const CKeyID &keyid) const +{ + CKey key; + return LookupHelper(keys, keyid, key); +} bool FlatSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const { return LookupHelper(keys, keyid, key); } bool FlatSigningProvider::GetTaprootSpendData(const XOnlyPubKey& output_key, TaprootSpendData& spenddata) const { diff --git a/src/script/signingprovider.h b/src/script/signingprovider.h index efdfd9ee566b0..f0fb21c8b18ff 100644 --- a/src/script/signingprovider.h +++ b/src/script/signingprovider.h @@ -215,6 +215,7 @@ struct FlatSigningProvider final : public SigningProvider bool GetCScript(const CScriptID& scriptid, CScript& script) const override; bool GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const override; bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override; + bool HaveKey(const CKeyID &keyid) const override; bool GetKey(const CKeyID& keyid, CKey& key) const override; bool GetTaprootSpendData(const XOnlyPubKey& output_key, TaprootSpendData& spenddata) const override; bool GetTaprootBuilder(const XOnlyPubKey& output_key, TaprootBuilder& builder) const override; diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index 62384056dc6e4..7787e2ff6bfb0 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -2456,7 +2456,11 @@ std::unique_ptr DescriptorScriptPubKeyMan::GetSigningProvid int32_t index = it->second; // Always try to get the signing provider with private keys. This function should only be called during signing anyways - return GetSigningProvider(index, true); + std::unique_ptr out = GetSigningProvider(index, true); + if (!out->HaveKey(pubkey.GetID())) { + return nullptr; + } + return out; } std::unique_ptr DescriptorScriptPubKeyMan::GetSigningProvider(int32_t index, bool include_private) const