Bitcoin Core  21.99.0
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/coinstats.h>
9 #include <node/transaction.h>
10 #include <outputtype.h>
11 #include <protocol.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 <script/standard.h>
18 #include <univalue.h>
19 #include <util/check.h>
20 
21 #include <string>
22 #include <variant>
23 #include <vector>
24 
29 extern const std::string UNIX_EPOCH_TIME;
30 
35 extern const std::string EXAMPLE_ADDRESS[2];
36 
38 class CPubKey;
39 class CScript;
40 struct Sections;
41 
44 struct UniValueType {
45  UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
46  UniValueType() : typeAny(true) {}
47  bool typeAny;
49 };
50 
55 void RPCTypeCheck(const UniValue& params,
56  const std::list<UniValueType>& typesExpected, bool fAllowNull=false);
57 
61 void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected);
62 
63 /*
64  Check for expected keys/value types in an Object.
65 */
66 void RPCTypeCheckObj(const UniValue& o,
67  const std::map<std::string, UniValueType>& typesExpected,
68  bool fAllowNull = false,
69  bool fStrict = false);
70 
75 extern uint256 ParseHashV(const UniValue& v, std::string strName);
76 extern uint256 ParseHashO(const UniValue& o, std::string strKey);
77 extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
78 extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
79 
80 CoinStatsHashType ParseHashType(const UniValue& param, const CoinStatsHashType default_type);
81 
82 extern CAmount AmountFromValue(const UniValue& value);
83 extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
84 extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
85 
86 CPubKey HexToPubKey(const std::string& hex_in);
87 CPubKey AddrToPubKey(const FillableSigningProvider& keystore, const std::string& addr_in);
88 CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, FillableSigningProvider& keystore, CScript& script_out);
89 
91 
93 unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target);
94 
96 UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string = "");
97 
99 std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value);
100 
102 std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider);
103 
106 
111 enum class OuterType {
112  ARR,
113  OBJ,
114  NONE, // Only set on first recursion
115 };
116 
117 struct RPCArg {
118  enum class Type {
119  OBJ,
120  ARR,
121  STR,
122  NUM,
123  BOOL,
124  OBJ_USER_KEYS,
125  AMOUNT,
126  STR_HEX,
127  RANGE,
128  };
129 
130  enum class Optional {
132  NO,
137  OMITTED_NAMED_ARG,
144  OMITTED,
145  };
146  using Fallback = std::variant<Optional, /* default value for optional args */ std::string>;
147  const std::string m_names;
148  const Type m_type;
149  const bool m_hidden;
150  const std::vector<RPCArg> m_inner;
152  const std::string m_description;
153  const std::string m_oneline_description;
154  const std::vector<std::string> m_type_str;
155 
157  const std::string name,
158  const Type type,
159  const Fallback fallback,
160  const std::string description,
161  const std::string oneline_description = "",
162  const std::vector<std::string> type_str = {},
163  const bool hidden = false)
164  : m_names{std::move(name)},
165  m_type{std::move(type)},
166  m_hidden{hidden},
167  m_fallback{std::move(fallback)},
168  m_description{std::move(description)},
169  m_oneline_description{std::move(oneline_description)},
170  m_type_str{std::move(type_str)}
171  {
172  CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ);
173  }
174 
176  const std::string name,
177  const Type type,
178  const Fallback fallback,
179  const std::string description,
180  const std::vector<RPCArg> inner,
181  const std::string oneline_description = "",
182  const std::vector<std::string> type_str = {})
183  : m_names{std::move(name)},
184  m_type{std::move(type)},
185  m_hidden{false},
186  m_inner{std::move(inner)},
187  m_fallback{std::move(fallback)},
188  m_description{std::move(description)},
189  m_oneline_description{std::move(oneline_description)},
190  m_type_str{std::move(type_str)}
191  {
192  CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ);
193  }
194 
195  bool IsOptional() const;
196 
198  std::string GetFirstName() const;
199 
201  std::string GetName() const;
202 
207  std::string ToString(bool oneline) const;
212  std::string ToStringObj(bool oneline) const;
217  std::string ToDescriptionString() const;
218 };
219 
220 struct RPCResult {
221  enum class Type {
222  OBJ,
223  ARR,
224  STR,
225  NUM,
226  BOOL,
227  NONE,
228  STR_AMOUNT,
229  STR_HEX,
230  OBJ_DYN,
231  ARR_FIXED,
232  NUM_TIME,
233  ELISION,
234  };
235 
236  const Type m_type;
237  const std::string m_key_name;
238  const std::vector<RPCResult> m_inner;
239  const bool m_optional;
240  const std::string m_description;
241  const std::string m_cond;
242 
244  const std::string cond,
245  const Type type,
246  const std::string m_key_name,
247  const bool optional,
248  const std::string description,
249  const std::vector<RPCResult> inner = {})
250  : m_type{std::move(type)},
251  m_key_name{std::move(m_key_name)},
252  m_inner{std::move(inner)},
253  m_optional{optional},
254  m_description{std::move(description)},
255  m_cond{std::move(cond)}
256  {
257  CHECK_NONFATAL(!m_cond.empty());
258  const bool inner_needed{type == Type::ARR || type == Type::ARR_FIXED || type == Type::OBJ || type == Type::OBJ_DYN};
259  CHECK_NONFATAL(inner_needed != inner.empty());
260  }
261 
263  const std::string cond,
264  const Type type,
265  const std::string m_key_name,
266  const std::string description,
267  const std::vector<RPCResult> inner = {})
268  : RPCResult{cond, type, m_key_name, false, description, inner} {}
269 
271  const Type type,
272  const std::string m_key_name,
273  const bool optional,
274  const std::string description,
275  const std::vector<RPCResult> inner = {})
276  : m_type{std::move(type)},
277  m_key_name{std::move(m_key_name)},
278  m_inner{std::move(inner)},
279  m_optional{optional},
280  m_description{std::move(description)},
281  m_cond{}
282  {
283  const bool inner_needed{type == Type::ARR || type == Type::ARR_FIXED || type == Type::OBJ || type == Type::OBJ_DYN};
284  CHECK_NONFATAL(inner_needed != inner.empty());
285  }
286 
288  const Type type,
289  const std::string m_key_name,
290  const std::string description,
291  const std::vector<RPCResult> inner = {})
292  : RPCResult{type, m_key_name, false, description, inner} {}
293 
295  void ToSections(Sections& sections, OuterType outer_type = OuterType::NONE, const int current_indent = 0) const;
297  std::string ToStringObj() const;
299  std::string ToDescriptionString() const;
300 };
301 
302 struct RPCResults {
303  const std::vector<RPCResult> m_results;
304 
306  : m_results{{result}}
307  {
308  }
309 
310  RPCResults(std::initializer_list<RPCResult> results)
311  : m_results{results}
312  {
313  }
314 
318  std::string ToDescriptionString() const;
319 };
320 
321 struct RPCExamples {
322  const std::string m_examples;
323  explicit RPCExamples(
324  std::string examples)
325  : m_examples(std::move(examples))
326  {
327  }
328  std::string ToDescriptionString() const;
329 };
330 
332 {
333 public:
334  RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples);
335  using RPCMethodImpl = std::function<UniValue(const RPCHelpMan&, const JSONRPCRequest&)>;
336  RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);
337 
338  std::string ToString() const;
340  {
341  Check(request);
342  return m_fun(*this, request);
343  }
345  bool IsValidNumArgs(size_t num_args) const;
350  inline void Check(const JSONRPCRequest& request) const {
351  if (request.fHelp || !IsValidNumArgs(request.params.size())) {
352  throw std::runtime_error(ToString());
353  }
354  }
355 
356  std::vector<std::string> GetArgNames() const;
357 
358  const std::string m_name;
359 
360 private:
362  const std::string m_description;
363  const std::vector<RPCArg> m_args;
366 };
367 
368 #endif // BITCOIN_RPC_UTIL_H
UniValue DescribeAddress(const CTxDestination &dest)
Definition: util.cpp:268
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:133
UniValueType(UniValue::VType _type)
Definition: util.h:45
void RPCTypeCheck(const UniValue &params, const std::list< UniValueType > &typesExpected, bool fAllowNull=false)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: util.cpp:23
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: util.cpp:89
std::vector< unsigned char > ParseHexV(const UniValue &v, std::string strName)
Definition: util.cpp:102
const std::vector< RPCResult > m_inner
Only used for arrays or dicts.
Definition: util.h:238
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:829
const Fallback m_fallback
Definition: util.h:151
ServiceFlags
nServices flags
Definition: protocol.h:269
uint256 ParseHashO(const UniValue &o, std::string strKey)
Definition: util.cpp:98
RPCResult(const Type type, const std::string m_key_name, const bool optional, const std::string description, const std::vector< RPCResult > inner={})
Definition: util.h:270
Keeps track of RPCArgs by transforming them into sections for the purpose of serializing everything t...
Definition: util.cpp:326
const std::string m_oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
Definition: util.h:153
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:20
bool typeAny
Definition: util.h:47
CPubKey AddrToPubKey(const FillableSigningProvider &keystore, const std::string &addr_in)
Definition: util.cpp:158
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:145
const std::string EXAMPLE_ADDRESS[2]
Example bech32 addresses for the RPCExamples help documentation.
Definition: util.cpp:21
UniValue HandleRequest(const JSONRPCRequest &request)
Definition: util.h:339
#define CHECK_NONFATAL(condition)
Throw a NonFatalCheckError when the condition evaluates to false.
Definition: check.h:32
CAmount AmountFromValue(const UniValue &value)
Definition: util.cpp:77
const std::string m_key_name
Only used for dicts.
Definition: util.h:237
RPCResult(const Type type, const std::string m_key_name, const std::string description, const std::vector< RPCResult > inner={})
Definition: util.h:287
const RPCExamples m_examples
Definition: util.h:365
RPCArg(const std::string name, const Type type, const Fallback fallback, const std::string description, const std::string oneline_description="", const std::vector< std::string > type_str={}, const bool hidden=false)
Definition: util.h:156
const RPCMethodImpl m_fun
Definition: util.h:361
RPCResult(const std::string cond, const Type type, const std::string m_key_name, const bool optional, const std::string description, const std::vector< RPCResult > inner={})
Definition: util.h:243
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:212
void Check(const JSONRPCRequest &request) const
Check if the given request is valid according to this command or if the user is asking for help infor...
Definition: util.h:350
const std::vector< RPCArg > m_inner
Only used for arrays or dicts.
Definition: util.h:150
OutputType
Definition: outputtype.h:17
const std::string m_cond
Definition: util.h:241
void RPCTypeCheckArgument(const UniValue &value, const UniValueType &typeExpected)
Type-check one argument; throws JSONRPCError if wrong type given.
Definition: util.cpp:40
RPCErrorCode RPCErrorFromTransactionError(TransactionError terr)
Definition: util.cpp:283
const Type m_type
Definition: util.h:236
UniValue::VType type
Definition: util.h:48
const std::string m_description
Definition: util.h:362
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
std::variant< Optional, std::string > Fallback
Definition: util.h:146
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull=false, bool fStrict=false)
Definition: util.cpp:47
CoinStatsHashType
Definition: coinstats.h:17
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:71
Definition: util.h:117
CTxDestination AddAndGetMultisigDestination(const int required, const std::vector< CPubKey > &pubkeys, OutputType type, FillableSigningProvider &keystore, CScript &script_out)
Definition: util.cpp:179
UniValue params
Definition: request.h:36
const char * name
Definition: rest.cpp:41
RPCResults(std::initializer_list< RPCResult > results)
Definition: util.h:310
An encapsulated public key.
Definition: pubkey.h:31
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:147
UniValue GetServicesNames(ServiceFlags services)
Returns, given services flags, a list of humanly readable (known) network services.
Definition: util.cpp:867
std::function< UniValue(const RPCHelpMan &, const JSONRPCRequest &)> RPCMethodImpl
Definition: util.h:335
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:273
const std::vector< RPCResult > m_results
Definition: util.h:303
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:138
const std::vector< RPCArg > m_args
Definition: util.h:363
const std::string m_description
Definition: util.h:152
UniValue JSONRPCTransactionError(TransactionError terr, const std::string &err_string="")
Definition: util.cpp:302
const std::string m_examples
Definition: util.h:322
const std::vector< std::string > m_type_str
Should be empty unless it is supposed to override the auto-generated type strings. Vector length is either 0 or 2, m_type_str.at(0) will override the type of the value in a key-value pair, m_type_str.at(1) will override the type in the argument description.
Definition: util.h:154
const RPCResults m_results
Definition: util.h:364
bool fHelp
Definition: request.h:37
OuterType
Serializing JSON objects depends on the outer type.
Definition: util.h:111
256-bit opaque blob.
Definition: uint256.h:124
UniValueType()
Definition: util.h:46
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:404
Optional
Definition: util.h:130
const std::string m_description
Definition: util.h:240
CoinStatsHashType ParseHashType(const UniValue &param, const CoinStatsHashType default_type)
Definition: util.cpp:116
TransactionError
Definition: error.h:22
RPCResults(RPCResult result)
Definition: util.h:305
RPCResult(const std::string cond, const Type type, const std::string m_key_name, const std::string description, const std::vector< RPCResult > inner={})
Definition: util.h:262
const Type m_type
Definition: util.h:148
RPCArg(const std::string name, const Type type, const Fallback fallback, const std::string description, const std::vector< RPCArg > inner, const std::string oneline_description="", const std::vector< std::string > type_str={})
Definition: util.h:175
RPCExamples(std::string examples)
Definition: util.h:323
const bool m_hidden
Definition: util.h:149
const bool m_optional
Definition: util.h:239
size_t size() const
Definition: univalue.h:68
const std::string m_name
Definition: util.h:358
RPCErrorCode
Bitcoin RPC error codes.
Definition: protocol.h:23
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
Definition: util.cpp:813
Wrapper for UniValue::VType, which includes typeAny: Used to denote don&#39;t care type.
Definition: util.h:44
std::optional< T > Optional
Substitute for C++17 std::optional DEPRECATED use std::optional in new code.
Definition: optional.h:14
std::vector< unsigned char > ParseHexO(const UniValue &o, std::string strKey)
Definition: util.cpp:111