wallet: implement IsKeyActive() in scriptpubkeyman

This new method returns true if the given CScript key is derived
from the SPKM. For Legacy that means checking the hd_seed_id in the
key's metadata.

Also patches PKDescriptor to return associated public keys in
MakeScripts()

Github-Pull: #27216
Rebased-From: f39957f5deec87d141e995a3bc90cc54e2d0ccbf
This commit is contained in:
Matthew Zipkin 2023-04-14 15:05:04 -04:00 committed by Luke Dashjr
parent 55bd5d8015
commit 0b5e99a074
3 changed files with 28 additions and 1 deletions

View File

@ -772,8 +772,11 @@ class PKDescriptor final : public DescriptorImpl
private:
const bool m_xonly;
protected:
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override
std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override
{
CKeyID id = keys[0].GetID();
out.pubkeys.emplace(id, keys[0]);
if (m_xonly) {
CScript script = CScript() << ToByteVector(XOnlyPubKey(keys[0])) << OP_CHECKSIG;
return Vector(std::move(script));

View File

@ -395,6 +395,23 @@ std::vector<WalletDestination> LegacyScriptPubKeyMan::MarkUnusedAddresses(const
return result;
}
bool LegacyScriptPubKeyMan::IsKeyActive(const CScript& script) const
{
LOCK(cs_KeyStore);
if (!IsMine(script)) return false; // Not in the keystore at all
for (const auto& key_id : GetAffectedKeys(script, *this)) {
const auto it = mapKeyMetadata.find(key_id);
if (it == mapKeyMetadata.end()) return false; // This key must be really old
if (!it->second.hd_seed_id.IsNull() && it->second.hd_seed_id == m_hd_chain.seed_id) return true;
}
// Imported or dumped for a new keypool
return false;
}
void LegacyScriptPubKeyMan::UpgradeKeyMetadata()
{
LOCK(cs_KeyStore);

View File

@ -204,6 +204,9 @@ public:
*/
virtual std::vector<WalletDestination> MarkUnusedAddresses(const CScript& script) { return {}; }
/* Determines if address is derived from active key manager */
virtual bool IsKeyActive(const CScript& script) const = 0;
/** Sets up the key generation stuff, i.e. generates new HD seeds and sets them as active.
* Returns false if already setup or setup fails, true if setup is successful
* Set force=true to make it re-setup if already setup, used for upgrades
@ -393,6 +396,8 @@ public:
std::vector<WalletDestination> MarkUnusedAddresses(const CScript& script) override;
[[nodiscard]] bool IsKeyActive(const CScript& script) const override;
//! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
void UpgradeKeyMetadata();
@ -627,6 +632,8 @@ public:
std::vector<WalletDestination> MarkUnusedAddresses(const CScript& script) override;
[[nodiscard]] bool IsKeyActive(const CScript& script) const override { return IsMine(script); }
bool IsHDEnabled() const override;
//! Setup descriptors based on the given CExtkey