/tmp/bitcoin/src/rpc/server.h
Line | Count | Source |
1 | | // Copyright (c) 2010 Satoshi Nakamoto |
2 | | // Copyright (c) 2009-present 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 <cstdint> |
13 | | #include <functional> |
14 | | #include <map> |
15 | | #include <string> |
16 | | #include <string_view> |
17 | | |
18 | | #include <univalue.h> |
19 | | |
20 | | class CRPCCommand; |
21 | | |
22 | | /** Query whether RPC is running */ |
23 | | bool IsRPCRunning(); |
24 | | |
25 | | /** Throw JSONRPCError if RPC is not running */ |
26 | | void RpcInterruptionPoint(); |
27 | | |
28 | | /** |
29 | | * Set the RPC warmup status. When this is done, all RPC calls will error out |
30 | | * immediately with RPC_IN_WARMUP. |
31 | | */ |
32 | | void SetRPCWarmupStatus(const std::string& newStatus); |
33 | | void SetRPCWarmupStarting(); |
34 | | /* Mark warmup as done. RPC calls will be processed from now on. */ |
35 | | void SetRPCWarmupFinished(); |
36 | | |
37 | | /* returns the current warmup state. */ |
38 | | bool RPCIsInWarmup(std::string *outStatus); |
39 | | |
40 | | typedef RPCMethod (*RpcMethodFnType)(); |
41 | | |
42 | | class CRPCCommand |
43 | | { |
44 | | public: |
45 | | //! RPC method handler reading request and assigning result. Should return |
46 | | //! true if request is fully handled, false if it should be passed on to |
47 | | //! subsequent handlers. |
48 | | using Actor = std::function<bool(const JSONRPCRequest& request, UniValue& result, bool last_handler)>; |
49 | | |
50 | | //! Constructor taking Actor callback supporting multiple handlers. |
51 | | CRPCCommand(std::string category, std::string name, Actor actor, std::vector<std::pair<std::string, bool>> args, intptr_t unique_id) |
52 | 186k | : category(std::move(category)), name(std::move(name)), actor(std::move(actor)), argNames(std::move(args)), |
53 | 186k | unique_id(unique_id) |
54 | 186k | { |
55 | 186k | } |
56 | | |
57 | | //! Simplified constructor taking plain RpcMethodFnType function pointer. |
58 | | CRPCCommand(std::string category, RpcMethodFnType fn) |
59 | 161k | : CRPCCommand( |
60 | 161k | category, |
61 | 161k | fn().m_name, |
62 | 197k | [fn](const JSONRPCRequest& request, UniValue& result, bool) { result = fn().HandleRequest(request); return true; }, |
63 | 161k | fn().GetArgNames(), |
64 | 161k | intptr_t(fn)) |
65 | 161k | { |
66 | 161k | this->metadata_fn = fn; |
67 | 161k | } |
68 | | |
69 | | std::string category; |
70 | | std::string name; |
71 | | Actor actor; |
72 | | //! List of method arguments and whether they are named-only. Incoming RPC |
73 | | //! requests contain a "params" field that can either be an array containing |
74 | | //! unnamed arguments or an object containing named arguments. The |
75 | | //! "argNames" vector is used in the latter case to transform the params |
76 | | //! object into an array. Each argument in "argNames" gets mapped to a |
77 | | //! unique position in the array, based on the order it is listed, unless |
78 | | //! the argument is a named-only argument with argNames[x].second set to |
79 | | //! true. Named-only arguments are combined into a JSON object that is |
80 | | //! appended after other arguments, see transformNamedArguments for details. |
81 | | std::vector<std::pair<std::string, bool>> argNames; |
82 | | intptr_t unique_id; |
83 | | RpcMethodFnType metadata_fn{nullptr}; |
84 | | }; |
85 | | |
86 | | /** |
87 | | * RPC command dispatcher. |
88 | | */ |
89 | | class CRPCTable |
90 | | { |
91 | | private: |
92 | | std::map<std::string, std::vector<const CRPCCommand*>> mapCommands; |
93 | | public: |
94 | | CRPCTable(); |
95 | | std::string help(std::string_view name, const JSONRPCRequest& helpreq) const; |
96 | | |
97 | | /** |
98 | | * Execute a method. |
99 | | * @param request The JSONRPCRequest to execute |
100 | | * @returns Result of the call. |
101 | | * @throws an exception (UniValue) when an error happens. |
102 | | */ |
103 | | UniValue execute(const JSONRPCRequest &request) const; |
104 | | |
105 | | /** |
106 | | * Returns a list of registered commands |
107 | | * @returns List of registered commands. |
108 | | */ |
109 | | std::vector<std::string> listCommands() const; |
110 | | /** Return a complete OpenRPC 1.4.1 document for registered commands. */ |
111 | | UniValue buildOpenRPCDoc(bool include_hidden = false) const; |
112 | | |
113 | | /** |
114 | | * Return all named arguments that need to be converted by the client from string to another JSON type |
115 | | */ |
116 | | UniValue dumpArgMap(const JSONRPCRequest& request) const; |
117 | | |
118 | | /** |
119 | | * Appends a CRPCCommand to the dispatch table. |
120 | | * |
121 | | * Precondition: RPC server is not running |
122 | | * |
123 | | * Commands with different method names but the same unique_id will |
124 | | * be considered aliases, and only the first registered method name will |
125 | | * show up in the help text command listing. Aliased commands do not have |
126 | | * to have the same behavior. Server and client code can distinguish |
127 | | * between calls based on method name, and aliased commands can also |
128 | | * register different names, types, and numbers of parameters. |
129 | | */ |
130 | | void appendCommand(const std::string& name, const CRPCCommand* pcmd); |
131 | | bool removeCommand(const std::string& name, const CRPCCommand* pcmd); |
132 | | }; |
133 | | |
134 | | bool IsDeprecatedRPCEnabled(const std::string& method); |
135 | | |
136 | | extern CRPCTable tableRPC; |
137 | | |
138 | | void StartRPC(); |
139 | | void InterruptRPC(); |
140 | | void StopRPC(); |
141 | | UniValue JSONRPCExec(const JSONRPCRequest& jreq, bool catch_errors); |
142 | | |
143 | | #endif // BITCOIN_RPC_SERVER_H |