Bitcoin Core  26.1.0
P2P Digital Currency
util.h
Go to the documentation of this file.
1 // Copyright (c) 2017-2022 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 <addresstype.h>
9 #include <consensus/amount.h>
10 #include <node/transaction.h>
11 #include <outputtype.h>
12 #include <protocol.h>
13 #include <pubkey.h>
14 #include <rpc/protocol.h>
15 #include <rpc/request.h>
16 #include <script/script.h>
17 #include <script/sign.h>
18 #include <uint256.h>
19 #include <univalue.h>
20 #include <util/check.h>
21 
22 #include <cstddef>
23 #include <cstdint>
24 #include <functional>
25 #include <initializer_list>
26 #include <map>
27 #include <optional>
28 #include <string>
29 #include <type_traits>
30 #include <utility>
31 #include <variant>
32 #include <vector>
33 
34 class JSONRPCRequest;
35 enum ServiceFlags : uint64_t;
36 enum class OutputType;
37 enum class TransactionError;
38 struct FlatSigningProvider;
39 struct bilingual_str;
40 
41 static constexpr bool DEFAULT_RPC_DOC_CHECK{
42 #ifdef RPC_DOC_CHECK
43  true
44 #else
45  false
46 #endif
47 };
48 
53 extern const std::string UNIX_EPOCH_TIME;
54 
59 extern const std::string EXAMPLE_ADDRESS[2];
60 
62 class CPubKey;
63 class CScript;
64 struct Sections;
65 
71 std::string GetAllOutputTypes();
72 
75 struct UniValueType {
76  UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
77  UniValueType() : typeAny(true) {}
78  bool typeAny;
80 };
81 
82 /*
83  Check for expected keys/value types in an Object.
84 */
85 void RPCTypeCheckObj(const UniValue& o,
86  const std::map<std::string, UniValueType>& typesExpected,
87  bool fAllowNull = false,
88  bool fStrict = false);
89 
94 uint256 ParseHashV(const UniValue& v, std::string strName);
95 uint256 ParseHashO(const UniValue& o, std::string strKey);
96 std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
97 std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
98 
106 CAmount AmountFromValue(const UniValue& value, int decimals = 8);
107 
108 using RPCArgList = std::vector<std::pair<std::string, UniValue>>;
109 std::string HelpExampleCli(const std::string& methodname, const std::string& args);
110 std::string HelpExampleCliNamed(const std::string& methodname, const RPCArgList& args);
111 std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
112 std::string HelpExampleRpcNamed(const std::string& methodname, const RPCArgList& args);
113 
114 CPubKey HexToPubKey(const std::string& hex_in);
115 CPubKey AddrToPubKey(const FillableSigningProvider& keystore, const std::string& addr_in);
116 CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, FillableSigningProvider& keystore, CScript& script_out);
117 
119 
122 
124 unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target);
125 
127 UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string = "");
128 
130 std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value);
131 
133 std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider, const bool expand_priv = false);
134 
137 
142 enum class OuterType {
143  ARR,
144  OBJ,
145  NONE, // Only set on first recursion
146 };
147 
149  bool skip_type_check{false};
150  std::string oneline_description{};
151  std::vector<std::string> type_str{};
152  bool hidden{false};
153  bool also_positional{false};
154 };
163 
164 struct RPCArg {
165  enum class Type {
166  OBJ,
167  ARR,
168  STR,
169  NUM,
170  BOOL,
172  OBJ_USER_KEYS,
179  AMOUNT,
180  STR_HEX,
181  RANGE,
182  };
183 
184  enum class Optional {
186  NO,
195  OMITTED,
196  };
198  using DefaultHint = std::string;
200  using Default = UniValue;
201  using Fallback = std::variant<Optional, DefaultHint, Default>;
202 
203  const std::string m_names;
204  const Type m_type;
205  const std::vector<RPCArg> m_inner;
207  const std::string m_description;
209 
211  std::string name,
212  Type type,
213  Fallback fallback,
214  std::string description,
215  RPCArgOptions opts = {})
216  : m_names{std::move(name)},
217  m_type{std::move(type)},
218  m_fallback{std::move(fallback)},
219  m_description{std::move(description)},
220  m_opts{std::move(opts)}
221  {
222  CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ && type != Type::OBJ_NAMED_PARAMS && type != Type::OBJ_USER_KEYS);
223  }
224 
226  std::string name,
227  Type type,
228  Fallback fallback,
229  std::string description,
230  std::vector<RPCArg> inner,
231  RPCArgOptions opts = {})
232  : m_names{std::move(name)},
233  m_type{std::move(type)},
234  m_inner{std::move(inner)},
235  m_fallback{std::move(fallback)},
236  m_description{std::move(description)},
237  m_opts{std::move(opts)}
238  {
239  CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ || type == Type::OBJ_NAMED_PARAMS || 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 
260  std::string ToString(bool oneline) const;
265  std::string ToStringObj(bool oneline) const;
270  std::string ToDescriptionString(bool is_named_arg) const;
271 };
272 
273 struct RPCResult {
274  enum class Type {
275  OBJ,
276  ARR,
277  STR,
278  NUM,
279  BOOL,
280  NONE,
281  ANY,
282  STR_AMOUNT,
283  STR_HEX,
284  OBJ_DYN,
285  ARR_FIXED,
286  NUM_TIME,
287  ELISION,
288  };
289 
290  const Type m_type;
291  const std::string m_key_name;
292  const std::vector<RPCResult> m_inner;
293  const bool m_optional;
294  const bool m_skip_type_check;
295  const std::string m_description;
296  const std::string m_cond;
297 
299  std::string cond,
300  Type type,
301  std::string m_key_name,
302  bool optional,
303  std::string description,
304  std::vector<RPCResult> inner = {})
305  : m_type{std::move(type)},
306  m_key_name{std::move(m_key_name)},
307  m_inner{std::move(inner)},
308  m_optional{optional},
309  m_skip_type_check{false},
310  m_description{std::move(description)},
311  m_cond{std::move(cond)}
312  {
313  CHECK_NONFATAL(!m_cond.empty());
314  CheckInnerDoc();
315  }
316 
318  std::string cond,
319  Type type,
320  std::string m_key_name,
321  std::string description,
322  std::vector<RPCResult> inner = {})
323  : RPCResult{std::move(cond), type, std::move(m_key_name), /*optional=*/false, std::move(description), std::move(inner)} {}
324 
326  Type type,
327  std::string m_key_name,
328  bool optional,
329  std::string description,
330  std::vector<RPCResult> inner = {},
331  bool skip_type_check = false)
332  : m_type{std::move(type)},
333  m_key_name{std::move(m_key_name)},
334  m_inner{std::move(inner)},
335  m_optional{optional},
336  m_skip_type_check{skip_type_check},
337  m_description{std::move(description)},
338  m_cond{}
339  {
340  CheckInnerDoc();
341  }
342 
344  Type type,
345  std::string m_key_name,
346  std::string description,
347  std::vector<RPCResult> inner = {},
348  bool skip_type_check = false)
349  : RPCResult{type, std::move(m_key_name), /*optional=*/false, std::move(description), std::move(inner), skip_type_check} {}
350 
352  void ToSections(Sections& sections, OuterType outer_type = OuterType::NONE, const int current_indent = 0) const;
354  std::string ToStringObj() const;
356  std::string ToDescriptionString() const;
360  UniValue MatchesType(const UniValue& result) const;
361 
362 private:
363  void CheckInnerDoc() const;
364 };
365 
366 struct RPCResults {
367  const std::vector<RPCResult> m_results;
368 
370  : m_results{{result}}
371  {
372  }
373 
374  RPCResults(std::initializer_list<RPCResult> results)
375  : m_results{results}
376  {
377  }
378 
382  std::string ToDescriptionString() const;
383 };
384 
385 struct RPCExamples {
386  const std::string m_examples;
387  explicit RPCExamples(
388  std::string examples)
389  : m_examples(std::move(examples))
390  {
391  }
392  std::string ToDescriptionString() const;
393 };
394 
396 {
397 public:
398  RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples);
399  using RPCMethodImpl = std::function<UniValue(const RPCHelpMan&, const JSONRPCRequest&)>;
400  RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);
401 
402  UniValue HandleRequest(const JSONRPCRequest& request) const;
417  template <typename R>
418  auto Arg(size_t i) const
419  {
420  // Return argument (required or with default value).
421  if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
422  // Return numbers by value.
423  return ArgValue<R>(i);
424  } else {
425  // Return everything else by reference.
426  return ArgValue<const R&>(i);
427  }
428  }
429  template <typename R>
430  auto MaybeArg(size_t i) const
431  {
432  // Return optional argument (without default).
433  if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
434  // Return numbers by value, wrapped in optional.
435  return ArgValue<std::optional<R>>(i);
436  } else {
437  // Return other types by pointer.
438  return ArgValue<const R*>(i);
439  }
440  }
441  std::string ToString() const;
443  UniValue GetArgMap() const;
445  bool IsValidNumArgs(size_t num_args) const;
447  std::vector<std::pair<std::string, bool>> GetArgNames() const;
448 
449  const std::string m_name;
450 
451 private:
453  const std::string m_description;
454  const std::vector<RPCArg> m_args;
457  mutable const JSONRPCRequest* m_req{nullptr}; // A pointer to the request for the duration of m_fun()
458  template <typename R>
459  R ArgValue(size_t i) const;
460 };
461 
468 void PushWarnings(const UniValue& warnings, UniValue& obj);
469 void PushWarnings(const std::vector<bilingual_str>& warnings, UniValue& obj);
470 
471 #endif // BITCOIN_RPC_UTIL_H
UniValue DescribeAddress(const CTxDestination &dest)
Definition: util.cpp:317
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:143
UniValueType(UniValue::VType _type)
Definition: util.h:76
static const std::string sighash
Definition: sighash.json.h:3
CAmount AmountFromValue(const UniValue &value, int decimals=8)
Validate and return a CAmount from a UniValue number or string.
Definition: util.cpp:65
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: util.cpp:77
std::vector< unsigned char > ParseHexV(const UniValue &v, std::string strName)
Definition: util.cpp:90
const std::vector< RPCResult > m_inner
Only used for arrays or dicts.
Definition: util.h:292
std::vector< std::string > type_str
Should be empty unless it is supposed to override the auto-generated type strings. Vector length is either 0 or 2, m_opts.type_str.at(0) will override the type of the value in a key-value pair, m_opts.type_str.at(1) will override the type in the argument description.
Definition: util.h:151
Type
Definition: util.h:165
RPCArg(std::string name, Type type, Fallback fallback, std::string description, std::vector< RPCArg > inner, RPCArgOptions opts={})
Definition: util.h:225
const Fallback m_fallback
Definition: util.h:206
ServiceFlags
nServices flags
Definition: protocol.h:274
void CheckInnerDoc() const
Definition: util.cpp:1142
std::string ToDescriptionString() const
Return the description string.
Definition: util.cpp:572
uint256 ParseHashO(const UniValue &o, std::string strKey)
Definition: util.cpp:86
const RPCArgOptions m_opts
Definition: util.h:208
Required arg.
auto Arg(size_t i) const
Helper to get a request argument.
Definition: util.h:418
std::vector< CScript > EvalDescriptorStringOrObject(const UniValue &scanobject, FlatSigningProvider &provider, const bool expand_priv=false)
Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range ...
Definition: util.cpp:1265
RPCResult(Type type, std::string m_key_name, bool optional, std::string description, std::vector< RPCResult > inner={}, bool skip_type_check=false)
Definition: util.h:325
Bilingual messages:
Definition: translation.h:18
Keeps track of RPCArgs by transforming them into sections for the purpose of serializing everything t...
Definition: util.cpp:392
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
bool typeAny
Definition: util.h:78
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:153
CPubKey AddrToPubKey(const FillableSigningProvider &keystore, const std::string &addr_in)
Definition: util.cpp:192
bool hidden
For testing only.
Definition: util.h:152
R ArgValue(size_t i) const
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:179
std::string GetAllOutputTypes()
Gets all existing output types formatted for RPC help sections.
Definition: util.cpp:28
const std::string EXAMPLE_ADDRESS[2]
Example bech32 addresses for the RPCExamples help documentation.
Definition: util.cpp:26
static constexpr bool DEFAULT_RPC_DOC_CHECK
Definition: util.h:41
void ToSections(Sections &sections, OuterType outer_type=OuterType::NONE, const int current_indent=0) const
Append the sections of the result.
Definition: util.cpp:942
RPCArg(std::string name, Type type, Fallback fallback, std::string description, RPCArgOptions opts={})
Definition: util.h:210
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:46
Special type that behaves almost exactly like OBJ, defining an options object with a list of pre-defi...
int ParseSighashString(const UniValue &sighash)
Parse a sighash string representation and raise an RPC error if it is invalid.
Definition: util.cpp:327
const std::string m_key_name
Only used for dicts.
Definition: util.h:291
std::string ToDescriptionString() const
Definition: util.cpp:589
RPCResult(std::string cond, Type type, std::string m_key_name, std::string description, std::vector< RPCResult > inner={})
Definition: util.h:317
std::vector< std::pair< std::string, bool > > GetArgNames() const
Return list of arguments and whether they are named-only.
Definition: util.cpp:702
const RPCExamples m_examples
Definition: util.h:456
const RPCMethodImpl m_fun
Definition: util.h:452
bool skip_type_check
Definition: util.h:149
bool IsValidNumArgs(size_t num_args) const
If the supplied number of args is neither too small nor too high.
Definition: util.cpp:690
UniValue GetArgMap() const
Return the named args that need to be converted from string to another JSON type. ...
Definition: util.cpp:779
std::string ToStringObj() const
Return the type string of the result when it is in an object (dict).
std::string ToString() const
Definition: util.cpp:717
const bool m_skip_type_check
Definition: util.h:294
const std::vector< RPCArg > m_inner
Only used for arrays or dicts.
Definition: util.h:205
OutputType
Definition: outputtype.h:17
const std::string m_cond
Definition: util.h:296
RPCErrorCode RPCErrorFromTransactionError(TransactionError terr)
Definition: util.cpp:349
const Type m_type
Definition: util.h:290
UniValue::VType type
Definition: util.h:79
const std::string m_description
Definition: util.h:453
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull=false, bool fStrict=false)
Definition: util.cpp:38
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
Definition: util.h:150
void PushWarnings(const UniValue &warnings, UniValue &obj)
Push warning messages to an RPC "warnings" field as a JSON array of strings.
Definition: util.cpp:1328
Special type that is a STR with only hex chars.
std::string GetName() const
Return the name, throws when there are aliases.
Definition: util.cpp:863
Special string with only hex chars.
Definition: util.h:164
ArgsManager & args
Definition: bitcoind.cpp:269
CTxDestination AddAndGetMultisigDestination(const int required, const std::vector< CPubKey > &pubkeys, OutputType type, FillableSigningProvider &keystore, CScript &script_out)
Definition: util.cpp:213
const char * name
Definition: rest.cpp:45
Special array that has a fixed number of entries.
RPCResults(std::initializer_list< RPCResult > results)
Definition: util.h:374
bool IsOptional() const
Definition: util.cpp:869
An encapsulated public key.
Definition: pubkey.h:33
Fillable signing provider that keeps keys in an address->secret map.
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:203
RPCResult(Type type, std::string m_key_name, std::string description, std::vector< RPCResult > inner={}, bool skip_type_check=false)
Definition: util.h:343
Special type where the user must set the keys e.g. to define multiple addresses; as opposed to e...
Special type to disable type checks (for testing only)
UniValue GetServicesNames(ServiceFlags services)
Returns, given services flags, a list of humanly readable (known) network services.
Definition: util.cpp:1306
std::function< UniValue(const RPCHelpMan &, const JSONRPCRequest &)> RPCMethodImpl
Definition: util.h:399
unsigned int ParseConfirmTarget(const UniValue &value, unsigned int max_target)
Parse a confirm target option and raise an RPC error if it is invalid.
Definition: util.cpp:339
const std::vector< RPCResult > m_results
Definition: util.h:367
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:161
std::string DefaultHint
Hint for default value.
Definition: util.h:198
std::string GetFirstName() const
Return the first of all aliases.
Definition: util.cpp:858
const std::vector< RPCArg > m_args
Definition: util.h:454
const std::string m_description
Definition: util.h:207
Special numeric to denote unix epoch time.
UniValue JSONRPCTransactionError(TransactionError terr, const std::string &err_string="")
Definition: util.cpp:368
const std::string m_examples
Definition: util.h:386
const JSONRPCRequest * m_req
Definition: util.h:457
std::vector< std::pair< std::string, UniValue > > RPCArgList
Definition: util.h:108
const RPCResults m_results
Definition: util.h:455
Special type that is a NUM or [NUM,NUM].
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:129
std::variant< Optional, DefaultHint, Default > Fallback
Definition: util.h:201
OuterType
Serializing JSON objects depends on the outer type.
Definition: util.h:142
RPCHelpMan(std::string name, std::string description, std::vector< RPCArg > args, RPCResults results, RPCExamples examples)
Definition: util.cpp:504
256-bit opaque blob.
Definition: uint256.h:106
Optional argument for which the default value is omitted from help text for one of two reasons: ...
UniValueType()
Definition: util.h:77
Special string to represent a floating point amount.
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:412
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:167
Optional
Definition: util.h:184
const std::string m_description
Definition: util.h:295
Special type representing a floating point amount (can be either NUM or STR)
TransactionError
Definition: error.h:22
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:148
RPCResults(RPCResult result)
Definition: util.h:369
UniValue MatchesType(const UniValue &request) const
Check whether the request JSON type matches.
Definition: util.cpp:845
auto MaybeArg(size_t i) const
Definition: util.h:430
const Type m_type
Definition: util.h:204
UniValue MatchesType(const UniValue &result) const
Check whether the result JSON type matches.
Definition: util.cpp:1075
RPCExamples(std::string examples)
Definition: util.h:387
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:878
const bool m_optional
Definition: util.h:293
const std::string m_name
Definition: util.h:449
RPCErrorCode
Bitcoin RPC error codes.
Definition: protocol.h:23
Special dictionary with keys that are not literals.
UniValue HandleRequest(const JSONRPCRequest &request) const
Definition: util.cpp:594
std::string ToString(bool oneline) const
Return the type string of the argument.
Definition: util.cpp:1191
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
Definition: util.cpp:1249
Wrapper for UniValue::VType, which includes typeAny: Used to denote don&#39;t care type.
Definition: util.h:75
RPCResult(std::string cond, Type type, std::string m_key_name, bool optional, std::string description, std::vector< RPCResult > inner={})
Definition: util.h:298
Special type to denote elision (...)
std::string ToDescriptionString() const
Return the description string, including the result type.
std::vector< unsigned char > ParseHexO(const UniValue &o, std::string strKey)
Definition: util.cpp:99
std::string ToStringObj(bool oneline) const
Return the type string of the argument when it is in an object (dict).
Definition: util.cpp:1153