diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2019-02-16 15:24:15 -0800 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2019-05-10 14:31:21 -0700 |
commit | fb90ec3c33e824f5abb6a68452c683d6ce8b3e4a (patch) | |
tree | a03bedacd78630ec669ccefbe445ee971c1e4184 /src/rpc/util.cpp | |
parent | eaf4f887348a08c620732125ad4430e1a133d434 (diff) |
Abstract out EvalDescriptorStringOrObject from scantxoutset
Diffstat (limited to 'src/rpc/util.cpp')
-rw-r--r-- | src/rpc/util.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index 9cdb22001f..7a9312aa03 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -5,6 +5,7 @@ #include <key_io.h> #include <keystore.h> #include <rpc/util.h> +#include <script/descriptor.h> #include <tinyformat.h> #include <util/strencodings.h> @@ -685,3 +686,40 @@ std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value) } return {low, high}; } + +std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider) +{ + std::string desc_str; + std::pair<int64_t, int64_t> range = {0, 1000}; + if (scanobject.isStr()) { + desc_str = scanobject.get_str(); + } else if (scanobject.isObject()) { + UniValue desc_uni = find_value(scanobject, "desc"); + if (desc_uni.isNull()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Descriptor needs to be provided in scan object"); + desc_str = desc_uni.get_str(); + UniValue range_uni = find_value(scanobject, "range"); + if (!range_uni.isNull()) { + range = ParseDescriptorRange(range_uni); + } + } else { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan object needs to be either a string or an object"); + } + + auto desc = Parse(desc_str, provider); + if (!desc) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Invalid descriptor '%s'", desc_str)); + } + if (!desc->IsRange()) { + range.first = 0; + range.second = 0; + } + std::vector<CScript> ret; + for (int i = range.first; i <= range.second; ++i) { + std::vector<CScript> scripts; + if (!desc->Expand(i, provider, scripts, provider)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Cannot derive script without private keys: '%s'", desc_str)); + } + std::move(scripts.begin(), scripts.end(), std::back_inserter(ret)); + } + return ret; +} |