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