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