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