Branch data Line data Source code
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 : 193744 : CRPCCommand(std::string category, std::string name, Actor actor, std::vector<std::pair<std::string, bool>> args, intptr_t unique_id)
52 : 193744 : : category(std::move(category)), name(std::move(name)), actor(std::move(actor)), argNames(std::move(args)),
53 : 193744 : unique_id(unique_id)
54 : : {
55 : 193744 : }
56 : :
57 : : //! Simplified constructor taking plain RpcMethodFnType function pointer.
58 : 168792 : CRPCCommand(std::string category, RpcMethodFnType fn)
59 : 168792 : : CRPCCommand(
60 : : category,
61 [ + - ]: 337584 : fn().m_name,
62 [ + - + + ]: 399521 : [fn](const JSONRPCRequest& request, UniValue& result, bool) { result = fn().HandleRequest(request); return true; },
63 [ + - ]: 337584 : fn().GetArgNames(),
64 [ - + ]: 506376 : intptr_t(fn))
65 : : {
66 : 168792 : this->metadata_fn = fn;
67 : 168792 : }
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 : 13 : 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
|