1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #ifndef BITCOIN_RPC_SERVER_H
7 #define BITCOIN_RPC_SERVER_H
8 
9 #include <amount.h>
10 #include <rpc/protocol.h>
11 #include <uint256.h>
12 
13 #include <list>
14 #include <map>
15 #include <stdint.h>
16 #include <string>
17 
18 #include <univalue.h>
19 
20 static const unsigned int DEFAULT_RPC_SERIALIZE_VERSION = 1;
21 
22 class CRPCCommand;
23 
24 namespace RPCServer
25 {
26     void OnStarted(std::function<void ()> slot);
27     void OnStopped(std::function<void ()> slot);
28 }
29 
30 /** Wrapper for UniValue::VType, which includes typeAny:
31  * Used to denote don't care type. */
32 struct UniValueType {
UniValueTypeUniValueType33     UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
UniValueTypeUniValueType34     UniValueType() : typeAny(true) {}
35     bool typeAny;
36     UniValue::VType type;
37 };
38 
39 class JSONRPCRequest
40 {
41 public:
42     UniValue id;
43     std::string strMethod;
44     UniValue params;
45     bool fHelp;
46     std::string URI;
47     std::string authUser;
48     std::string peerAddr;
49 
JSONRPCRequest()50     JSONRPCRequest() : id(NullUniValue), params(NullUniValue), fHelp(false) {}
51     void parse(const UniValue& valRequest);
52 };
53 
54 /** Query whether RPC is running */
55 bool IsRPCRunning();
56 
57 /**
58  * Set the RPC warmup status.  When this is done, all RPC calls will error out
59  * immediately with RPC_IN_WARMUP.
60  */
61 void SetRPCWarmupStatus(const std::string& newStatus);
62 /* Mark warmup as done.  RPC calls will be processed from now on.  */
63 void SetRPCWarmupFinished();
64 
65 /* returns the current warmup state.  */
66 bool RPCIsInWarmup(std::string *outStatus);
67 
68 /**
69  * Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
70  * the right number of arguments are passed, just that any passed are the correct type.
71  */
72 void RPCTypeCheck(const UniValue& params,
73                   const std::list<UniValueType>& typesExpected, bool fAllowNull=false);
74 
75 /**
76  * Type-check one argument; throws JSONRPCError if wrong type given.
77  */
78 void RPCTypeCheckArgument(const UniValue& value, const UniValueType& typeExpected);
79 
80 /*
81   Check for expected keys/value types in an Object.
82 */
83 void RPCTypeCheckObj(const UniValue& o,
84     const std::map<std::string, UniValueType>& typesExpected,
85     bool fAllowNull = false,
86     bool fStrict = false);
87 
88 /** Opaque base class for timers returned by NewTimerFunc.
89  * This provides no methods at the moment, but makes sure that delete
90  * cleans up the whole state.
91  */
92 class RPCTimerBase
93 {
94 public:
~RPCTimerBase()95     virtual ~RPCTimerBase() {}
96 };
97 
98 /**
99  * RPC timer "driver".
100  */
101 class RPCTimerInterface
102 {
103 public:
~RPCTimerInterface()104     virtual ~RPCTimerInterface() {}
105     /** Implementation name */
106     virtual const char *Name() = 0;
107     /** Factory function for timers.
108      * RPC will call the function to create a timer that will call func in *millis* milliseconds.
109      * @note As the RPC mechanism is backend-neutral, it can use different implementations of timers.
110      * This is needed to cope with the case in which there is no HTTP server, but
111      * only GUI RPC console, and to break the dependency of pcserver on httprpc.
112      */
113     virtual RPCTimerBase* NewTimer(std::function<void()>& func, int64_t millis) = 0;
114 };
115 
116 /** Set the factory function for timers */
117 void RPCSetTimerInterface(RPCTimerInterface *iface);
118 /** Set the factory function for timer, but only, if unset */
119 void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface);
120 /** Unset factory function for timers */
121 void RPCUnsetTimerInterface(RPCTimerInterface *iface);
122 
123 /**
124  * Run func nSeconds from now.
125  * Overrides previous timer <name> (if any).
126  */
127 void RPCRunLater(const std::string& name, std::function<void()> func, int64_t nSeconds);
128 
129 typedef UniValue(*rpcfn_type)(const JSONRPCRequest& jsonRequest);
130 
131 class CRPCCommand
132 {
133 public:
134     std::string category;
135     std::string name;
136     rpcfn_type actor;
137     std::vector<std::string> argNames;
138 };
139 
140 /**
141  * Bitcoin RPC command dispatcher.
142  */
143 class CRPCTable
144 {
145 private:
146     std::map<std::string, const CRPCCommand*> mapCommands;
147 public:
148     CRPCTable();
149     const CRPCCommand* operator[](const std::string& name) const;
150     std::string help(const std::string& name, const JSONRPCRequest& helpreq) const;
151 
152     /**
153      * Execute a method.
154      * @param request The JSONRPCRequest to execute
155      * @returns Result of the call.
156      * @throws an exception (UniValue) when an error happens.
157      */
158     UniValue execute(const JSONRPCRequest &request) const;
159 
160     /**
161     * Returns a list of registered commands
162     * @returns List of registered commands.
163     */
164     std::vector<std::string> listCommands() const;
165 
166 
167     /**
168      * Appends a CRPCCommand to the dispatch table.
169      *
170      * Returns false if RPC server is already running (dump concurrency protection).
171      *
172      * Commands cannot be overwritten (returns false).
173      *
174      * Commands with different method names but the same callback function will
175      * be considered aliases, and only the first registered method name will
176      * show up in the help text command listing. Aliased commands do not have
177      * to have the same behavior. Server and client code can distinguish
178      * between calls based on method name, and aliased commands can also
179      * register different names, types, and numbers of parameters.
180      */
181     bool appendCommand(const std::string& name, const CRPCCommand* pcmd);
182 };
183 
184 bool IsDeprecatedRPCEnabled(const std::string& method);
185 
186 extern CRPCTable tableRPC;
187 
188 /**
189  * Utilities: convert hex-encoded Values
190  * (throws error if not hex).
191  */
192 extern uint256 ParseHashV(const UniValue& v, std::string strName);
193 extern uint256 ParseHashO(const UniValue& o, std::string strKey);
194 extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
195 extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
196 
197 extern CAmount AmountFromValue(const UniValue& value);
198 extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
199 extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
200 
201 void StartRPC();
202 void InterruptRPC();
203 void StopRPC();
204 std::string JSONRPCExecBatch(const JSONRPCRequest& jreq, const UniValue& vReq);
205 
206 // Retrieves any serialization flags requested in command line argument
207 int RPCSerializationFlags();
208 
209 #endif // BITCOIN_RPC_SERVER_H
210