1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 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_RPCSERVER_H
7 #define BITCOIN_RPCSERVER_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 <boost/function.hpp>
19 
20 #include <univalue.h>
21 
22 static const unsigned int DEFAULT_RPC_SERIALIZE_VERSION = 1;
23 
24 class CRPCCommand;
25 
26 namespace RPCServer
27 {
28     void OnStarted(boost::function<void ()> slot);
29     void OnStopped(boost::function<void ()> slot);
30     void OnPreCommand(boost::function<void (const CRPCCommand&)> slot);
31     void OnPostCommand(boost::function<void (const CRPCCommand&)> slot);
32 }
33 
34 class CBlockIndex;
35 class CNetAddr;
36 
37 /** Wrapper for UniValue::VType, which includes typeAny:
38  * Used to denote don't care type. Only used by RPCTypeCheckObj */
39 struct UniValueType {
UniValueTypeUniValueType40     UniValueType(UniValue::VType _type) : typeAny(false), type(_type) {}
UniValueTypeUniValueType41     UniValueType() : typeAny(true) {}
42     bool typeAny;
43     UniValue::VType type;
44 };
45 
46 class JSONRequest
47 {
48 public:
49     UniValue id;
50     std::string strMethod;
51     UniValue params;
52 
JSONRequest()53     JSONRequest() { id = NullUniValue; }
54     void parse(const UniValue& valRequest);
55 };
56 
57 /** Query whether RPC is running */
58 bool IsRPCRunning();
59 
60 /**
61  * Set the RPC warmup status.  When this is done, all RPC calls will error out
62  * immediately with RPC_IN_WARMUP.
63  */
64 void SetRPCWarmupStatus(const std::string& newStatus);
65 /* Mark warmup as done.  RPC calls will be processed from now on.  */
66 void SetRPCWarmupFinished();
67 
68 /* returns the current warmup state.  */
69 bool RPCIsInWarmup(std::string *statusOut);
70 
71 /**
72  * Type-check arguments; throws JSONRPCError if wrong type given. Does not check that
73  * the right number of arguments are passed, just that any passed are the correct type.
74  */
75 void RPCTypeCheck(const UniValue& params,
76                   const std::list<UniValue::VType>& typesExpected, bool fAllowNull=false);
77 
78 /*
79   Check for expected keys/value types in an Object.
80 */
81 void RPCTypeCheckObj(const UniValue& o,
82     const std::map<std::string, UniValueType>& typesExpected,
83     bool fAllowNull = false,
84     bool fStrict = false);
85 
86 /** Opaque base class for timers returned by NewTimerFunc.
87  * This provides no methods at the moment, but makes sure that delete
88  * cleans up the whole state.
89  */
90 class RPCTimerBase
91 {
92 public:
~RPCTimerBase()93     virtual ~RPCTimerBase() {}
94 };
95 
96 /**
97  * RPC timer "driver".
98  */
99 class RPCTimerInterface
100 {
101 public:
~RPCTimerInterface()102     virtual ~RPCTimerInterface() {}
103     /** Implementation name */
104     virtual const char *Name() = 0;
105     /** Factory function for timers.
106      * RPC will call the function to create a timer that will call func in *millis* milliseconds.
107      * @note As the RPC mechanism is backend-neutral, it can use different implementations of timers.
108      * This is needed to cope with the case in which there is no HTTP server, but
109      * only GUI RPC console, and to break the dependency of pcserver on httprpc.
110      */
111     virtual RPCTimerBase* NewTimer(boost::function<void(void)>& func, int64_t millis) = 0;
112 };
113 
114 /** Set the factory function for timers */
115 void RPCSetTimerInterface(RPCTimerInterface *iface);
116 /** Set the factory function for timer, but only, if unset */
117 void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface);
118 /** Unset factory function for timers */
119 void RPCUnsetTimerInterface(RPCTimerInterface *iface);
120 
121 /**
122  * Run func nSeconds from now.
123  * Overrides previous timer <name> (if any).
124  */
125 void RPCRunLater(const std::string& name, boost::function<void(void)> func, int64_t nSeconds);
126 
127 typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp);
128 
129 class CRPCCommand
130 {
131 public:
132     std::string category;
133     std::string name;
134     rpcfn_type actor;
135     bool okSafeMode;
136 };
137 
138 /**
139  * Bitcoin RPC command dispatcher.
140  */
141 class CRPCTable
142 {
143 private:
144     std::map<std::string, const CRPCCommand*> mapCommands;
145 public:
146     CRPCTable();
147     const CRPCCommand* operator[](const std::string& name) const;
148     std::string help(const std::string& name) const;
149 
150     /**
151      * Execute a method.
152      * @param method   Method to execute
153      * @param params   UniValue Array of arguments (JSON objects)
154      * @returns Result of the call.
155      * @throws an exception (UniValue) when an error happens.
156      */
157     UniValue execute(const std::string &method, const UniValue &params) const;
158 
159     /**
160     * Returns a list of registered commands
161     * @returns List of registered commands.
162     */
163     std::vector<std::string> listCommands() const;
164 
165 
166     /**
167      * Appends a CRPCCommand to the dispatch table.
168      * Returns false if RPC server is already running (dump concurrency protection).
169      * Commands cannot be overwritten (returns false).
170      */
171     bool appendCommand(const std::string& name, const CRPCCommand* pcmd);
172 };
173 
174 extern CRPCTable tableRPC;
175 
176 /**
177  * Utilities: convert hex-encoded Values
178  * (throws error if not hex).
179  */
180 extern uint256 ParseHashV(const UniValue& v, std::string strName);
181 extern uint256 ParseHashO(const UniValue& o, std::string strKey);
182 extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
183 extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
184 
185 extern int64_t nWalletUnlockTime;
186 extern CAmount AmountFromValue(const UniValue& value);
187 extern UniValue ValueFromAmount(const CAmount& amount);
188 extern double GetDifficulty(const CBlockIndex* blockindex = NULL);
189 extern std::string HelpRequiringPassphrase();
190 extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
191 extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);
192 
193 extern void EnsureWalletIsUnlocked();
194 
195 bool StartRPC();
196 void InterruptRPC();
197 void StopRPC();
198 std::string JSONRPCExecBatch(const UniValue& vReq);
199 
200 // Retrieves any serialization flags requested in command line argument
201 int RPCSerializationFlags();
202 
203 #endif // BITCOIN_RPCSERVER_H
204