Bitcoin ABC 0.32.12
P2P Digital Currency
util.h
Go to the documentation of this file.
1// Copyright (c) 2017-2021 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#ifndef BITCOIN_RPC_UTIL_H
6#define BITCOIN_RPC_UTIL_H
7
8#include <consensus/amount.h>
9#include <node/transaction.h>
10#include <outputtype.h>
11#include <protocol.h>
12#include <rpc/protocol.h>
13#include <rpc/request.h>
14#include <script/script.h>
15#include <script/sign.h>
16#include <script/standard.h> // For CTxDestination
17#include <uint256.h>
18#include <univalue.h>
19#include <util/check.h>
20
21#include <cstddef>
22#include <cstdint>
23#include <functional>
24#include <initializer_list>
25#include <map>
26#include <optional>
27#include <string>
28#include <type_traits>
29#include <utility>
30#include <variant>
31#include <vector>
32
33class CChainParams;
35class CPubKey;
36class CScript;
37class JSONRPCRequest;
39enum class OutputType;
40struct Sections;
41enum ServiceFlags : uint64_t;
42namespace common {
43enum class PSBTError;
44} // namespace common
45namespace node {
46enum class TransactionError;
47} // namespace node
48
49static constexpr bool DEFAULT_RPC_DOC_CHECK{false};
50
55extern const std::string UNIX_EPOCH_TIME;
56
60extern const std::string EXAMPLE_ADDRESS;
61
67 UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
68 UniValueType() : typeAny(true) {}
69 bool typeAny;
71};
72
76void RPCTypeCheckObj(const UniValue &o,
77 const std::map<std::string, UniValueType> &typesExpected,
78 bool fAllowNull = false, bool fStrict = false);
79
83extern uint256 ParseHashV(const UniValue &v, std::string strName);
84extern uint256 ParseHashO(const UniValue &o, std::string strKey);
85extern std::vector<uint8_t> ParseHexV(const UniValue &v, std::string strName);
86extern std::vector<uint8_t> ParseHexO(const UniValue &o, std::string strKey);
87
88extern Amount AmountFromValue(const UniValue &value);
89
90using RPCArgList = std::vector<std::pair<std::string, UniValue>>;
91extern std::string HelpExampleCli(const std::string &methodname,
92 const std::string &args);
93extern std::string HelpExampleCliNamed(const std::string &methodname,
94 const RPCArgList &args);
95extern std::string HelpExampleRpc(const std::string &methodname,
96 const std::string &args);
97extern std::string HelpExampleRpcNamed(const std::string &methodname,
98 const RPCArgList &args);
99
100CPubKey HexToPubKey(const std::string &hex_in);
101CPubKey AddrToPubKey(const CChainParams &chainparams,
102 const FillableSigningProvider &keystore,
103 const std::string &addr_in);
105 const std::vector<CPubKey> &pubkeys,
106 OutputType type,
107 FillableSigningProvider &keystore,
108 CScript &script_out);
109
111std::string GetAllOutputTypes();
112
116 const std::string &err_string = "");
117
119std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue &value);
120
125std::vector<CScript>
126EvalDescriptorStringOrObject(const UniValue &scanobject,
127 FlatSigningProvider &provider);
128
134
139enum class OuterType {
140 ARR,
141 OBJ,
142 NONE, // Only set on first recursion
143};
144
146 bool skip_type_check{false};
149 std::string oneline_description{};
155 std::vector<std::string> type_str{};
157 bool hidden{false};
168 bool also_positional{false};
169};
170
171struct RPCArg {
172 enum class Type {
173 OBJ,
174 ARR,
175 STR,
176 NUM,
177 BOOL,
184 OBJ_NAMED_PARAMS,
188 OBJ_USER_KEYS,
191 AMOUNT,
193 STR_HEX,
195 RANGE,
196 };
197
198 enum class Optional {
200 NO,
209 OMITTED,
210 };
212 using DefaultHint = std::string;
215 using Fallback = std::variant<Optional, DefaultHint, Default>;
216
219 const std::string m_names;
222 const std::vector<RPCArg> m_inner;
224 const std::string m_description;
226
227 RPCArg(std::string name, Type type, Fallback fallback,
228 std::string description, RPCArgOptions opts = {})
229 : m_names{std::move(name)}, m_type{std::move(type)},
230 m_fallback{std::move(fallback)},
231 m_description{std::move(description)}, m_opts{std::move(opts)} {
232 CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ &&
233 type != Type::OBJ_NAMED_PARAMS &&
234 type != Type::OBJ_USER_KEYS);
235 }
236
237 RPCArg(std::string name, Type type, Fallback fallback,
238 std::string description, std::vector<RPCArg> inner,
239 RPCArgOptions opts = {})
240 : m_names{std::move(name)}, m_type{std::move(type)},
241 m_inner{std::move(inner)}, m_fallback{std::move(fallback)},
242 m_description{std::move(description)}, m_opts{std::move(opts)} {
243 CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ ||
244 type == Type::OBJ_NAMED_PARAMS ||
245 type == Type::OBJ_USER_KEYS);
246 }
247
248 bool IsOptional() const;
249
254 UniValue MatchesType(const UniValue &request) const;
255
257 std::string GetFirstName() const;
258
260 std::string GetName() const;
261
267 std::string ToString(bool oneline) const;
272 std::string ToStringObj(bool oneline) const;
277 std::string ToDescriptionString(bool is_named_arg) const;
278};
279
280struct RPCResult {
281 enum class Type {
282 OBJ,
283 ARR,
284 STR,
285 NUM,
286 BOOL,
287 NONE,
288 ANY,
289 STR_AMOUNT,
290 STR_HEX,
291 OBJ_DYN,
292 ARR_FIXED,
293 NUM_TIME,
294 ELISION,
295 };
296
298 const std::string m_key_name;
299 const std::vector<RPCResult> m_inner;
300 const bool m_optional;
302 const std::string m_description;
303 const std::string m_cond;
304
305 RPCResult(std::string cond, Type type, std::string key_name, bool optional,
306 std::string description, std::vector<RPCResult> inner = {})
307 : m_type{std::move(type)}, m_key_name{std::move(key_name)},
308 m_inner{std::move(inner)}, m_optional{optional},
309 m_skip_type_check{false}, m_description{std::move(description)},
310 m_cond{std::move(cond)} {
311 CHECK_NONFATAL(!m_cond.empty());
313 }
314
315 RPCResult(std::string cond, Type type, std::string key_name,
316 std::string description, std::vector<RPCResult> inner = {})
317 : RPCResult{std::move(cond), type,
318 std::move(key_name), /*optional=*/false,
319 std::move(description), std::move(inner)} {}
320
321 RPCResult(Type type, std::string key_name, bool optional,
322 std::string description, std::vector<RPCResult> inner = {},
323 bool skip_type_check = false)
324 : m_type{std::move(type)}, m_key_name{std::move(key_name)},
325 m_inner{std::move(inner)}, m_optional{optional},
326 m_skip_type_check{skip_type_check},
327 m_description{std::move(description)}, m_cond{} {
329 }
330
331 RPCResult(Type type, std::string key_name, std::string description,
332 std::vector<RPCResult> inner = {}, bool skip_type_check = false)
333 : RPCResult{type,
334 std::move(key_name),
335 /*optional=*/false,
336 std::move(description),
337 std::move(inner),
338 skip_type_check} {}
339
341 void ToSections(Sections &sections, OuterType outer_type = OuterType::NONE,
342 const int current_indent = 0) const;
344 std::string ToStringObj() const;
346 std::string ToDescriptionString() const;
351 UniValue MatchesType(const UniValue &result) const;
352
353private:
354 void CheckInnerDoc() const;
355};
356
358 const std::vector<RPCResult> m_results;
359
360 RPCResults(RPCResult result) : m_results{{result}} {}
361
362 RPCResults(std::initializer_list<RPCResult> results) : m_results{results} {}
363
367 std::string ToDescriptionString() const;
368};
369
371 const std::string m_examples;
372 explicit RPCExamples(std::string examples)
373 : m_examples(std::move(examples)) {}
374 RPCExamples() : m_examples(std::move("")) {}
375 std::string ToDescriptionString() const;
376};
377
379public:
380 RPCHelpMan(std::string name, std::string description,
381 std::vector<RPCArg> args, RPCResults results,
382 RPCExamples examples);
383 using RPCMethodImpl = std::function<UniValue(
384 const RPCHelpMan &, const Config &config, const JSONRPCRequest &)>;
385 RPCHelpMan(std::string name, std::string description,
386 std::vector<RPCArg> args, RPCResults results,
387 RPCExamples examples, RPCMethodImpl fun);
388
389 UniValue HandleRequest(const Config &config,
390 const JSONRPCRequest &request) const;
416 template <typename R> auto Arg(size_t i) const {
417 // Return argument (required or with default value).
418 if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
419 // Return numbers by value.
420 return ArgValue<R>(i);
421 } else {
422 // Return everything else by reference.
423 return ArgValue<const R &>(i);
424 }
425 }
426 template <typename R> auto Arg(std::string_view key) const {
427 return Arg<R>(GetParamIndex(key));
428 }
456 template <typename R> auto MaybeArg(size_t i) const {
457 // Return optional argument (without default).
458 if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
459 // Return numbers by value, wrapped in optional.
460 return ArgValue<std::optional<R>>(i);
461 } else {
462 // Return other types by pointer.
463 return ArgValue<const R *>(i);
464 }
465 }
466 template <typename R> auto MaybeArg(std::string_view key) const {
467 return MaybeArg<R>(GetParamIndex(key));
468 }
469 std::string ToString() const;
474 UniValue GetArgMap() const;
476 bool IsValidNumArgs(size_t num_args) const;
478 std::vector<std::pair<std::string, bool>> GetArgNames() const;
479
480 const std::string m_name;
481
482private:
484 const std::string m_description;
485 const std::vector<RPCArg> m_args;
489 mutable const JSONRPCRequest *m_req{nullptr};
490 template <typename R> R ArgValue(size_t i) const;
492 size_t GetParamIndex(std::string_view key) const;
493};
494
495#endif // BITCOIN_RPC_UTIL_H
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:53
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:86
An encapsulated public key.
Definition: pubkey.h:31
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:432
Definition: config.h:19
Fillable signing provider that keeps keys in an address->secret map.
const RPCExamples m_examples
Definition: util.h:487
size_t GetParamIndex(std::string_view key) const
Return positional index of a parameter using its name as key.
Definition: util.cpp:748
RPCHelpMan(std::string name, std::string description, std::vector< RPCArg > args, RPCResults results, RPCExamples examples)
Definition: util.cpp:510
const std::string m_description
Definition: util.h:484
R ArgValue(size_t i) const
auto Arg(size_t i) const
Helper to get a required or default-valued request argument.
Definition: util.h:416
bool IsValidNumArgs(size_t num_args) const
If the supplied number of args is neither too small nor too high.
Definition: util.cpp:723
std::function< UniValue(const RPCHelpMan &, const Config &config, const JSONRPCRequest &)> RPCMethodImpl
Definition: util.h:384
const RPCMethodImpl m_fun
Definition: util.h:483
const std::string m_name
Definition: util.h:480
auto MaybeArg(size_t i) const
Helper to get an optional request argument.
Definition: util.h:456
const RPCResults m_results
Definition: util.h:486
UniValue HandleRequest(const Config &config, const JSONRPCRequest &request) const
Definition: util.cpp:610
const std::vector< RPCArg > m_args
Definition: util.h:485
std::string ToString() const
Definition: util.cpp:758
UniValue GetArgMap() const
Return the named args that need to be converted from string to another JSON type.
Definition: util.cpp:841
auto Arg(std::string_view key) const
Definition: util.h:426
std::vector< std::pair< std::string, bool > > GetArgNames() const
Return list of arguments and whether they are named-only.
Definition: util.cpp:734
auto MaybeArg(std::string_view key) const
Definition: util.h:466
const JSONRPCRequest * m_req
A pointer to the request for the duration of m_fun()
Definition: util.h:489
256-bit opaque blob.
Definition: uint256.h:129
Definition: args.cpp:864
PSBTError
Definition: types.h:17
Definition: messages.h:12
TransactionError
Definition: types.h:17
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
OutputType
Definition: outputtype.h:16
ServiceFlags
nServices flags.
Definition: protocol.h:336
const char * name
Definition: rest.cpp:47
RPCErrorCode
Bitcoin RPC error codes.
Definition: protocol.h:22
RPCErrorCode RPCErrorFromTransactionError(node::TransactionError terr)
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
Definition: util.cpp:1365
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:163
std::vector< std::pair< std::string, UniValue > > RPCArgList
Definition: util.h:90
UniValue GetServicesNames(ServiceFlags services)
Returns, given services flags, a list of humanly readable (known) network services.
Definition: util.cpp:1429
CTxDestination AddAndGetMultisigDestination(const int required, const std::vector< CPubKey > &pubkeys, OutputType type, FillableSigningProvider &keystore, CScript &script_out)
Definition: util.cpp:246
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:189
static constexpr bool DEFAULT_RPC_DOC_CHECK
Definition: util.h:49
Amount AmountFromValue(const UniValue &value)
Definition: util.cpp:68
std::vector< uint8_t > ParseHexV(const UniValue &v, std::string strName)
Definition: util.cpp:107
const std::string EXAMPLE_ADDRESS
Example CashAddr address used in multiple RPCExamples.
Definition: util.cpp:36
OuterType
Serializing JSON objects depends on the outer type.
Definition: util.h:139
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:180
std::vector< CScript > EvalDescriptorStringOrObject(const UniValue &scanobject, FlatSigningProvider &provider)
Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range ...
Definition: util.cpp:1382
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency.
Definition: util.cpp:35
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull=false, bool fStrict=false)
Check for expected keys/value types in an Object.
Definition: util.cpp:39
std::string GetAllOutputTypes()
Definition: util.cpp:318
UniValue JSONRPCTransactionError(node::TransactionError terr, const std::string &err_string="")
UniValue JSONRPCPSBTError(common::PSBTError err)
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:204
CPubKey AddrToPubKey(const CChainParams &chainparams, const FillableSigningProvider &keystore, const std::string &addr_in)
Definition: util.cpp:218
uint256 ParseHashO(const UniValue &o, std::string strKey)
Definition: util.cpp:103
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded values (throws error if not hex).
Definition: util.cpp:86
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:168
UniValue DescribeAddress(const CTxDestination &dest)
Definition: util.cpp:314
std::vector< uint8_t > ParseHexO(const UniValue &o, std::string strKey)
Definition: util.cpp:121
#define STR(x)
Definition: util.h:16
std::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:85
Definition: amount.h:21
Definition: util.h:171
Type
Definition: util.h:172
@ OBJ_USER_KEYS
Special type where the user must set the keys e.g.
@ OBJ_NAMED_PARAMS
Special type that behaves almost exactly like OBJ, defining an options object with a list of pre-defi...
const std::vector< RPCArg > m_inner
Only used for arrays or dicts.
Definition: util.h:222
const RPCArgOptions m_opts
Definition: util.h:225
const std::string m_names
The name of the arg (can be empty for inner args, can contain multiple aliases separated by | for nam...
Definition: util.h:219
const Fallback m_fallback
Definition: util.h:223
std::string ToString(bool oneline) const
Return the type string of the argument.
Definition: util.cpp:1307
RPCArg(std::string name, Type type, Fallback fallback, std::string description, RPCArgOptions opts={})
Definition: util.h:227
UniValue MatchesType(const UniValue &request) const
Check whether the request JSON type matches.
Definition: util.cpp:908
const std::string m_description
Definition: util.h:224
std::string DefaultHint
Hint for default value.
Definition: util.h:212
bool IsOptional() const
Definition: util.cpp:937
std::variant< Optional, DefaultHint, Default > Fallback
Definition: util.h:215
std::string ToDescriptionString(bool is_named_arg) const
Return the description string, including the argument type and whether the argument is required.
Definition: util.cpp:945
const Type m_type
Definition: util.h:220
RPCArg(std::string name, Type type, Fallback fallback, std::string description, std::vector< RPCArg > inner, RPCArgOptions opts={})
Definition: util.h:237
std::string GetName() const
Return the name, throws when there are aliases.
Definition: util.cpp:932
std::string GetFirstName() const
Return the first of all aliases.
Definition: util.cpp:928
std::string ToStringObj(bool oneline) const
Return the type string of the argument when it is in an object (dict).
Definition: util.cpp:1267
Optional
Definition: util.h:198
bool hidden
For testing only.
Definition: util.h:157
std::vector< std::string > type_str
Should be empty unless it is supposed to override the auto-generated type strings.
Definition: util.h:155
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
Definition: util.h:149
bool also_positional
If set allows a named-parameter field in an OBJ_NAMED_PARAM options object to have the same name as a...
Definition: util.h:168
bool skip_type_check
Definition: util.h:146
std::string ToDescriptionString() const
Definition: util.cpp:606
RPCExamples(std::string examples)
Definition: util.h:372
const std::string m_examples
Definition: util.h:371
RPCExamples()
Definition: util.h:374
const std::string m_description
Definition: util.h:302
void ToSections(Sections &sections, OuterType outer_type=OuterType::NONE, const int current_indent=0) const
Append the sections of the result.
Definition: util.cpp:1016
const std::vector< RPCResult > m_inner
Only used for arrays or dicts.
Definition: util.h:299
const std::string m_cond
Definition: util.h:303
UniValue MatchesType(const UniValue &result) const
Check whether the result JSON type matches.
Definition: util.cpp:1164
std::string ToDescriptionString() const
Return the description string, including the result type.
std::string ToStringObj() const
Return the type string of the result when it is in an object (dict).
void CheckInnerDoc() const
Definition: util.cpp:1256
RPCResult(Type type, std::string key_name, std::string description, std::vector< RPCResult > inner={}, bool skip_type_check=false)
Definition: util.h:331
RPCResult(std::string cond, Type type, std::string key_name, std::string description, std::vector< RPCResult > inner={})
Definition: util.h:315
const bool m_optional
Definition: util.h:300
const std::string m_key_name
Only used for dicts.
Definition: util.h:298
RPCResult(std::string cond, Type type, std::string key_name, bool optional, std::string description, std::vector< RPCResult > inner={})
Definition: util.h:305
const Type m_type
Definition: util.h:297
RPCResult(Type type, std::string key_name, bool optional, std::string description, std::vector< RPCResult > inner={}, bool skip_type_check=false)
Definition: util.h:321
const bool m_skip_type_check
Definition: util.h:301
RPCResults(RPCResult result)
Definition: util.h:360
const std::vector< RPCResult > m_results
Definition: util.h:358
RPCResults(std::initializer_list< RPCResult > results)
Definition: util.h:362
Keeps track of RPCArgs by transforming them into sections for the purpose of serializing everything t...
Definition: util.cpp:381
Wrapper for UniValue::VType, which includes typeAny: used to denote don't care type.
Definition: util.h:66
bool typeAny
Definition: util.h:69
UniValueType(UniValue::VType _type)
Definition: util.h:67
UniValue::VType type
Definition: util.h:70
UniValueType()
Definition: util.h:68