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