1 // Copyright (c) 2017-2019 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/transaction.h> 9 #include <outputtype.h> 10 #include <pubkey.h> 11 #include <rpc/protocol.h> 12 #include <script/standard.h> 13 #include <univalue.h> 14 15 #include <string> 16 #include <vector> 17 18 #include <boost/variant.hpp> 19 20 class CKeyStore; 21 class CPubKey; 22 class CScript; 23 struct InitInterfaces; 24 25 //! Pointers to interfaces that need to be accessible from RPC methods. Due to 26 //! limitations of the RPC framework, there's currently no direct way to pass in 27 //! state to RPC method implementations. 28 extern InitInterfaces* g_rpc_interfaces; 29 30 CPubKey HexToPubKey(const std::string& hex_in); 31 CPubKey AddrToPubKey(CKeyStore* const keystore, const std::string& addr_in); 32 CTxDestination AddAndGetMultisigDestination(const int required, const std::vector<CPubKey>& pubkeys, OutputType type, CKeyStore& keystore, CScript& script_out); 33 34 UniValue DescribeAddress(const CTxDestination& dest); 35 36 //! Parse a confirm target option and raise an RPC error if it is invalid. 37 unsigned int ParseConfirmTarget(const UniValue& value); 38 39 RPCErrorCode RPCErrorFromTransactionError(TransactionError terr); 40 UniValue JSONRPCTransactionError(TransactionError terr, const std::string& err_string = ""); 41 42 //! Parse a JSON range specified as int64, or [int64, int64] 43 std::pair<int64_t, int64_t> ParseRange(const UniValue& value); 44 45 struct RPCArg { 46 enum class Type { 47 OBJ, 48 ARR, 49 STR, 50 NUM, 51 BOOL, 52 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 53 AMOUNT, //!< Special type representing a floating point amount (can be either NUM or STR) 54 STR_HEX, //!< Special type that is a STR with only hex chars 55 RANGE, //!< Special type that is a NUM or [NUM,NUM] 56 }; 57 58 enum class Optional { 59 /** Required arg */ 60 NO, 61 /** 62 * Optional arg that is a named argument and has a default value of 63 * `null`. When possible, the default value should be specified. 64 */ 65 OMITTED_NAMED_ARG, 66 /** 67 * Optional argument with default value omitted because they are 68 * implicitly clear. That is, elements in an array or object may not 69 * exist by default. 70 * When possible, the default value should be specified. 71 */ 72 OMITTED, 73 }; 74 using Fallback = boost::variant<Optional, /* default value for optional args */ std::string>; 75 const std::string m_name; //!< The name of the arg (can be empty for inner args) 76 const Type m_type; 77 const std::vector<RPCArg> m_inner; //!< Only used for arrays or dicts 78 const Fallback m_fallback; 79 const std::string m_description; 80 const std::string m_oneline_description; //!< Should be empty unless it is supposed to override the auto-generated summary line 81 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. 82 83 RPCArg( 84 const std::string& name, 85 const Type& type, 86 const Fallback& fallback, 87 const std::string& description, 88 const std::string& oneline_description = "", 89 const std::vector<std::string>& type_str = {}) 90 : m_name{name}, 91 m_type{type}, 92 m_fallback{fallback}, 93 m_description{description}, 94 m_oneline_description{oneline_description}, 95 m_type_str{type_str} 96 { 97 assert(type != Type::ARR && type != Type::OBJ); 98 } 99 100 RPCArg( 101 const std::string& name, 102 const Type& type, 103 const Fallback& fallback, 104 const std::string& description, 105 const std::vector<RPCArg>& inner, 106 const std::string& oneline_description = "", 107 const std::vector<std::string>& type_str = {}) 108 : m_name{name}, 109 m_type{type}, 110 m_inner{inner}, 111 m_fallback{fallback}, 112 m_description{description}, 113 m_oneline_description{oneline_description}, 114 m_type_str{type_str} 115 { 116 assert(type == Type::ARR || type == Type::OBJ); 117 } 118 119 bool IsOptional() const; 120 121 /** 122 * Return the type string of the argument. 123 * Set oneline to allow it to be overridden by a custom oneline type string (m_oneline_description). 124 */ 125 std::string ToString(bool oneline) const; 126 /** 127 * Return the type string of the argument when it is in an object (dict). 128 * Set oneline to get the oneline representation (less whitespace) 129 */ 130 std::string ToStringObj(bool oneline) const; 131 /** 132 * Return the description string, including the argument type and whether 133 * the argument is required. 134 */ 135 std::string ToDescriptionString() const; 136 }; 137 138 struct RPCResult { 139 const std::string m_cond; 140 const std::string m_result; 141 RPCResultRPCResult142 explicit RPCResult(std::string result) 143 : m_cond{}, m_result{std::move(result)} 144 { 145 assert(!m_result.empty()); 146 } 147 RPCResultRPCResult148 RPCResult(std::string cond, std::string result) 149 : m_cond{std::move(cond)}, m_result{std::move(result)} 150 { 151 assert(!m_cond.empty()); 152 assert(!m_result.empty()); 153 } 154 }; 155 156 struct RPCResults { 157 const std::vector<RPCResult> m_results; 158 RPCResultsRPCResults159 RPCResults() 160 : m_results{} 161 { 162 } 163 RPCResultsRPCResults164 RPCResults(RPCResult result) 165 : m_results{{result}} 166 { 167 } 168 RPCResultsRPCResults169 RPCResults(std::initializer_list<RPCResult> results) 170 : m_results{results} 171 { 172 } 173 174 /** 175 * Return the description string. 176 */ 177 std::string ToDescriptionString() const; 178 }; 179 180 struct RPCExamples { 181 const std::string m_examples; RPCExamplesRPCExamples182 RPCExamples( 183 std::string examples) 184 : m_examples(std::move(examples)) 185 { 186 } 187 std::string ToDescriptionString() const; 188 }; 189 190 class RPCHelpMan 191 { 192 public: 193 RPCHelpMan(std::string name, std::string description, std::vector<RPCArg> args, RPCResults results, RPCExamples examples); 194 195 std::string ToString() const; 196 /** If the supplied number of args is neither too small nor too high */ 197 bool IsValidNumArgs(size_t num_args) const; 198 199 private: 200 const std::string m_name; 201 const std::string m_description; 202 const std::vector<RPCArg> m_args; 203 const RPCResults m_results; 204 const RPCExamples m_examples; 205 }; 206 207 #endif // BITCOIN_RPC_UTIL_H 208