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