Bitcoin ABC  0.29.9
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  {
221  "how long to wait in ms", RPCArgOptions{.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()) {
232  UninterruptibleSleep(std::chrono::milliseconds{
233  jsonRequest.params[0].getInt<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",
293  int64_t{Ticks<std::chrono::microseconds>(
294  SteadyClock::now() - info.start)});
295  active_commands.push_back(entry);
296  }
297 
298  UniValue result(UniValue::VOBJ);
299  result.pushKV("active_commands", active_commands);
300 
301  const std::string path = LogInstance().m_file_path.u8string();
302  UniValue log_path(UniValue::VSTR, path);
303  result.pushKV("logpath", log_path);
304 
305  return result;
306  }};
307 }
308 
309 // clang-format off
310 static const CRPCCommand vRPCCommands[] = {
311  // category actor (function)
312  // ------------------- ----------------------
313  /* Overall control/query calls */
314  { "control", getrpcinfo, },
315  { "control", help, },
316  { "control", stop, },
317  { "control", uptime, },
318 };
319 // clang-format on
320 
322  for (const auto &c : vRPCCommands) {
323  appendCommand(c.name, &c);
324  }
325 }
326 
327 void CRPCTable::appendCommand(const std::string &name,
328  const CRPCCommand *pcmd) {
329  // Only add commands before rpc is running
331 
332  mapCommands[name].push_back(pcmd);
333 }
334 
335 bool CRPCTable::removeCommand(const std::string &name,
336  const CRPCCommand *pcmd) {
337  auto it = mapCommands.find(name);
338  if (it != mapCommands.end()) {
339  auto new_end = std::remove(it->second.begin(), it->second.end(), pcmd);
340  if (it->second.end() != new_end) {
341  it->second.erase(new_end, it->second.end());
342  return true;
343  }
344  }
345  return false;
346 }
347 
348 void StartRPC() {
349  LogPrint(BCLog::RPC, "Starting RPC\n");
350  g_rpc_running = true;
352 }
353 
354 void InterruptRPC() {
355  static std::once_flag g_rpc_interrupt_flag;
356  // This function could be called twice if the GUI has been started with
357  // -server=1.
358  std::call_once(g_rpc_interrupt_flag, []() {
359  LogPrint(BCLog::RPC, "Interrupting RPC\n");
360  // Interrupt e.g. running longpolls
361  g_rpc_running = false;
362  });
363 }
364 
365 void StopRPC() {
366  static std::once_flag g_rpc_stop_flag;
367  // This function could be called twice if the GUI has been started with
368  // -server=1.
370  std::call_once(g_rpc_stop_flag, []() {
371  LogPrint(BCLog::RPC, "Stopping RPC\n");
372  WITH_LOCK(g_deadline_timers_mutex, deadlineTimers.clear());
375  });
376 }
377 
378 bool IsRPCRunning() {
379  return g_rpc_running;
380 }
381 
383  if (!IsRPCRunning()) {
384  throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
385  }
386 }
387 
388 void SetRPCWarmupStatus(const std::string &newStatus) {
390  rpcWarmupStatus = newStatus;
391 }
392 
395  assert(fRPCInWarmup);
396  fRPCInWarmup = false;
397 }
398 
399 bool RPCIsInWarmup(std::string *outStatus) {
401  if (outStatus) {
402  *outStatus = rpcWarmupStatus;
403  }
404  return fRPCInWarmup;
405 }
406 
408  const std::string &method) {
409  const std::vector<std::string> enabled_methods =
410  args.GetArgs("-deprecatedrpc");
411 
412  return find(enabled_methods.begin(), enabled_methods.end(), method) !=
413  enabled_methods.end();
414 }
415 
416 static UniValue JSONRPCExecOne(const Config &config, RPCServer &rpcServer,
417  JSONRPCRequest jreq, const UniValue &req) {
418  UniValue rpc_result(UniValue::VOBJ);
419 
420  try {
421  jreq.parse(req);
422 
423  UniValue result = rpcServer.ExecuteCommand(config, jreq);
424  rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id);
425  } catch (const UniValue &objError) {
426  rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id);
427  } catch (const std::exception &e) {
428  rpc_result = JSONRPCReplyObj(
429  NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
430  }
431 
432  return rpc_result;
433 }
434 
435 std::string JSONRPCExecBatch(const Config &config, RPCServer &rpcServer,
436  const JSONRPCRequest &jreq, const UniValue &vReq) {
438  for (size_t i = 0; i < vReq.size(); i++) {
439  ret.push_back(JSONRPCExecOne(config, rpcServer, jreq, vReq[i]));
440  }
441 
442  return ret.write() + "\n";
443 }
444 
450  const JSONRPCRequest &in,
451  const std::vector<std::pair<std::string, bool>> &argNames) {
452  JSONRPCRequest out = in;
454  // Build a map of parameters, and remove ones that have been processed, so
455  // that we can throw a focused error if there is an unknown one.
456  const std::vector<std::string> &keys = in.params.getKeys();
457  const std::vector<UniValue> &values = in.params.getValues();
458  std::unordered_map<std::string, const UniValue *> argsIn;
459  for (size_t i = 0; i < keys.size(); ++i) {
460  auto [_, inserted] = argsIn.emplace(keys[i], &values[i]);
461  if (!inserted) {
463  "Parameter " + keys[i] +
464  " specified multiple times");
465  }
466  }
467  // Process expected parameters. If any parameters were left unspecified in
468  // the request before a parameter that was specified, null values need to be
469  // inserted at the unspecifed parameter positions, and the "hole" variable
470  // below tracks the number of null values that need to be inserted.
471  // The "initial_hole_size" variable stores the size of the initial hole,
472  // i.e. how many initial positional arguments were left unspecified. This is
473  // used after the for-loop to add initial positional arguments from the
474  // "args" parameter, if present.
475  size_t hole = 0;
476  size_t initial_hole_size = 0;
477  const std::string *initial_param = nullptr;
478  UniValue options{UniValue::VOBJ};
479  for (const auto &[argNamePattern, named_only] : argNames) {
480  std::vector<std::string> vargNames = SplitString(argNamePattern, '|');
481  auto fr = argsIn.end();
482  for (const std::string &argName : vargNames) {
483  fr = argsIn.find(argName);
484  if (fr != argsIn.end()) {
485  break;
486  }
487  }
488 
489  // Handle named-only parameters by pushing them into a temporary options
490  // object, and then pushing the accumulated options as the next
491  // positional argument.
492  if (named_only) {
493  if (fr != argsIn.end()) {
494  if (options.exists(fr->first)) {
496  "Parameter " + fr->first +
497  " specified multiple times");
498  }
499  options.pushKVEnd(fr->first, *fr->second);
500  argsIn.erase(fr);
501  }
502  continue;
503  }
504 
505  if (!options.empty() || fr != argsIn.end()) {
506  for (size_t i = 0; i < hole; ++i) {
507  // Fill hole between specified parameters with JSON nulls,
508  // but not at the end (for backwards compatibility with calls
509  // that act based on number of specified parameters).
510  out.params.push_back(UniValue());
511  }
512  hole = 0;
513  if (!initial_param) {
514  initial_param = &argNamePattern;
515  }
516  } else {
517  hole += 1;
518  if (out.params.empty()) {
519  initial_hole_size = hole;
520  }
521  }
522 
523  // If named input parameter "fr" is present, push it onto out.params. If
524  // options are present, push them onto out.params. If both are present,
525  // throw an error.
526  if (fr != argsIn.end()) {
527  if (!options.empty()) {
529  "Parameter " + fr->first +
530  " conflicts with parameter " +
531  options.getKeys().front());
532  }
533  out.params.push_back(*fr->second);
534  argsIn.erase(fr);
535  }
536  if (!options.empty()) {
537  out.params.push_back(std::move(options));
538  options = UniValue{UniValue::VOBJ};
539  }
540  }
541  // If leftover "args" param was found, use it as a source of positional
542  // arguments and add named arguments after. This is a convenience for
543  // clients that want to pass a combination of named and positional
544  // arguments as described in doc/JSON-RPC-interface.md#parameter-passing
545  auto positional_args{argsIn.extract("args")};
546  if (positional_args && positional_args.mapped()->isArray()) {
547  if (initial_hole_size < positional_args.mapped()->size() &&
548  initial_param) {
549  throw JSONRPCError(
551  "Parameter " + *initial_param +
552  " specified twice both as positional and named argument");
553  }
554  // Assign positional_args to out.params and append named_args after.
555  UniValue named_args{std::move(out.params)};
556  out.params = *positional_args.mapped();
557  for (size_t i{out.params.size()}; i < named_args.size(); ++i) {
558  out.params.push_back(named_args[i]);
559  }
560  }
561  // If there are still arguments in the argsIn map, this is an error.
562  if (!argsIn.empty()) {
564  "Unknown named parameter " + argsIn.begin()->first);
565  }
566  // Return request with named arguments transformed to positional arguments
567  return out;
568 }
569 
570 static bool ExecuteCommands(const Config &config,
571  const std::vector<const CRPCCommand *> &commands,
572  const JSONRPCRequest &request, UniValue &result) {
573  for (const auto &command : commands) {
574  if (ExecuteCommand(config, *command, request, result,
575  &command == &commands.back())) {
576  return true;
577  }
578  }
579  return false;
580 }
581 
583  const JSONRPCRequest &request) const {
584  // Return immediately if in warmup
585  {
587  if (fRPCInWarmup) {
588  throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus);
589  }
590  }
591 
592  // Find method
593  auto it = mapCommands.find(request.strMethod);
594  if (it != mapCommands.end()) {
595  UniValue result;
596  if (ExecuteCommands(config, it->second, request, result)) {
597  return result;
598  }
599  }
600  throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
601 }
602 
603 static bool ExecuteCommand(const Config &config, const CRPCCommand &command,
604  const JSONRPCRequest &request, UniValue &result,
605  bool last_handler) {
606  try {
607  RPCCommandExecution execution(request.strMethod);
608  // Execute, convert arguments to array if necessary
609  if (request.params.isObject()) {
610  return command.actor(
611  config, transformNamedArguments(request, command.argNames),
612  result, last_handler);
613  } else {
614  return command.actor(config, request, result, last_handler);
615  }
616  } catch (const UniValue::type_error &e) {
617  throw JSONRPCError(RPC_TYPE_ERROR, e.what());
618  } catch (const std::exception &e) {
619  throw JSONRPCError(RPC_MISC_ERROR, e.what());
620  }
621 }
622 
623 std::vector<std::string> CRPCTable::listCommands() const {
624  std::vector<std::string> commandList;
625  for (const auto &i : mapCommands) {
626  commandList.emplace_back(i.first);
627  }
628  return commandList;
629 }
630 
632  const JSONRPCRequest &args_request) const {
633  JSONRPCRequest request = args_request;
634  request.mode = JSONRPCRequest::GET_ARGS;
635 
637  for (const auto &cmd : mapCommands) {
638  UniValue result;
639  if (ExecuteCommands(config, cmd.second, request, result)) {
640  for (const auto &values : result.getValues()) {
641  ret.push_back(values);
642  }
643  }
644  }
645  return ret;
646 }
647 
649  if (!timerInterface) {
650  timerInterface = iface;
651  }
652 }
653 
655  timerInterface = iface;
656 }
657 
659  if (timerInterface == iface) {
660  timerInterface = nullptr;
661  }
662 }
663 
664 void RPCRunLater(const std::string &name, std::function<void()> func,
665  int64_t nSeconds) {
666  if (!timerInterface) {
668  "No timer handler registered for RPC");
669  }
671  deadlineTimers.erase(name);
672  LogPrint(BCLog::RPC, "queue run of timer %s in %i seconds (using %s)\n",
673  name, nSeconds, timerInterface->Name());
674  deadlineTimers.emplace(
675  name, std::unique_ptr<RPCTimerBase>(
676  timerInterface->NewTimer(func, nSeconds * 1000)));
677 }
678 
680  return 0;
681 }
682 
#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:111
std::string category
Definition: server.h:175
intptr_t unique_id
Definition: server.h:188
std::vector< std::pair< std::string, bool > > argNames
List of method arguments and whether they are named-only.
Definition: server.h:187
std::string name
Definition: server.h:176
Actor actor
Definition: server.h:177
RPC command dispatcher.
Definition: server.h:194
std::map< std::string, std::vector< const CRPCCommand * > > mapCommands
Definition: server.h:196
CRPCTable()
Definition: server.cpp:321
bool removeCommand(const std::string &name, const CRPCCommand *pcmd)
Definition: server.cpp:335
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:623
UniValue execute(const Config &config, const JSONRPCRequest &request) const
Execute a method.
Definition: server.cpp:582
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:327
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:631
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
void push_back(UniValue val)
Definition: univalue.cpp:96
const std::string & get_str() const
@ VOBJ
Definition: univalue.h:31
@ VSTR
Definition: univalue.h:33
@ VARR
Definition: univalue.h:32
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
size_t size() const
Definition: univalue.h:92
const std::vector< UniValue > & getValues() const
const std::vector< std::string > & getKeys() const
bool empty() const
Definition: univalue.h:90
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:115
bool isObject() const
Definition: univalue.h:111
std::string u8string() const
Definition: fs.h:72
BCLog::Logger & LogInstance()
Definition: logging.cpp:20
#define LogPrint(category,...)
Definition: logging.h:211
@ 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_TYPE_ERROR
Unexpected type was passed as parameter.
Definition: protocol.h:40
@ 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:150
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:167
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
Set the factory function for timer, but only, if unset.
Definition: server.cpp:648
void SetRPCWarmupFinished()
Mark warmup as done.
Definition: server.cpp:393
bool IsDeprecatedRPCEnabled(const ArgsManager &args, const std::string &method)
Definition: server.cpp:407
static RPCHelpMan uptime()
Definition: server.cpp:240
std::chrono::steady_clock SteadyClock
Definition: server.cpp:28
void StartRPC()
Definition: server.cpp:348
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
Unset factory function for timers.
Definition: server.cpp:658
static RPCHelpMan getrpcinfo()
Definition: server.cpp:255
void RPCRunLater(const std::string &name, std::function< void()> func, int64_t nSeconds)
Run func nSeconds from now.
Definition: server.cpp:664
bool RPCIsInWarmup(std::string *outStatus)
Returns the current warmup state.
Definition: server.cpp:399
static UniValue JSONRPCExecOne(const Config &config, RPCServer &rpcServer, JSONRPCRequest jreq, const UniValue &req)
Definition: server.cpp:416
static RPCTimerInterface * timerInterface
Definition: server.cpp:36
void StopRPC()
Definition: server.cpp:365
static RPCHelpMan stop()
Definition: server.cpp:211
static JSONRPCRequest transformNamedArguments(const JSONRPCRequest &in, const std::vector< std::pair< std::string, bool >> &argNames)
Process named arguments into a vector of positional arguments, based on the passed-in specification f...
Definition: server.cpp:449
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:378
static bool ExecuteCommands(const Config &config, const std::vector< const CRPCCommand * > &commands, const JSONRPCRequest &request, UniValue &result)
Definition: server.cpp:570
int RPCSerializationFlags()
Retrieves any serialization flags requested in command line argument.
Definition: server.cpp:679
void InterruptRPC()
Definition: server.cpp:354
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:603
static RPCServerInfo g_rpc_server_info
Definition: server.cpp:55
static const CRPCCommand vRPCCommands[]
Definition: server.cpp:310
std::string JSONRPCExecBatch(const Config &config, RPCServer &rpcServer, const JSONRPCRequest &jreq, const UniValue &vReq)
Definition: server.cpp:435
void SetRPCWarmupStatus(const std::string &newStatus)
Set the RPC warmup status.
Definition: server.cpp:388
CRPCTable tableRPC
Definition: server.cpp:683
void RPCSetTimerInterface(RPCTimerInterface *iface)
Set the factory function for timers.
Definition: server.cpp:654
void RpcInterruptionPoint()
Throw JSONRPCError if RPC is not running.
Definition: server.cpp:382
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:22
boost::signals2::signal< void()> Started
Definition: server.cpp:109
boost::signals2::signal< void()> Stopped
Definition: server.cpp:110
std::string DefaultHint
Hint for default value.
Definition: util.h:195
bool hidden
For testing only.
Definition: util.h:136
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
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:68
const UniValue NullUniValue
Definition: univalue.cpp:16
assert(!tx.IsCoinBase())