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", "VACUUM the transaction db.")(
358  "valid", "Consider the initial ledger a valid network ledger.")(
359  "validateShards", shardsText.c_str());
360 
361  po::options_description rpc("RPC Client Options");
362  rpc.add_options()(
363  "rpc",
364  "Perform rpc command - see below for available commands. "
365  "This is assumed if any positional parameters are provided.")(
366  "rpc_ip",
367  po::value<std::string>(),
368  "Specify the IP address for RPC command. "
369  "Format: <ip-address>[':'<port-number>]")(
370  "rpc_port",
371  po::value<std::uint16_t>(),
372  "DEPRECATED: include with rpc_ip instead. "
373  "Specify the port number for RPC command.");
374 
375  po::options_description test("Unit Test Options");
376  test.add_options()(
377  "quiet,q",
378  "Suppress test suite messages, "
379  "including suite/case name (at start) and test log messages.")(
380  "unittest,u",
381  po::value<std::string>()->implicit_value(""),
382  "Perform unit tests. The optional argument specifies one or "
383  "more comma-separated selectors. Each selector specifies a suite name, "
384  "full-name (lib.module.suite), module, or library "
385  "(checked in that "
386  "order).")(
387  "unittest-arg",
388  po::value<std::string>()->implicit_value(""),
389  "Supplies an argument string to unit tests. If provided, this argument "
390  "is made available to each suite that runs. Interpretation of the "
391  "argument is handled individually by any suite that accesses it -- "
392  "as such, it typically only make sense to provide this when running "
393  "a single suite.")(
394  "unittest-ipv6",
395  "Use IPv6 localhost when running unittests (default is IPv4).")(
396  "unittest-log",
397  "Force unit test log message output. Only useful in combination with "
398  "--quiet, in which case log messages will print but suite/case names "
399  "will not.")(
400  "unittest-jobs",
401  po::value<std::size_t>(),
402  "Number of unittest jobs to run in parallel (child processes).");
403 
404  // These are hidden options, not intended to be shown in the usage/help
405  // message
406  po::options_description hidden("Hidden Options");
407  hidden.add_options()(
408  "parameters",
409  po::value<vector<string>>(),
410  "Specify rpc command and parameters. This option must be repeated "
411  "for each command/param. Positional parameters also serve this "
412  "purpose, "
413  "so this option is not needed for users")(
414  "unittest-child",
415  "For internal use only when spawning child unit test processes.")(
416  "fg", "Deprecated: server always in foreground mode.");
417 
418  // Interpret positional arguments as --parameters.
419  po::positional_options_description p;
420  p.add("parameters", -1);
421 
422  po::options_description all;
423  all.add(gen).add(rpc).add(data).add(test).add(hidden);
424 
425  po::options_description desc;
426  desc.add(gen).add(rpc).add(data).add(test);
427 
428  // Parse options, if no error.
429  try
430  {
431  po::store(
432  po::command_line_parser(argc, argv)
433  .options(all) // Parse options.
434  .positional(p) // Remainder as --parameters.
435  .run(),
436  vm);
437  po::notify(vm); // Invoke option notify functions.
438  }
439  catch (std::exception const& ex)
440  {
441  std::cerr << "rippled: " << ex.what() << std::endl;
442  std::cerr << "Try 'rippled --help' for a list of options." << std::endl;
443  return 1;
444  }
445 
446  if (vm.count("help"))
447  {
448  printHelp(desc);
449  return 0;
450  }
451 
452  if (vm.count("version"))
453  {
454  std::cout << "rippled version " << BuildInfo::getVersionString()
455  << std::endl;
456  return 0;
457  }
458 
459  // Run the unit tests if requested.
460  // The unit tests will exit the application with an appropriate return code.
461  //
462  if (vm.count("unittest"))
463  {
464  std::string argument;
465 
466  if (vm.count("unittest-arg"))
467  argument = vm["unittest-arg"].as<std::string>();
468 
469  std::size_t numJobs = 1;
470  bool unittestChild = false;
471  if (vm.count("unittest-jobs"))
472  numJobs = std::max(numJobs, vm["unittest-jobs"].as<std::size_t>());
473  unittestChild = bool(vm.count("unittest-child"));
474 
475  return runUnitTests(
476  vm["unittest"].as<std::string>(),
477  argument,
478  bool(vm.count("quiet")),
479  bool(vm.count("unittest-log")),
480  unittestChild,
481  bool(vm.count("unittest-ipv6")),
482  numJobs,
483  argc,
484  argv);
485  }
486  else
487  {
488  if (vm.count("unittest-jobs"))
489  {
490  // unittest jobs only makes sense with `unittest`
491  std::cerr << "rippled: '--unittest-jobs' specified without "
492  "'--unittest'.\n";
493  std::cerr << "To run the unit tests the '--unittest' option must "
494  "be present.\n";
495  return 1;
496  }
497  }
498 
499  auto config = std::make_unique<Config>();
500 
501  auto configFile =
502  vm.count("conf") ? vm["conf"].as<std::string>() : std::string();
503 
504  // config file, quiet flag.
505  config->setup(
506  configFile,
507  bool(vm.count("quiet")),
508  bool(vm.count("silent")),
509  bool(vm.count("standalone")));
510 
511  if (vm.count("vacuum"))
512  {
513  if (config->standalone())
514  {
515  std::cerr << "vacuum not applicable in standalone mode.\n";
516  return -1;
517  }
518 
519  using namespace boost::filesystem;
520  DatabaseCon::Setup const dbSetup = setup_DatabaseCon(*config);
521  path dbPath = dbSetup.dataDir / TxDBName;
522 
523  try
524  {
525  uintmax_t const dbSize = file_size(dbPath);
526  assert(dbSize != static_cast<uintmax_t>(-1));
527 
528  if (auto available = space(dbPath.parent_path()).available;
529  available < dbSize)
530  {
531  std::cerr << "The database filesystem must have at least as "
532  "much free space as the size of "
533  << dbPath.string() << ", which is " << dbSize
534  << " bytes. Only " << available
535  << " bytes are available.\n";
536  return -1;
537  }
538 
539  auto txnDB = std::make_unique<DatabaseCon>(
540  dbSetup, TxDBName, TxDBPragma, TxDBInit);
541  auto& session = txnDB->getSession();
542  std::uint32_t pageSize;
543 
544  // Only the most trivial databases will fit in memory on typical
545  // (recommended) software. Force temp files to be written to disk
546  // regardless of the config settings.
547  session << boost::format(CommonDBPragmaTemp) % "file";
548  session << "PRAGMA page_size;", soci::into(pageSize);
549 
550  std::cout << "VACUUM beginning. page_size: " << pageSize
551  << std::endl;
552 
553  session << "VACUUM;";
554  assert(dbSetup.globalPragma);
555  for (auto const& p : *dbSetup.globalPragma)
556  session << p;
557  session << "PRAGMA page_size;", soci::into(pageSize);
558 
559  std::cout << "VACUUM finished. page_size: " << pageSize
560  << std::endl;
561  }
562  catch (std::exception const& e)
563  {
564  std::cerr << "exception " << e.what() << " in function " << __func__
565  << std::endl;
566  return -1;
567  }
568 
569  return 0;
570  }
571 
572  if (vm.count("start"))
573  config->START_UP = Config::FRESH;
574 
575  if (vm.count("import"))
576  config->doImport = true;
577 
578  if (vm.count("nodetoshard"))
579  config->nodeToShard = true;
580 
581  if (vm.count("validateShards"))
582  config->validateShards = true;
583 
584  if (vm.count("ledger"))
585  {
586  config->START_LEDGER = vm["ledger"].as<std::string>();
587  if (vm.count("replay"))
588  config->START_UP = Config::REPLAY;
589  else
590  config->START_UP = Config::LOAD;
591  }
592  else if (vm.count("ledgerfile"))
593  {
594  config->START_LEDGER = vm["ledgerfile"].as<std::string>();
595  config->START_UP = Config::LOAD_FILE;
596  }
597  else if (vm.count("load"))
598  {
599  config->START_UP = Config::LOAD;
600  }
601 
602  if (vm.count("valid"))
603  {
604  config->START_VALID = true;
605  }
606 
607  if (vm.count("net"))
608  {
609  if ((config->START_UP == Config::LOAD) ||
610  (config->START_UP == Config::REPLAY))
611  {
612  std::cerr << "Net and load/replay options are incompatible"
613  << std::endl;
614  return -1;
615  }
616 
617  config->START_UP = Config::NETWORK;
618  }
619 
620  // Override the RPC destination IP address. This must
621  // happen after the config file is loaded.
622  if (vm.count("rpc_ip"))
623  {
625  vm["rpc_ip"].as<std::string>());
626  if (!endpoint)
627  {
628  std::cerr << "Invalid rpc_ip = " << vm["rpc_ip"].as<std::string>()
629  << "\n";
630  return -1;
631  }
632 
633  if (endpoint->port() == 0)
634  {
635  std::cerr << "No port specified in rpc_ip.\n";
636  if (vm.count("rpc_port"))
637  {
638  std::cerr << "WARNING: using deprecated rpc_port param.\n";
639  try
640  {
641  endpoint =
642  endpoint->at_port(vm["rpc_port"].as<std::uint16_t>());
643  if (endpoint->port() == 0)
644  throw std::domain_error("0");
645  }
646  catch (std::exception const& e)
647  {
648  std::cerr << "Invalid rpc_port = " << e.what() << "\n";
649  return -1;
650  }
651  }
652  else
653  return -1;
654  }
655 
656  config->rpc_ip = std::move(*endpoint);
657  }
658 
659  if (vm.count("quorum"))
660  {
661  try
662  {
663  config->VALIDATION_QUORUM = vm["quorum"].as<std::size_t>();
664  if (config->VALIDATION_QUORUM == std::size_t{})
665  {
666  throw std::domain_error("0");
667  }
668  }
669  catch (std::exception const& e)
670  {
671  std::cerr << "Invalid value specified for --quorum (" << e.what()
672  << ")\n";
673  return -1;
674  }
675  }
676 
677  // Construct the logs object at the configured severity
678  using namespace beast::severities;
679  Severity thresh = kInfo;
680 
681  if (vm.count("quiet"))
682  thresh = kFatal;
683  else if (vm.count("verbose"))
684  thresh = kTrace;
685 
686  auto logs = std::make_unique<Logs>(thresh);
687 
688  // No arguments. Run server.
689  if (!vm.count("parameters"))
690  {
691  // TODO: this comment can be removed in a future release -
692  // say 1.7 or higher
693  if (config->had_trailing_comments())
694  {
695  JLOG(logs->journal("Application").warn())
696  << "Trailing comments were seen in your config file. "
697  << "The treatment of inline/trailing comments has changed "
698  "recently. "
699  << "Any `#` characters NOT intended to delimit comments should "
700  "be "
701  << "preceded by a \\";
702  }
703 
704  // We want at least 1024 file descriptors. We'll
705  // tweak this further.
706  if (!adjustDescriptorLimit(1024, logs->journal("Application")))
707  return -1;
708 
709  if (vm.count("debug"))
710  setDebugLogSink(logs->makeSink("Debug", beast::severities::kTrace));
711 
712  auto timeKeeper = make_TimeKeeper(logs->journal("TimeKeeper"));
713 
714  auto app = make_Application(
715  std::move(config), std::move(logs), std::move(timeKeeper));
716 
717  if (!app->setup())
718  return -1;
719 
720  // With our configuration parsed, ensure we have
721  // enough file descriptors available:
723  app->fdRequired(), app->logs().journal("Application")))
724  return -1;
725 
726  // Start the server
727  app->doStart(true /*start timers*/);
728 
729  // Block until we get a stop RPC.
730  app->run();
731 
732  return 0;
733  }
734 
735  // We have an RPC command to process:
736  beast::setCurrentThreadName("rippled: rpc");
738  *config, vm["parameters"].as<std::vector<std::string>>(), *logs);
739 }
740 
741 } // namespace ripple
742 
743 // Must be outside the namespace for obvious reasons
744 //
745 int
746 main(int argc, char** argv)
747 {
748 #if BOOST_OS_WINDOWS
749  {
750  // Work around for https://svn.boost.org/trac/boost/ticket/10657
751  // Reported against boost version 1.56.0. If an application's
752  // first call to GetTimeZoneInformation is from a coroutine, an
753  // unhandled exception is generated. A workaround is to call
754  // GetTimeZoneInformation at least once before launching any
755  // coroutines. At the time of this writing the _ftime call is
756  // used to initialize the timezone information.
757  struct _timeb t;
758 #ifdef _INC_TIME_INL
759  _ftime_s(&t);
760 #else
761  _ftime(&t);
762 #endif
763  }
764 #endif
765 
766  atexit(&google::protobuf::ShutdownProtobufLibrary);
767 
768  auto const result(ripple::run(argc, argv));
769 
770  return result;
771 }
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:123
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:73
stdexcept
std::atexit
T atexit(T... args)
std::log
T log(T... args)
ripple::Config::NETWORK
@ NETWORK
Definition: Config.h:123
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
ripple::CommonDBPragmaTemp
constexpr char const * CommonDBPragmaTemp
Definition: DBInit.h:34
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:1670
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
ripple::setup_DatabaseCon
DatabaseCon::Setup setup_DatabaseCon(Config const &c, boost::optional< beast::Journal > j=boost::none)
Definition: DatabaseCon.cpp:93
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: NegativeUNLVote.h:38
ripple::Config::FRESH
@ FRESH
Definition: Config.h:123
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:123
ripple::make_TimeKeeper
std::unique_ptr< TimeKeeper > make_TimeKeeper(beast::Journal j)
Definition: TimeKeeper.cpp:119
ripple::TxDBPragma
constexpr std::array TxDBPragma
Definition: DBInit.h:76
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:34
std::size_t
std::vector::end
T end(T... args)
ripple::TxDBInit
constexpr std::array< char const *, 8 > TxDBInit
Definition: DBInit.h:84
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::Config::LOAD_FILE
@ LOAD_FILE
Definition: Config.h:123
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:2222
ripple::ConfigSection::nodeDatabase
static std::string nodeDatabase()
Definition: ConfigSections.h:33
std::exception::what
T what(T... args)