Branch data Line data Source code
# 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 : :
# 25 : : /**
# 26 : : * String used to describe UNIX epoch time in documentation, factored out to a
# 27 : : * constant for consistency.
# 28 : : */
# 29 : : extern const std::string UNIX_EPOCH_TIME;
# 30 : :
# 31 : : /**
# 32 : : * Example bech32 addresses for the RPCExamples help documentation. They are intentionally
# 33 : : * invalid to prevent accidental transactions by users.
# 34 : : */
# 35 : : extern const std::string EXAMPLE_ADDRESS[2];
# 36 : :
# 37 : : class FillableSigningProvider;
# 38 : : class CPubKey;
# 39 : : class CScript;
# 40 : : struct Sections;
# 41 : :
# 42 : : /**
# 43 : : * Gets all existing output types formatted for RPC help sections.
# 44 : : *
# 45 : : * @return Comma separated string representing output type names.
# 46 : : */
# 47 : : std::string GetAllOutputTypes();
# 48 : :
# 49 : : /** Wrapper for UniValue::VType, which includes typeAny:
# 50 : : * Used to denote don't care type. */
# 51 : : struct UniValueType {
# 52 : 54587 : UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
# 53 : 20966 : UniValueType() : typeAny(true) {}
# 54 : : bool typeAny;
# 55 : : UniValue::VType type;
# 56 : : };
# 57 : :
# 58 : : /**
# 59 : : * Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
# 60 : : * the right number of arguments are passed, just that any passed are the correct type.
# 61 : : */
# 62 : : void RPCTypeCheck(const UniValue& params,
# 63 : : const std::list<UniValueType>& typesExpected, bool fAllowNull=false);
# 64 : :
# 65 : : /**
# 66 : : * Type-check one argument; throws JSONRPCError if wrong type given.
# 67 : : */
# 68 : : void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected);
# 69 : :
# 70 : : /*
# 71 : : Check for expected keys/value types in an Object.
# 72 : : */
# 73 : : void RPCTypeCheckObj(const UniValue& o,
# 74 : : const std::map<std::string, UniValueType>& typesExpected,
# 75 : : bool fAllowNull = false,
# 76 : : bool fStrict = false);
# 77 : :
# 78 : : /**
# 79 : : * Utilities: convert hex-encoded Values
# 80 : : * (throws error if not hex).
# 81 : : */
# 82 : : uint256 ParseHashV(const UniValue& v, std::string strName);
# 83 : : uint256 ParseHashO(const UniValue& o, std::string strKey);
# 84 : : std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
# 85 : : std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
# 86 : :
# 87 : : /**
# 88 : : * Validate and return a CAmount from a UniValue number or string.
# 89 : : *
# 90 : : * @param[in] value UniValue number or string to parse.
# 91 : : * @param[in] decimals Number of significant digits (default: 8).
# 92 : : * @returns a CAmount if the various checks pass.
# 93 : : */
# 94 : : CAmount AmountFromValue(const UniValue& value, int decimals = 8);
# 95 : :
# 96 : : using RPCArgList = std::vector<std::pair<std::string, UniValue>>;
# 97 : : std::string HelpExampleCli(const std::string& methodname, const std::string& args);
# 98 : : std::string HelpExampleCliNamed(const std::string& methodname, const RPCArgList& args);
# 99 : : std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
# 100 : : std::string HelpExampleRpcNamed(const std::string& methodname, const RPCArgList& args);
# 101 : :
# 102 : : CPubKey HexToPubKey(const std::string& hex_in);
# 103 : : CPubKey AddrToPubKey(const FillableSigningProvider& keystore, const std::string& addr_in);
# 104 : : CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, FillableSigningProvider& keystore, CScript& script_out);
# 105 : :
# 106 : : UniValue DescribeAddress(const CTxDestination& dest);
# 107 : :
# 108 : : //! Parse a confirm target option and raise an RPC error if it is invalid.
# 109 : : unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target);
# 110 : :
# 111 : : RPCErrorCode RPCErrorFromTransactionError(TransactionError terr);
# 112 : : UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string = "");
# 113 : :
# 114 : : //! Parse a JSON range specified as int64, or [int64, int64]
# 115 : : std::pair<int64_t, int64_t> ParseDescriptorRange(const UniValue& value);
# 116 : :
# 117 : : /** Evaluate a descriptor given as a string, or as a {"desc":...,"range":...} object, with default range of 1000. */
# 118 : : std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, FlatSigningProvider& provider);
# 119 : :
# 120 : : /** Returns, given services flags, a list of humanly readable (known) network services */
# 121 : : UniValue GetServicesNames(ServiceFlags services);
# 122 : :
# 123 : : /**
# 124 : : * Serializing JSON objects depends on the outer type. Only arrays and
# 125 : : * dictionaries can be nested in json. The top-level outer type is "NONE".
# 126 : : */
# 127 : : enum class OuterType {
# 128 : : ARR,
# 129 : : OBJ,
# 130 : : NONE, // Only set on first recursion
# 131 : : };
# 132 : :
# 133 : : struct RPCArg {
# 134 : : enum class Type {
# 135 : : OBJ,
# 136 : : ARR,
# 137 : : STR,
# 138 : : NUM,
# 139 : : BOOL,
# 140 : : 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
# 141 : : AMOUNT, //!< Special type representing a floating point amount (can be either NUM or STR)
# 142 : : STR_HEX, //!< Special type that is a STR with only hex chars
# 143 : : RANGE, //!< Special type that is a NUM or [NUM,NUM]
# 144 : : };
# 145 : :
# 146 : : enum class Optional {
# 147 : : /** Required arg */
# 148 : : NO,
# 149 : : /**
# 150 : : * Optional arg that is a named argument and has a default value of
# 151 : : * `null`. When possible, the default value should be specified.
# 152 : : */
# 153 : : OMITTED_NAMED_ARG,
# 154 : : /**
# 155 : : * Optional argument with default value omitted because they are
# 156 : : * implicitly clear. That is, elements in an array or object may not
# 157 : : * exist by default.
# 158 : : * When possible, the default value should be specified.
# 159 : : */
# 160 : : OMITTED,
# 161 : : };
# 162 : : using DefaultHint = std::string;
# 163 : : using Default = UniValue;
# 164 : : using Fallback = std::variant<Optional, /* hint for default value */ DefaultHint, /* default constant value */ Default>;
# 165 : : 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)
# 166 : : const Type m_type;
# 167 : : const bool m_hidden;
# 168 : : const std::vector<RPCArg> m_inner; //!< Only used for arrays or dicts
# 169 : : const Fallback m_fallback;
# 170 : : const std::string m_description;
# 171 : : const std::string m_oneline_description; //!< Should be empty unless it is supposed to override the auto-generated summary line
# 172 : : 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.
# 173 : :
# 174 : : RPCArg(
# 175 : : const std::string name,
# 176 : : const Type type,
# 177 : : const Fallback fallback,
# 178 : : const std::string description,
# 179 : : const std::string oneline_description = "",
# 180 : : const std::vector<std::string> type_str = {},
# 181 : : const bool hidden = false)
# 182 : : : m_names{std::move(name)},
# 183 : : m_type{std::move(type)},
# 184 : : m_hidden{hidden},
# 185 : : m_fallback{std::move(fallback)},
# 186 : : m_description{std::move(description)},
# 187 : : m_oneline_description{std::move(oneline_description)},
# 188 : : m_type_str{std::move(type_str)}
# 189 : 993256 : {
# 190 [ + - ][ + - ]: 993256 : CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ && type != Type::OBJ_USER_KEYS);
# [ + - ]
# 191 : 993256 : }
# 192 : :
# 193 : : RPCArg(
# 194 : : const std::string name,
# 195 : : const Type type,
# 196 : : const Fallback fallback,
# 197 : : const std::string description,
# 198 : : const std::vector<RPCArg> inner,
# 199 : : const std::string oneline_description = "",
# 200 : : const std::vector<std::string> type_str = {})
# 201 : : : m_names{std::move(name)},
# 202 : : m_type{std::move(type)},
# 203 : : m_hidden{false},
# 204 : : m_inner{std::move(inner)},
# 205 : : m_fallback{std::move(fallback)},
# 206 : : m_description{std::move(description)},
# 207 : : m_oneline_description{std::move(oneline_description)},
# 208 : : m_type_str{std::move(type_str)}
# 209 : 160799 : {
# 210 [ + + ][ + + ]: 160799 : CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ || type == Type::OBJ_USER_KEYS);
# [ + - ]
# 211 : 160799 : }
# 212 : :
# 213 : : bool IsOptional() const;
# 214 : :
# 215 : : /** Return the first of all aliases */
# 216 : : std::string GetFirstName() const;
# 217 : :
# 218 : : /** Return the name, throws when there are aliases */
# 219 : : std::string GetName() const;
# 220 : :
# 221 : : /**
# 222 : : * Return the type string of the argument.
# 223 : : * Set oneline to allow it to be overridden by a custom oneline type string (m_oneline_description).
# 224 : : */
# 225 : : std::string ToString(bool oneline) const;
# 226 : : /**
# 227 : : * Return the type string of the argument when it is in an object (dict).
# 228 : : * Set oneline to get the oneline representation (less whitespace)
# 229 : : */
# 230 : : std::string ToStringObj(bool oneline) const;
# 231 : : /**
# 232 : : * Return the description string, including the argument type and whether
# 233 : : * the argument is required.
# 234 : : */
# 235 : : std::string ToDescriptionString() const;
# 236 : : };
# 237 : :
# 238 : : struct RPCResult {
# 239 : : enum class Type {
# 240 : : OBJ,
# 241 : : ARR,
# 242 : : STR,
# 243 : : NUM,
# 244 : : BOOL,
# 245 : : NONE,
# 246 : : ANY, //!< Special type to disable type checks (for testing only)
# 247 : : STR_AMOUNT, //!< Special string to represent a floating point amount
# 248 : : STR_HEX, //!< Special string with only hex chars
# 249 : : OBJ_DYN, //!< Special dictionary with keys that are not literals
# 250 : : ARR_FIXED, //!< Special array that has a fixed number of entries
# 251 : : NUM_TIME, //!< Special numeric to denote unix epoch time
# 252 : : ELISION, //!< Special type to denote elision (...)
# 253 : : };
# 254 : :
# 255 : : const Type m_type;
# 256 : : const std::string m_key_name; //!< Only used for dicts
# 257 : : const std::vector<RPCResult> m_inner; //!< Only used for arrays or dicts
# 258 : : const bool m_optional;
# 259 : : const bool m_skip_type_check;
# 260 : : const std::string m_description;
# 261 : : const std::string m_cond;
# 262 : :
# 263 : : RPCResult(
# 264 : : const std::string cond,
# 265 : : const Type type,
# 266 : : const std::string m_key_name,
# 267 : : const bool optional,
# 268 : : const std::string description,
# 269 : : const std::vector<RPCResult> inner = {})
# 270 : : : m_type{std::move(type)},
# 271 : : m_key_name{std::move(m_key_name)},
# 272 : : m_inner{std::move(inner)},
# 273 : : m_optional{optional},
# 274 : : m_skip_type_check{false},
# 275 : : m_description{std::move(description)},
# 276 : : m_cond{std::move(cond)}
# 277 : 118521 : {
# 278 [ - + ]: 118521 : CHECK_NONFATAL(!m_cond.empty());
# 279 : 118521 : CheckInnerDoc();
# 280 : 118521 : }
# 281 : :
# 282 : : RPCResult(
# 283 : : const std::string cond,
# 284 : : const Type type,
# 285 : : const std::string m_key_name,
# 286 : : const std::string description,
# 287 : : const std::vector<RPCResult> inner = {})
# 288 : 118521 : : RPCResult{cond, type, m_key_name, false, description, inner} {}
# 289 : :
# 290 : : RPCResult(
# 291 : : const Type type,
# 292 : : const std::string m_key_name,
# 293 : : const bool optional,
# 294 : : const std::string description,
# 295 : : const std::vector<RPCResult> inner = {},
# 296 : : bool skip_type_check = false)
# 297 : : : m_type{std::move(type)},
# 298 : : m_key_name{std::move(m_key_name)},
# 299 : : m_inner{std::move(inner)},
# 300 : : m_optional{optional},
# 301 : : m_skip_type_check{skip_type_check},
# 302 : : m_description{std::move(description)},
# 303 : : m_cond{}
# 304 : 3130485 : {
# 305 : 3130485 : CheckInnerDoc();
# 306 : 3130485 : }
# 307 : :
# 308 : : RPCResult(
# 309 : : const Type type,
# 310 : : const std::string m_key_name,
# 311 : : const std::string description,
# 312 : : const std::vector<RPCResult> inner = {},
# 313 : : bool skip_type_check = false)
# 314 : 2404187 : : RPCResult{type, m_key_name, false, description, inner, skip_type_check} {}
# 315 : :
# 316 : : /** Append the sections of the result. */
# 317 : : void ToSections(Sections& sections, OuterType outer_type = OuterType::NONE, const int current_indent = 0) const;
# 318 : : /** Return the type string of the result when it is in an object (dict). */
# 319 : : std::string ToStringObj() const;
# 320 : : /** Return the description string, including the result type. */
# 321 : : std::string ToDescriptionString() const;
# 322 : : /** Check whether the result JSON type matches. */
# 323 : : bool MatchesType(const UniValue& result) const;
# 324 : :
# 325 : : private:
# 326 : : void CheckInnerDoc() const;
# 327 : : };
# 328 : :
# 329 : : struct RPCResults {
# 330 : : const std::vector<RPCResult> m_results;
# 331 : :
# 332 : : RPCResults(RPCResult result)
# 333 : : : m_results{{result}}
# 334 : 342914 : {
# 335 : 342914 : }
# 336 : :
# 337 : : RPCResults(std::initializer_list<RPCResult> results)
# 338 : : : m_results{results}
# 339 : 50810 : {
# 340 : 50810 : }
# 341 : :
# 342 : : /**
# 343 : : * Return the description string.
# 344 : : */
# 345 : : std::string ToDescriptionString() const;
# 346 : : };
# 347 : :
# 348 : : struct RPCExamples {
# 349 : : const std::string m_examples;
# 350 : : explicit RPCExamples(
# 351 : : std::string examples)
# 352 : : : m_examples(std::move(examples))
# 353 : 393724 : {
# 354 : 393724 : }
# 355 : : std::string ToDescriptionString() const;
# 356 : : };
# 357 : :
# 358 : : class RPCHelpMan
# 359 : : {
# 360 : : public:
# 361 : : RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples);
# 362 : : using RPCMethodImpl = std::function<UniValue(const RPCHelpMan&, const JSONRPCRequest&)>;
# 363 : : RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples, RPCMethodImpl fun);
# 364 : :
# 365 : : UniValue HandleRequest(const JSONRPCRequest& request) const;
# 366 : : std::string ToString() const;
# 367 : : /** Return the named args that need to be converted from string to another JSON type */
# 368 : : UniValue GetArgMap() const;
# 369 : : /** If the supplied number of args is neither too small nor too high */
# 370 : : bool IsValidNumArgs(size_t num_args) const;
# 371 : : std::vector<std::string> GetArgNames() const;
# 372 : :
# 373 : : const std::string m_name;
# 374 : :
# 375 : : private:
# 376 : : const RPCMethodImpl m_fun;
# 377 : : const std::string m_description;
# 378 : : const std::vector<RPCArg> m_args;
# 379 : : const RPCResults m_results;
# 380 : : const RPCExamples m_examples;
# 381 : : };
# 382 : :
# 383 : : #endif // BITCOIN_RPC_UTIL_H
|