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