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