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 <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 :
26 : /**
27 : * String used to describe UNIX epoch time in documentation, factored out to a
28 : * constant for consistency.
29 : */
30 : extern const std::string UNIX_EPOCH_TIME;
31 :
32 : /**
33 : * Example bech32 addresses for the RPCExamples help documentation. They are intentionally
34 : * invalid to prevent accidental transactions by users.
35 : */
36 : extern const std::string EXAMPLE_ADDRESS[2];
37 :
38 : class FillableSigningProvider;
39 : class CPubKey;
40 : class CScript;
41 : struct Sections;
42 :
43 : /** Wrapper for UniValue::VType, which includes typeAny:
44 : * Used to denote don't care type. */
45 : struct UniValueType {
46 49470 : UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
47 19766 : UniValueType() : typeAny(true) {}
48 : bool typeAny;
49 : UniValue::VType type;
50 : };
51 :
52 : /**
53 : * Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
54 : * the right number of arguments are passed, just that any passed are the correct type.
55 : */
56 : void RPCTypeCheck(const UniValue& params,
57 : const std::list<UniValueType>& typesExpected, bool fAllowNull=false);
58 :
59 : /**
60 : * Type-check one argument; throws JSONRPCError if wrong type given.
61 : */
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 :
72 : /**
73 : * Utilities: convert hex-encoded Values
74 : * (throws error if not hex).
75 : */
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 :
91 : UniValue DescribeAddress(const CTxDestination& dest);
92 :
93 : //! Parse a confirm target option and raise an RPC error if it is invalid.
94 : unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target);
95 :
96 : RPCErrorCode RPCErrorFromTransactionError(TransactionError terr);
97 : UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string = "");
98 :
99 : //! Parse a JSON range specified as int64, or [int64, int64]
100 : std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value);
101 :
102 : /** Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range of 1000. */
103 : std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider);
104 :
105 : /** Returns, given services flags, a list of humanly readable (known) network services */
106 : UniValue GetServicesNames(ServiceFlags services);
107 :
108 : /**
109 : * Serializing JSON objects depends on the outer type. Only arrays and
110 : * dictionaries can be nested in json. The top-level outer type is "NONE".
111 : */
112 : enum class OuterType {
113 : ARR,
114 : OBJ,
115 : NONE, // Only set on first recursion
116 : };
117 :
118 4776644 : struct RPCArg {
119 : enum class Type {
120 : OBJ,
121 : ARR,
122 : STR,
123 : NUM,
124 : BOOL,
125 : 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
126 : AMOUNT, //!< Special type representing a floating point amount (can be either NUM or STR)
127 : STR_HEX, //!< Special type that is a STR with only hex chars
128 : RANGE, //!< Special type that is a NUM or [NUM,NUM]
129 : };
130 :
131 : enum class Optional {
132 : /** Required arg */
133 : NO,
134 : /**
135 : * Optional arg that is a named argument and has a default value of
136 : * `null`. When possible, the default value should be specified.
137 : */
138 : OMITTED_NAMED_ARG,
139 : /**
140 : * Optional argument with default value omitted because they are
141 : * implicitly clear. That is, elements in an array or object may not
142 : * exist by default.
143 : * When possible, the default value should be specified.
144 : */
145 : OMITTED,
146 : };
147 : using Fallback = boost::variant<Optional, /* default value for optional args */ std::string>;
148 : 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)
149 : const Type m_type;
150 : const bool m_hidden;
151 : const std::vector<RPCArg> m_inner; //!< Only used for arrays or dicts
152 : const Fallback m_fallback;
153 : const std::string m_description;
154 : const std::string m_oneline_description; //!< Should be empty unless it is supposed to override the auto-generated summary line
155 : 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.
156 :
157 838014 : RPCArg(
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 419007 : : m_names{std::move(name)},
166 419007 : m_type{std::move(type)},
167 419007 : m_hidden{hidden},
168 419007 : m_fallback{std::move(fallback)},
169 419007 : m_description{std::move(description)},
170 419007 : m_oneline_description{std::move(oneline_description)},
171 419007 : m_type_str{std::move(type_str)}
172 419007 : {
173 419007 : CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ);
174 838014 : }
175 :
176 112510 : RPCArg(
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 56255 : : m_names{std::move(name)},
185 56255 : m_type{std::move(type)},
186 56255 : m_hidden{false},
187 56255 : m_inner{std::move(inner)},
188 56255 : m_fallback{std::move(fallback)},
189 56255 : m_description{std::move(description)},
190 56255 : m_oneline_description{std::move(oneline_description)},
191 56255 : m_type_str{std::move(type_str)}
192 56255 : {
193 56255 : CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ);
194 112510 : }
195 :
196 : bool IsOptional() const;
197 :
198 : /** Return the first of all aliases */
199 : std::string GetFirstName() const;
200 :
201 : /** Return the name, throws when there are aliases */
202 : std::string GetName() const;
203 :
204 : /**
205 : * Return the type string of the argument.
206 : * Set oneline to allow it to be overridden by a custom oneline type string (m_oneline_description).
207 : */
208 : std::string ToString(bool oneline) const;
209 : /**
210 : * Return the type string of the argument when it is in an object (dict).
211 : * Set oneline to get the oneline representation (less whitespace)
212 : */
213 : std::string ToStringObj(bool oneline) const;
214 : /**
215 : * Return the description string, including the argument type and whether
216 : * the argument is required.
217 : */
218 : std::string ToDescriptionString() const;
219 : };
220 :
221 37445595 : struct RPCResult {
222 : enum class Type {
223 : OBJ,
224 : ARR,
225 : STR,
226 : NUM,
227 : BOOL,
228 : NONE,
229 : STR_AMOUNT, //!< Special string to represent a floating point amount
230 : STR_HEX, //!< Special string with only hex chars
231 : OBJ_DYN, //!< Special dictionary with keys that are not literals
232 : ARR_FIXED, //!< Special array that has a fixed number of entries
233 : NUM_TIME, //!< Special numeric to denote unix epoch time
234 : ELISION, //!< Special type to denote elision (...)
235 : };
236 :
237 : const Type m_type;
238 : const std::string m_key_name; //!< Only used for dicts
239 : const std::vector<RPCResult> m_inner; //!< Only used for arrays or dicts
240 : const bool m_optional;
241 : const std::string m_description;
242 : const std::string m_cond;
243 :
244 67514 : RPCResult(
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 33757 : : m_type{std::move(type)},
252 33757 : m_key_name{std::move(m_key_name)},
253 33757 : m_inner{std::move(inner)},
254 33757 : m_optional{optional},
255 33757 : m_description{std::move(description)},
256 33757 : m_cond{std::move(cond)}
257 33757 : {
258 33757 : CHECK_NONFATAL(!m_cond.empty());
259 33757 : const bool inner_needed{type == Type::ARR || type == Type::ARR_FIXED || type == Type::OBJ || type == Type::OBJ_DYN};
260 33757 : CHECK_NONFATAL(inner_needed != inner.empty());
261 67514 : }
262 :
263 33757 : RPCResult(
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 33757 : : RPCResult{cond, type, m_key_name, false, description, inner} {}
270 :
271 2218126 : RPCResult(
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 1109063 : : m_type{std::move(type)},
278 1109063 : m_key_name{std::move(m_key_name)},
279 1109063 : m_inner{std::move(inner)},
280 1109063 : m_optional{optional},
281 1109063 : m_description{std::move(description)},
282 1109063 : m_cond{}
283 1109063 : {
284 1109063 : const bool inner_needed{type == Type::ARR || type == Type::ARR_FIXED || type == Type::OBJ || type == Type::OBJ_DYN};
285 1109063 : CHECK_NONFATAL(inner_needed != inner.empty());
286 2218126 : }
287 :
288 1047619 : RPCResult(
289 : const Type type,
290 : const std::string m_key_name,
291 : const std::string description,
292 : const std::vector<RPCResult> inner = {})
293 1047619 : : RPCResult{type, m_key_name, false, description, inner} {}
294 :
295 : /** Append the sections of the result. */
296 : void ToSections(Sections& sections, OuterType outer_type = OuterType::NONE, const int current_indent = 0) const;
297 : /** Return the type string of the result when it is in an object (dict). */
298 : std::string ToStringObj() const;
299 : /** Return the description string, including the result type. */
300 : std::string ToDescriptionString() const;
301 : };
302 :
303 1326594 : struct RPCResults {
304 : const std::vector<RPCResult> m_results;
305 :
306 309960 : RPCResults(RPCResult result)
307 154980 : : m_results{{result}}
308 154980 : {
309 309960 : }
310 :
311 34142 : RPCResults(std::initializer_list<RPCResult> results)
312 17071 : : m_results{results}
313 17071 : {
314 34142 : }
315 :
316 : /**
317 : * Return the description string.
318 : */
319 : std::string ToDescriptionString() const;
320 : };
321 :
322 1326594 : struct RPCExamples {
323 : const std::string m_examples;
324 344102 : explicit RPCExamples(
325 : std::string examples)
326 172051 : : m_examples(std::move(examples))
327 172051 : {
328 344102 : }
329 : std::string ToDescriptionString() const;
330 : };
331 :
332 344102 : class RPCHelpMan
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;
340 5179 : UniValue HandleRequest(const JSONRPCRequest& request)
341 : {
342 5179 : Check(request);
343 5179 : return m_fun(*this, request);
344 : }
345 : /** If the supplied number of args is neither too small nor too high */
346 : bool IsValidNumArgs(size_t num_args) const;
347 : /**
348 : * Check if the given request is valid according to this command or if
349 : * the user is asking for help information, and throw help when appropriate.
350 : */
351 78718 : inline void Check(const JSONRPCRequest& request) const {
352 78718 : if (request.fHelp || !IsValidNumArgs(request.params.size())) {
353 572 : throw std::runtime_error(ToString());
354 : }
355 78718 : }
356 :
357 : std::vector<std::string> GetArgNames() const;
358 :
359 : const std::string m_name;
360 :
361 : private:
362 : const RPCMethodImpl m_fun;
363 : const std::string m_description;
364 : const std::vector<RPCArg> m_args;
365 : const RPCResults m_results;
366 : const RPCExamples m_examples;
367 : };
368 :
369 : #endif // BITCOIN_RPC_UTIL_H
|