Bitcoin Core  31.0.0
P2P Digital Currency
util.h
Go to the documentation of this file.
1 // Copyright (c) 2017-present 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 <pubkey.h>
13 #include <rpc/protocol.h>
14 #include <rpc/request.h>
15 #include <script/script.h>
16 #include <script/sign.h>
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 <string_view>
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 struct FlatSigningProvider;
38 struct bilingual_str;
39 namespace common {
40 enum class PSBTError;
41 } // namespace common
42 namespace node {
43 enum class TransactionError;
44 } // namespace node
45 
46 static constexpr bool DEFAULT_RPC_DOC_CHECK{
47 #ifdef RPC_DOC_CHECK
48  true
49 #else
50  false
51 #endif
52 };
53 
58 extern const std::string UNIX_EPOCH_TIME;
59 
64 extern const std::string EXAMPLE_ADDRESS[2];
65 
67 class CScript;
68 struct Sections;
69 
70 struct HelpResult : std::runtime_error {
71  explicit HelpResult(const std::string& msg) : std::runtime_error{msg} {}
72 };
73 
79 std::string GetAllOutputTypes();
80 
83 struct UniValueType {
84  UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
85  UniValueType() : typeAny(true) {}
86  bool typeAny;
88 };
89 
90 /*
91  Check for expected keys/value types in an Object.
92 */
93 void RPCTypeCheckObj(const UniValue& o,
94  const std::map<std::string, UniValueType>& typesExpected,
95  bool fAllowNull = false,
96  bool fStrict = false);
97 
102 uint256 ParseHashV(const UniValue& v, std::string_view name);
103 uint256 ParseHashO(const UniValue& o, std::string_view strKey);
104 std::vector<unsigned char> ParseHexV(const UniValue& v, std::string_view name);
105 std::vector<unsigned char> ParseHexO(const UniValue& o, std::string_view strKey);
106 
116 int ParseVerbosity(const UniValue& arg, int default_verbosity, bool allow_bool);
117 
125 CAmount AmountFromValue(const UniValue& value, int decimals = 8);
131 
132 using RPCArgList = std::vector<std::pair<std::string, UniValue>>;
133 std::string HelpExampleCli(const std::string& methodname, const std::string& args);
134 std::string HelpExampleCliNamed(const std::string& methodname, const RPCArgList& args);
135 std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
136 std::string HelpExampleRpcNamed(const std::string& methodname, const RPCArgList& args);
137 
138 CPubKey HexToPubKey(const std::string& hex_in);
139 CTxDestination AddAndGetMultisigDestination(int required, const std::vector<CPubKey>& pubkeys, OutputType type, FlatSigningProvider& keystore, CScript& script_out);
140 
142 
144 std::optional<int> ParseSighashString(const UniValue& sighash);
145 
147 unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target);
148 
151 UniValue JSONRPCTransactionError(node::TransactionError terr, const std::string& err_string = "");
152 
154 std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value);
155 
157 std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider, bool expand_priv = false);
158 
163 enum class OuterType {
164  ARR,
165  OBJ,
166  NONE, // Only set on first recursion
167 };
168 
170  bool skip_type_check{false};
171  std::string oneline_description{};
172  std::vector<std::string> type_str{};
173  bool hidden{false};
174  bool also_positional{false};
175 };
184 
185 // NOLINTNEXTLINE(misc-no-recursion)
186 struct RPCArg {
187  enum class Type {
188  OBJ,
189  ARR,
190  STR,
191  NUM,
192  BOOL,
194  OBJ_USER_KEYS,
201  AMOUNT,
202  STR_HEX,
203  RANGE,
204  };
205 
206  enum class Optional {
208  NO,
217  OMITTED,
218  };
220  using DefaultHint = std::string;
222  using Default = UniValue;
223  using Fallback = std::variant<Optional, DefaultHint, Default>;
224 
225  const std::string m_names;
226  const Type m_type;
227  const std::vector<RPCArg> m_inner;
229  const std::string m_description;
231 
233  std::string name,
234  Type type,
235  Fallback fallback,
236  std::string description,
237  RPCArgOptions opts = {})
238  : m_names{std::move(name)},
239  m_type{std::move(type)},
240  m_fallback{std::move(fallback)},
241  m_description{std::move(description)},
242  m_opts{std::move(opts)}
243  {
244  CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ && type != Type::OBJ_NAMED_PARAMS && type != Type::OBJ_USER_KEYS);
245  }
246 
248  std::string name,
249  Type type,
250  Fallback fallback,
251  std::string description,
252  std::vector<RPCArg> inner,
253  RPCArgOptions opts = {})
254  : m_names{std::move(name)},
255  m_type{std::move(type)},
256  m_inner{std::move(inner)},
257  m_fallback{std::move(fallback)},
258  m_description{std::move(description)},
259  m_opts{std::move(opts)}
260  {
261  CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ || type == Type::OBJ_NAMED_PARAMS || type == Type::OBJ_USER_KEYS);
262  }
263 
264  bool IsOptional() const;
265 
270  UniValue MatchesType(const UniValue& request) const;
271 
273  std::string GetFirstName() const;
274 
276  std::string GetName() const;
277 
282  std::string ToString(bool oneline) const;
287  std::string ToStringObj(bool oneline) const;
292  std::string ToDescriptionString(bool is_named_arg) const;
293 };
294 
295 // NOLINTNEXTLINE(misc-no-recursion)
296 struct RPCResult {
297  enum class Type {
298  OBJ,
299  ARR,
300  STR,
301  NUM,
302  BOOL,
303  NONE,
304  ANY,
305  STR_AMOUNT,
306  STR_HEX,
307  OBJ_DYN,
308  ARR_FIXED,
309  NUM_TIME,
310  ELISION,
311  };
312 
313  const Type m_type;
314  const std::string m_key_name;
315  const std::vector<RPCResult> m_inner;
316  const bool m_optional;
317  const bool m_skip_type_check;
318  const std::string m_description;
319  const std::string m_cond;
320 
322  std::string cond,
323  Type type,
324  std::string m_key_name,
325  bool optional,
326  std::string description,
327  std::vector<RPCResult> inner = {})
328  : m_type{std::move(type)},
329  m_key_name{std::move(m_key_name)},
330  m_inner{std::move(inner)},
331  m_optional{optional},
332  m_skip_type_check{false},
333  m_description{std::move(description)},
334  m_cond{std::move(cond)}
335  {
336  CHECK_NONFATAL(!m_cond.empty());
337  CheckInnerDoc();
338  }
339 
341  std::string cond,
342  Type type,
343  std::string m_key_name,
344  std::string description,
345  std::vector<RPCResult> inner = {})
346  : RPCResult{std::move(cond), type, std::move(m_key_name), /*optional=*/false, std::move(description), std::move(inner)} {}
347 
349  Type type,
350  std::string m_key_name,
351  bool optional,
352  std::string description,
353  std::vector<RPCResult> inner = {},
354  bool skip_type_check = false)
355  : m_type{std::move(type)},
356  m_key_name{std::move(m_key_name)},
357  m_inner{std::move(inner)},
358  m_optional{optional},
359  m_skip_type_check{skip_type_check},
360  m_description{std::move(description)},
361  m_cond{}
362  {
363  CheckInnerDoc();
364  }
365 
367  Type type,
368  std::string m_key_name,
369  std::string description,
370  std::vector<RPCResult> inner = {},
371  bool skip_type_check = false)
372  : RPCResult{type, std::move(m_key_name), /*optional=*/false, std::move(description), std::move(inner), skip_type_check} {}
373 
375  void ToSections(Sections& sections, OuterType outer_type = OuterType::NONE, int current_indent = 0) const;
377  std::string ToStringObj() const;
379  std::string ToDescriptionString() const;
383  UniValue MatchesType(const UniValue& result) const;
384 
385 private:
386  void CheckInnerDoc() const;
387 };
388 
389 struct RPCResults {
390  const std::vector<RPCResult> m_results;
391 
393  : m_results{{result}}
394  {
395  }
396 
397  RPCResults(std::initializer_list<RPCResult> results)
398  : m_results{results}
399  {
400  }
401 
405  std::string ToDescriptionString() const;
406 };
407 
408 struct RPCExamples {
409  const std::string m_examples;
410  explicit RPCExamples(
411  std::string examples)
412  : m_examples(std::move(examples))
413  {
414  }
415  std::string ToDescriptionString() const;
416 };
417 
419 {
420 public:
421  RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples);
422  using RPCMethodImpl = std::function<UniValue(const RPCHelpMan&, const JSONRPCRequest&)>;
423  RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);
424 
425  UniValue HandleRequest(const JSONRPCRequest& request) const;
443  template <typename R>
444  auto Arg(std::string_view key) const
445  {
446  auto i{GetParamIndex(key)};
447  // Return argument (required or with default value).
448  if constexpr (std::is_trivially_copyable_v<R>) {
449  // Return trivially copyable types by value.
450  return ArgValue<R>(i);
451  } else {
452  // Return everything else by reference.
453  return ArgValue<const R&>(i);
454  }
455  }
475  template <typename R>
476  auto MaybeArg(std::string_view key) const
477  {
478  auto i{GetParamIndex(key)};
479  // Return optional argument (without default).
480  if constexpr (std::is_trivially_copyable_v<R>) {
481  // Return trivially copyable types by value, wrapped in optional.
482  return ArgValue<std::optional<R>>(i);
483  } else {
484  // Return other types by pointer.
485  return ArgValue<const R*>(i);
486  }
487  }
488  std::string ToString() const;
490  UniValue GetArgMap() const;
492  bool IsValidNumArgs(size_t num_args) const;
494  std::vector<std::pair<std::string, bool>> GetArgNames() const;
495 
496  const std::string m_name;
497 
498 private:
500  const std::string m_description;
501  const std::vector<RPCArg> m_args;
504  mutable const JSONRPCRequest* m_req{nullptr}; // A pointer to the request for the duration of m_fun()
505  template <typename R>
506  R ArgValue(size_t i) const;
508  size_t GetParamIndex(std::string_view key) const;
509 };
510 
517 void PushWarnings(const UniValue& warnings, UniValue& obj);
518 void PushWarnings(const std::vector<bilingual_str>& warnings, UniValue& obj);
519 
520 std::vector<RPCResult> ScriptPubKeyDoc();
521 
522 /***
523  * Get the target for a given block index.
524  *
525  * @param[in] blockindex the block
526  * @param[in] pow_limit PoW limit (consensus parameter)
527  *
528  * @return the target
529  */
530 uint256 GetTarget(const CBlockIndex& blockindex, uint256 pow_limit);
531 
532 #endif // BITCOIN_RPC_UTIL_H
UniValue DescribeAddress(const CTxDestination &dest)
Definition: util.cpp:347
char const * json() noexcept
Template to generate JSON data.
TransactionError
Definition: types.h:28
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:183
UniValueType(UniValue::VType _type)
Definition: util.h:84
size_t GetParamIndex(std::string_view key) const
Return positional index of a parameter using its name as key.
Definition: util.cpp:760
std::vector< unsigned char > ParseHexO(const UniValue &o, std::string_view strKey)
Definition: util.cpp:139
PSBTError
Definition: types.h:17
CAmount AmountFromValue(const UniValue &value, int decimals=8)
Validate and return a CAmount from a UniValue number or string.
Definition: util.cpp:98
const std::vector< RPCResult > m_inner
Only used for arrays or dicts.
Definition: util.h:315
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:172
Type
Definition: util.h:187
RPCArg(std::string name, Type type, Fallback fallback, std::string description, std::vector< RPCArg > inner, RPCArgOptions opts={})
Definition: util.h:247
const Fallback m_fallback
Definition: util.h:228
ServiceFlags
nServices flags
Definition: protocol.h:309
UniValue JSONRPCTransactionError(node::TransactionError terr, const std::string &err_string="")
void CheckInnerDoc() const
Definition: util.cpp:1198
std::string ToDescriptionString() const
Return the description string.
Definition: util.cpp:613
uint256 ParseHashV(const UniValue &v, std::string_view name)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: util.cpp:117
const RPCArgOptions m_opts
Definition: util.h:230
Required arg.
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:348
Bilingual messages:
Definition: translation.h:24
Keeps track of RPCArgs by transforming them into sections for the purpose of serializing everything t...
Definition: util.cpp:432
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:43
bool typeAny
Definition: util.h:86
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:174
bool hidden
For testing only.
Definition: util.h:173
R ArgValue(size_t i) const
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:219
std::string GetAllOutputTypes()
Gets all existing output types formatted for RPC help sections.
Definition: util.cpp:46
const std::string EXAMPLE_ADDRESS[2]
Example bech32 addresses for the RPCExamples help documentation.
Definition: util.cpp:44
static constexpr bool DEFAULT_RPC_DOC_CHECK
Definition: util.h:46
RPCArg(std::string name, Type type, Fallback fallback, std::string description, RPCArgOptions opts={})
Definition: util.h:232
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:109
Special type that behaves almost exactly like OBJ, defining an options object with a list of pre-defi...
const std::string m_key_name
Only used for dicts.
Definition: util.h:314
std::string ToDescriptionString() const
Definition: util.cpp:630
std::vector< unsigned char > ParseHexV(const UniValue &v, std::string_view name)
Definition: util.cpp:130
RPCResult(std::string cond, Type type, std::string m_key_name, std::string description, std::vector< RPCResult > inner={})
Definition: util.h:340
std::vector< std::pair< std::string, bool > > GetArgNames() const
Return list of arguments and whether they are named-only.
Definition: util.cpp:745
const RPCExamples m_examples
Definition: util.h:503
Definition: common.h:29
const RPCMethodImpl m_fun
Definition: util.h:499
bool skip_type_check
Definition: util.h:170
bool IsValidNumArgs(size_t num_args) const
If the supplied number of args is neither too small nor too high.
Definition: util.cpp:733
UniValue GetArgMap() const
Return the named args that need to be converted from string to another JSON type. ...
Definition: util.cpp:833
void ToSections(Sections &sections, OuterType outer_type=OuterType::NONE, int current_indent=0) const
Append the sections of the result.
Definition: util.cpp:997
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:770
const bool m_skip_type_check
Definition: util.h:317
std::optional< int > ParseSighashString(const UniValue &sighash)
Parse a sighash string representation and raise an RPC error if it is invalid.
Definition: util.cpp:357
const std::vector< RPCArg > m_inner
Only used for arrays or dicts.
Definition: util.h:227
RPCErrorCode RPCErrorFromTransactionError(node::TransactionError terr)
OutputType
Definition: outputtype.h:18
const std::string m_cond
Definition: util.h:319
std::vector< CScript > EvalDescriptorStringOrObject(const UniValue &scanobject, FlatSigningProvider &provider, bool expand_priv=false)
Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range ...
Definition: util.cpp:1324
const Type m_type
Definition: util.h:313
UniValue::VType type
Definition: util.h:87
const std::string m_description
Definition: util.h:500
CFeeRate ParseFeeRate(const UniValue &json)
Parse a json number or string, denoting BTC/kvB, into a CFeeRate (sat/kvB).
Definition: util.cpp:110
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:56
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
Definition: util.h:171
void PushWarnings(const UniValue &warnings, UniValue &obj)
Push warning messages to an RPC "warnings" field as a JSON array of strings.
Definition: util.cpp:1378
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:917
Special string with only hex chars.
Definition: util.h:186
ArgsManager & args
Definition: bitcoind.cpp:277
const char * name
Definition: rest.cpp:48
Special array that has a fixed number of entries.
RPCResults(std::initializer_list< RPCResult > results)
Definition: util.h:397
bool IsOptional() const
Definition: util.cpp:923
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:225
RPCResult(Type type, std::string m_key_name, std::string description, std::vector< RPCResult > inner={}, bool skip_type_check=false)
Definition: util.h:366
std::vector< RPCResult > ScriptPubKeyDoc()
Definition: util.cpp:1390
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)
std::function< UniValue(const RPCHelpMan &, const JSONRPCRequest &)> RPCMethodImpl
Definition: util.h:422
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:369
const std::vector< RPCResult > m_results
Definition: util.h:390
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:201
std::string DefaultHint
Hint for default value.
Definition: util.h:220
std::string GetFirstName() const
Return the first of all aliases.
Definition: util.cpp:912
const std::vector< RPCArg > m_args
Definition: util.h:501
const std::string m_description
Definition: util.h:229
Special numeric to denote unix epoch time.
const std::string m_examples
Definition: util.h:409
Definition: messages.h:21
const JSONRPCRequest * m_req
Definition: util.h:504
std::vector< std::pair< std::string, UniValue > > RPCArgList
Definition: util.h:132
Definition: init.cpp:17
const RPCResults m_results
Definition: util.h:502
Special type that is a NUM or [NUM,NUM].
std::variant< Optional, DefaultHint, Default > Fallback
Definition: util.h:223
OuterType
Serializing JSON objects depends on the outer type.
Definition: util.h:163
RPCHelpMan(std::string name, std::string description, std::vector< RPCArg > args, RPCResults results, RPCExamples examples)
Definition: util.cpp:545
HelpResult(const std::string &msg)
Definition: util.h:71
256-bit opaque blob.
Definition: uint256.h:195
Optional argument for which the default value is omitted from help text for one of two reasons: ...
UniValue JSONRPCPSBTError(common::PSBTError err)
auto result
Definition: common-types.h:74
auto Arg(std::string_view key) const
Helper to get a required or default-valued request argument.
Definition: util.h:444
CTxDestination AddAndGetMultisigDestination(int required, const std::vector< CPubKey > &pubkeys, OutputType type, FlatSigningProvider &keystore, CScript &script_out)
Definition: util.cpp:235
UniValueType()
Definition: util.h:85
Special string to represent a floating point amount.
auto MaybeArg(std::string_view key) const
Helper to get an optional request argument.
Definition: util.h:476
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:93
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:404
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:207
Optional
Definition: util.h:206
const std::string m_description
Definition: util.h:318
uint256 ParseHashO(const UniValue &o, std::string_view strKey)
Definition: util.cpp:126
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:143
Special type representing a floating point amount (can be either NUM or STR)
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac...
Definition: feerate.h:31
uint256 GetTarget(const CBlockIndex &blockindex, uint256 pow_limit)
Definition: util.cpp:1401
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:188
RPCResults(RPCResult result)
Definition: util.h:392
UniValue MatchesType(const UniValue &request) const
Check whether the request JSON type matches.
Definition: util.cpp:899
const Type m_type
Definition: util.h:226
UniValue MatchesType(const UniValue &result) const
Check whether the result JSON type matches.
Definition: util.cpp:1131
RPCExamples(std::string examples)
Definition: util.h:410
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:932
const bool m_optional
Definition: util.h:316
const std::string m_name
Definition: util.h:496
RPCErrorCode
Bitcoin RPC error codes.
Definition: protocol.h:24
Special dictionary with keys that are not literals.
UniValue HandleRequest(const JSONRPCRequest &request) const
Definition: util.cpp:635
std::string ToString(bool oneline) const
Return the type string of the argument.
Definition: util.cpp:1249
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
Definition: util.cpp:1308
Wrapper for UniValue::VType, which includes typeAny: Used to denote don&#39;t care type.
Definition: util.h:83
RPCResult(std::string cond, Type type, std::string m_key_name, bool optional, std::string description, std::vector< RPCResult > inner={})
Definition: util.h:321
int ParseVerbosity(const UniValue &arg, int default_verbosity, bool allow_bool)
Parses verbosity from provided UniValue.
Definition: util.cpp:83
Special type to denote elision (...)
std::string ToDescriptionString() const
Return the description string, including the result type.
std::string ToStringObj(bool oneline) const
Return the type string of the argument when it is in an object (dict).
Definition: util.cpp:1210