Bitcoin ABC  0.26.3
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 <node/transaction.h>
9 #include <outputtype.h>
10 #include <protocol.h>
11 #include <rpc/protocol.h>
12 #include <rpc/request.h>
13 #include <script/script.h>
14 #include <script/sign.h>
15 #include <script/standard.h> // For CTxDestination
16 #include <univalue.h>
17 #include <util/check.h>
18 
19 #include <string>
20 #include <variant>
21 #include <vector>
22 
23 class CChainParams;
25 class CPubKey;
26 class CScript;
27 struct Sections;
28 
29 static constexpr bool DEFAULT_RPC_DOC_CHECK{false};
30 
35 extern const std::string UNIX_EPOCH_TIME;
36 
40 extern const std::string EXAMPLE_ADDRESS;
41 
46 struct UniValueType {
47  UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
48  UniValueType() : typeAny(true) {}
49  bool typeAny;
51 };
52 
56 void RPCTypeCheckObj(const UniValue &o,
57  const std::map<std::string, UniValueType> &typesExpected,
58  bool fAllowNull = false, bool fStrict = false);
59 
63 extern uint256 ParseHashV(const UniValue &v, std::string strName);
64 extern uint256 ParseHashO(const UniValue &o, std::string strKey);
65 extern std::vector<uint8_t> ParseHexV(const UniValue &v, std::string strName);
66 extern std::vector<uint8_t> ParseHexO(const UniValue &o, std::string strKey);
67 
68 extern Amount AmountFromValue(const UniValue &value);
69 
70 using RPCArgList = std::vector<std::pair<std::string, UniValue>>;
71 extern std::string HelpExampleCli(const std::string &methodname,
72  const std::string &args);
73 extern std::string HelpExampleCliNamed(const std::string &methodname,
74  const RPCArgList &args);
75 extern std::string HelpExampleRpc(const std::string &methodname,
76  const std::string &args);
77 extern std::string HelpExampleRpcNamed(const std::string &methodname,
78  const RPCArgList &args);
79 
80 CPubKey HexToPubKey(const std::string &hex_in);
81 CPubKey AddrToPubKey(const CChainParams &chainparams,
82  const FillableSigningProvider &keystore,
83  const std::string &addr_in);
85  const std::vector<CPubKey> &pubkeys,
86  OutputType type,
87  FillableSigningProvider &keystore,
88  CScript &script_out);
89 
91 std::string GetAllOutputTypes();
92 
95  const std::string &err_string = "");
96 
98 std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue &value);
99 
104 std::vector<CScript>
105 EvalDescriptorStringOrObject(const UniValue &scanobject,
106  FlatSigningProvider &provider);
107 
113 
118 enum class OuterType {
119  ARR,
120  OBJ,
121  NONE, // Only set on first recursion
122 };
123 
125  bool skip_type_check{false};
128  std::string oneline_description{};
134  std::vector<std::string> type_str{};
136  bool hidden{false};
147  bool also_positional{false};
148 };
149 
150 struct RPCArg {
151  enum class Type {
152  OBJ,
153  ARR,
154  STR,
155  NUM,
156  BOOL,
170  AMOUNT,
172  STR_HEX,
174  RANGE,
175  };
176 
177  enum class Optional {
179  NO,
191  OMITTED,
192  OMITTED_NAMED_ARG, // Deprecated alias for OMITTED, can be removed
193  };
195  using DefaultHint = std::string;
197  using Default = UniValue;
198  using Fallback = std::variant<Optional, DefaultHint, Default>;
199 
202  const std::string m_names;
203  const Type m_type;
205  const std::vector<RPCArg> m_inner;
207  const std::string m_description;
209 
210  RPCArg(std::string name, Type type, Fallback fallback,
211  std::string description, RPCArgOptions opts = {})
212  : m_names{std::move(name)}, m_type{std::move(type)},
213  m_fallback{std::move(fallback)},
214  m_description{std::move(description)}, m_opts{std::move(opts)} {
215  CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ &&
216  type != Type::OBJ_NAMED_PARAMS &&
217  type != Type::OBJ_USER_KEYS);
218  }
219 
220  RPCArg(std::string name, Type type, Fallback fallback,
221  std::string description, std::vector<RPCArg> inner,
222  RPCArgOptions opts = {})
223  : m_names{std::move(name)}, m_type{std::move(type)},
224  m_inner{std::move(inner)}, 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  bool IsOptional() const;
232 
237  UniValue MatchesType(const UniValue &request) const;
238 
240  std::string GetFirstName() const;
241 
243  std::string GetName() const;
244 
250  std::string ToString(bool oneline) const;
255  std::string ToStringObj(bool oneline) const;
260  std::string ToDescriptionString(bool is_named_arg) const;
261 };
262 
263 struct RPCResult {
264  enum class Type {
265  OBJ,
266  ARR,
267  STR,
268  NUM,
269  BOOL,
270  NONE,
271  ANY,
272  STR_AMOUNT,
273  STR_HEX,
274  OBJ_DYN,
275  ARR_FIXED,
276  NUM_TIME,
277  ELISION,
278  };
279 
280  const Type m_type;
281  const std::string m_key_name;
282  const std::vector<RPCResult> m_inner;
283  const bool m_optional;
284  const bool m_skip_type_check;
285  const std::string m_description;
286  const std::string m_cond;
287 
288  RPCResult(std::string cond, Type type, std::string key_name, bool optional,
289  std::string description, std::vector<RPCResult> inner = {})
290  : m_type{std::move(type)},
291  m_key_name{std::move(key_name)}, m_inner{std::move(inner)},
292  m_optional{optional}, m_skip_type_check{false},
293  m_description{std::move(description)}, m_cond{std::move(cond)} {
294  CHECK_NONFATAL(!m_cond.empty());
295  CheckInnerDoc();
296  }
297 
298  RPCResult(std::string cond, Type type, std::string key_name,
299  std::string description, std::vector<RPCResult> inner = {})
300  : RPCResult{std::move(cond), type,
301  std::move(key_name), /*optional=*/false,
302  std::move(description), std::move(inner)} {}
303 
304  RPCResult(Type type, std::string key_name, bool optional,
305  std::string description, std::vector<RPCResult> inner = {},
306  bool skip_type_check = false)
307  : m_type{std::move(type)},
308  m_key_name{std::move(key_name)}, m_inner{std::move(inner)},
309  m_optional{optional}, m_skip_type_check{skip_type_check},
310  m_description{std::move(description)}, m_cond{} {
311  CheckInnerDoc();
312  }
313 
314  RPCResult(Type type, std::string key_name, std::string description,
315  std::vector<RPCResult> inner = {}, bool skip_type_check = false)
316  : RPCResult{type,
317  std::move(key_name),
318  /*optional=*/false,
319  std::move(description),
320  std::move(inner),
321  skip_type_check} {}
322 
324  void ToSections(Sections &sections, OuterType outer_type = OuterType::NONE,
325  const int current_indent = 0) const;
327  std::string ToStringObj() const;
329  std::string ToDescriptionString() const;
334  UniValue MatchesType(const UniValue &result) const;
335 
336 private:
337  void CheckInnerDoc() const;
338 };
339 
340 struct RPCResults {
341  const std::vector<RPCResult> m_results;
342 
343  RPCResults(RPCResult result) : m_results{{result}} {}
344 
345  RPCResults(std::initializer_list<RPCResult> results) : m_results{results} {}
346 
350  std::string ToDescriptionString() const;
351 };
352 
353 struct RPCExamples {
354  const std::string m_examples;
355  explicit RPCExamples(std::string examples)
356  : m_examples(std::move(examples)) {}
357  RPCExamples() : m_examples(std::move("")) {}
358  std::string ToDescriptionString() const;
359 };
360 
361 class RPCHelpMan {
362 public:
363  RPCHelpMan(std::string name, std::string description,
364  std::vector<RPCArg> args, RPCResults results,
365  RPCExamples examples);
366  using RPCMethodImpl = std::function<UniValue(
367  const RPCHelpMan &, const Config &config, const JSONRPCRequest &)>;
368  RPCHelpMan(std::string name, std::string description,
369  std::vector<RPCArg> args, RPCResults results,
370  RPCExamples examples, RPCMethodImpl fun);
371 
372  UniValue HandleRequest(const Config &config,
373  const JSONRPCRequest &request) const;
374  std::string ToString() const;
379  UniValue GetArgMap() const;
381  bool IsValidNumArgs(size_t num_args) const;
383  std::vector<std::pair<std::string, bool>> GetArgNames() const;
384 
385  const std::string m_name;
386 
387 private:
389  const std::string m_description;
390  const std::vector<RPCArg> m_args;
393 };
394 
395 #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:80
An encapsulated public key.
Definition: pubkey.h:31
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:431
Definition: config.h:19
Fillable signing provider that keeps keys in an address->secret map.
const RPCExamples m_examples
Definition: util.h:392
RPCHelpMan(std::string name, std::string description, std::vector< RPCArg > args, RPCResults results, RPCExamples examples)
Definition: util.cpp:487
const std::string m_description
Definition: util.h:389
bool IsValidNumArgs(size_t num_args) const
If the supplied number of args is neither too small nor too high.
Definition: util.cpp:639
std::function< UniValue(const RPCHelpMan &, const Config &config, const JSONRPCRequest &)> RPCMethodImpl
Definition: util.h:367
const RPCMethodImpl m_fun
Definition: util.h:388
const std::string m_name
Definition: util.h:385
const RPCResults m_results
Definition: util.h:391
UniValue HandleRequest(const Config &config, const JSONRPCRequest &request) const
Definition: util.cpp:587
const std::vector< RPCArg > m_args
Definition: util.h:390
std::string ToString() const
Definition: util.cpp:664
UniValue GetArgMap() const
Return the named args that need to be converted from string to another JSON type.
Definition: util.cpp:747
std::vector< std::pair< std::string, bool > > GetArgNames() const
Return list of arguments and whether they are named-only.
Definition: util.cpp:650
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:257
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:1273
std::vector< uint8_t > ParseHexV(const UniValue &v, std::string strName)
Definition: util.cpp:94
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:150
std::vector< std::pair< std::string, UniValue > > RPCArgList
Definition: util.h:70
UniValue GetServicesNames(ServiceFlags services)
Returns, given services flags, a list of humanly readable (known) network services.
Definition: util.cpp:1337
CTxDestination AddAndGetMultisigDestination(const int required, const std::vector< CPubKey > &pubkeys, OutputType type, FillableSigningProvider &keystore, CScript &script_out)
Definition: util.cpp:233
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:176
UniValue JSONRPCTransactionError(TransactionError terr, const std::string &err_string="")
Definition: util.cpp:333
static constexpr bool DEFAULT_RPC_DOC_CHECK
Definition: util.h:29
Amount AmountFromValue(const UniValue &value)
Definition: util.cpp:55
RPCErrorCode RPCErrorFromTransactionError(TransactionError terr)
Definition: util.cpp:314
std::vector< uint8_t > ParseHexO(const UniValue &o, std::string strKey)
Definition: util.cpp:108
const std::string EXAMPLE_ADDRESS
Example CashAddr address used in multiple RPCExamples.
Definition: util.cpp:23
OuterType
Serializing JSON objects depends on the outer type.
Definition: util.h:118
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:1290
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:167
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:22
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:26
std::string GetAllOutputTypes()
Definition: util.cpp:305
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:191
CPubKey AddrToPubKey(const CChainParams &chainparams, const FillableSigningProvider &keystore, const std::string &addr_in)
Definition: util.cpp:205
uint256 ParseHashO(const UniValue &o, std::string strKey)
Definition: util.cpp:90
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded values (throws error if not hex).
Definition: util.cpp:73
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:155
UniValue DescribeAddress(const CTxDestination &dest)
Definition: util.cpp:301
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:150
Type
Definition: util.h:151
@ RANGE
Special type that is a NUM or [NUM,NUM].
@ OBJ_USER_KEYS
Special type where the user must set the keys e.g.
@ STR_HEX
Special type that is a STR with only hex chars.
@ AMOUNT
Special type representing a floating point amount (can be either NUM or STR)
@ 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:205
const RPCArgOptions m_opts
Definition: util.h:208
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:202
const Fallback m_fallback
Definition: util.h:206
std::string ToString(bool oneline) const
Return the type string of the argument.
Definition: util.cpp:1215
RPCArg(std::string name, Type type, Fallback fallback, std::string description, RPCArgOptions opts={})
Definition: util.h:210
UniValue MatchesType(const UniValue &request) const
Check whether the request JSON type matches.
Definition: util.cpp:814
const std::string m_description
Definition: util.h:207
std::string DefaultHint
Hint for default value.
Definition: util.h:195
bool IsOptional() const
Definition: util.cpp:843
std::variant< Optional, DefaultHint, Default > Fallback
Definition: util.h:198
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:851
const Type m_type
Definition: util.h:203
RPCArg(std::string name, Type type, Fallback fallback, std::string description, std::vector< RPCArg > inner, RPCArgOptions opts={})
Definition: util.h:220
std::string GetName() const
Return the name, throws when there are aliases.
Definition: util.cpp:838
std::string GetFirstName() const
Return the first of all aliases.
Definition: util.cpp:834
std::string ToStringObj(bool oneline) const
Return the type string of the argument when it is in an object (dict).
Definition: util.cpp:1175
Optional
Definition: util.h:177
@ OMITTED
The arg is optional for one of two reasons:
@ NO
Required arg.
bool hidden
For testing only.
Definition: util.h:136
std::vector< std::string > type_str
Should be empty unless it is supposed to override the auto-generated type strings.
Definition: util.h:134
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
Definition: util.h:128
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:147
bool skip_type_check
Definition: util.h:125
std::string ToDescriptionString() const
Definition: util.cpp:583
RPCExamples(std::string examples)
Definition: util.h:355
const std::string m_examples
Definition: util.h:354
RPCExamples()
Definition: util.h:357
const std::string m_description
Definition: util.h:285
void ToSections(Sections &sections, OuterType outer_type=OuterType::NONE, const int current_indent=0) const
Append the sections of the result.
Definition: util.cpp:924
@ ELISION
Special type to denote elision (...)
@ NUM_TIME
Special numeric to denote unix epoch time.
@ ANY
Special type to disable type checks (for testing only)
@ ARR_FIXED
Special array that has a fixed number of entries.
@ OBJ_DYN
Special dictionary with keys that are not literals.
@ STR_HEX
Special string with only hex chars.
@ STR_AMOUNT
Special string to represent a floating point amount.
const std::vector< RPCResult > m_inner
Only used for arrays or dicts.
Definition: util.h:282
const std::string m_cond
Definition: util.h:286
UniValue MatchesType(const UniValue &result) const
Check whether the result JSON type matches.
Definition: util.cpp:1072
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:1164
RPCResult(Type type, std::string key_name, std::string description, std::vector< RPCResult > inner={}, bool skip_type_check=false)
Definition: util.h:314
RPCResult(std::string cond, Type type, std::string key_name, std::string description, std::vector< RPCResult > inner={})
Definition: util.h:298
const bool m_optional
Definition: util.h:283
const std::string m_key_name
Only used for dicts.
Definition: util.h:281
RPCResult(std::string cond, Type type, std::string key_name, bool optional, std::string description, std::vector< RPCResult > inner={})
Definition: util.h:288
const Type m_type
Definition: util.h:280
RPCResult(Type type, std::string key_name, bool optional, std::string description, std::vector< RPCResult > inner={}, bool skip_type_check=false)
Definition: util.h:304
const bool m_skip_type_check
Definition: util.h:284
RPCResults(RPCResult result)
Definition: util.h:343
const std::vector< RPCResult > m_results
Definition: util.h:341
RPCResults(std::initializer_list< RPCResult > results)
Definition: util.h:345
Keeps track of RPCArgs by transforming them into sections for the purpose of serializing everything t...
Definition: util.cpp:358
Wrapper for UniValue::VType, which includes typeAny: used to denote don't care type.
Definition: util.h:46
bool typeAny
Definition: util.h:49
UniValueType(UniValue::VType _type)
Definition: util.h:47
UniValue::VType type
Definition: util.h:50
UniValueType()
Definition: util.h:48