Bitcoin Core  24.99.0
P2P Digital Currency
server.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2022 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 #include <rpc/server.h>
7 
8 #include <rpc/util.h>
9 #include <shutdown.h>
10 #include <sync.h>
11 #include <util/strencodings.h>
12 #include <util/string.h>
13 #include <util/system.h>
14 #include <util/time.h>
15 
16 #include <boost/signals2/signal.hpp>
17 
18 #include <cassert>
19 #include <chrono>
20 #include <memory>
21 #include <mutex>
22 #include <unordered_map>
23 
25 static std::atomic<bool> g_rpc_running{false};
26 static bool fRPCInWarmup GUARDED_BY(g_rpc_warmup_mutex) = true;
27 static std::string rpcWarmupStatus GUARDED_BY(g_rpc_warmup_mutex) = "RPC server started";
28 /* Timer-creating functions */
30 /* Map of name to timer. */
32 static std::map<std::string, std::unique_ptr<RPCTimerBase> > deadlineTimers GUARDED_BY(g_deadline_timers_mutex);
33 static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& request, UniValue& result, bool last_handler);
34 
36 {
37  std::string method;
38  SteadyClock::time_point start;
39 };
40 
42 {
44  std::list<RPCCommandExecutionInfo> active_commands GUARDED_BY(mutex);
45 };
46 
48 
50 {
51  std::list<RPCCommandExecutionInfo>::iterator it;
52  explicit RPCCommandExecution(const std::string& method)
53  {
55  it = g_rpc_server_info.active_commands.insert(g_rpc_server_info.active_commands.end(), {method, SteadyClock::now()});
56  }
58  {
60  g_rpc_server_info.active_commands.erase(it);
61  }
62 };
63 
64 static struct CRPCSignals
65 {
66  boost::signals2::signal<void ()> Started;
67  boost::signals2::signal<void ()> Stopped;
69 
70 void RPCServer::OnStarted(std::function<void ()> slot)
71 {
72  g_rpcSignals.Started.connect(slot);
73 }
74 
75 void RPCServer::OnStopped(std::function<void ()> slot)
76 {
77  g_rpcSignals.Stopped.connect(slot);
78 }
79 
80 std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& helpreq) const
81 {
82  std::string strRet;
83  std::string category;
84  std::set<intptr_t> setDone;
85  std::vector<std::pair<std::string, const CRPCCommand*> > vCommands;
86 
87  for (const auto& entry : mapCommands)
88  vCommands.push_back(make_pair(entry.second.front()->category + entry.first, entry.second.front()));
89  sort(vCommands.begin(), vCommands.end());
90 
91  JSONRPCRequest jreq = helpreq;
93  jreq.params = UniValue();
94 
95  for (const std::pair<std::string, const CRPCCommand*>& command : vCommands)
96  {
97  const CRPCCommand *pcmd = command.second;
98  std::string strMethod = pcmd->name;
99  if ((strCommand != "" || pcmd->category == "hidden") && strMethod != strCommand)
100  continue;
101  jreq.strMethod = strMethod;
102  try
103  {
104  UniValue unused_result;
105  if (setDone.insert(pcmd->unique_id).second)
106  pcmd->actor(jreq, unused_result, /*last_handler=*/true);
107  }
108  catch (const std::exception& e)
109  {
110  // Help text is returned in an exception
111  std::string strHelp = std::string(e.what());
112  if (strCommand == "")
113  {
114  if (strHelp.find('\n') != std::string::npos)
115  strHelp = strHelp.substr(0, strHelp.find('\n'));
116 
117  if (category != pcmd->category)
118  {
119  if (!category.empty())
120  strRet += "\n";
121  category = pcmd->category;
122  strRet += "== " + Capitalize(category) + " ==\n";
123  }
124  }
125  strRet += strHelp + "\n";
126  }
127  }
128  if (strRet == "")
129  strRet = strprintf("help: unknown command: %s\n", strCommand);
130  strRet = strRet.substr(0,strRet.size()-1);
131  return strRet;
132 }
133 
134 static RPCHelpMan help()
135 {
136  return RPCHelpMan{"help",
137  "\nList all commands, or get help for a specified command.\n",
138  {
139  {"command", RPCArg::Type::STR, RPCArg::DefaultHint{"all commands"}, "The command to get help on"},
140  },
141  {
142  RPCResult{RPCResult::Type::STR, "", "The help text"},
144  },
145  RPCExamples{""},
146  [&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue
147 {
148  std::string strCommand;
149  if (jsonRequest.params.size() > 0) {
150  strCommand = jsonRequest.params[0].get_str();
151  }
152  if (strCommand == "dump_all_command_conversions") {
153  // Used for testing only, undocumented
154  return tableRPC.dumpArgMap(jsonRequest);
155  }
156 
157  return tableRPC.help(strCommand, jsonRequest);
158 },
159  };
160 }
161 
162 static RPCHelpMan stop()
163 {
164  static const std::string RESULT{PACKAGE_NAME " stopping"};
165  return RPCHelpMan{"stop",
166  // Also accept the hidden 'wait' integer argument (milliseconds)
167  // For instance, 'stop 1000' makes the call wait 1 second before returning
168  // to the client (intended for testing)
169  "\nRequest a graceful shutdown of " PACKAGE_NAME ".",
170  {
171  {"wait", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "how long to wait in ms", RPCArgOptions{.hidden=true}},
172  },
173  RPCResult{RPCResult::Type::STR, "", "A string with the content '" + RESULT + "'"},
174  RPCExamples{""},
175  [&](const RPCHelpMan& self, const JSONRPCRequest& jsonRequest) -> UniValue
176 {
177  // Event loop will exit after current HTTP requests have been handled, so
178  // this reply will get back to the client.
179  StartShutdown();
180  if (jsonRequest.params[0].isNum()) {
181  UninterruptibleSleep(std::chrono::milliseconds{jsonRequest.params[0].getInt<int>()});
182  }
183  return RESULT;
184 },
185  };
186 }
187 
189 {
190  return RPCHelpMan{"uptime",
191  "\nReturns the total uptime of the server.\n",
192  {},
193  RPCResult{
194  RPCResult::Type::NUM, "", "The number of seconds that the server has been running"
195  },
196  RPCExamples{
197  HelpExampleCli("uptime", "")
198  + HelpExampleRpc("uptime", "")
199  },
200  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
201 {
202  return GetTime() - GetStartupTime();
203 }
204  };
205 }
206 
208 {
209  return RPCHelpMan{"getrpcinfo",
210  "\nReturns details of the RPC server.\n",
211  {},
212  RPCResult{
213  RPCResult::Type::OBJ, "", "",
214  {
215  {RPCResult::Type::ARR, "active_commands", "All active commands",
216  {
217  {RPCResult::Type::OBJ, "", "Information about an active command",
218  {
219  {RPCResult::Type::STR, "method", "The name of the RPC command"},
220  {RPCResult::Type::NUM, "duration", "The running time in microseconds"},
221  }},
222  }},
223  {RPCResult::Type::STR, "logpath", "The complete file path to the debug log"},
224  }
225  },
226  RPCExamples{
227  HelpExampleCli("getrpcinfo", "")
228  + HelpExampleRpc("getrpcinfo", "")},
229  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
230 {
232  UniValue active_commands(UniValue::VARR);
233  for (const RPCCommandExecutionInfo& info : g_rpc_server_info.active_commands) {
234  UniValue entry(UniValue::VOBJ);
235  entry.pushKV("method", info.method);
236  entry.pushKV("duration", int64_t{Ticks<std::chrono::microseconds>(SteadyClock::now() - info.start)});
237  active_commands.push_back(entry);
238  }
239 
240  UniValue result(UniValue::VOBJ);
241  result.pushKV("active_commands", active_commands);
242 
243  const std::string path = LogInstance().m_file_path.u8string();
244  UniValue log_path(UniValue::VSTR, path);
245  result.pushKV("logpath", log_path);
246 
247  return result;
248 }
249  };
250 }
251 
252 static const CRPCCommand vRPCCommands[]{
253  /* Overall control/query calls */
254  {"control", &getrpcinfo},
255  {"control", &help},
256  {"control", &stop},
257  {"control", &uptime},
258 };
259 
261 {
262  for (const auto& c : vRPCCommands) {
263  appendCommand(c.name, &c);
264  }
265 }
266 
267 void CRPCTable::appendCommand(const std::string& name, const CRPCCommand* pcmd)
268 {
269  CHECK_NONFATAL(!IsRPCRunning()); // Only add commands before rpc is running
270 
271  mapCommands[name].push_back(pcmd);
272 }
273 
274 bool CRPCTable::removeCommand(const std::string& name, const CRPCCommand* pcmd)
275 {
276  auto it = mapCommands.find(name);
277  if (it != mapCommands.end()) {
278  auto new_end = std::remove(it->second.begin(), it->second.end(), pcmd);
279  if (it->second.end() != new_end) {
280  it->second.erase(new_end, it->second.end());
281  return true;
282  }
283  }
284  return false;
285 }
286 
287 void StartRPC()
288 {
289  LogPrint(BCLog::RPC, "Starting RPC\n");
290  g_rpc_running = true;
292 }
293 
295 {
296  static std::once_flag g_rpc_interrupt_flag;
297  // This function could be called twice if the GUI has been started with -server=1.
298  std::call_once(g_rpc_interrupt_flag, []() {
299  LogPrint(BCLog::RPC, "Interrupting RPC\n");
300  // Interrupt e.g. running longpolls
301  g_rpc_running = false;
302  });
303 }
304 
305 void StopRPC()
306 {
307  static std::once_flag g_rpc_stop_flag;
308  // This function could be called twice if the GUI has been started with -server=1.
310  std::call_once(g_rpc_stop_flag, []() {
311  LogPrint(BCLog::RPC, "Stopping RPC\n");
312  WITH_LOCK(g_deadline_timers_mutex, deadlineTimers.clear());
315  });
316 }
317 
319 {
320  return g_rpc_running;
321 }
322 
324 {
325  if (!IsRPCRunning()) throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
326 }
327 
328 void SetRPCWarmupStatus(const std::string& newStatus)
329 {
331  rpcWarmupStatus = newStatus;
332 }
333 
335 {
337  assert(fRPCInWarmup);
338  fRPCInWarmup = false;
339 }
340 
341 bool RPCIsInWarmup(std::string *outStatus)
342 {
344  if (outStatus)
345  *outStatus = rpcWarmupStatus;
346  return fRPCInWarmup;
347 }
348 
349 bool IsDeprecatedRPCEnabled(const std::string& method)
350 {
351  const std::vector<std::string> enabled_methods = gArgs.GetArgs("-deprecatedrpc");
352 
353  return find(enabled_methods.begin(), enabled_methods.end(), method) != enabled_methods.end();
354 }
355 
357 {
358  UniValue rpc_result(UniValue::VOBJ);
359 
360  try {
361  jreq.parse(req);
362 
363  UniValue result = tableRPC.execute(jreq);
364  rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id);
365  }
366  catch (const UniValue& objError)
367  {
368  rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id);
369  }
370  catch (const std::exception& e)
371  {
372  rpc_result = JSONRPCReplyObj(NullUniValue,
373  JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
374  }
375 
376  return rpc_result;
377 }
378 
379 std::string JSONRPCExecBatch(const JSONRPCRequest& jreq, const UniValue& vReq)
380 {
382  for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
383  ret.push_back(JSONRPCExecOne(jreq, vReq[reqIdx]));
384 
385  return ret.write() + "\n";
386 }
387 
392 static inline JSONRPCRequest transformNamedArguments(const JSONRPCRequest& in, const std::vector<std::string>& argNames)
393 {
394  JSONRPCRequest out = in;
396  // Build a map of parameters, and remove ones that have been processed, so that we can throw a focused error if
397  // there is an unknown one.
398  const std::vector<std::string>& keys = in.params.getKeys();
399  const std::vector<UniValue>& values = in.params.getValues();
400  std::unordered_map<std::string, const UniValue*> argsIn;
401  for (size_t i=0; i<keys.size(); ++i) {
402  auto [_, inserted] = argsIn.emplace(keys[i], &values[i]);
403  if (!inserted) {
404  throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter " + keys[i] + " specified multiple times");
405  }
406  }
407  // Process expected parameters. If any parameters were left unspecified in
408  // the request before a parameter that was specified, null values need to be
409  // inserted at the unspecifed parameter positions, and the "hole" variable
410  // below tracks the number of null values that need to be inserted.
411  // The "initial_hole_size" variable stores the size of the initial hole,
412  // i.e. how many initial positional arguments were left unspecified. This is
413  // used after the for-loop to add initial positional arguments from the
414  // "args" parameter, if present.
415  int hole = 0;
416  int initial_hole_size = 0;
417  for (const std::string &argNamePattern: argNames) {
418  std::vector<std::string> vargNames = SplitString(argNamePattern, '|');
419  auto fr = argsIn.end();
420  for (const std::string & argName : vargNames) {
421  fr = argsIn.find(argName);
422  if (fr != argsIn.end()) {
423  break;
424  }
425  }
426  if (fr != argsIn.end()) {
427  for (int i = 0; i < hole; ++i) {
428  // Fill hole between specified parameters with JSON nulls,
429  // but not at the end (for backwards compatibility with calls
430  // that act based on number of specified parameters).
431  out.params.push_back(UniValue());
432  }
433  hole = 0;
434  out.params.push_back(*fr->second);
435  argsIn.erase(fr);
436  } else {
437  hole += 1;
438  if (out.params.empty()) initial_hole_size = hole;
439  }
440  }
441  // If leftover "args" param was found, use it as a source of positional
442  // arguments and add named arguments after. This is a convenience for
443  // clients that want to pass a combination of named and positional
444  // arguments as described in doc/JSON-RPC-interface.md#parameter-passing
445  auto positional_args{argsIn.extract("args")};
446  if (positional_args && positional_args.mapped()->isArray()) {
447  const bool has_named_arguments{initial_hole_size < (int)argNames.size()};
448  if (initial_hole_size < (int)positional_args.mapped()->size() && has_named_arguments) {
449  throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter " + argNames[initial_hole_size] + " specified twice both as positional and named argument");
450  }
451  // Assign positional_args to out.params and append named_args after.
452  UniValue named_args{std::move(out.params)};
453  out.params = *positional_args.mapped();
454  for (size_t i{out.params.size()}; i < named_args.size(); ++i) {
455  out.params.push_back(named_args[i]);
456  }
457  }
458  // If there are still arguments in the argsIn map, this is an error.
459  if (!argsIn.empty()) {
460  throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown named parameter " + argsIn.begin()->first);
461  }
462  // Return request with named arguments transformed to positional arguments
463  return out;
464 }
465 
466 static bool ExecuteCommands(const std::vector<const CRPCCommand*>& commands, const JSONRPCRequest& request, UniValue& result)
467 {
468  for (const auto& command : commands) {
469  if (ExecuteCommand(*command, request, result, &command == &commands.back())) {
470  return true;
471  }
472  }
473  return false;
474 }
475 
477 {
478  // Return immediately if in warmup
479  {
481  if (fRPCInWarmup)
482  throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
483  }
484 
485  // Find method
486  auto it = mapCommands.find(request.strMethod);
487  if (it != mapCommands.end()) {
488  UniValue result;
489  if (ExecuteCommands(it->second, request, result)) {
490  return result;
491  }
492  }
493  throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
494 }
495 
496 static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& request, UniValue& result, bool last_handler)
497 {
498  try {
499  RPCCommandExecution execution(request.strMethod);
500  // Execute, convert arguments to array if necessary
501  if (request.params.isObject()) {
502  return command.actor(transformNamedArguments(request, command.argNames), result, last_handler);
503  } else {
504  return command.actor(request, result, last_handler);
505  }
506  } catch (const UniValue::type_error& e) {
507  throw JSONRPCError(RPC_TYPE_ERROR, e.what());
508  } catch (const std::exception& e) {
509  throw JSONRPCError(RPC_MISC_ERROR, e.what());
510  }
511 }
512 
513 std::vector<std::string> CRPCTable::listCommands() const
514 {
515  std::vector<std::string> commandList;
516  for (const auto& i : mapCommands) commandList.emplace_back(i.first);
517  return commandList;
518 }
519 
521 {
522  JSONRPCRequest request = args_request;
523  request.mode = JSONRPCRequest::GET_ARGS;
524 
526  for (const auto& cmd : mapCommands) {
527  UniValue result;
528  if (ExecuteCommands(cmd.second, request, result)) {
529  for (const auto& values : result.getValues()) {
530  ret.push_back(values);
531  }
532  }
533  }
534  return ret;
535 }
536 
538 {
539  if (!timerInterface)
540  timerInterface = iface;
541 }
542 
544 {
545  timerInterface = iface;
546 }
547 
549 {
550  if (timerInterface == iface)
551  timerInterface = nullptr;
552 }
553 
554 void RPCRunLater(const std::string& name, std::function<void()> func, int64_t nSeconds)
555 {
556  if (!timerInterface)
557  throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC");
559  deadlineTimers.erase(name);
560  LogPrint(BCLog::RPC, "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name());
561  deadlineTimers.emplace(name, std::unique_ptr<RPCTimerBase>(timerInterface->NewTimer(func, nSeconds*1000)));
562 }
563 
565 {
566  int flag = 0;
567  if (gArgs.GetIntArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0)
569  return flag;
570 }
571 
int ret
#define PACKAGE_NAME
const auto cmd
const auto command
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:46
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:470
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:590
fs::path m_file_path
Definition: logging.h:123
std::string category
Definition: server.h:115
intptr_t unique_id
Definition: server.h:119
std::string name
Definition: server.h:116
Actor actor
Definition: server.h:117
RPC command dispatcher.
Definition: server.h:126
CRPCTable()
Definition: server.cpp:260
std::map< std::string, std::vector< const CRPCCommand * > > mapCommands
Definition: server.h:128
bool removeCommand(const std::string &name, const CRPCCommand *pcmd)
Definition: server.cpp:274
std::vector< std::string > listCommands() const
Returns a list of registered commands.
Definition: server.cpp:513
UniValue execute(const JSONRPCRequest &request) const
Execute a method.
Definition: server.cpp:476
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:267
std::string help(const std::string &name, const JSONRPCRequest &helpreq) const
Definition: server.cpp:80
UniValue dumpArgMap(const JSONRPCRequest &request) const
Return all named arguments that need to be converted by the client from string to another JSON type.
Definition: server.cpp:520
Different type to mark Mutex at global scope.
Definition: sync.h:141
UniValue params
Definition: request.h:33
std::string strMethod
Definition: request.h:32
enum JSONRPCRequest::Mode mode
UniValue id
Definition: request.h:31
void parse(const UniValue &valRequest)
Definition: request.cpp:158
RPC timer "driver".
Definition: server.h:60
virtual RPCTimerBase * NewTimer(std::function< void()> &func, int64_t millis)=0
Factory function for timers.
virtual const char * Name()=0
Implementation name.
void push_back(UniValue val)
Definition: univalue.cpp:104
const std::string & get_str() const
@ VOBJ
Definition: univalue.h:21
@ VSTR
Definition: univalue.h:21
@ VARR
Definition: univalue.h:21
size_t size() const
Definition: univalue.h:68
const std::vector< UniValue > & getValues() const
const std::vector< std::string > & getKeys() const
bool empty() const
Definition: univalue.h:66
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:126
bool isObject() const
Definition: univalue.h:83
std::string u8string() const
Definition: fs.h:55
BCLog::Logger & LogInstance()
Definition: logging.cpp:20
#define LogPrint(category,...)
Definition: logging.h:245
@ RPC
Definition: logging.h:47
void OnStarted(std::function< void()> slot)
Definition: server.cpp:70
void OnStopped(std::function< void()> slot)
Definition: server.cpp:75
static const int SERIALIZE_TRANSACTION_NO_WITNESS
A flag that is ORed into the protocol version to designate that a transaction should be (un)serialize...
Definition: transaction.h:32
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:56
void DeleteAuthCookie()
Delete RPC authentication cookie from disk.
Definition: request.cpp:129
UniValue JSONRPCReplyObj(const UniValue &result, const UniValue &error, const UniValue &id)
Definition: request.cpp:38
const char * name
Definition: rest.cpp:46
@ RPC_PARSE_ERROR
Definition: protocol.h:36
@ RPC_MISC_ERROR
General application defined errors.
Definition: protocol.h:39
@ RPC_METHOD_NOT_FOUND
Definition: protocol.h:31
@ RPC_TYPE_ERROR
Unexpected type was passed as parameter.
Definition: protocol.h:40
@ RPC_CLIENT_NOT_CONNECTED
P2P client errors.
Definition: protocol.h:58
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:43
@ RPC_IN_WARMUP
Client still warming up.
Definition: protocol.h:49
@ RPC_INTERNAL_ERROR
Definition: protocol.h:35
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:139
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:157
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
Set the factory function for timer, but only, if unset.
Definition: server.cpp:537
bool IsDeprecatedRPCEnabled(const std::string &method)
Definition: server.cpp:349
void SetRPCWarmupFinished()
Definition: server.cpp:334
static RPCHelpMan uptime()
Definition: server.cpp:188
void StartRPC()
Definition: server.cpp:287
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
Unset factory function for timers.
Definition: server.cpp:548
static RPCHelpMan getrpcinfo()
Definition: server.cpp:207
void RPCRunLater(const std::string &name, std::function< void()> func, int64_t nSeconds)
Run func nSeconds from now.
Definition: server.cpp:554
static bool ExecuteCommands(const std::vector< const CRPCCommand * > &commands, const JSONRPCRequest &request, UniValue &result)
Definition: server.cpp:466
bool RPCIsInWarmup(std::string *outStatus)
Definition: server.cpp:341
static RPCTimerInterface * timerInterface
Definition: server.cpp:29
static bool ExecuteCommand(const CRPCCommand &command, const JSONRPCRequest &request, UniValue &result, bool last_handler)
Definition: server.cpp:496
void StopRPC()
Definition: server.cpp:305
static RPCHelpMan stop()
Definition: server.cpp:162
static std::atomic< bool > g_rpc_running
Definition: server.cpp:25
static GlobalMutex g_deadline_timers_mutex
Definition: server.cpp:31
bool IsRPCRunning()
Query whether RPC is running.
Definition: server.cpp:318
std::string JSONRPCExecBatch(const JSONRPCRequest &jreq, const UniValue &vReq)
Definition: server.cpp:379
static UniValue JSONRPCExecOne(JSONRPCRequest jreq, const UniValue &req)
Definition: server.cpp:356
int RPCSerializationFlags()
Definition: server.cpp:564
void InterruptRPC()
Definition: server.cpp:294
static struct CRPCSignals g_rpcSignals
static bool fRPCInWarmup GUARDED_BY(g_rpc_warmup_mutex)
static GlobalMutex g_rpc_warmup_mutex
Definition: server.cpp:24
static RPCHelpMan help()
Definition: server.cpp:134
static RPCServerInfo g_rpc_server_info
Definition: server.cpp:47
static const CRPCCommand vRPCCommands[]
Definition: server.cpp:252
void SetRPCWarmupStatus(const std::string &newStatus)
Set the RPC warmup status.
Definition: server.cpp:328
CRPCTable tableRPC
Definition: server.cpp:572
static JSONRPCRequest transformNamedArguments(const JSONRPCRequest &in, const std::vector< std::string > &argNames)
Process named arguments into a vector of positional arguments, based on the passed-in specification f...
Definition: server.cpp:392
void RPCSetTimerInterface(RPCTimerInterface *iface)
Set the factory function for timers.
Definition: server.cpp:543
void RpcInterruptionPoint()
Throw JSONRPCError if RPC is not running.
Definition: server.cpp:323
static const unsigned int DEFAULT_RPC_SERIALIZE_VERSION
Definition: server.h:19
void StartShutdown()
Request shutdown of the application.
Definition: shutdown.cpp:58
std::vector< std::string > SplitString(std::string_view str, char sep)
Definition: string.h:21
boost::signals2::signal< void()> Started
Definition: server.cpp:66
boost::signals2::signal< void()> Stopped
Definition: server.cpp:67
std::string DefaultHint
Hint for default value.
Definition: util.h:162
@ OMITTED
Optional argument for which the default value is omitted from help text for one of two reasons:
bool hidden
For testing only.
Definition: util.h:132
RPCCommandExecution(const std::string &method)
Definition: server.cpp:52
std::list< RPCCommandExecutionInfo >::iterator it
Definition: server.cpp:51
SteadyClock::time_point start
Definition: server.cpp:38
std::string method
Definition: server.cpp:37
@ ANY
Special type to disable type checks (for testing only)
Mutex mutex
Definition: server.cpp:43
std::list< RPCCommandExecutionInfo > active_commands GUARDED_BY(mutex)
#define LOCK(cs)
Definition: sync.h:258
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:302
void UninterruptibleSleep(const std::chrono::microseconds &n)
Definition: time.cpp:23
int64_t GetTime()
Definition: time.cpp:110
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1162
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:78
const UniValue NullUniValue
Definition: univalue.cpp:16
std::string Capitalize(std::string str)
Capitalizes the first character of the given string.
int64_t GetStartupTime()
Definition: system.cpp:1344
ArgsManager gArgs
Definition: system.cpp:73
assert(!tx.IsCoinBase())