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 : :
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 : : typedef RPCHelpMan (*RpcMethodFnType)();
39 : :
40 : : class CRPCCommand
41 : : {
42 : : public:
43 : : //! RPC method handler reading request and assigning result. Should return
44 : : //! true if request is fully handled, false if it should be passed on to
45 : : //! subsequent handlers.
46 : : using Actor = std::function<bool(const JSONRPCRequest& request, UniValue& result, bool last_handler)>;
47 : :
48 : : //! Constructor taking Actor callback supporting multiple handlers.
49 : 166523 : CRPCCommand(std::string category, std::string name, Actor actor, std::vector<std::pair<std::string, bool>> args, intptr_t unique_id)
50 : 166523 : : category(std::move(category)), name(std::move(name)), actor(std::move(actor)), argNames(std::move(args)),
51 : 166523 : unique_id(unique_id)
52 : : {
53 : 166523 : }
54 : :
55 : : //! Simplified constructor taking plain RpcMethodFnType function pointer.
56 : 143195 : CRPCCommand(std::string category, RpcMethodFnType fn)
57 : 143195 : : CRPCCommand(
58 : : category,
59 : 143195 : fn().m_name,
60 [ + - + + ]: 344101 : [fn](const JSONRPCRequest& request, UniValue& result, bool) { result = fn().HandleRequest(request); return true; },
61 [ + - ]: 286390 : fn().GetArgNames(),
62 [ + - + - : 429585 : intptr_t(fn))
+ - ]
63 : : {
64 : 143195 : }
65 : :
66 : : std::string category;
67 : : std::string name;
68 : : Actor actor;
69 : : //! List of method arguments and whether they are named-only. Incoming RPC
70 : : //! requests contain a "params" field that can either be an array containing
71 : : //! unnamed arguments or an object containing named arguments. The
72 : : //! "argNames" vector is used in the latter case to transform the params
73 : : //! object into an array. Each argument in "argNames" gets mapped to a
74 : : //! unique position in the array, based on the order it is listed, unless
75 : : //! the argument is a named-only argument with argNames[x].second set to
76 : : //! true. Named-only arguments are combined into a JSON object that is
77 : : //! appended after other arguments, see transformNamedArguments for details.
78 : : std::vector<std::pair<std::string, bool>> argNames;
79 : : intptr_t unique_id;
80 : : };
81 : :
82 : : /**
83 : : * RPC command dispatcher.
84 : : */
85 : 12 : class CRPCTable
86 : : {
87 : : private:
88 : : std::map<std::string, std::vector<const CRPCCommand*>> mapCommands;
89 : : public:
90 : : CRPCTable();
91 : : std::string help(const std::string& name, const JSONRPCRequest& helpreq) const;
92 : :
93 : : /**
94 : : * Execute a method.
95 : : * @param request The JSONRPCRequest to execute
96 : : * @returns Result of the call.
97 : : * @throws an exception (UniValue) when an error happens.
98 : : */
99 : : UniValue execute(const JSONRPCRequest &request) const;
100 : :
101 : : /**
102 : : * Returns a list of registered commands
103 : : * @returns List of registered commands.
104 : : */
105 : : std::vector<std::string> listCommands() const;
106 : :
107 : : /**
108 : : * Return all named arguments that need to be converted by the client from string to another JSON type
109 : : */
110 : : UniValue dumpArgMap(const JSONRPCRequest& request) const;
111 : :
112 : : /**
113 : : * Appends a CRPCCommand to the dispatch table.
114 : : *
115 : : * Precondition: RPC server is not running
116 : : *
117 : : * Commands with different method names but the same unique_id will
118 : : * be considered aliases, and only the first registered method name will
119 : : * show up in the help text command listing. Aliased commands do not have
120 : : * to have the same behavior. Server and client code can distinguish
121 : : * between calls based on method name, and aliased commands can also
122 : : * register different names, types, and numbers of parameters.
123 : : */
124 : : void appendCommand(const std::string& name, const CRPCCommand* pcmd);
125 : : bool removeCommand(const std::string& name, const CRPCCommand* pcmd);
126 : : };
127 : :
128 : : bool IsDeprecatedRPCEnabled(const std::string& method);
129 : :
130 : : extern CRPCTable tableRPC;
131 : :
132 : : void StartRPC();
133 : : void InterruptRPC();
134 : : void StopRPC();
135 : : UniValue JSONRPCExec(const JSONRPCRequest& jreq, bool catch_errors);
136 : :
137 : : #endif // BITCOIN_RPC_SERVER_H
|