Coverage Report

Created: 2025-04-14 16:24

/Users/mcomp/contrib/bitcoin/src/rpc/server.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2010 Satoshi Nakamoto
2
// Copyright (c) 2009-2021 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 <functional>
13
#include <map>
14
#include <stdint.h>
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
/** Opaque base class for timers returned by NewTimerFunc.
39
 * This provides no methods at the moment, but makes sure that delete
40
 * cleans up the whole state.
41
 */
42
class RPCTimerBase
43
{
44
public:
45
0
    virtual ~RPCTimerBase() = default;
46
};
47
48
/**
49
 * RPC timer "driver".
50
 */
51
class RPCTimerInterface
52
{
53
public:
54
0
    virtual ~RPCTimerInterface() = default;
55
    /** Implementation name */
56
    virtual const char *Name() = 0;
57
    /** Factory function for timers.
58
     * RPC will call the function to create a timer that will call func in *millis* milliseconds.
59
     * @note As the RPC mechanism is backend-neutral, it can use different implementations of timers.
60
     * This is needed to cope with the case in which there is no HTTP server, but
61
     * only GUI RPC console, and to break the dependency of pcserver on httprpc.
62
     */
63
    virtual RPCTimerBase* NewTimer(std::function<void()>& func, int64_t millis) = 0;
64
};
65
66
/** Set the factory function for timers */
67
void RPCSetTimerInterface(RPCTimerInterface *iface);
68
/** Set the factory function for timer, but only, if unset */
69
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface);
70
/** Unset factory function for timers */
71
void RPCUnsetTimerInterface(RPCTimerInterface *iface);
72
73
/**
74
 * Run func nSeconds from now.
75
 * Overrides previous timer <name> (if any).
76
 */
77
void RPCRunLater(const std::string& name, std::function<void()> func, int64_t nSeconds);
78
79
typedef RPCHelpMan (*RpcMethodFnType)();
80
81
class CRPCCommand
82
{
83
public:
84
    //! RPC method handler reading request and assigning result. Should return
85
    //! true if request is fully handled, false if it should be passed on to
86
    //! subsequent handlers.
87
    using Actor = std::function<bool(const JSONRPCRequest& request, UniValue& result, bool last_handler)>;
88
89
    //! Constructor taking Actor callback supporting multiple handlers.
90
    CRPCCommand(std::string category, std::string name, Actor actor, std::vector<std::pair<std::string, bool>> args, intptr_t unique_id)
91
0
        : category(std::move(category)), name(std::move(name)), actor(std::move(actor)), argNames(std::move(args)),
92
0
          unique_id(unique_id)
93
0
    {
94
0
    }
95
96
    //! Simplified constructor taking plain RpcMethodFnType function pointer.
97
    CRPCCommand(std::string category, RpcMethodFnType fn)
98
0
        : CRPCCommand(
99
0
              category,
100
0
              fn().m_name,
101
0
              [fn](const JSONRPCRequest& request, UniValue& result, bool) { result = fn().HandleRequest(request); return true; },
102
0
              fn().GetArgNames(),
103
0
              intptr_t(fn))
104
0
    {
105
0
    }
106
107
    std::string category;
108
    std::string name;
109
    Actor actor;
110
    //! List of method arguments and whether they are named-only. Incoming RPC
111
    //! requests contain a "params" field that can either be an array containing
112
    //! unnamed arguments or an object containing named arguments. The
113
    //! "argNames" vector is used in the latter case to transform the params
114
    //! object into an array. Each argument in "argNames" gets mapped to a
115
    //! unique position in the array, based on the order it is listed, unless
116
    //! the argument is a named-only argument with argNames[x].second set to
117
    //! true. Named-only arguments are combined into a JSON object that is
118
    //! appended after other arguments, see transformNamedArguments for details.
119
    std::vector<std::pair<std::string, bool>> argNames;
120
    intptr_t unique_id;
121
};
122
123
/**
124
 * RPC command dispatcher.
125
 */
126
class CRPCTable
127
{
128
private:
129
    std::map<std::string, std::vector<const CRPCCommand*>> mapCommands;
130
public:
131
    CRPCTable();
132
    std::string help(const std::string& name, const JSONRPCRequest& helpreq) const;
133
134
    /**
135
     * Execute a method.
136
     * @param request The JSONRPCRequest to execute
137
     * @returns Result of the call.
138
     * @throws an exception (UniValue) when an error happens.
139
     */
140
    UniValue execute(const JSONRPCRequest &request) const;
141
142
    /**
143
    * Returns a list of registered commands
144
    * @returns List of registered commands.
145
    */
146
    std::vector<std::string> listCommands() const;
147
148
    /**
149
     * Return all named arguments that need to be converted by the client from string to another JSON type
150
     */
151
    UniValue dumpArgMap(const JSONRPCRequest& request) const;
152
153
    /**
154
     * Appends a CRPCCommand to the dispatch table.
155
     *
156
     * Precondition: RPC server is not running
157
     *
158
     * Commands with different method names but the same unique_id will
159
     * be considered aliases, and only the first registered method name will
160
     * show up in the help text command listing. Aliased commands do not have
161
     * to have the same behavior. Server and client code can distinguish
162
     * between calls based on method name, and aliased commands can also
163
     * register different names, types, and numbers of parameters.
164
     */
165
    void appendCommand(const std::string& name, const CRPCCommand* pcmd);
166
    bool removeCommand(const std::string& name, const CRPCCommand* pcmd);
167
};
168
169
bool IsDeprecatedRPCEnabled(const std::string& method);
170
171
extern CRPCTable tableRPC;
172
173
void StartRPC();
174
void InterruptRPC();
175
void StopRPC();
176
UniValue JSONRPCExec(const JSONRPCRequest& jreq, bool catch_errors);
177
178
#endif // BITCOIN_RPC_SERVER_H