mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
Abstract out EvalDescriptorStringOrObject from scantxoutset
This commit is contained in:
parent
eaf4f88734
commit
fb90ec3c33
3 changed files with 48 additions and 34 deletions
|
@ -2241,43 +2241,14 @@ UniValue scantxoutset(const JSONRPCRequest& request)
|
||||||
|
|
||||||
// loop through the scan objects
|
// loop through the scan objects
|
||||||
for (const UniValue& scanobject : request.params[1].get_array().getValues()) {
|
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;
|
FlatSigningProvider provider;
|
||||||
auto desc = Parse(desc_str, provider);
|
auto scripts = EvalDescriptorStringOrObject(scanobject, 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) {
|
for (const auto& script : scripts) {
|
||||||
std::string inferred = InferDescriptor(script, provider)->ToString();
|
std::string inferred = InferDescriptor(script, provider)->ToString();
|
||||||
needles.emplace(script);
|
needles.emplace(script);
|
||||||
descriptors.emplace(std::move(script), std::move(inferred));
|
descriptors.emplace(std::move(script), std::move(inferred));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Scan the unspent transaction output set for inputs
|
// Scan the unspent transaction output set for inputs
|
||||||
UniValue unspents(UniValue::VARR);
|
UniValue unspents(UniValue::VARR);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
#include <keystore.h>
|
#include <keystore.h>
|
||||||
#include <rpc/util.h>
|
#include <rpc/util.h>
|
||||||
|
#include <script/descriptor.h>
|
||||||
#include <tinyformat.h>
|
#include <tinyformat.h>
|
||||||
#include <util/strencodings.h>
|
#include <util/strencodings.h>
|
||||||
|
|
||||||
|
@ -685,3 +686,40 @@ std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value)
|
||||||
}
|
}
|
||||||
return {low, high};
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include <node/transaction.h>
|
#include <node/transaction.h>
|
||||||
#include <pubkey.h>
|
#include <pubkey.h>
|
||||||
#include <rpc/protocol.h>
|
#include <rpc/protocol.h>
|
||||||
|
#include <script/script.h>
|
||||||
|
#include <script/sign.h>
|
||||||
#include <script/standard.h>
|
#include <script/standard.h>
|
||||||
#include <univalue.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]
|
//! Parse a JSON range specified as int64, or [int64, int64]
|
||||||
std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value);
|
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 {
|
struct RPCArg {
|
||||||
enum class Type {
|
enum class Type {
|
||||||
OBJ,
|
OBJ,
|
||||||
|
|
Loading…
Reference in a new issue