rippled
Main.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/app/main/Application.h>
21 #include <ripple/app/main/DBInit.h>
22 #include <ripple/basics/Log.h>
23 #include <ripple/basics/StringUtilities.h>
24 #include <ripple/basics/contract.h>
25 #include <ripple/beast/clock/basic_seconds_clock.h>
26 #include <ripple/beast/core/CurrentThreadName.h>
27 #include <ripple/core/Config.h>
28 #include <ripple/core/ConfigSections.h>
29 #include <ripple/core/DatabaseCon.h>
30 #include <ripple/core/TimeKeeper.h>
31 #include <ripple/json/to_string.h>
32 #include <ripple/net/RPCCall.h>
33 #include <ripple/protocol/BuildInfo.h>
34 #include <ripple/resource/Fees.h>
35 #include <ripple/rpc/RPCHandler.h>
36 
37 #include <beast/unit_test/match.hpp>
38 #include <test/unit_test/multi_runner.h>
39 
40 #include <google/protobuf/stubs/common.h>
41 
42 #include <boost/filesystem.hpp>
43 #include <boost/predef.h>
44 #include <boost/process.hpp>
45 #include <boost/program_options.hpp>
46 
47 #include <cstdlib>
48 #include <iostream>
49 #include <stdexcept>
50 #include <utility>
51 
52 #if BOOST_OS_WINDOWS
53 #include <sys/timeb.h>
54 #include <sys/types.h>
55 #endif
56 
57 // Do we know the plaform we're compiling on? If you're adding new platforms
58 // modify this check accordingly.
59 #if !BOOST_OS_LINUX && !BOOST_OS_WINDOWS && !BOOST_OS_MACOS
60 #error Supported platforms are: Linux, Windows and MacOS
61 #endif
62 
63 // Ensure that precisely one platform is detected.
64 #if (BOOST_OS_LINUX && (BOOST_OS_WINDOWS || BOOST_OS_MACOS)) || \
65  (BOOST_OS_MACOS && (BOOST_OS_WINDOWS || BOOST_OS_LINUX)) || \
66  (BOOST_OS_WINDOWS && (BOOST_OS_LINUX || BOOST_OS_MACOS))
67 #error Multiple supported platforms appear active at once
68 #endif
69 
70 namespace po = boost::program_options;
71 
72 namespace ripple {
73 
74 bool
76 {
77 #ifdef RLIMIT_NOFILE
78  // Get the current limit, then adjust it to what we need.
79  struct rlimit rl;
80 
81  int available = 0;
82 
83  if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
84  {
85  // If the limit is infinite, then we are good.
86  if (rl.rlim_cur == RLIM_INFINITY)
87  available = needed;
88  else
89  available = rl.rlim_cur;
90 
91  if (available < needed)
92  {
93  // Ignore the rlim_max, as the process may
94  // be configured to override it anyways. We
95  // ask for the number descriptors we need.
96  rl.rlim_cur = needed;
97 
98  if (setrlimit(RLIMIT_NOFILE, &rl) == 0)
99  available = rl.rlim_cur;
100  }
101  }
102 
103  if (needed > available)
104  {
105  j.fatal() << "Insufficient number of file descriptors: " << needed
106  << " are needed, but only " << available << " are available.";
107 
108  std::cerr << "Insufficient number of file descriptors: " << needed
109  << " are needed, but only " << available
110  << " are available.\n";
111 
112  return false;
113  }
114 #endif
115 
116  return true;
117 }
118 
119 void
120 printHelp(const po::options_description& desc)
121 {
122  std::cerr
123  << systemName() << "d [options] <command> <params>\n"
124  << desc << std::endl
125  << "Commands: \n"
126  " account_currencies <account> [<ledger>] [strict]\n"
127  " account_info <account>|<seed>|<pass_phrase>|<key> [<ledger>] "
128  "[strict]\n"
129  " account_lines <account> <account>|\"\" [<ledger>]\n"
130  " account_channels <account> <account>|\"\" [<ledger>]\n"
131  " account_objects <account> [<ledger>] [strict]\n"
132  " account_offers <account>|<account_public_key> [<ledger>] "
133  "[strict]\n"
134  " account_tx accountID [ledger_min [ledger_max [limit "
135  "[offset]]]] [binary] [count] [descending]\n"
136  " book_offers <taker_pays> <taker_gets> [<taker [<ledger> "
137  "[<limit> [<proof> [<marker>]]]]]\n"
138  " can_delete [<ledgerid>|<ledgerhash>|now|always|never]\n"
139  " channel_authorize <private_key> <channel_id> <drops>\n"
140  " channel_verify <public_key> <channel_id> <drops> <signature>\n"
141  " connect <ip> [<port>]\n"
142  " consensus_info\n"
143  " deposit_authorized <source_account> <destination_account> "
144  "[<ledger>]\n"
145  " download_shard [[<index> <url>]]\n"
146  " feature [<feature> [accept|reject]]\n"
147  " fetch_info [clear]\n"
148  " gateway_balances [<ledger>] <issuer_account> [ <hotwallet> [ "
149  "<hotwallet> ]]\n"
150  " get_counts\n"
151  " json <method> <json>\n"
152  " ledger [<id>|current|closed|validated] [full]\n"
153  " ledger_accept\n"
154  " ledger_cleaner\n"
155  " ledger_closed\n"
156  " ledger_current\n"
157  " ledger_request <ledger>\n"
158  " log_level [[<partition>] <severity>]\n"
159  " logrotate \n"
160  " peers\n"
161  " ping\n"
162  " random\n"
163  " peer_reservations_add <public_key> [<description>]\n"
164  " peer_reservations_del <public_key>\n"
165  " peer_reservations_list\n"
166  " ripple ...\n"
167  " ripple_path_find <json> [<ledger>]\n"
168  " server_info [counters]\n"
169  " server_state [counters]\n"
170  " sign <private_key> <tx_json> [offline]\n"
171  " sign_for <signer_address> <signer_private_key> <tx_json> "
172  "[offline]\n"
173  " stop\n"
174  " submit <tx_blob>|[<private_key> <tx_json>]\n"
175  " submit_multisigned <tx_json>\n"
176  " tx <id>\n"
177  " validation_create [<seed>|<pass_phrase>|<key>]\n"
178  " validators\n"
179  " validator_list_sites\n"
180  " version\n"
181  " wallet_propose [<passphrase>]\n";
182 }
183 
184 //------------------------------------------------------------------------------
185 
186 /* simple unit test selector that allows a comma separated list
187  * of selectors
188  */
189 class multi_selector
190 {
191 private:
193 
194 public:
195  explicit multi_selector(std::string const& patterns = "")
196  {
198  boost::split(v, patterns, boost::algorithm::is_any_of(","));
199  selectors_.reserve(v.size());
200  std::for_each(v.begin(), v.end(), [this](std::string s) {
201  boost::trim(s);
202  if (selectors_.empty() || !s.empty())
203  selectors_.emplace_back(
204  beast::unit_test::selector::automatch, s);
205  });
206  }
207 
208  bool
209  operator()(beast::unit_test::suite_info const& s)
210  {
211  for (auto& sel : selectors_)
212  if (sel(s))
213  return true;
214  return false;
215  }
216 };
217 
218 namespace test {
220 }
221 
222 static int
223 runUnitTests(
224  std::string const& pattern,
225  std::string const& argument,
226  bool quiet,
227  bool log,
228  bool child,
229  bool ipv6,
230  std::size_t num_jobs,
231  int argc,
232  char** argv)
233 {
234  using namespace beast::unit_test;
235  using namespace ripple::test;
236 
237  ripple::test::envUseIPv4 = (!ipv6);
238 
239  if (!child && num_jobs == 1)
240  {
241  multi_runner_parent parent_runner;
242 
243  multi_runner_child child_runner{num_jobs, quiet, log};
244  child_runner.arg(argument);
245  auto const any_failed = child_runner.run_multi(multi_selector(pattern));
246 
247  if (any_failed)
248  return EXIT_FAILURE;
249  return EXIT_SUCCESS;
250  }
251  if (!child)
252  {
253  multi_runner_parent parent_runner;
255 
256  std::string const exe_name = argv[0];
258  {
259  args.reserve(argc);
260  for (int i = 1; i < argc; ++i)
261  args.emplace_back(argv[i]);
262  args.emplace_back("--unittest-child");
263  }
264 
265  for (std::size_t i = 0; i < num_jobs; ++i)
266  children.emplace_back(
267  boost::process::exe = exe_name, boost::process::args = args);
268 
269  int bad_child_exits = 0;
270  for (auto& c : children)
271  {
272  try
273  {
274  c.wait();
275  if (c.exit_code())
276  ++bad_child_exits;
277  }
278  catch (...)
279  {
280  // wait throws if process was terminated with a signal
281  ++bad_child_exits;
282  }
283  }
284 
285  if (parent_runner.any_failed() || bad_child_exits)
286  return EXIT_FAILURE;
287  return EXIT_SUCCESS;
288  }
289  else
290  {
291  // child
292  multi_runner_child runner{num_jobs, quiet, log};
293  runner.arg(argument);
294  auto const anyFailed = runner.run_multi(multi_selector(pattern));
295 
296  if (anyFailed)
297  return EXIT_FAILURE;
298  return EXIT_SUCCESS;
299  }
300 }
301 
302 //------------------------------------------------------------------------------
303 
304 int
305 run(int argc, char** argv)
306 {
307  using namespace std;
308 
310  "rippled: main " + BuildInfo::getVersionString());
311 
312  po::variables_map vm;
313 
314  std::string importText;
315  {
316  importText += "Import an existing node database (specified in the [";
317  importText += ConfigSection::importNodeDatabase();
318  importText += "] configuration file section) into the current ";
319  importText += "node database (specified in the [";
320  importText += ConfigSection::nodeDatabase();
321  importText += "] configuration file section).";
322  }
323  std::string shardsText;
324  {
325  shardsText += "Validate an existing shard database (specified in the [";
326  shardsText += ConfigSection::shardDatabase();
327  shardsText += "] configuration file section).";
328  }
329 
330  // Set up option parsing.
331  //
332  po::options_description gen("General Options");
333  gen.add_options()(
334  "conf", po::value<std::string>(), "Specify the configuration file.")(
335  "debug", "Enable normally suppressed debug logging")(
336  "help,h", "Display this message.")(
337  "quorum",
338  po::value<std::size_t>(),
339  "Override the minimum validation quorum.")(
340  "silent", "No output to the console after startup.")(
341  "standalone,a", "Run with no peers.")("verbose,v", "Verbose logging.")(
342  "version", "Display the build version.");
343 
344  po::options_description data("Ledger/Data Options");
345  data.add_options()("import", importText.c_str())(
346  "ledger",
347  po::value<std::string>(),
348  "Load the specified ledger and start from the value given.")(
349  "ledgerfile",
350  po::value<std::string>(),
351  "Load the specified ledger file.")(
352  "load", "Load the current ledger from the local DB.")(
353  "net", "Get the initial ledger from the network.")(
354  "nodetoshard", "Import node store into shards")(
355  "replay", "Replay a ledger close.")(
356  "start", "Start from a fresh Ledger.")(
357  "vacuum",
358  po::value<std::string>(),
359  "VACUUM the transaction db. Mandatory string argument specifies "
360  "temporary directory path.")(
361  "valid", "Consider the initial ledger a valid network ledger.")(
362  "validateShards", shardsText.c_str());
363 
364  po::options_description rpc("RPC Client Options");
365  rpc.add_options()(
366  "rpc",
367  "Perform rpc command - see below for available commands. "
368  "This is assumed if any positional parameters are provided.")(
369  "rpc_ip",
370  po::value<std::string>(),
371  "Specify the IP address for RPC command. "
372  "Format: <ip-address>[':'<port-number>]")(
373  "rpc_port",
374  po::value<std::uint16_t>(),
375  "DEPRECATED: include with rpc_ip instead. "
376  "Specify the port number for RPC command.");
377 
378  po::options_description test("Unit Test Options");
379  test.add_options()(
380  "quiet,q",
381  "Suppress test suite messages, "
382  "including suite/case name (at start) and test log messages.")(
383  "unittest,u",
384  po::value<std::string>()->implicit_value(""),
385  "Perform unit tests. The optional argument specifies one or "
386  "more comma-separated selectors. Each selector specifies a suite name, "
387  "full-name (lib.module.suite), module, or library "
388  "(checked in that "
389  "order).")(
390  "unittest-arg",
391  po::value<std::string>()->implicit_value(""),
392  "Supplies an argument string to unit tests. If provided, this argument "
393  "is made available to each suite that runs. Interpretation of the "
394  "argument is handled individually by any suite that accesses it -- "
395  "as such, it typically only make sense to provide this when running "
396  "a single suite.")(
397  "unittest-ipv6",
398  "Use IPv6 localhost when running unittests (default is IPv4).")(
399  "unittest-log",
400  "Force unit test log message output. Only useful in combination with "
401  "--quiet, in which case log messages will print but suite/case names "
402  "will not.")(
403  "unittest-jobs",
404  po::value<std::size_t>(),
405  "Number of unittest jobs to run in parallel (child processes).");
406 
407  // These are hidden options, not intended to be shown in the usage/help
408  // message
409  po::options_description hidden("Hidden Options");
410  hidden.add_options()(
411  "parameters",
412  po::value<vector<string>>(),
413  "Specify rpc command and parameters. This option must be repeated "
414  "for each command/param. Positional parameters also serve this "
415  "purpose, "
416  "so this option is not needed for users")(
417  "unittest-child",
418  "For internal use only when spawning child unit test processes.")(
419  "fg", "Deprecated: server always in foreground mode.");
420 
421  // Interpret positional arguments as --parameters.
422  po::positional_options_description p;
423  p.add("parameters", -1);
424 
425  po::options_description all;
426  all.add(gen).add(rpc).add(data).add(test).add(hidden);
427 
428  po::options_description desc;
429  desc.add(gen).add(rpc).add(data).add(test);
430 
431  // Parse options, if no error.
432  try
433  {
434  po::store(
435  po::command_line_parser(argc, argv)
436  .options(all) // Parse options.
437  .positional(p) // Remainder as --parameters.
438  .run(),
439  vm);
440  po::notify(vm); // Invoke option notify functions.
441  }
442  catch (std::exception const& ex)
443  {
444  std::cerr << "rippled: " << ex.what() << std::endl;
445  std::cerr << "Try 'rippled --help' for a list of options." << std::endl;
446  return 1;
447  }
448 
449  if (vm.count("help"))
450  {
451  printHelp(desc);
452  return 0;
453  }
454 
455  if (vm.count("version"))
456  {
457  std::cout << "rippled version " << BuildInfo::getVersionString()
458  << std::endl;
459  return 0;
460  }
461 
462  // Run the unit tests if requested.
463  // The unit tests will exit the application with an appropriate return code.
464  //
465  if (vm.count("unittest"))
466  {
467  std::string argument;
468 
469  if (vm.count("unittest-arg"))
470  argument = vm["unittest-arg"].as<std::string>();
471 
472  std::size_t numJobs = 1;
473  bool unittestChild = false;
474  if (vm.count("unittest-jobs"))
475  numJobs = std::max(numJobs, vm["unittest-jobs"].as<std::size_t>());
476  unittestChild = bool(vm.count("unittest-child"));
477 
478  return runUnitTests(
479  vm["unittest"].as<std::string>(),
480  argument,
481  bool(vm.count("quiet")),
482  bool(vm.count("unittest-log")),
483  unittestChild,
484  bool(vm.count("unittest-ipv6")),
485  numJobs,
486  argc,
487  argv);
488  }
489  else
490  {
491  if (vm.count("unittest-jobs"))
492  {
493  // unittest jobs only makes sense with `unittest`
494  std::cerr << "rippled: '--unittest-jobs' specified without "
495  "'--unittest'.\n";
496  std::cerr << "To run the unit tests the '--unittest' option must "
497  "be present.\n";
498  return 1;
499  }
500  }
501 
502  auto config = std::make_unique<Config>();
503 
504  auto configFile =
505  vm.count("conf") ? vm["conf"].as<std::string>() : std::string();
506 
507  // config file, quiet flag.
508  config->setup(
509  configFile,
510  bool(vm.count("quiet")),
511  bool(vm.count("silent")),
512  bool(vm.count("standalone")));
513 
514  if (vm.count("vacuum"))
515  {
516  if (config->standalone())
517  {
518  std::cerr << "vacuum not applicable in standalone mode.\n";
519  return -1;
520  }
521 
522  using namespace boost::filesystem;
523  DatabaseCon::Setup dbSetup = setup_DatabaseCon(*config);
524  path dbPath = dbSetup.dataDir / TxDBName;
525  path tmpPath = vm["vacuum"].as<std::string>();
526 
527  try
528  {
529  uintmax_t const dbSize = file_size(dbPath);
530  assert(dbSize != static_cast<uintmax_t>(-1));
531 
532  if (space(tmpPath).available < dbSize)
533  {
534  std::cerr << "A valid directory for vacuuming must be "
535  "specified on a filesystem with at least "
536  "as much free space as the size of "
537  << dbPath.string() << ", which is " << dbSize
538  << " bytes. The filesystem for " << tmpPath.string()
539  << " only has " << space(tmpPath).available
540  << " bytes.\n";
541  return -1;
542  }
543 
544  auto txnDB = std::make_unique<DatabaseCon>(
545  dbSetup, TxDBName, TxDBPragma, TxDBInit);
546  auto& session = txnDB->getSession();
547  std::uint32_t pageSize;
548 
549  session << "PRAGMA page_size;", soci::into(pageSize);
550 
551  std::cout << "VACUUM beginning. page_size: " << pageSize
552  << std::endl;
553 
554  session << "PRAGMA journal_mode=OFF;";
555  session << "PRAGMA temp_store_directory=\"" << tmpPath.string()
556  << "\";";
557  session << "VACUUM;";
558  session << "PRAGMA journal_mode=WAL;";
559  session << "PRAGMA page_size;", soci::into(pageSize);
560 
561  std::cout << "VACUUM finished. page_size: " << pageSize
562  << std::endl;
563  }
564  catch (std::exception const& e)
565  {
566  std::cerr << "exception " << e.what() << " in function " << __func__
567  << std::endl;
568  return -1;
569  }
570 
571  return 0;
572  }
573 
574  if (vm.count("start"))
575  config->START_UP = Config::FRESH;
576 
577  if (vm.count("import"))
578  config->doImport = true;
579 
580  if (vm.count("nodetoshard"))
581  config->nodeToShard = true;
582 
583  if (vm.count("validateShards"))
584  config->validateShards = true;
585 
586  if (vm.count("ledger"))
587  {
588  config->START_LEDGER = vm["ledger"].as<std::string>();
589  if (vm.count("replay"))
590  config->START_UP = Config::REPLAY;
591  else
592  config->START_UP = Config::LOAD;
593  }
594  else if (vm.count("ledgerfile"))
595  {
596  config->START_LEDGER = vm["ledgerfile"].as<std::string>();
597  config->START_UP = Config::LOAD_FILE;
598  }
599  else if (vm.count("load"))
600  {
601  config->START_UP = Config::LOAD;
602  }
603 
604  if (vm.count("valid"))
605  {
606  config->START_VALID = true;
607  }
608 
609  if (vm.count("net"))
610  {
611  if ((config->START_UP == Config::LOAD) ||
612  (config->START_UP == Config::REPLAY))
613  {
614  std::cerr << "Net and load/reply options are incompatible"
615  << std::endl;
616  return -1;
617  }
618 
619  config->START_UP = Config::NETWORK;
620  }
621 
622  // Override the RPC destination IP address. This must
623  // happen after the config file is loaded.
624  if (vm.count("rpc_ip"))
625  {
627  vm["rpc_ip"].as<std::string>());
628  if (!endpoint)
629  {
630  std::cerr << "Invalid rpc_ip = " << vm["rpc_ip"].as<std::string>()
631  << "\n";
632  return -1;
633  }
634 
635  if (endpoint->port() == 0)
636  {
637  std::cerr << "No port specified in rpc_ip.\n";
638  if (vm.count("rpc_port"))
639  {
640  std::cerr << "WARNING: using deprecated rpc_port param.\n";
641  try
642  {
643  endpoint =
644  endpoint->at_port(vm["rpc_port"].as<std::uint16_t>());
645  if (endpoint->port() == 0)
646  throw std::domain_error("0");
647  }
648  catch (std::exception const& e)
649  {
650  std::cerr << "Invalid rpc_port = " << e.what() << "\n";
651  return -1;
652  }
653  }
654  else
655  return -1;
656  }
657 
658  config->rpc_ip = std::move(*endpoint);
659  }
660 
661  if (vm.count("quorum"))
662  {
663  try
664  {
665  config->VALIDATION_QUORUM = vm["quorum"].as<std::size_t>();
666  if (config->VALIDATION_QUORUM == std::size_t{})
667  {
668  throw std::domain_error("0");
669  }
670  }
671  catch (std::exception const& e)
672  {
673  std::cerr << "Invalid value specified for --quorum (" << e.what()
674  << ")\n";
675  return -1;
676  }
677  }
678 
679  // Construct the logs object at the configured severity
680  using namespace beast::severities;
681  Severity thresh = kInfo;
682 
683  if (vm.count("quiet"))
684  thresh = kFatal;
685  else if (vm.count("verbose"))
686  thresh = kTrace;
687 
688  auto logs = std::make_unique<Logs>(thresh);
689 
690  // No arguments. Run server.
691  if (!vm.count("parameters"))
692  {
693  // TODO: this comment can be removed in a future release -
694  // say 1.7 or higher
695  if (config->had_trailing_comments())
696  {
697  JLOG(logs->journal("Application").warn())
698  << "Trailing comments were seen in your config file. "
699  << "The treatment of inline/trailing comments has changed "
700  "recently. "
701  << "Any `#` characters NOT intended to delimit comments should "
702  "be "
703  << "preceded by a \\";
704  }
705 
706  // We want at least 1024 file descriptors. We'll
707  // tweak this further.
708  if (!adjustDescriptorLimit(1024, logs->journal("Application")))
709  return -1;
710 
711  if (vm.count("debug"))
712  setDebugLogSink(logs->makeSink("Debug", beast::severities::kTrace));
713 
714  auto timeKeeper = make_TimeKeeper(logs->journal("TimeKeeper"));
715 
716  auto app = make_Application(
717  std::move(config), std::move(logs), std::move(timeKeeper));
718 
719  if (!app->setup())
720  return -1;
721 
722  // With our configuration parsed, ensure we have
723  // enough file descriptors available:
725  app->fdRequired(), app->logs().journal("Application")))
726  return -1;
727 
728  // Start the server
729  app->doStart(true /*start timers*/);
730 
731  // Block until we get a stop RPC.
732  app->run();
733 
734  return 0;
735  }
736 
737  // We have an RPC command to process:
738  beast::setCurrentThreadName("rippled: rpc");
740  *config, vm["parameters"].as<std::vector<std::string>>(), *logs);
741 }
742 
743 } // namespace ripple
744 
745 // Must be outside the namespace for obvious reasons
746 //
747 int
748 main(int argc, char** argv)
749 {
750 #if BOOST_OS_WINDOWS
751  {
752  // Work around for https://svn.boost.org/trac/boost/ticket/10657
753  // Reported against boost version 1.56.0. If an application's
754  // first call to GetTimeZoneInformation is from a coroutine, an
755  // unhandled exception is generated. A workaround is to call
756  // GetTimeZoneInformation at least once before launching any
757  // coroutines. At the time of this writing the _ftime call is
758  // used to initialize the timezone information.
759  struct _timeb t;
760 #ifdef _INC_TIME_INL
761  _ftime_s(&t);
762 #else
763  _ftime(&t);
764 #endif
765  }
766 #endif
767 
768  atexit(&google::protobuf::ShutdownProtobufLibrary);
769 
770  auto const result(ripple::run(argc, argv));
771 
772  return result;
773 }
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:339
beast::severities::kTrace
@ kTrace
Definition: Journal.h:34
std::for_each
T for_each(T... args)
std::experimental::filesystem::file_size
T file_size(T... args)
std::domain_error
STL class.
std::string
STL class.
utility
std::exception
STL class.
ripple::printHelp
void printHelp(const po::options_description &desc)
Definition: Main.cpp:120
std::vector::reserve
T reserve(T... args)
std::vector
STL class.
beast::unit_test
Definition: define_print.cpp:16
ripple::ConfigSection::shardDatabase
static std::string shardDatabase()
Definition: ConfigSections.h:38
std::vector::size
T size(T... args)
ripple::ConfigSection::importNodeDatabase
static std::string importNodeDatabase()
Definition: ConfigSections.h:43
ripple::Config::LOAD
@ LOAD
Definition: Config.h:122
beast::severities
A namespace for easy access to logging severity values.
Definition: Journal.h:29
std::cerr
iostream
std::cout
ripple::TxDBName
constexpr auto TxDBName
Definition: DBInit.h:62
stdexcept
ripple::setup_DatabaseCon
DatabaseCon::Setup setup_DatabaseCon(Config const &c)
Definition: DatabaseCon.cpp:29
std::atexit
T atexit(T... args)
std::log
T log(T... args)
ripple::Config::NETWORK
@ NETWORK
Definition: Config.h:122
std::string::c_str
T c_str(T... args)
ripple::setDebugLogSink
std::unique_ptr< beast::Journal::Sink > setDebugLogSink(std::unique_ptr< beast::Journal::Sink > sink)
Set the sink for the debug journal.
Definition: Log.cpp:446
ripple::BuildInfo::getVersionString
std::string const & getVersionString()
Server version.
Definition: BuildInfo.cpp:61
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::test::multi_runner_parent::any_failed
bool any_failed() const
Definition: multi_runner.cpp:443
std::uintmax_t
std::atomic< bool >
beast::severities::kInfo
@ kInfo
Definition: Journal.h:36
std::experimental::filesystem::space
T space(T... args)
ripple::RPCCall::fromCommandLine
int fromCommandLine(Config const &config, const std::vector< std::string > &vCmd, Logs &logs)
Definition: RPCCall.cpp:1664
ripple::test::envUseIPv4
std::atomic< bool > envUseIPv4
Definition: envconfig.cpp:34
beast::setCurrentThreadName
void setCurrentThreadName(std::string_view name)
Changes the name of the caller thread.
Definition: CurrentThreadName.cpp:119
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test
Definition: BookStep.cpp:1091
ripple::Config::FRESH
@ FRESH
Definition: Config.h:122
cstdlib
std::endl
T endl(T... args)
beast::severities::Severity
Severity
Severity level / threshold of a Journal message.
Definition: Journal.h:31
std::vector::begin
T begin(T... args)
std
STL namespace.
ripple::Config::REPLAY
@ REPLAY
Definition: Config.h:122
ripple::make_TimeKeeper
std::unique_ptr< TimeKeeper > make_TimeKeeper(beast::Journal j)
Definition: TimeKeeper.cpp:119
ripple::test::multi_runner_child
A class to run a subset of unit tests.
Definition: multi_runner.h:229
ripple::systemName
static std::string const & systemName()
Definition: SystemParameters.h:33
std::size_t
std::vector::end
T end(T... args)
ripple::TxDBInit
constexpr std::array< char const *, 8 > TxDBInit
Definition: DBInit.h:82
beast::severities::kFatal
@ kFatal
Definition: Journal.h:39
beast::IP::Endpoint::from_string_checked
static boost::optional< Endpoint > from_string_checked(std::string const &s)
Create an Endpoint from a string.
Definition: IPEndpoint.cpp:35
std::max
T max(T... args)
ripple::test::multi_runner_parent
Manager for children running unit tests.
Definition: multi_runner.h:203
ripple::adjustDescriptorLimit
bool adjustDescriptorLimit(int needed, beast::Journal j)
Definition: Main.cpp:75
ripple::TxDBPragma
constexpr std::array< char const *, 5 > TxDBPragma
Definition: DBInit.h:71
ripple::Config::LOAD_FILE
@ LOAD_FILE
Definition: Config.h:122
std::data
T data(T... args)
ripple::make_Application
std::unique_ptr< Application > make_Application(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
Definition: Application.cpp:2348
ripple::ConfigSection::nodeDatabase
static std::string nodeDatabase()
Definition: ConfigSections.h:33
std::exception::what
T what(T... args)