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