descriptors: Change Parse to return vector of descriptors

When given a descriptor which contins a multipath derivation specifier,
a vector of descriptors will be returned.
This commit is contained in:
Ava Chow
2024-08-07 16:29:06 -04:00
parent 0d640c6f02
commit 1bbf46e2da
22 changed files with 178 additions and 111 deletions

View File

@@ -180,35 +180,36 @@ static UniValue generateBlocks(ChainstateManager& chainman, Mining& miner, const
static bool getScriptFromDescriptor(const std::string& descriptor, CScript& script, std::string& error)
{
FlatSigningProvider key_provider;
const auto desc = Parse(descriptor, key_provider, error, /* require_checksum = */ false);
if (desc) {
if (desc->IsRange()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Ranged descriptor not accepted. Maybe pass through deriveaddresses first?");
}
FlatSigningProvider provider;
std::vector<CScript> scripts;
if (!desc->Expand(0, key_provider, scripts, provider)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot derive script without private keys");
}
// Combo descriptors can have 2 or 4 scripts, so we can't just check scripts.size() == 1
CHECK_NONFATAL(scripts.size() > 0 && scripts.size() <= 4);
if (scripts.size() == 1) {
script = scripts.at(0);
} else if (scripts.size() == 4) {
// For uncompressed keys, take the 3rd script, since it is p2wpkh
script = scripts.at(2);
} else {
// Else take the 2nd script, since it is p2pkh
script = scripts.at(1);
}
return true;
} else {
return false;
const auto descs = Parse(descriptor, key_provider, error, /* require_checksum = */ false);
if (descs.empty()) return false;
if (descs.size() > 1) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Multipath descriptor not accepted");
}
const auto& desc = descs.at(0);
if (desc->IsRange()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Ranged descriptor not accepted. Maybe pass through deriveaddresses first?");
}
FlatSigningProvider provider;
std::vector<CScript> scripts;
if (!desc->Expand(0, key_provider, scripts, provider)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot derive script without private keys");
}
// Combo descriptors can have 2 or 4 scripts, so we can't just check scripts.size() == 1
CHECK_NONFATAL(scripts.size() > 0 && scripts.size() <= 4);
if (scripts.size() == 1) {
script = scripts.at(0);
} else if (scripts.size() == 4) {
// For uncompressed keys, take the 3rd script, since it is p2wpkh
script = scripts.at(2);
} else {
// Else take the 2nd script, since it is p2pkh
script = scripts.at(1);
}
return true;
}
static RPCHelpMan generatetodescriptor()