Bitcoin ABC  0.29.2
P2P Digital Currency
server.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 The Bitcoin Core developers
3 // Copyright (c) 2018-2019 The Bitcoin developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include <rpc/server.h>
8 
9 #include <config.h>
10 #include <rpc/util.h>
11 #include <shutdown.h>
12 #include <sync.h>
13 #include <util/strencodings.h>
14 #include <util/string.h>
15 #include <util/time.h>
16 
17 #include <boost/signals2/signal.hpp>
18 
19 #include <cassert>
20 #include <chrono>
21 #include <memory>
22 #include <mutex>
23 #include <set>
24 #include <unordered_map>
25 
26 using SteadyClock = std::chrono::steady_clock;
27 
29 static std::atomic<bool> g_rpc_running{false};
30 static bool fRPCInWarmup GUARDED_BY(g_rpc_warmup_mutex) = true;
31 static std::string
32  rpcWarmupStatus GUARDED_BY(g_rpc_warmup_mutex) = "RPC server started";
33 /* Timer-creating functions */
35 /* Map of name to timer. */
37 static std::map<std::string, std::unique_ptr<RPCTimerBase>>
39 static bool ExecuteCommand(const Config &config, const CRPCCommand &command,
40  const JSONRPCRequest &request, UniValue &result,
41  bool last_handler);
42 
44  std::string method;
45  SteadyClock::time_point start;
46 };
47 
48 struct RPCServerInfo {
50  std::list<RPCCommandExecutionInfo> active_commands GUARDED_BY(mutex);
51 };
52 
54 
56  std::list<RPCCommandExecutionInfo>::iterator it;
57  explicit RPCCommandExecution(const std::string &method) {
59  it = g_rpc_server_info.active_commands.insert(
60  g_rpc_server_info.active_commands.cend(),
61  {method, SteadyClock::now()});
62  }
65  g_rpc_server_info.active_commands.erase(it);
66  }
67 };
68 
70  const JSONRPCRequest &request) const {
71  // Return immediately if in warmup
72  // This is retained from the old RPC implementation because a lot of state
73  // is set during warmup that RPC commands may depend on. This can be
74  // safely removed once global variable usage has been eliminated.
75  {
77  if (fRPCInWarmup) {
78  throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
79  }
80  }
81 
82  std::string commandName = request.strMethod;
83  {
84  auto commandsReadView = commands.getReadView();
85  auto iter = commandsReadView->find(commandName);
86  if (iter != commandsReadView.end()) {
87  return iter->second.get()->Execute(request);
88  }
89  }
90 
91  // TODO Remove the below call to tableRPC.execute() and only call it for
92  // context-free RPC commands via an implementation of RPCCommand.
93 
94  // Check if context-free RPC method is valid and execute it
95  return tableRPC.execute(config, request);
96 }
97 
98 void RPCServer::RegisterCommand(std::unique_ptr<RPCCommand> command) {
99  if (command != nullptr) {
100  const std::string &commandName = command->GetName();
101  commands.getWriteView()->insert(
102  std::make_pair(commandName, std::move(command)));
103  }
104 }
105 
106 static struct CRPCSignals {
107  boost::signals2::signal<void()> Started;
108  boost::signals2::signal<void()> Stopped;
110 
111 void RPCServerSignals::OnStarted(std::function<void()> slot) {
112  g_rpcSignals.Started.connect(slot);
113 }
114 
115 void RPCServerSignals::OnStopped(std::function<void()> slot) {
116  g_rpcSignals.Stopped.connect(slot);
117 }
118 
119 std::string CRPCTable::help(const Config &config, const std::string &strCommand,
120  const JSONRPCRequest &helpreq) const {
121  std::string strRet;
122  std::string category;
123  std::set<intptr_t> setDone;
124  std::vector<std::pair<std::string, const CRPCCommand *>> vCommands;
125 
126  for (const auto &entry : mapCommands) {
127  vCommands.push_back(
128  std::make_pair(entry.second.front()->category + entry.first,
129  entry.second.front()));
130  }
131  sort(vCommands.begin(), vCommands.end());
132 
133  JSONRPCRequest jreq = helpreq;
135  jreq.params = UniValue();
136 
137  for (const std::pair<std::string, const CRPCCommand *> &command :
138  vCommands) {
139  const CRPCCommand *pcmd = command.second;
140  std::string strMethod = pcmd->name;
141  if ((strCommand != "" || pcmd->category == "hidden") &&
142  strMethod != strCommand) {
143  continue;
144  }
145 
146  jreq.strMethod = strMethod;
147  try {
148  UniValue unused_result;
149  if (setDone.insert(pcmd->unique_id).second) {
150  pcmd->actor(config, jreq, unused_result,
151  true /* last_handler */);
152  }
153  } catch (const std::exception &e) {
154  // Help text is returned in an exception
155  std::string strHelp = std::string(e.what());
156  if (strCommand == "") {
157  if (strHelp.find('\n') != std::string::npos) {
158  strHelp = strHelp.substr(0, strHelp.find('\n'));
159  }
160 
161  if (category != pcmd->category) {
162  if (!category.empty()) {
163  strRet += "\n";
164  }
165  category = pcmd->category;
166  strRet += "== " + Capitalize(category) + " ==\n";
167  }
168  }
169  strRet += strHelp + "\n";
170  }
171  }
172  if (strRet == "") {
173  strRet = strprintf("help: unknown command: %s\n", strCommand);
174  }
175 
176  strRet = strRet.substr(0, strRet.size() - 1);
177  return strRet;
178 }
179 
180 static RPCHelpMan help() {
181  return RPCHelpMan{
182  "help",
183  "List all commands, or get help for a specified command.\n",
184  {
185  {"command", RPCArg::Type::STR, RPCArg::DefaultHint{"all commands"},
186  "The command to get help on"},
187  },
188  {
189  RPCResult{RPCResult::Type::STR, "", "The help text"},
191  },
192  RPCExamples{""},
193  [&](const RPCHelpMan &self, const Config &config,
194  const JSONRPCRequest &jsonRequest) -> UniValue {
195  std::string strCommand;
196  if (jsonRequest.params.size() > 0) {
197  strCommand = jsonRequest.params[0].get_str();
198  }
199  if (strCommand == "dump_all_command_conversions") {
200  // Used for testing only, undocumented
201  return tableRPC.dumpArgMap(config, jsonRequest);
202  }
203 
204  return tableRPC.help(config, strCommand, jsonRequest);
205  },
206  };
207 }
208 
209 static RPCHelpMan stop() {
210  static const std::string RESULT{PACKAGE_NAME " stopping"};
211  return RPCHelpMan{
212  "stop",
213  // Also accept the hidden 'wait' integer argument (milliseconds)
214  // For instance, 'stop 1000' makes the call wait 1 second before
215  // returning to the client (intended for testing)
216  "\nRequest a graceful shutdown of " PACKAGE_NAME ".",
217  {
218  {"wait",
221  "how long to wait in ms",
222  "",
223  {},
224  /* hidden */ true},
225  },
227  "A string with the content '" + RESULT + "'"},
228  RPCExamples{""},
229  [&](const RPCHelpMan &self, const Config &config,
230  const JSONRPCRequest &jsonRequest) -> UniValue {
231  // Event loop will exit after current HTTP requests have been
232  // handled, so this reply will get back to the client.
233  StartShutdown();
234  if (jsonRequest.params[0].isNum()) {
236  std::chrono::milliseconds{jsonRequest.params[0].get_int()});
237  }
238  return RESULT;
239  },
240  };
241 }
242 
243 static RPCHelpMan uptime() {
244  return RPCHelpMan{
245  "uptime",
246  "Returns the total uptime of the server.\n",
247  {},
249  "The number of seconds that the server has been running"},
250  RPCExamples{HelpExampleCli("uptime", "") +
251  HelpExampleRpc("uptime", "")},
252  [&](const RPCHelpMan &self, const Config &config,
253  const JSONRPCRequest &request) -> UniValue {
254  return GetTime() - GetStartupTime();
255  }};
256 }
257 
259  return RPCHelpMan{
260  "getrpcinfo",
261  "Returns details of the RPC server.\n",
262  {},
264  "",
265  "",
266  {
268  "active_commands",
269  "All active commands",
270  {
272  "",
273  "Information about an active command",
274  {
275  {RPCResult::Type::STR, "method",
276  "The name of the RPC command"},
277  {RPCResult::Type::NUM, "duration",
278  "The running time in microseconds"},
279  }},
280  }},
281  {RPCResult::Type::STR, "logpath",
282  "The complete file path to the debug log"},
283  }},
284  RPCExamples{HelpExampleCli("getrpcinfo", "") +
285  HelpExampleRpc("getrpcinfo", "")},
286 
287  [&](const RPCHelpMan &self, const Config &config,
288  const JSONRPCRequest &request) -> UniValue {
290  UniValue active_commands(UniValue::VARR);
291  for (const RPCCommandExecutionInfo &info :
292  g_rpc_server_info.active_commands) {
293  UniValue entry(UniValue::VOBJ);
294  entry.pushKV("method", info.method);
295  entry.pushKV("duration",
296  int64_t{Ticks<std::chrono::microseconds>(
297  SteadyClock::now() - info.start)});
298  active_commands.push_back(entry);
299  }
300 
301  UniValue result(UniValue::VOBJ);
302  result.pushKV("active_commands", active_commands);
303 
304  const std::string path = LogInstance().m_file_path.u8string();
305  UniValue log_path(UniValue::VSTR, path);
306  result.pushKV("logpath", log_path);
307 
308  return result;
309  }};
310 }
311 
312 // clang-format off
313 static const CRPCCommand vRPCCommands[] = {
314  // category actor (function)
315  // ------------------- ----------------------
316  /* Overall control/query calls */
317  { "control", getrpcinfo, },
318  { "control", help, },
319  { "control", stop, },
320  { "control", uptime, },
321 };
322 // clang-format on
323 
325  for (const auto &c : vRPCCommands) {
326  appendCommand(c.name, &c);
327  }
328 }
329 
330 void CRPCTable::appendCommand(const std::string &name,
331  const CRPCCommand *pcmd) {
332  // Only add commands before rpc is running
334 
335  mapCommands[name].push_back(pcmd);
336 }
337 
338 bool CRPCTable::removeCommand(const std::string &name,
339  const CRPCCommand *pcmd) {
340  auto it = mapCommands.find(name);
341  if (it != mapCommands.end()) {
342  auto new_end = std::remove(it->second.begin(), it->second.end(), pcmd);
343  if (it->second.end() != new_end) {
344  it->second.erase(new_end, it->second.end());
345  return true;
346  }
347  }
348  return false;
349 }
350 
351 void StartRPC() {
352  LogPrint(BCLog::RPC, "Starting RPC\n");
353  g_rpc_running = true;
355 }
356 
357 void InterruptRPC() {
358  static std::once_flag g_rpc_interrupt_flag;
359  // This function could be called twice if the GUI has been started with
360  // -server=1.
361  std::call_once(g_rpc_interrupt_flag, []() {
362  LogPrint(BCLog::RPC, "Interrupting RPC\n");
363  // Interrupt e.g. running longpolls
364  g_rpc_running = false;
365  });
366 }
367 
368 void StopRPC() {
369  static std::once_flag g_rpc_stop_flag;
370  // This function could be called twice if the GUI has been started with
371  // -server=1.
373  std::call_once(g_rpc_stop_flag, []() {
374  LogPrint(BCLog::RPC, "Stopping RPC\n");
375  WITH_LOCK(g_deadline_timers_mutex, deadlineTimers.clear());
378  });
379 }
380 
381 bool IsRPCRunning() {
382  return g_rpc_running;
383 }
384 
386  if (!IsRPCRunning()) {
387  throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
388  }
389 }
390 
391 void SetRPCWarmupStatus(const std::string &newStatus) {
393  rpcWarmupStatus = newStatus;
394 }
395 
398  assert(fRPCInWarmup);
399  fRPCInWarmup = false;
400 }
401 
402 bool RPCIsInWarmup(std::string *outStatus) {
404  if (outStatus) {
405  *outStatus = rpcWarmupStatus;
406  }
407  return fRPCInWarmup;
408 }
409 
411  const std::string &method) {
412  const std::vector<std::string> enabled_methods =
413  args.GetArgs("-deprecatedrpc");
414 
415  return find(enabled_methods.begin(), enabled_methods.end(), method) !=
416  enabled_methods.end();
417 }
418 
419 static UniValue JSONRPCExecOne(const Config &config, RPCServer &rpcServer,
420  JSONRPCRequest jreq, const UniValue &req) {
421  UniValue rpc_result(UniValue::VOBJ);
422 
423  try {
424  jreq.parse(req);
425 
426  UniValue result = rpcServer.ExecuteCommand(config, jreq);
427  rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id);
428  } catch (const UniValue &objError) {
429  rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id);
430  } catch (const std::exception &e) {
431  rpc_result = JSONRPCReplyObj(
432  NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
433  }
434 
435  return rpc_result;
436 }
437 
438 std::string JSONRPCExecBatch(const Config &config, RPCServer &rpcServer,
439  const JSONRPCRequest &jreq, const UniValue &vReq) {
441  for (size_t i = 0; i < vReq.size(); i++) {
442  ret.push_back(JSONRPCExecOne(config, rpcServer, jreq, vReq[i]));
443  }
444 
445  return ret.write() + "\n";
446 }
447 
452 static inline JSONRPCRequest
454  const std::vector<std::string> &argNames) {
455  JSONRPCRequest out = in;
457  // Build a map of parameters, and remove ones that have been processed, so
458  // that we can throw a focused error if there is an unknown one.
459  const std::vector<std::string> &keys = in.params.getKeys();
460  const std::vector<UniValue> &values = in.params.getValues();
461  std::unordered_map<std::string, const UniValue *> argsIn;
462  for (size_t i = 0; i < keys.size(); ++i) {
463  argsIn[keys[i]] = &values[i];
464  }
465  // Process expected parameters.
466  int hole = 0;
467  for (const std::string &argNamePattern : argNames) {
468  std::vector<std::string> vargNames = SplitString(argNamePattern, '|');
469  auto fr = argsIn.end();
470  for (const std::string &argName : vargNames) {
471  fr = argsIn.find(argName);
472  if (fr != argsIn.end()) {
473  break;
474  }
475  }
476  if (fr != argsIn.end()) {
477  for (int i = 0; i < hole; ++i) {
478  // Fill hole between specified parameters with JSON nulls, but
479  // not at the end (for backwards compatibility with calls that
480  // act based on number of specified parameters).
481  out.params.push_back(UniValue());
482  }
483  hole = 0;
484  out.params.push_back(*fr->second);
485  argsIn.erase(fr);
486  } else {
487  hole += 1;
488  }
489  }
490  // If there are still arguments in the argsIn map, this is an error.
491  if (!argsIn.empty()) {
493  "Unknown named parameter " + argsIn.begin()->first);
494  }
495  // Return request with named arguments transformed to positional arguments
496  return out;
497 }
498 
499 static bool ExecuteCommands(const Config &config,
500  const std::vector<const CRPCCommand *> &commands,
501  const JSONRPCRequest &request, UniValue &result) {
502  for (const auto &command : commands) {
503  if (ExecuteCommand(config, *command, request, result,
504  &command == &commands.back())) {
505  return true;
506  }
507  }
508  return false;
509 }
510 
512  const JSONRPCRequest &request) const {
513  // Return immediately if in warmup
514  {
516  if (fRPCInWarmup) {
517  throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
518  }
519  }
520 
521  // Find method
522  auto it = mapCommands.find(request.strMethod);
523  if (it != mapCommands.end()) {
524  UniValue result;
525  if (ExecuteCommands(config, it->second, request, result)) {
526  return result;
527  }
528  }
529  throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
530 }
531 
532 static bool ExecuteCommand(const Config &config, const CRPCCommand &command,
533  const JSONRPCRequest &request, UniValue &result,
534  bool last_handler) {
535  try {
536  RPCCommandExecution execution(request.strMethod);
537  // Execute, convert arguments to array if necessary
538  if (request.params.isObject()) {
539  return command.actor(
540  config, transformNamedArguments(request, command.argNames),
541  result, last_handler);
542  } else {
543  return command.actor(config, request, result, last_handler);
544  }
545  } catch (const std::exception &e) {
546  throw JSONRPCError(RPC_MISC_ERROR, e.what());
547  }
548 }
549 
550 std::vector<std::string> CRPCTable::listCommands() const {
551  std::vector<std::string> commandList;
552  for (const auto &i : mapCommands) {
553  commandList.emplace_back(i.first);
554  }
555  return commandList;
556 }
557 
559  const JSONRPCRequest &args_request) const {
560  JSONRPCRequest request = args_request;
561  request.mode = JSONRPCRequest::GET_ARGS;
562 
564  for (const auto &cmd : mapCommands) {
565  UniValue result;
566  if (ExecuteCommands(config, cmd.second, request, result)) {
567  for (const auto &values : result.getValues()) {
568  ret.push_back(values);
569  }
570  }
571  }
572  return ret;
573 }
574 
576  if (!timerInterface) {
577  timerInterface = iface;
578  }
579 }
580 
582  timerInterface = iface;
583 }
584 
586  if (timerInterface == iface) {
587  timerInterface = nullptr;
588  }
589 }
590 
591 void RPCRunLater(const std::string &name, std::function<void()> func,
592  int64_t nSeconds) {
593  if (!timerInterface) {
595  "No timer handler registered for RPC");
596  }
598  deadlineTimers.erase(name);
599  LogPrint(BCLog::RPC, "queue run of timer %s in %i seconds (using %s)\n",
600  name, nSeconds, timerInterface->Name());
601  deadlineTimers.emplace(
602  name, std::unique_ptr<RPCTimerBase>(
603  timerInterface->NewTimer(func, nSeconds * 1000)));
604 }
605 
607  return 0;
608 }
609 
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:53
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:480
fs::path m_file_path
Definition: logging.h:110
std::vector< std::string > argNames
Definition: server.h:176
std::string category
Definition: server.h:173
intptr_t unique_id
Definition: server.h:177
std::string name
Definition: server.h:174
Actor actor
Definition: server.h:175
RPC command dispatcher.
Definition: server.h:183
std::map< std::string, std::vector< const CRPCCommand * > > mapCommands
Definition: server.h:185
CRPCTable()
Definition: server.cpp:324
bool removeCommand(const std::string &name, const CRPCCommand *pcmd)
Definition: server.cpp:338
std::string help(const Config &config, const std::string &name, const JSONRPCRequest &helpreq) const
Definition: server.cpp:119
std::vector< std::string > listCommands() const
Returns a list of registered commands.
Definition: server.cpp:550
UniValue execute(const Config &config, const JSONRPCRequest &request) const
Execute a method.
Definition: server.cpp:511
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:330
UniValue dumpArgMap(const Config &config, 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:558
Definition: config.h:17
Different type to mark Mutex at global scope.
Definition: sync.h:144
UniValue params
Definition: request.h:34
std::string strMethod
Definition: request.h:33
enum JSONRPCRequest::Mode mode
UniValue id
Definition: request.h:32
void parse(const UniValue &valRequest)
Definition: request.cpp:163
Class for registering and managing all RPC calls.
Definition: server.h:39
UniValue ExecuteCommand(const Config &config, const JSONRPCRequest &request) const
Attempts to execute an RPC command from the given request.
Definition: server.cpp:69
RWCollection< RPCCommandMap > commands
Definition: server.h:41
void RegisterCommand(std::unique_ptr< RPCCommand > command)
Register an RPC command.
Definition: server.cpp:98
RPC timer "driver".
Definition: server.h:99
virtual RPCTimerBase * NewTimer(std::function< void()> &func, int64_t millis)=0
Factory function for timers.
virtual const char * Name()=0
Implementation name.
ReadView getReadView() const
Definition: rwcollection.h:78
WriteView getWriteView()
Definition: rwcollection.h:84
const std::string & get_str() const
@ VOBJ
Definition: univalue.h:27
@ VSTR
Definition: univalue.h:27
@ VARR
Definition: univalue.h:27
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
size_t size() const
Definition: univalue.h:80
const std::vector< UniValue > & getValues() const
const std::vector< std::string > & getKeys() const
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
bool isObject() const
Definition: univalue.h:96
std::string u8string() const
Definition: fs.h:72
BCLog::Logger & LogInstance()
Definition: logging.cpp:20
#define LogPrint(category,...)
Definition: logging.h:210
@ RPC
Definition: logging.h:47
void OnStarted(std::function< void()> slot)
Definition: server.cpp:111
void OnStopped(std::function< void()> slot)
Definition: server.cpp:115
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:57
void DeleteAuthCookie()
Delete RPC authentication cookie from disk.
Definition: request.cpp:134
UniValue JSONRPCReplyObj(const UniValue &result, const UniValue &error, const UniValue &id)
Definition: request.cpp:38
const char * name
Definition: rest.cpp:48
@ RPC_PARSE_ERROR
Definition: protocol.h:34
@ RPC_MISC_ERROR
General application defined errors std::exception thrown in command handling.
Definition: protocol.h:38
@ RPC_METHOD_NOT_FOUND
Definition: protocol.h:29
@ RPC_CLIENT_NOT_CONNECTED
P2P client errors Bitcoin is not connected.
Definition: protocol.h:69
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:46
@ RPC_IN_WARMUP
Client still warming up.
Definition: protocol.h:58
@ RPC_INTERNAL_ERROR
Definition: protocol.h:33
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:175
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:192
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
Set the factory function for timer, but only, if unset.
Definition: server.cpp:575
void SetRPCWarmupFinished()
Mark warmup as done.
Definition: server.cpp:396
bool IsDeprecatedRPCEnabled(const ArgsManager &args, const std::string &method)
Definition: server.cpp:410
static RPCHelpMan uptime()
Definition: server.cpp:243
std::chrono::steady_clock SteadyClock
Definition: server.cpp:26
void StartRPC()
Definition: server.cpp:351
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
Unset factory function for timers.
Definition: server.cpp:585
static RPCHelpMan getrpcinfo()
Definition: server.cpp:258
void RPCRunLater(const std::string &name, std::function< void()> func, int64_t nSeconds)
Run func nSeconds from now.
Definition: server.cpp:591
bool RPCIsInWarmup(std::string *outStatus)
Returns the current warmup state.
Definition: server.cpp:402
static UniValue JSONRPCExecOne(const Config &config, RPCServer &rpcServer, JSONRPCRequest jreq, const UniValue &req)
Definition: server.cpp:419
static RPCTimerInterface * timerInterface
Definition: server.cpp:34
void StopRPC()
Definition: server.cpp:368
static RPCHelpMan stop()
Definition: server.cpp:209
static std::atomic< bool > g_rpc_running
Definition: server.cpp:29
static GlobalMutex g_deadline_timers_mutex
Definition: server.cpp:36
bool IsRPCRunning()
Query whether RPC is running.
Definition: server.cpp:381
static bool ExecuteCommands(const Config &config, const std::vector< const CRPCCommand * > &commands, const JSONRPCRequest &request, UniValue &result)
Definition: server.cpp:499
int RPCSerializationFlags()
Retrieves any serialization flags requested in command line argument.
Definition: server.cpp:606
void InterruptRPC()
Definition: server.cpp:357
static struct CRPCSignals g_rpcSignals
static bool fRPCInWarmup GUARDED_BY(g_rpc_warmup_mutex)
static GlobalMutex g_rpc_warmup_mutex
Definition: server.cpp:28
static RPCHelpMan help()
Definition: server.cpp:180
static bool ExecuteCommand(const Config &config, const CRPCCommand &command, const JSONRPCRequest &request, UniValue &result, bool last_handler)
Definition: server.cpp:532
static RPCServerInfo g_rpc_server_info
Definition: server.cpp:53
static const CRPCCommand vRPCCommands[]
Definition: server.cpp:313
std::string JSONRPCExecBatch(const Config &config, RPCServer &rpcServer, const JSONRPCRequest &jreq, const UniValue &vReq)
Definition: server.cpp:438
void SetRPCWarmupStatus(const std::string &newStatus)
Set the RPC warmup status.
Definition: server.cpp:391
CRPCTable tableRPC
Definition: server.cpp:610
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:453
void RPCSetTimerInterface(RPCTimerInterface *iface)
Set the factory function for timers.
Definition: server.cpp:581
void RpcInterruptionPoint()
Throw JSONRPCError if RPC is not running.
Definition: server.cpp:385
void StartShutdown()
Request shutdown of the application.
Definition: shutdown.cpp:55
std::string Capitalize(std::string str)
Capitalizes the first character of the given string.
std::vector< std::string > SplitString(std::string_view str, char sep)
Definition: string.h:23
boost::signals2::signal< void()> Started
Definition: server.cpp:107
boost::signals2::signal< void()> Stopped
Definition: server.cpp:108
std::string DefaultHint
Definition: util.h:173
@ OMITTED_NAMED_ARG
Optional arg that is a named argument and has a default value of null.
RPCCommandExecution(const std::string &method)
Definition: server.cpp:57
std::list< RPCCommandExecutionInfo >::iterator it
Definition: server.cpp:56
SteadyClock::time_point start
Definition: server.cpp:45
std::string method
Definition: server.cpp:44
@ ANY
Special type to disable type checks (for testing only)
Mutex mutex
Definition: server.cpp:49
std::list< RPCCommandExecutionInfo > active_commands GUARDED_BY(mutex)
#define LOCK(cs)
Definition: sync.h:306
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:357
int64_t GetStartupTime()
Server/client environment: argument handling, config file parsing, thread wrappers,...
Definition: system.cpp:1449
void UninterruptibleSleep(const std::chrono::microseconds &n)
Definition: time.cpp:23
int64_t GetTime()
Definition: time.cpp:109
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
const UniValue NullUniValue
Definition: univalue.cpp:13
assert(!tx.IsCoinBase())