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