Line data Source code
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 <consensus/amount.h>
9 : #include <node/transaction.h>
10 : #include <pubkey.h>
11 : #include <rpc/protocol.h>
12 : #include <rpc/request.h>
13 : #include <script/script.h>
14 : #include <script/sign.h>
15 : #include <script/signingprovider.h>
16 : #include <script/standard.h>
17 : #include <uint256.h>
18 : #include <univalue.h>
19 : #include <util/check.h>
20 : #include <util/strencodings.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 :
49 : /**
50 : * String used to describe UNIX epoch time in documentation, factored out to a
51 : * constant for consistency.
52 : */
53 : extern const std::string UNIX_EPOCH_TIME;
54 :
55 : /**
56 : * Example Dash addresses for the RPCExamples help documentation. They are intentionally
57 : * invalid to prevent accidental transactions by users.
58 : */
59 : extern const std::string EXAMPLE_ADDRESS[2];
60 :
61 : class FillableSigningProvider;
62 : class FillableSigningProvider;
63 : class CScript;
64 : struct Sections;
65 :
66 : /**
67 : * Gets all existing output types formatted for RPC help sections.
68 : *
69 : * @return Comma separated string representing output type names.
70 : */
71 : std::string GetAllOutputTypes();
72 :
73 : /** Wrapper for UniValue::VType, which includes typeAny:
74 : * Used to denote don't care type. */
75 : struct UniValueType {
76 386596 : UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
77 43386 : UniValueType() : typeAny(true) {}
78 : bool typeAny;
79 : UniValue::VType type;
80 : };
81 :
82 : /**
83 : * Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
84 : * the right number of arguments are passed, just that any passed are the correct type.
85 : */
86 : void RPCTypeCheck(const UniValue& params,
87 : const std::list<UniValueType>& typesExpected, bool fAllowNull=false);
88 :
89 : /**
90 : * Type-check one argument; throws JSONRPCError if wrong type given.
91 : */
92 : void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected);
93 :
94 : /*
95 : Check for expected keys/value types in an Object.
96 : */
97 : void RPCTypeCheckObj(const UniValue& o,
98 : const std::map<std::string, UniValueType>& typesExpected,
99 : bool fAllowNull = false,
100 : bool fStrict = false);
101 :
102 : /**
103 : * Utilities: convert hex-encoded Values
104 : * (throws error if not hex).
105 : */
106 : uint256 ParseHashV(const UniValue& v, std::string strName);
107 : uint256 ParseHashO(const UniValue& o, std::string strKey);
108 : std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
109 : std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
110 :
111 : bool ParseBoolV(const UniValue& v, const std::string &strName);
112 :
113 : /**
114 : * Validate and return a CAmount from a UniValue number or string.
115 : *
116 : * @param[in] value UniValue number or string to parse.
117 : * @param[in] decimals Number of significant digits (default: 8).
118 : * @returns a CAmount if the various checks pass.
119 : */
120 : CAmount AmountFromValue(const UniValue& value, int decimals = 8);
121 :
122 : using RPCArgList = std::vector<std::pair<std::string, UniValue>>;
123 : std::string HelpExampleCli(const std::string& methodname, const std::string& args);
124 : std::string HelpExampleCliNamed(const std::string& methodname, const RPCArgList& args);
125 : std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
126 : std::string HelpExampleRpcNamed(const std::string& methodname, const RPCArgList& args);
127 :
128 : CPubKey HexToPubKey(const std::string& hex_in);
129 : CPubKey AddrToPubKey(const FillableSigningProvider& keystore, const std::string& addr_in);
130 : CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, FillableSigningProvider& keystore, CScript& script_out);
131 :
132 : UniValue DescribeAddress(const CTxDestination& dest);
133 :
134 : //! Parse a confirm target option and raise an RPC error if it is invalid.
135 : unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target);
136 :
137 :
138 : //! Parse a JSON range specified as int64, or [int64, int64]
139 : std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value);
140 :
141 : /**
142 : * Serializing JSON objects depends on the outer type. Only arrays and
143 : * dictionaries can be nested in json. The top-level outer type is "NONE".
144 : */
145 : enum class OuterType {
146 : ARR,
147 : OBJ,
148 : NONE, // Only set on first recursion
149 : };
150 : /** Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range of 1000. */
151 : std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider);
152 :
153 7022439 : struct RPCArg {
154 : enum class Type {
155 : OBJ,
156 : ARR,
157 : STR,
158 : NUM,
159 : BOOL,
160 : OBJ_USER_KEYS, //!< Special type where the user must set the keys e.g. to define multiple addresses; as opposed to e.g. an options object where the keys are predefined
161 : AMOUNT, //!< Special type representing a floating point amount (can be either NUM or STR)
162 : STR_HEX, //!< Special type that is a STR with only hex chars
163 : RANGE, //!< Special type that is a NUM or [NUM,NUM]
164 : };
165 :
166 : enum class Optional {
167 : /** Required arg */
168 : NO,
169 : /**
170 : * The arg is optional for one of two reasons:
171 : *
172 : * Optional arg that is a named argument and has a default value of
173 : * `null`.
174 : *
175 : * Optional argument with default value omitted because they are
176 : * implicitly clear. That is, elements in an array may not
177 : * exist by default.
178 : * When possible, the default value should be specified.
179 : */
180 : OMITTED,
181 : OMITTED_NAMED_ARG, // Deprecated alias for OMITTED, can be removed
182 : };
183 : /** Hint for default value */
184 : using DefaultHint = std::string;
185 : /** Default constant value */
186 : using Default = UniValue;
187 : using Fallback = std::variant<Optional, DefaultHint, Default>;
188 :
189 : const std::string m_names; //!< The name of the arg (can be empty for inner args, can contain multiple aliases separated by | for named request arguments)
190 : const Type m_type;
191 : const bool m_hidden;
192 : const std::vector<RPCArg> m_inner; //!< Only used for arrays or dicts
193 : const Fallback m_fallback;
194 : const std::string m_description;
195 : const std::string m_oneline_description; //!< Should be empty unless it is supposed to override the auto-generated summary line
196 : 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.
197 :
198 11237202 : RPCArg(
199 : std::string name,
200 : Type type,
201 : Fallback fallback,
202 : std::string description,
203 : std::string oneline_description = "",
204 : std::vector<std::string> type_str = {},
205 : bool hidden = false)
206 3745734 : : m_names{std::move(name)},
207 3745734 : m_type{std::move(type)},
208 3745734 : m_hidden{hidden},
209 3745734 : m_fallback{std::move(fallback)},
210 3745734 : m_description{std::move(description)},
211 3745734 : m_oneline_description{std::move(oneline_description)},
212 3745734 : m_type_str{std::move(type_str)}
213 3745734 : {
214 3745734 : CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ && type != Type::OBJ_USER_KEYS);
215 7491468 : }
216 :
217 1006088 : RPCArg(
218 : std::string name,
219 : Type type,
220 : Fallback fallback,
221 : std::string description,
222 : std::vector<RPCArg> inner,
223 : std::string oneline_description = "",
224 : std::vector<std::string> type_str = {})
225 503044 : : m_names{std::move(name)},
226 503044 : m_type{std::move(type)},
227 503044 : m_hidden{false},
228 503044 : m_inner{std::move(inner)},
229 503044 : m_fallback{std::move(fallback)},
230 503044 : m_description{std::move(description)},
231 503044 : m_oneline_description{std::move(oneline_description)},
232 503044 : m_type_str{std::move(type_str)}
233 503044 : {
234 503044 : CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ || type == Type::OBJ_USER_KEYS);
235 1006088 : }
236 :
237 : bool IsOptional() const;
238 :
239 : /** Return the first of all aliases */
240 : std::string GetFirstName() const;
241 :
242 : /** Return the name, throws when there are aliases */
243 : std::string GetName() const;
244 :
245 : /**
246 : * Return the type string of the argument.
247 : * Set oneline to allow it to be overridden by a custom oneline type string (m_oneline_description).
248 : */
249 : std::string ToString(bool oneline) const;
250 : /**
251 : * Return the type string of the argument when it is in an object (dict).
252 : * Set oneline to get the oneline representation (less whitespace)
253 : */
254 : std::string ToStringObj(bool oneline) const;
255 : /**
256 : * Return the description string, including the argument type and whether
257 : * the argument is required.
258 : */
259 : std::string ToDescriptionString(bool is_named_arg) const;
260 : };
261 :
262 141672704 : struct RPCResult {
263 : enum class Type {
264 : OBJ,
265 : ARR,
266 : STR,
267 : NUM,
268 : BOOL,
269 : NONE,
270 : ANY, //!< Special type to disable type checks (for testing only)
271 : STR_AMOUNT, //!< Special string to represent a floating point amount
272 : STR_HEX, //!< Special string with only hex chars
273 : OBJ_DYN, //!< Special dictionary with keys that are not literals
274 : ARR_FIXED, //!< Special array that has a fixed number of entries
275 : NUM_TIME, //!< Special numeric to denote unix epoch time
276 : ELISION, //!< Special type to denote elision (...)
277 : };
278 :
279 : const Type m_type;
280 : const std::string m_key_name; //!< Only used for dicts
281 : const std::vector<RPCResult> m_inner; //!< Only used for arrays or dicts
282 : const bool m_optional;
283 : const std::string m_description;
284 : const std::string m_cond;
285 :
286 2359872 : RPCResult(
287 : std::string cond,
288 : Type type,
289 : std::string m_key_name,
290 : bool optional,
291 : std::string description,
292 : std::vector<RPCResult> inner = {})
293 1179936 : : m_type{std::move(type)},
294 1179936 : m_key_name{std::move(m_key_name)},
295 1179936 : m_inner{std::move(inner)},
296 1179936 : m_optional{optional},
297 1179936 : m_description{std::move(description)},
298 1179936 : m_cond{std::move(cond)}
299 1179936 : {
300 1179936 : CHECK_NONFATAL(!m_cond.empty());
301 1179936 : CheckInnerDoc();
302 2359872 : }
303 :
304 1179936 : RPCResult(
305 : std::string cond,
306 : Type type,
307 : std::string m_key_name,
308 : std::string description,
309 : std::vector<RPCResult> inner = {})
310 1179936 : : RPCResult{std::move(cond), type, std::move(m_key_name), /*optional=*/false, std::move(description), std::move(inner)} {}
311 :
312 39406350 : RPCResult(
313 : Type type,
314 : std::string m_key_name,
315 : bool optional,
316 : std::string description,
317 : std::vector<RPCResult> inner = {})
318 19703175 : : m_type{std::move(type)},
319 19703175 : m_key_name{std::move(m_key_name)},
320 19703175 : m_inner{std::move(inner)},
321 19703175 : m_optional{optional},
322 19703175 : m_description{std::move(description)},
323 19703175 : m_cond{}
324 19703175 : {
325 19703175 : CheckInnerDoc();
326 39406350 : }
327 :
328 13916668 : RPCResult(
329 : Type type,
330 : std::string m_key_name,
331 : std::string description,
332 : std::vector<RPCResult> inner = {})
333 13916668 : : RPCResult{type, m_key_name, false, description, inner} {}
334 :
335 : /** Append the sections of the result. */
336 : void ToSections(Sections& sections, OuterType outer_type = OuterType::NONE, const int current_indent = 0) const;
337 : /** Return the type string of the result when it is in an object (dict). */
338 : std::string ToStringObj() const;
339 : /** Return the description string, including the result type. */
340 : std::string ToDescriptionString() const;
341 : /** Check whether the result JSON type matches. */
342 : bool MatchesType(const UniValue& result) const;
343 :
344 : private:
345 : void CheckInnerDoc() const;
346 : };
347 :
348 : struct RPCResults {
349 : const std::vector<RPCResult> m_results;
350 :
351 3189544 : RPCResults(RPCResult result)
352 1594772 : : m_results{{result}}
353 1594772 : {
354 3189544 : }
355 :
356 518426 : RPCResults(std::initializer_list<RPCResult> results)
357 259213 : : m_results{results}
358 259213 : {
359 518426 : }
360 :
361 : /**
362 : * Return the description string.
363 : */
364 : std::string ToDescriptionString() const;
365 : };
366 :
367 : struct RPCExamples {
368 : const std::string m_examples;
369 3726486 : explicit RPCExamples(
370 : std::string examples)
371 1863243 : : m_examples(std::move(examples))
372 1863243 : {
373 3726486 : }
374 : std::string ToDescriptionString() const;
375 : };
376 :
377 : class RPCHelpMan
378 : {
379 : public:
380 : RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples);
381 : using RPCMethodImpl = std::function<UniValue(const RPCHelpMan&, const JSONRPCRequest&)>;
382 : RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);
383 :
384 : UniValue HandleRequest(const JSONRPCRequest& request) const;
385 : /**
386 : * Helper to get a request argument.
387 : * This function only works during m_fun(), i.e. it should only be used in
388 : * RPC method implementations. The helper internally checks whether the
389 : * user-passed argument isNull() and parses (from JSON) and returns the
390 : * user-passed argument, or the default value derived from the RPCArg
391 : * documention, or a falsy value if no default was given.
392 : *
393 : * Use Arg<Type>(i) to get the argument or its default value. Otherwise,
394 : * use MaybeArg<Type>(i) to get the optional argument or a falsy value.
395 : *
396 : * The Type passed to this helper must match the corresponding
397 : * RPCArg::Type.
398 : */
399 : template <typename R>
400 4064 : auto Arg(size_t i) const
401 : {
402 : // Return argument (required or with default value).
403 : if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
404 : // Return numbers by value.
405 2728 : return ArgValue<R>(i);
406 : } else {
407 : // Return everything else by reference.
408 1336 : return ArgValue<const R&>(i);
409 : }
410 : }
411 : template <typename R>
412 2319 : auto MaybeArg(size_t i) const
413 : {
414 : // Return optional argument (without default).
415 : if constexpr (std::is_integral_v<R> || std::is_floating_point_v<R>) {
416 : // Return numbers by value, wrapped in optional.
417 364 : return ArgValue<std::optional<R>>(i);
418 : } else {
419 : // Return other types by pointer.
420 1955 : return ArgValue<const R*>(i);
421 : }
422 : }
423 : std::string ToString() const;
424 : /** Return the named args that need to be converted from string to another JSON type */
425 : UniValue GetArgMap() const;
426 : /** If the supplied number of args is neither too small nor too high */
427 : bool IsValidNumArgs(size_t num_args) const;
428 :
429 : std::vector<std::string> GetArgNames() const;
430 :
431 : const std::string m_name;
432 :
433 : private:
434 : const RPCMethodImpl m_fun;
435 : const std::string m_description;
436 : const std::vector<RPCArg> m_args;
437 : const RPCResults m_results;
438 : const RPCExamples m_examples;
439 : mutable const JSONRPCRequest* m_req{nullptr}; // A pointer to the request for the duration of m_fun()
440 : template <typename R>
441 : R ArgValue(size_t i) const;
442 : };
443 :
444 : RPCErrorCode RPCErrorFromTransactionError(TransactionError terr);
445 : UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string = "");
446 :
447 : #endif // BITCOIN_RPC_UTIL_H
|