descriptors: Check result of InferPubkey

InferPubkey can return a nullptr, so check it's result before continuing
with creating the inferred descriptor.
This commit is contained in:
Andrew Chow
2023-10-05 12:29:22 -04:00
parent db283a6b6f
commit b7485f11ab

View File

@ -1491,15 +1491,19 @@ struct KeyParser {
if (miniscript::IsTapscript(m_script_ctx) && end - begin == 32) { if (miniscript::IsTapscript(m_script_ctx) && end - begin == 32) {
XOnlyPubKey pubkey; XOnlyPubKey pubkey;
std::copy(begin, end, pubkey.begin()); std::copy(begin, end, pubkey.begin());
m_keys.push_back(InferPubkey(pubkey.GetEvenCorrespondingCPubKey(), ParseContext(), *m_in)); if (auto pubkey_provider = InferPubkey(pubkey.GetEvenCorrespondingCPubKey(), ParseContext(), *m_in)) {
m_keys.push_back(std::move(pubkey_provider));
return key; return key;
}
} else if (!miniscript::IsTapscript(m_script_ctx)) { } else if (!miniscript::IsTapscript(m_script_ctx)) {
CPubKey pubkey{begin, end}; CPubKey pubkey(begin, end);
if (pubkey.IsValidNonHybrid()) { if (pubkey.IsValidNonHybrid()) {
m_keys.push_back(InferPubkey(pubkey, ParseContext(), *m_in)); if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) {
m_keys.push_back(std::move(pubkey_provider));
return key; return key;
} }
} }
}
return {}; return {};
} }
@ -1512,10 +1516,12 @@ struct KeyParser {
CKeyID keyid(hash); CKeyID keyid(hash);
CPubKey pubkey; CPubKey pubkey;
if (m_in->GetPubKey(keyid, pubkey)) { if (m_in->GetPubKey(keyid, pubkey)) {
if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) {
Key key = m_keys.size(); Key key = m_keys.size();
m_keys.push_back(InferPubkey(pubkey, ParseContext(), *m_in)); m_keys.push_back(std::move(pubkey_provider));
return key; return key;
} }
}
return {}; return {};
} }
@ -1850,7 +1856,9 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
if (txntype == TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) { if (txntype == TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
CPubKey pubkey(data[0]); CPubKey pubkey(data[0]);
if (pubkey.IsValidNonHybrid()) { if (pubkey.IsValidNonHybrid()) {
return std::make_unique<PKDescriptor>(InferPubkey(pubkey, ctx, provider)); if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
}
} }
} }
if (txntype == TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) { if (txntype == TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
@ -1858,7 +1866,9 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
CKeyID keyid(hash); CKeyID keyid(hash);
CPubKey pubkey; CPubKey pubkey;
if (provider.GetPubKey(keyid, pubkey)) { if (provider.GetPubKey(keyid, pubkey)) {
return std::make_unique<PKHDescriptor>(InferPubkey(pubkey, ctx, provider)); if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
}
} }
} }
if (txntype == TxoutType::WITNESS_V0_KEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) { if (txntype == TxoutType::WITNESS_V0_KEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) {
@ -1866,16 +1876,24 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
CKeyID keyid(hash); CKeyID keyid(hash);
CPubKey pubkey; CPubKey pubkey;
if (provider.GetPubKey(keyid, pubkey)) { if (provider.GetPubKey(keyid, pubkey)) {
return std::make_unique<WPKHDescriptor>(InferPubkey(pubkey, ctx, provider)); if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
}
} }
} }
if (txntype == TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) { if (txntype == TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
bool ok = true;
std::vector<std::unique_ptr<PubkeyProvider>> providers; std::vector<std::unique_ptr<PubkeyProvider>> providers;
for (size_t i = 1; i + 1 < data.size(); ++i) { for (size_t i = 1; i + 1 < data.size(); ++i) {
CPubKey pubkey(data[i]); CPubKey pubkey(data[i]);
providers.push_back(InferPubkey(pubkey, ctx, provider)); if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
providers.push_back(std::move(pubkey_provider));
} else {
ok = false;
break;
} }
return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers)); }
if (ok) return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers));
} }
if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) { if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
uint160 hash(data[0]); uint160 hash(data[0]);