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