aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rpc/blockchain.cpp39
-rw-r--r--src/rpc/util.cpp38
-rw-r--r--src/rpc/util.h5
3 files changed, 48 insertions, 34 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index b8ef758661..01c3265656 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -2241,41 +2241,12 @@ UniValue scantxoutset(const JSONRPCRequest& request)
// loop through the scan objects
for (const UniValue& scanobject : request.params[1].get_array().getValues()) {
- 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");
- }
-
FlatSigningProvider provider;
- 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;
- }
- 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));
- }
- for (const auto& script : scripts) {
- std::string inferred = InferDescriptor(script, provider)->ToString();
- needles.emplace(script);
- descriptors.emplace(std::move(script), std::move(inferred));
- }
+ auto scripts = EvalDescriptorStringOrObject(scanobject, provider);
+ for (const auto& script : scripts) {
+ std::string inferred = InferDescriptor(script, provider)->ToString();
+ needles.emplace(script);
+ descriptors.emplace(std::move(script), std::move(inferred));
}
}
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;
+}
diff --git a/src/rpc/util.h b/src/rpc/util.h
index e4fa8fc3d7..ce485a2095 100644
--- a/src/rpc/util.h
+++ b/src/rpc/util.h
@@ -8,6 +8,8 @@
#include <node/transaction.h>
#include <pubkey.h>
#include <rpc/protocol.h>
+#include <script/script.h>
+#include <script/sign.h>
#include <script/standard.h>
#include <univalue.h>
@@ -83,6 +85,9 @@ UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_s
//! Parse a JSON range specified as int64, or [int64, int64]
std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value);
+/** Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range of 1000. */
+std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider);
+
struct RPCArg {
enum class Type {
OBJ,