Bitcoin ABC 0.31.2
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;
42enum class TransactionError;
43
44static constexpr bool DEFAULT_RPC_DOC_CHECK{false};
45
50extern const std::string UNIX_EPOCH_TIME;
51
55extern const std::string EXAMPLE_ADDRESS;
56
62 UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
63 UniValueType() : typeAny(true) {}
64 bool typeAny;
66};
67
71void RPCTypeCheckObj(const UniValue &o,
72 const std::map<std::string, UniValueType> &typesExpected,
73 bool fAllowNull = false, bool fStrict = false);
74
78extern uint256 ParseHashV(const UniValue &v, std::string strName);
79extern uint256 ParseHashO(const UniValue &o, std::string strKey);
80extern std::vector<uint8_t> ParseHexV(const UniValue &v, std::string strName);
81extern std::vector<uint8_t> ParseHexO(const UniValue &o, std::string strKey);
82
83extern Amount AmountFromValue(const UniValue &value);
84
85using RPCArgList = std::vector<std::pair<std::string, UniValue>>;
86extern std::string HelpExampleCli(const std::string &methodname,
87 const std::string &args);
88extern std::string HelpExampleCliNamed(const std::string &methodname,
89 const RPCArgList &args);
90extern std::string HelpExampleRpc(const std::string &methodname,
91 const std::string &args);
92extern std::string HelpExampleRpcNamed(const std::string &methodname,
93 const RPCArgList &args);
94
95CPubKey HexToPubKey(const std::string &hex_in);
96CPubKey AddrToPubKey(const CChainParams &chainparams,
97 const FillableSigningProvider &keystore,
98 const std::string &addr_in);
100 const std::vector<CPubKey> &pubkeys,
101 OutputType type,
102 FillableSigningProvider &keystore,
103 CScript &script_out);
104
106std::string GetAllOutputTypes();
107
110 const std::string &err_string = "");
111
113std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue &value);
114
119std::vector<CScript>
120EvalDescriptorStringOrObject(const UniValue &scanobject,
121 FlatSigningProvider &provider);
122
128
133enum class OuterType {
134 ARR,
135 OBJ,
136 NONE, // Only set on first recursion
137};
138
140 bool skip_type_check{false};
143 std::string oneline_description{};
149 std::vector<std::string> type_str{};
151 bool hidden{false};
162 bool also_positional{false};
163};
164
165struct RPCArg {
166 enum class Type {
167 OBJ,
168 ARR,
169 STR,
170 NUM,
171 BOOL,
178 OBJ_NAMED_PARAMS,
182 OBJ_USER_KEYS,
185 AMOUNT,
187 STR_HEX,
189 RANGE,
190 };
191
192 enum class Optional {
194 NO,
203 OMITTED,
204 };
206 using DefaultHint = std::string;
209 using Fallback = std::variant<Optional, DefaultHint, Default>;
210
213 const std::string m_names;
216 const std::vector<RPCArg> m_inner;
218 const std::string m_description;
220
221 RPCArg(std::string name, Type type, Fallback fallback,
222 std::string description, RPCArgOptions opts = {})
223 : m_names{std::move(name)}, m_type{std::move(type)},
224 m_fallback{std::move(fallback)},
225 m_description{std::move(description)}, m_opts{std::move(opts)} {
226 CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ &&
227 type != Type::OBJ_NAMED_PARAMS &&
228 type != Type::OBJ_USER_KEYS);
229 }
230
231 RPCArg(std::string name, Type type, Fallback fallback,
232 std::string description, std::vector<RPCArg> inner,
233 RPCArgOptions opts = {})
234 : m_names{std::move(name)}, m_type{std::move(type)},
235 m_inner{std::move(inner)}, m_fallback{std::move(fallback)},
236 m_description{std::move(description)}, m_opts{std::move(opts)} {
237 CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ ||
238 type == Type::OBJ_NAMED_PARAMS ||
239 type == Type::OBJ_USER_KEYS);
240 }
241
242 bool IsOptional() const;
243
248 UniValue MatchesType(const UniValue &request) const;
249
251 std::string GetFirstName() const;
252
254 std::string GetName() const;
255
261 std::string ToString(bool oneline) const;
266 std::string ToStringObj(bool oneline) const;
271 std::string ToDescriptionString(bool is_named_arg) const;
272};
273
274struct RPCResult {
275 enum class Type {
276 OBJ,
277 ARR,
278 STR,
279 NUM,
280 BOOL,
281 NONE,
282 ANY,
283 STR_AMOUNT,
284 STR_HEX,
285 OBJ_DYN,
286 ARR_FIXED,
287 NUM_TIME,
288 ELISION,
289 };
290
292 const std::string m_key_name;
293 const std::vector<RPCResult> m_inner;
294 const bool m_optional;
296 const std::string m_description;
297 const std::string m_cond;
298
299 RPCResult(std::string cond, Type type, std::string key_name, bool optional,
300 std::string description, std::vector<RPCResult> inner = {})
301 : m_type{std::move(type)}, m_key_name{std::move(key_name)},
302 m_inner{std::move(inner)}, m_optional{optional},
303 m_skip_type_check{false}, m_description{std::move(description)},
304 m_cond{std::move(cond)} {
305 CHECK_NONFATAL(!m_cond.empty());
307 }
308
309 RPCResult(std::string cond, Type type, std::string key_name,
310 std::string description, std::vector<RPCResult> inner = {})
311 : RPCResult{std::move(cond), type,
312 std::move(key_name), /*optional=*/false,
313 std::move(description), std::move(inner)} {}
314
315 RPCResult(Type type, std::string key_name, bool optional,
316 std::string description, std::vector<RPCResult> inner = {},
317 bool skip_type_check = false)
318 : m_type{std::move(type)}, m_key_name{std::move(key_name)},
319 m_inner{std::move(inner)}, m_optional{optional},
320 m_skip_type_check{skip_type_check},
321 m_description{std::move(description)}, m_cond{} {
323 }
324
325 RPCResult(Type type, std::string key_name, std::string description,
326 std::vector<RPCResult> inner = {}, bool skip_type_check = false)
327 : RPCResult{type,
328 std::move(key_name),
329 /*optional=*/false,
330 std::move(description),
331 std::move(inner),
332 skip_type_check} {}
333
335 void ToSections(Sections &sections, OuterType outer_type = OuterType::NONE,
336 const int current_indent = 0) const;
338 std::string ToStringObj() const;
340 std::string ToDescriptionString() const;
345 UniValue MatchesType(const UniValue &result) const;
346
347private:
348 void CheckInnerDoc() const;
349};
350
352 const std::vector<RPCResult> m_results;
353
354 RPCResults(RPCResult result) : m_results{{result}} {}
355
356 RPCResults(std::initializer_list<RPCResult> results) : m_results{results} {}
357
361 std::string ToDescriptionString() const;
362};
363
365 const std::string m_examples;
366 explicit RPCExamples(std::string examples)
367 : m_examples(std::move(examples)) {}
368 RPCExamples() : m_examples(std::move("")) {}
369 std::string ToDescriptionString() const;
370};
371
373public:
374 RPCHelpMan(std::string name, std::string description,
375 std::vector<RPCArg> args, RPCResults results,
376 RPCExamples examples);
377 using RPCMethodImpl = std::function<UniValue(
378 const RPCHelpMan &, const Config &config, const JSONRPCRequest &)>;
379 RPCHelpMan(std::string name, std::string description,
380 std::vector<RPCArg> args, RPCResults results,
381 RPCExamples examples, RPCMethodImpl fun);
382
383 UniValue HandleRequest(const Config &config,
384 const JSONRPCRequest &request) const;
410 template <typename R> auto Arg(size_t i) const {
411 // Return argument (required or with default value).
412 if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
413 // Return numbers by value.
414 return ArgValue<R>(i);
415 } else {
416 // Return everything else by reference.
417 return ArgValue<const R &>(i);
418 }
419 }
420 template <typename R> auto Arg(std::string_view key) const {
421 return Arg<R>(GetParamIndex(key));
422 }
450 template <typename R> auto MaybeArg(size_t i) const {
451 // Return optional argument (without default).
452 if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
453 // Return numbers by value, wrapped in optional.
454 return ArgValue<std::optional<R>>(i);
455 } else {
456 // Return other types by pointer.
457 return ArgValue<const R *>(i);
458 }
459 }
460 template <typename R> auto MaybeArg(std::string_view key) const {
461 return MaybeArg<R>(GetParamIndex(key));
462 }
463 std::string ToString() const;
468 UniValue GetArgMap() const;
470 bool IsValidNumArgs(size_t num_args) const;
472 std::vector<std::pair<std::string, bool>> GetArgNames() const;
473
474 const std::string m_name;
475
476private:
478 const std::string m_description;
479 const std::vector<RPCArg> m_args;
483 mutable const JSONRPCRequest *m_req{nullptr};
484 template <typename R> R ArgValue(size_t i) const;
486 size_t GetParamIndex(std::string_view key) const;
487};
488
489#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:85
An encapsulated public key.
Definition: pubkey.h:31
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:424
Definition: config.h:19
Fillable signing provider that keeps keys in an address->secret map.
const RPCExamples m_examples
Definition: util.h:481
size_t GetParamIndex(std::string_view key) const
Return positional index of a parameter using its name as key.
Definition: util.cpp:728
RPCHelpMan(std::string name, std::string description, std::vector< RPCArg > args, RPCResults results, RPCExamples examples)
Definition: util.cpp:490
const std::string m_description
Definition: util.h:478
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:410
bool IsValidNumArgs(size_t num_args) const
If the supplied number of args is neither too small nor too high.
Definition: util.cpp:703
std::function< UniValue(const RPCHelpMan &, const Config &config, const JSONRPCRequest &)> RPCMethodImpl
Definition: util.h:378
const RPCMethodImpl m_fun
Definition: util.h:477
const std::string m_name
Definition: util.h:474
auto MaybeArg(size_t i) const
Helper to get an optional request argument.
Definition: util.h:450
const RPCResults m_results
Definition: util.h:480
UniValue HandleRequest(const Config &config, const JSONRPCRequest &request) const
Definition: util.cpp:590
const std::vector< RPCArg > m_args
Definition: util.h:479
std::string ToString() const
Definition: util.cpp:738
UniValue GetArgMap() const
Return the named args that need to be converted from string to another JSON type.
Definition: util.cpp:821
auto Arg(std::string_view key) const
Definition: util.h:420
std::vector< std::pair< std::string, bool > > GetArgNames() const
Return list of arguments and whether they are named-only.
Definition: util.cpp:714
auto MaybeArg(std::string_view key) const
Definition: util.h:460
const JSONRPCRequest * m_req
A pointer to the request for the duration of m_fun()
Definition: util.h:483
256-bit opaque blob.
Definition: uint256.h:129
TransactionError
Definition: error.h:22
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:335
const char * name
Definition: rest.cpp:47
RPCErrorCode
Bitcoin RPC error codes.
Definition: protocol.h:22
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
Definition: util.cpp:1345
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:153
std::vector< std::pair< std::string, UniValue > > RPCArgList
Definition: util.h:85
UniValue GetServicesNames(ServiceFlags services)
Returns, given services flags, a list of humanly readable (known) network services.
Definition: util.cpp:1409
CTxDestination AddAndGetMultisigDestination(const int required, const std::vector< CPubKey > &pubkeys, OutputType type, FillableSigningProvider &keystore, CScript &script_out)
Definition: util.cpp:236
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:179
UniValue JSONRPCTransactionError(TransactionError terr, const std::string &err_string="")
Definition: util.cpp:336
static constexpr bool DEFAULT_RPC_DOC_CHECK
Definition: util.h:44
Amount AmountFromValue(const UniValue &value)
Definition: util.cpp:58
std::vector< uint8_t > ParseHexV(const UniValue &v, std::string strName)
Definition: util.cpp:97
RPCErrorCode RPCErrorFromTransactionError(TransactionError terr)
Definition: util.cpp:317
const std::string EXAMPLE_ADDRESS
Example CashAddr address used in multiple RPCExamples.
Definition: util.cpp:26
OuterType
Serializing JSON objects depends on the outer type.
Definition: util.h:133
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:170
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:1362
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:25
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:29
std::string GetAllOutputTypes()
Definition: util.cpp:308
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:194
CPubKey AddrToPubKey(const CChainParams &chainparams, const FillableSigningProvider &keystore, const std::string &addr_in)
Definition: util.cpp:208
uint256 ParseHashO(const UniValue &o, std::string strKey)
Definition: util.cpp:93
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded values (throws error if not hex).
Definition: util.cpp:76
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:158
UniValue DescribeAddress(const CTxDestination &dest)
Definition: util.cpp:304
std::vector< uint8_t > ParseHexO(const UniValue &o, std::string strKey)
Definition: util.cpp:111
std::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:85
Definition: amount.h:19
Definition: util.h:165
Type
Definition: util.h:166
@ 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:216
const RPCArgOptions m_opts
Definition: util.h:219
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:213
const Fallback m_fallback
Definition: util.h:217
std::string ToString(bool oneline) const
Return the type string of the argument.
Definition: util.cpp:1287
RPCArg(std::string name, Type type, Fallback fallback, std::string description, RPCArgOptions opts={})
Definition: util.h:221
UniValue MatchesType(const UniValue &request) const
Check whether the request JSON type matches.
Definition: util.cpp:888
const std::string m_description
Definition: util.h:218
std::string DefaultHint
Hint for default value.
Definition: util.h:206
bool IsOptional() const
Definition: util.cpp:917
std::variant< Optional, DefaultHint, Default > Fallback
Definition: util.h:209
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:925
const Type m_type
Definition: util.h:214
RPCArg(std::string name, Type type, Fallback fallback, std::string description, std::vector< RPCArg > inner, RPCArgOptions opts={})
Definition: util.h:231
std::string GetName() const
Return the name, throws when there are aliases.
Definition: util.cpp:912
std::string GetFirstName() const
Return the first of all aliases.
Definition: util.cpp:908
std::string ToStringObj(bool oneline) const
Return the type string of the argument when it is in an object (dict).
Definition: util.cpp:1247
Optional
Definition: util.h:192
bool hidden
For testing only.
Definition: util.h:151
std::vector< std::string > type_str
Should be empty unless it is supposed to override the auto-generated type strings.
Definition: util.h:149
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
Definition: util.h:143
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:162
bool skip_type_check
Definition: util.h:140
std::string ToDescriptionString() const
Definition: util.cpp:586
RPCExamples(std::string examples)
Definition: util.h:366
const std::string m_examples
Definition: util.h:365
RPCExamples()
Definition: util.h:368
const std::string m_description
Definition: util.h:296
void ToSections(Sections &sections, OuterType outer_type=OuterType::NONE, const int current_indent=0) const
Append the sections of the result.
Definition: util.cpp:996
const std::vector< RPCResult > m_inner
Only used for arrays or dicts.
Definition: util.h:293
const std::string m_cond
Definition: util.h:297
UniValue MatchesType(const UniValue &result) const
Check whether the result JSON type matches.
Definition: util.cpp:1144
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:1236
RPCResult(Type type, std::string key_name, std::string description, std::vector< RPCResult > inner={}, bool skip_type_check=false)
Definition: util.h:325
RPCResult(std::string cond, Type type, std::string key_name, std::string description, std::vector< RPCResult > inner={})
Definition: util.h:309
const bool m_optional
Definition: util.h:294
const std::string m_key_name
Only used for dicts.
Definition: util.h:292
RPCResult(std::string cond, Type type, std::string key_name, bool optional, std::string description, std::vector< RPCResult > inner={})
Definition: util.h:299
const Type m_type
Definition: util.h:291
RPCResult(Type type, std::string key_name, bool optional, std::string description, std::vector< RPCResult > inner={}, bool skip_type_check=false)
Definition: util.h:315
const bool m_skip_type_check
Definition: util.h:295
RPCResults(RPCResult result)
Definition: util.h:354
const std::vector< RPCResult > m_results
Definition: util.h:352
RPCResults(std::initializer_list< RPCResult > results)
Definition: util.h:356
Keeps track of RPCArgs by transforming them into sections for the purpose of serializing everything t...
Definition: util.cpp:361
Wrapper for UniValue::VType, which includes typeAny: used to denote don't care type.
Definition: util.h:61
bool typeAny
Definition: util.h:64
UniValueType(UniValue::VType _type)
Definition: util.h:62
UniValue::VType type
Definition: util.h:65
UniValueType()
Definition: util.h:63