LCOV - code coverage report
Current view: top level - src/rpc - util.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 76 76 100.0 %
Date: 2020-09-26 01:30:44 Functions: 42 42 100.0 %

          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

Generated by: LCOV version 1.15