Line data Source code
1 : // Copyright (c) 2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2021 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 <rpc/request.h> 10 : #include <rpc/util.h> 11 : 12 : #include <functional> 13 : #include <map> 14 : #include <stdint.h> 15 : #include <string> 16 : 17 : #include <univalue.h> 18 : 19 : static const unsigned int DEFAULT_RPC_SERIALIZE_VERSION = 1; 20 : 21 : class CRPCCommand; 22 : 23 : namespace RPCServer 24 : { 25 : void OnStarted(std::function<void ()> slot); 26 : void OnStopped(std::function<void ()> slot); 27 : } 28 : 29 : /** Query whether RPC is running */ 30 : bool IsRPCRunning(); 31 : 32 : /** Throw JSONRPCError if RPC is not running */ 33 : void RpcInterruptionPoint(); 34 : 35 : /** 36 : * Set the RPC warmup status. When this is done, all RPC calls will error out 37 : * immediately with RPC_IN_WARMUP. 38 : */ 39 : void SetRPCWarmupStatus(const std::string& newStatus); 40 : /* Mark warmup as done. RPC calls will be processed from now on. */ 41 : void SetRPCWarmupFinished(); 42 : 43 : /* returns the current warmup state. */ 44 : bool RPCIsInWarmup(std::string *outStatus); 45 : 46 : /** Opaque base class for timers returned by NewTimerFunc. 47 : * This provides no methods at the moment, but makes sure that delete 48 : * cleans up the whole state. 49 : */ 50 : class RPCTimerBase 51 : { 52 : public: 53 0 : virtual ~RPCTimerBase() {} 54 : }; 55 : 56 : /** 57 : * RPC timer "driver". 58 : */ 59 : class RPCTimerInterface 60 : { 61 : public: 62 0 : virtual ~RPCTimerInterface() {} 63 : /** Implementation name */ 64 : virtual const char *Name() = 0; 65 : /** Factory function for timers. 66 : * RPC will call the function to create a timer that will call func in *millis* milliseconds. 67 : * @note As the RPC mechanism is backend-neutral, it can use different implementations of timers. 68 : * This is needed to cope with the case in which there is no HTTP server, but 69 : * only GUI RPC console, and to break the dependency of pcserver on httprpc. 70 : */ 71 : virtual RPCTimerBase* NewTimer(std::function<void()>& func, int64_t millis) = 0; 72 : }; 73 : 74 : /** Set the factory function for timers */ 75 : void RPCSetTimerInterface(RPCTimerInterface *iface); 76 : /** Set the factory function for timer, but only, if unset */ 77 : void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface); 78 : /** Unset factory function for timers */ 79 : void RPCUnsetTimerInterface(RPCTimerInterface *iface); 80 : 81 : /** 82 : * Run func nSeconds from now. 83 : * Overrides previous timer <name> (if any). 84 : */ 85 : void RPCRunLater(const std::string& name, std::function<void()> func, int64_t nSeconds); 86 : 87 : typedef RPCHelpMan (*RpcMethodFnType)(); 88 : 89 0 : class CRPCCommand 90 : { 91 : public: 92 : //! RPC method handler reading request and assigning result. Should return 93 : //! true if request is fully handled, false if it should be passed on to 94 : //! subsequent handlers. 95 : using Actor = std::function<bool(const JSONRPCRequest& request, UniValue& result, bool last_handler)>; 96 : 97 : //! Constructor taking Actor callback supporting multiple handlers. 98 107 : CRPCCommand(std::string category, std::string name, Actor actor, std::vector<std::pair<std::string, bool>> args, intptr_t unique_id) 99 107 : : category(std::move(category)), name(std::move(name)), actor(std::move(actor)), argNames(std::move(args)), 100 107 : unique_id(unique_id) 101 : { 102 107 : } 103 : 104 : //! Simplified constructor taking plain RpcMethodFnType function pointer. 105 107 : CRPCCommand(std::string category, RpcMethodFnType fn) 106 107 : : CRPCCommand( 107 107 : category, 108 107 : fn().m_name, 109 107 : [fn](const JSONRPCRequest& request, UniValue& result, bool) { result = fn().HandleRequest(request); return true; }, 110 107 : fn().GetArgNames(), 111 107 : intptr_t(fn)) 112 : { 113 107 : } 114 : 115 : std::string category; 116 : std::string name; 117 : Actor actor; 118 : //! List of method arguments and whether they are named-only. Incoming RPC 119 : //! requests contain a "params" field that can either be an array containing 120 : //! unnamed arguments or an object containing named arguments. The 121 : //! "argNames" vector is used in the latter case to transform the params 122 : //! object into an array. Each argument in "argNames" gets mapped to a 123 : //! unique position in the array, based on the order it is listed, unless 124 : //! the argument is a named-only argument with argNames[x].second set to 125 : //! true. Named-only arguments are combined into a JSON object that is 126 : //! appended after other arguments, see transformNamedArguments for details. 127 : std::vector<std::pair<std::string, bool>> argNames; 128 : intptr_t unique_id; 129 : }; 130 : 131 : /** 132 : * RPC command dispatcher. 133 : */ 134 : class CRPCTable 135 : { 136 : private: 137 : std::map<std::string, std::vector<const CRPCCommand*>> mapCommands; 138 : public: 139 : CRPCTable(); 140 : std::string help(const std::string& name, const JSONRPCRequest& helpreq) const; 141 : 142 : /** 143 : * Execute a method. 144 : * @param request The JSONRPCRequest to execute 145 : * @returns Result of the call. 146 : * @throws an exception (UniValue) when an error happens. 147 : */ 148 : UniValue execute(const JSONRPCRequest &request) const; 149 : 150 : /** 151 : * Returns a list of registered commands 152 : * @returns List of registered commands. 153 : */ 154 : std::vector<std::string> listCommands() const; 155 : 156 : /** 157 : * Return all named arguments that need to be converted by the client from string to another JSON type 158 : */ 159 : UniValue dumpArgMap(const JSONRPCRequest& request) const; 160 : 161 : /** 162 : * Appends a CRPCCommand to the dispatch table. 163 : * 164 : * Precondition: RPC server is not running 165 : * 166 : * Commands with different method names but the same unique_id will 167 : * be considered aliases, and only the first registered method name will 168 : * show up in the help text command listing. Aliased commands do not have 169 : * to have the same behavior. Server and client code can distinguish 170 : * between calls based on method name, and aliased commands can also 171 : * register different names, types, and numbers of parameters. 172 : */ 173 : void appendCommand(const std::string& name, const CRPCCommand* pcmd); 174 : bool removeCommand(const std::string& name, const CRPCCommand* pcmd); 175 : }; 176 : 177 : bool IsDeprecatedRPCEnabled(const std::string& method); 178 : 179 : extern CRPCTable tableRPC; 180 : 181 : void StartRPC(); 182 : void InterruptRPC(); 183 : void StopRPC(); 184 : std::string JSONRPCExecBatch(const JSONRPCRequest& jreq, const UniValue& vReq); 185 : 186 : // Retrieves any serialization flags requested in command line argument 187 : int RPCSerializationFlags(); 188 : 189 : #endif // BITCOIN_RPC_SERVER_H