rippled
Application.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/consensus/RCLValidations.h>
21 #include <ripple/app/ledger/InboundLedgers.h>
22 #include <ripple/app/ledger/InboundTransactions.h>
23 #include <ripple/app/ledger/LedgerCleaner.h>
24 #include <ripple/app/ledger/LedgerMaster.h>
25 #include <ripple/app/ledger/LedgerReplayer.h>
26 #include <ripple/app/ledger/LedgerToJson.h>
27 #include <ripple/app/ledger/OpenLedger.h>
28 #include <ripple/app/ledger/OrderBookDB.h>
29 #include <ripple/app/ledger/PendingSaves.h>
30 #include <ripple/app/ledger/TransactionMaster.h>
31 #include <ripple/app/main/Application.h>
32 #include <ripple/app/main/BasicApp.h>
33 #include <ripple/app/main/DBInit.h>
34 #include <ripple/app/main/GRPCServer.h>
35 #include <ripple/app/main/LoadManager.h>
36 #include <ripple/app/main/NodeIdentity.h>
37 #include <ripple/app/main/NodeStoreScheduler.h>
38 #include <ripple/app/main/Tuning.h>
39 #include <ripple/app/misc/AmendmentTable.h>
40 #include <ripple/app/misc/HashRouter.h>
41 #include <ripple/app/misc/LoadFeeTrack.h>
42 #include <ripple/app/misc/NetworkOPs.h>
43 #include <ripple/app/misc/SHAMapStore.h>
44 #include <ripple/app/misc/TxQ.h>
45 #include <ripple/app/misc/ValidatorKeys.h>
46 #include <ripple/app/misc/ValidatorSite.h>
47 #include <ripple/app/paths/PathRequests.h>
48 #include <ripple/app/rdb/RelationalDBInterface_global.h>
49 #include <ripple/app/rdb/backend/RelationalDBInterfacePostgres.h>
50 #include <ripple/app/reporting/ReportingETL.h>
51 #include <ripple/app/tx/apply.h>
52 #include <ripple/basics/ByteUtilities.h>
53 #include <ripple/basics/PerfLog.h>
54 #include <ripple/basics/ResolverAsio.h>
55 #include <ripple/basics/safe_cast.h>
56 #include <ripple/beast/asio/io_latency_probe.h>
57 #include <ripple/beast/core/LexicalCast.h>
58 #include <ripple/core/DatabaseCon.h>
59 #include <ripple/json/json_reader.h>
60 #include <ripple/nodestore/DatabaseShard.h>
61 #include <ripple/nodestore/DummyScheduler.h>
62 #include <ripple/overlay/Cluster.h>
63 #include <ripple/overlay/PeerReservationTable.h>
64 #include <ripple/overlay/PeerSet.h>
65 #include <ripple/overlay/make_Overlay.h>
66 #include <ripple/protocol/BuildInfo.h>
67 #include <ripple/protocol/Feature.h>
68 #include <ripple/protocol/Protocol.h>
69 #include <ripple/protocol/STParsedJSON.h>
70 #include <ripple/resource/Fees.h>
71 #include <ripple/rpc/ShardArchiveHandler.h>
72 #include <ripple/rpc/impl/RPCHelpers.h>
73 #include <ripple/shamap/NodeFamily.h>
74 #include <ripple/shamap/ShardFamily.h>
75 
76 #include <boost/algorithm/string/predicate.hpp>
77 #include <boost/asio/steady_timer.hpp>
78 #include <boost/system/error_code.hpp>
79 
80 #include <date/date.h>
81 
82 #include <chrono>
83 #include <condition_variable>
84 #include <cstring>
85 #include <iostream>
86 #include <limits>
87 #include <mutex>
88 #include <optional>
89 #include <sstream>
90 #include <utility>
91 #include <variant>
92 
93 namespace ripple {
94 
95 // VFALCO TODO Move the function definitions into the class declaration
96 class ApplicationImp : public Application, public BasicApp
97 {
98 private:
100  {
101  private:
106 
107  public:
111  std::chrono::milliseconds interval,
112  boost::asio::io_service& ios)
113  : m_event(ev)
114  , m_journal(journal)
115  , m_probe(interval, ios)
116  , lastSample_{}
117  {
118  }
119 
120  void
122  {
123  m_probe.sample(std::ref(*this));
124  }
125 
126  template <class Duration>
127  void
128  operator()(Duration const& elapsed)
129  {
130  using namespace std::chrono;
131  auto const lastSample = ceil<milliseconds>(elapsed);
132 
133  lastSample_ = lastSample;
134 
135  if (lastSample >= 10ms)
136  m_event.notify(lastSample);
137  if (lastSample >= 500ms)
138  {
139  JLOG(m_journal.warn())
140  << "io_service latency = " << lastSample.count();
141  }
142  }
143 
145  get() const
146  {
147  return lastSample_.load();
148  }
149 
150  void
152  {
153  m_probe.cancel();
154  }
155 
156  void
158  {
160  }
161  };
162 
163 public:
167 
171 
172  // Required by the SHAMapStore
174 
182 
187 
189 
195  // VFALCO TODO Make OrderBookDB abstract
219  boost::asio::steady_timer sweepTimer_;
220  boost::asio::steady_timer entropyTimer_;
221 
225 
226  boost::asio::signal_set m_signals;
227 
228  // Once we get C++20, we could use `std::atomic_flag` for `isTimeToStop`
229  // and eliminate the need for the condition variable and the mutex.
233 
235 
237 
239 
242 
243  //--------------------------------------------------------------------------
244 
245  static std::size_t
247  {
248 #if RIPPLE_SINGLE_IO_SERVICE_THREAD
249  return 1;
250 #else
251 
252  if (config.IO_WORKERS > 0)
253  return config.IO_WORKERS;
254 
255  auto const cores = std::thread::hardware_concurrency();
256 
257  // Use a single thread when running on under-provisioned systems
258  // or if we are configured to use minimal resources.
259  if ((cores == 1) || ((config.NODE_SIZE == 0) && (cores == 2)))
260  return 1;
261 
262  // Otherwise, prefer two threads.
263  return 2;
264 #endif
265  }
266 
267  //--------------------------------------------------------------------------
268 
274  , config_(std::move(config))
275  , logs_(std::move(logs))
276  , timeKeeper_(std::move(timeKeeper))
277  , m_journal(logs_->journal("Application"))
278 
279  // PerfLog must be started before any other threads are launched.
280  , perfLog_(perf::make_PerfLog(
281  perf::setup_PerfLog(
282  config_->section("perf"),
283  config_->CONFIG_DIR),
284  *this,
285  logs_->journal("PerfLog"),
286  [this] { signalStop(); }))
287 
288  , m_txMaster(*this)
289 
291  config_->section(SECTION_INSIGHT),
292  logs_->journal("Collector")))
293 
294  , m_jobQueue(std::make_unique<JobQueue>(
295  [](std::unique_ptr<Config> const& config) {
296  if (config->standalone() && !config->reporting() &&
298  return 1;
299 
300  if (config->WORKERS)
301  return config->WORKERS;
302 
303  auto count =
304  static_cast<int>(std::thread::hardware_concurrency());
305 
306  // Be more aggressive about the number of threads to use
307  // for the job queue if the server is configured as "large"
308  // or "huge" if there are enough cores.
309  if (config->NODE_SIZE >= 4 && count >= 16)
310  count = 6 + std::min(count, 8);
311  else if (config->NODE_SIZE >= 3 && count >= 8)
312  count = 4 + std::min(count, 6);
313  else
314  count = 2 + std::min(count, 4);
315 
316  return count;
317  }(config_),
318  m_collectorManager->group("jobq"),
319  logs_->journal("JobQueue"),
320  *logs_,
321  *perfLog_))
322 
324 
326  *this,
328  logs_->journal("SHAMapStore")))
329 
330  , accountIDCache_(128000)
331 
332  , m_tempNodeCache(
333  "NodeCache",
334  16384,
336  stopwatch(),
337  logs_->journal("TaggedCache"))
338 
339  , cachedSLEs_(
340  "Cached SLEs",
341  0,
343  stopwatch(),
344  logs_->journal("CachedSLEs"))
345 
347 
349  m_collectorManager->collector(),
350  logs_->journal("Resource")))
351 
352  , m_nodeStore(m_shaMapStore->makeNodeStore(
353  config_->PREFETCH_WORKERS > 0 ? config_->PREFETCH_WORKERS : 4))
354 
356 
357  // The shard store is optional and make_ShardStore can return null.
359  *this,
361  4,
362  logs_->journal("ShardStore")))
363 
364  , m_orderBookDB(*this)
365 
366  , m_pathRequests(std::make_unique<PathRequests>(
367  *this,
368  logs_->journal("PathRequest"),
369  m_collectorManager->collector()))
370 
371  , m_ledgerMaster(std::make_unique<LedgerMaster>(
372  *this,
373  stopwatch(),
374  m_collectorManager->collector(),
375  logs_->journal("LedgerMaster")))
376 
377  , ledgerCleaner_(
378  make_LedgerCleaner(*this, logs_->journal("LedgerCleaner")))
379 
380  // VFALCO NOTE must come before NetworkOPs to prevent a crash due
381  // to dependencies in the destructor.
382  //
384  *this,
385  stopwatch(),
386  m_collectorManager->collector()))
387 
389  *this,
390  m_collectorManager->collector(),
391  [this](std::shared_ptr<SHAMap> const& set, bool fromAcquire) {
392  gotTXSet(set, fromAcquire);
393  }))
394 
395  , m_ledgerReplayer(std::make_unique<LedgerReplayer>(
396  *this,
398  make_PeerSetBuilder(*this)))
399 
401  "AcceptedLedger",
402  4,
404  stopwatch(),
405  logs_->journal("TaggedCache"))
406 
408  *this,
409  stopwatch(),
410  config_->standalone(),
411  config_->NETWORK_QUORUM,
412  config_->START_VALID,
413  *m_jobQueue,
416  get_io_service(),
417  logs_->journal("NetworkOPs"),
418  m_collectorManager->collector()))
419 
420  , cluster_(std::make_unique<Cluster>(logs_->journal("Overlay")))
421 
422  , peerReservations_(std::make_unique<PeerReservationTable>(
423  logs_->journal("PeerReservationTable")))
424 
426  std::make_unique<ManifestCache>(logs_->journal("ManifestCache")))
427 
429  std::make_unique<ManifestCache>(logs_->journal("ManifestCache")))
430 
431  , validators_(std::make_unique<ValidatorList>(
434  *timeKeeper_,
435  config_->legacy("database_path"),
436  logs_->journal("ValidatorList"),
437  config_->VALIDATION_QUORUM))
438 
439  , validatorSites_(std::make_unique<ValidatorSite>(*this))
440 
442  *this,
443  get_io_service(),
444  *m_jobQueue,
445  *m_networkOPs,
448 
449  , mFeeTrack(
450  std::make_unique<LoadFeeTrack>(logs_->journal("LoadManager")))
451 
452  , hashRouter_(std::make_unique<HashRouter>(
453  stopwatch(),
455 
456  , mValidations(
457  ValidationParms(),
458  stopwatch(),
459  *this,
460  logs_->journal("Validations"))
461 
462  , m_loadManager(make_LoadManager(*this, logs_->journal("LoadManager")))
463 
464  , txQ_(
465  std::make_unique<TxQ>(setup_TxQ(*config_), logs_->journal("TxQ")))
466 
468 
470 
472 
473  , checkSigs_(true)
474 
475  , m_resolver(
476  ResolverAsio::New(get_io_service(), logs_->journal("Resolver")))
477 
479  m_collectorManager->collector()->make_event("ios_latency"),
480  logs_->journal("Application"),
482  get_io_service())
483  , grpcServer_(std::make_unique<GRPCServer>(*this))
484  , reportingETL_(
485  config_->reporting() ? std::make_unique<ReportingETL>(*this)
486  : nullptr)
487  {
488  add(m_resourceManager.get());
489 
490  //
491  // VFALCO - READ THIS!
492  //
493  // Do not start threads, open sockets, or do any sort of "real work"
494  // inside the constructor. Put it in start instead. Or if you must,
495  // put it in setup (but everything in setup should be moved to start
496  // anyway.
497  //
498  // The reason is that the unit tests require an Application object to
499  // be created. But we don't actually start all the threads, sockets,
500  // and services when running the unit tests. Therefore anything which
501  // needs to be stopped will not get stopped correctly if it is
502  // started in this constructor.
503  //
504 
505  add(ledgerCleaner_.get());
506  }
507 
508  //--------------------------------------------------------------------------
509 
510  bool
511  setup() override;
512  void
513  start(bool withTimers) override;
514  void
515  run() override;
516  void
517  signalStop() override;
518  bool
519  checkSigs() const override;
520  void
521  checkSigs(bool) override;
522  bool
523  isStopping() const override;
524  int
525  fdRequired() const override;
526 
527  //--------------------------------------------------------------------------
528 
529  Logs&
530  logs() override
531  {
532  return *logs_;
533  }
534 
535  Config&
536  config() override
537  {
538  return *config_;
539  }
540 
543  {
544  return *m_collectorManager;
545  }
546 
547  Family&
548  getNodeFamily() override
549  {
550  return nodeFamily_;
551  }
552 
553  // The shard store is an optional feature. If the sever is configured for
554  // shards, this function will return a valid pointer, otherwise a nullptr.
555  Family*
556  getShardFamily() override
557  {
558  return shardFamily_.get();
559  }
560 
561  TimeKeeper&
562  timeKeeper() override
563  {
564  return *timeKeeper_;
565  }
566 
567  JobQueue&
568  getJobQueue() override
569  {
570  return *m_jobQueue;
571  }
572 
574  nodeIdentity() override
575  {
576  return nodeIdentity_;
577  }
578 
579  PublicKey const&
580  getValidationPublicKey() const override
581  {
582  return validatorKeys_.publicKey;
583  }
584 
585  NetworkOPs&
586  getOPs() override
587  {
588  return *m_networkOPs;
589  }
590 
591  boost::asio::io_service&
592  getIOService() override
593  {
594  return get_io_service();
595  }
596 
598  getIOLatency() override
599  {
600  return m_io_latency_sampler.get();
601  }
602 
603  LedgerMaster&
604  getLedgerMaster() override
605  {
606  return *m_ledgerMaster;
607  }
608 
610  getLedgerCleaner() override
611  {
612  return *ledgerCleaner_;
613  }
614 
616  getLedgerReplayer() override
617  {
618  return *m_ledgerReplayer;
619  }
620 
622  getInboundLedgers() override
623  {
624  return *m_inboundLedgers;
625  }
626 
629  {
630  return *m_inboundTransactions;
631  }
632 
635  {
636  return m_acceptedLedgerCache;
637  }
638 
639  void
640  gotTXSet(std::shared_ptr<SHAMap> const& set, bool fromAcquire)
641  {
642  if (set)
643  m_networkOPs->mapComplete(set, fromAcquire);
644  }
645 
648  {
649  return m_txMaster;
650  }
651 
653  getPerfLog() override
654  {
655  return *perfLog_;
656  }
657 
658  NodeCache&
659  getTempNodeCache() override
660  {
661  return m_tempNodeCache;
662  }
663 
665  getNodeStore() override
666  {
667  return *m_nodeStore;
668  }
669 
670  // The shard store is an optional feature. If the sever is configured for
671  // shards, this function will return a valid pointer, otherwise a nullptr.
673  getShardStore() override
674  {
675  return shardStore_.get();
676  }
677 
679  getShardArchiveHandler(bool tryRecovery) override
680  {
681  static std::mutex handlerMutex;
682  std::lock_guard lock(handlerMutex);
683 
684  // After constructing the handler, try to
685  // initialize it. Log on error; set the
686  // member variable on success.
687  auto initAndSet =
689  if (!handler)
690  return false;
691 
692  if (!handler->init())
693  {
694  JLOG(m_journal.error())
695  << "Failed to initialize ShardArchiveHandler.";
696 
697  return false;
698  }
699 
700  shardArchiveHandler_ = std::move(handler);
701  return true;
702  };
703 
704  // Need to resume based on state from a previous
705  // run.
706  if (tryRecovery)
707  {
708  if (shardArchiveHandler_ != nullptr)
709  {
710  JLOG(m_journal.error())
711  << "ShardArchiveHandler already created at startup.";
712 
713  return nullptr;
714  }
715 
716  auto handler =
718 
719  if (!initAndSet(std::move(handler)))
720  return nullptr;
721  }
722 
723  // Construct the ShardArchiveHandler
724  if (shardArchiveHandler_ == nullptr)
725  {
726  auto handler =
728 
729  if (!initAndSet(std::move(handler)))
730  return nullptr;
731  }
732 
733  return shardArchiveHandler_.get();
734  }
735 
737  getMasterMutex() override
738  {
739  return m_masterMutex;
740  }
741 
742  LoadManager&
743  getLoadManager() override
744  {
745  return *m_loadManager;
746  }
747 
750  {
751  return *m_resourceManager;
752  }
753 
754  OrderBookDB&
755  getOrderBookDB() override
756  {
757  return m_orderBookDB;
758  }
759 
760  PathRequests&
761  getPathRequests() override
762  {
763  return *m_pathRequests;
764  }
765 
766  CachedSLEs&
767  cachedSLEs() override
768  {
769  return cachedSLEs_;
770  }
771 
773  getAmendmentTable() override
774  {
775  return *m_amendmentTable;
776  }
777 
778  LoadFeeTrack&
779  getFeeTrack() override
780  {
781  return *mFeeTrack;
782  }
783 
784  HashRouter&
785  getHashRouter() override
786  {
787  return *hashRouter_;
788  }
789 
791  getValidations() override
792  {
793  return mValidations;
794  }
795 
797  validators() override
798  {
799  return *validators_;
800  }
801 
803  validatorSites() override
804  {
805  return *validatorSites_;
806  }
807 
810  {
811  return *validatorManifests_;
812  }
813 
816  {
817  return *publisherManifests_;
818  }
819 
820  Cluster&
821  cluster() override
822  {
823  return *cluster_;
824  }
825 
827  peerReservations() override
828  {
829  return *peerReservations_;
830  }
831 
832  SHAMapStore&
833  getSHAMapStore() override
834  {
835  return *m_shaMapStore;
836  }
837 
838  PendingSaves&
839  pendingSaves() override
840  {
841  return pendingSaves_;
842  }
843 
844  AccountIDCache const&
845  accountIDCache() const override
846  {
847  return accountIDCache_;
848  }
849 
850  OpenLedger&
851  openLedger() override
852  {
853  if (config_->reporting())
854  Throw<ReportingShouldProxy>();
855  return *openLedger_;
856  }
857 
858  OpenLedger const&
859  openLedger() const override
860  {
861  if (config_->reporting())
862  Throw<ReportingShouldProxy>();
863  return *openLedger_;
864  }
865 
866  Overlay&
867  overlay() override
868  {
869  assert(overlay_);
870  return *overlay_;
871  }
872 
873  TxQ&
874  getTxQ() override
875  {
876  assert(txQ_.get() != nullptr);
877  return *txQ_;
878  }
879 
882  {
883  assert(mRelationalDBInterface.get() != nullptr);
884  return *mRelationalDBInterface;
885  }
886 
887  DatabaseCon&
888  getWalletDB() override
889  {
890  assert(mWalletDB.get() != nullptr);
891  return *mWalletDB;
892  }
893 
894  ReportingETL&
895  getReportingETL() override
896  {
897  assert(reportingETL_.get() != nullptr);
898  return *reportingETL_;
899  }
900 
901  bool
902  serverOkay(std::string& reason) override;
903 
905  journal(std::string const& name) override;
906 
907  //--------------------------------------------------------------------------
908 
909  bool
911  {
912  assert(mWalletDB.get() == nullptr);
913 
914  try
915  {
918 
919  // wallet database
921  setup.useGlobalPragma = false;
922 
924  }
925  catch (std::exception const& e)
926  {
927  JLOG(m_journal.fatal())
928  << "Failed to initialize SQL databases: " << e.what();
929  return false;
930  }
931 
932  return true;
933  }
934 
935  bool
937  {
938  if (config_->doImport)
939  {
940  auto j = logs_->journal("NodeObject");
941  NodeStore::DummyScheduler dummyScheduler;
944  megabytes(config_->getValueFor(
945  SizedItem::burstSize, std::nullopt)),
946  dummyScheduler,
947  0,
949  j);
950 
951  JLOG(j.warn()) << "Starting node import from '" << source->getName()
952  << "' to '" << m_nodeStore->getName() << "'.";
953 
954  using namespace std::chrono;
955  auto const start = steady_clock::now();
956 
957  m_nodeStore->importDatabase(*source);
958 
959  auto const elapsed =
960  duration_cast<seconds>(steady_clock::now() - start);
961  JLOG(j.warn()) << "Node import from '" << source->getName()
962  << "' took " << elapsed.count() << " seconds.";
963  }
964 
965  return true;
966  }
967 
968  //--------------------------------------------------------------------------
969  //
970  // PropertyStream
971  //
972 
973  void
975  {
976  }
977 
978  //--------------------------------------------------------------------------
979 
980  void
982  {
983  // Only start the timer if waitHandlerCounter_ is not yet joined.
984  if (auto optionalCountedHandler = waitHandlerCounter_.wrap(
985  [this](boost::system::error_code const& e) {
986  if (e.value() == boost::system::errc::success)
987  {
988  m_jobQueue->addJob(
989  jtSWEEP, "sweep", [this]() { doSweep(); });
990  }
991  // Recover as best we can if an unexpected error occurs.
992  if (e.value() != boost::system::errc::success &&
993  e.value() != boost::asio::error::operation_aborted)
994  {
995  // Try again later and hope for the best.
996  JLOG(m_journal.error())
997  << "Sweep timer got error '" << e.message()
998  << "'. Restarting timer.";
999  setSweepTimer();
1000  }
1001  }))
1002  {
1003  using namespace std::chrono;
1004  sweepTimer_.expires_from_now(
1005  seconds{config_->SWEEP_INTERVAL.value_or(
1006  config_->getValueFor(SizedItem::sweepInterval))});
1007  sweepTimer_.async_wait(std::move(*optionalCountedHandler));
1008  }
1009  }
1010 
1011  void
1013  {
1014  // Only start the timer if waitHandlerCounter_ is not yet joined.
1015  if (auto optionalCountedHandler = waitHandlerCounter_.wrap(
1016  [this](boost::system::error_code const& e) {
1017  if (e.value() == boost::system::errc::success)
1018  {
1019  crypto_prng().mix_entropy();
1020  setEntropyTimer();
1021  }
1022  // Recover as best we can if an unexpected error occurs.
1023  if (e.value() != boost::system::errc::success &&
1024  e.value() != boost::asio::error::operation_aborted)
1025  {
1026  // Try again later and hope for the best.
1027  JLOG(m_journal.error())
1028  << "Entropy timer got error '" << e.message()
1029  << "'. Restarting timer.";
1030  setEntropyTimer();
1031  }
1032  }))
1033  {
1034  using namespace std::chrono_literals;
1035  entropyTimer_.expires_from_now(5min);
1036  entropyTimer_.async_wait(std::move(*optionalCountedHandler));
1037  }
1038  }
1039 
1040  void
1042  {
1043  if (!config_->standalone() &&
1044  !getRelationalDBInterface().transactionDbHasSpace(*config_))
1045  {
1046  signalStop();
1047  }
1048 
1049  // VFALCO NOTE Does the order of calls matter?
1050  // VFALCO TODO fix the dependency inversion using an observer,
1051  // have listeners register for "onSweep ()" notification.
1052 
1053  nodeFamily_.sweep();
1054  if (shardFamily_)
1055  shardFamily_->sweep();
1057  getNodeStore().sweep();
1058  if (shardStore_)
1059  shardStore_->sweep();
1060  getLedgerMaster().sweep();
1061  getTempNodeCache().sweep();
1065  m_acceptedLedgerCache.sweep();
1066  cachedSLEs_.sweep();
1067 
1068 #ifdef RIPPLED_REPORTING
1069  if (auto pg = dynamic_cast<RelationalDBInterfacePostgres*>(
1071  pg->sweep();
1072 #endif
1073 
1074  // Set timer to do another sweep later.
1075  setSweepTimer();
1076  }
1077 
1078  LedgerIndex
1080  {
1081  return maxDisallowedLedger_;
1082  }
1083 
1084 private:
1085  // For a newly-started validator, this is the greatest persisted ledger
1086  // and new validations must be greater than this.
1088 
1089  bool
1090  nodeToShards();
1091 
1092  void
1094 
1097 
1099  loadLedgerFromFile(std::string const& ledgerID);
1100 
1101  bool
1102  loadOldLedger(std::string const& ledgerID, bool replay, bool isFilename);
1103 
1104  void
1106 };
1107 
1108 //------------------------------------------------------------------------------
1109 
1110 // TODO Break this up into smaller, more digestible initialization segments.
1111 bool
1113 {
1114  // We want to intercept CTRL-C and the standard termination signal SIGTERM
1115  // and terminate the process. This handler will NEVER be invoked twice.
1116  //
1117  // Note that async_wait is "one-shot": for each call, the handler will be
1118  // invoked exactly once, either when one of the registered signals in the
1119  // signal set occurs or the signal set is cancelled. Subsequent signals are
1120  // effectively ignored (technically, they are queued up, waiting for a call
1121  // to async_wait).
1122  m_signals.add(SIGINT);
1123  m_signals.add(SIGTERM);
1124  m_signals.async_wait(
1125  [this](boost::system::error_code const& ec, int signum) {
1126  // Indicates the signal handler has been aborted; do nothing
1127  if (ec == boost::asio::error::operation_aborted)
1128  return;
1129 
1130  JLOG(m_journal.info()) << "Received signal " << signum;
1131 
1132  if (signum == SIGTERM || signum == SIGINT)
1133  signalStop();
1134  });
1135 
1136  auto debug_log = config_->getDebugLogFile();
1137 
1138  if (!debug_log.empty())
1139  {
1140  // Let debug messages go to the file but only WARNING or higher to
1141  // regular output (unless verbose)
1142 
1143  if (!logs_->open(debug_log))
1144  std::cerr << "Can't open log file " << debug_log << '\n';
1145 
1146  using namespace beast::severities;
1147  if (logs_->threshold() > kDebug)
1148  logs_->threshold(kDebug);
1149  }
1150  JLOG(m_journal.info()) << "process starting: "
1152 
1153  if (numberOfThreads(*config_) < 2)
1154  {
1155  JLOG(m_journal.warn()) << "Limited to a single I/O service thread by "
1156  "system configuration.";
1157  }
1158 
1159  // Optionally turn off logging to console.
1160  logs_->silent(config_->silent());
1161 
1162  if (!config_->standalone())
1163  timeKeeper_->run(config_->SNTP_SERVERS);
1164 
1165  if (!initRDBMS() || !initNodeStore())
1166  return false;
1167 
1168  if (shardStore_)
1169  {
1170  shardFamily_ =
1171  std::make_unique<ShardFamily>(*this, *m_collectorManager);
1172 
1173  if (!shardStore_->init())
1174  return false;
1175  }
1176 
1177  if (!peerReservations_->load(getWalletDB()))
1178  {
1179  JLOG(m_journal.fatal()) << "Cannot find peer reservations!";
1180  return false;
1181  }
1182 
1185 
1186  // Configure the amendments the server supports
1187  {
1188  auto const supported = []() {
1189  auto const& amendments = detail::supportedAmendments();
1191  supported.reserve(amendments.size());
1192  for (auto const& [a, vote] : amendments)
1193  {
1194  auto const f = ripple::getRegisteredFeature(a);
1195  assert(f);
1196  if (f)
1197  supported.emplace_back(a, *f, vote);
1198  }
1199  return supported;
1200  }();
1201  Section const& downVoted = config_->section(SECTION_VETO_AMENDMENTS);
1202 
1203  Section const& upVoted = config_->section(SECTION_AMENDMENTS);
1204 
1206  *this,
1207  config().AMENDMENT_MAJORITY_TIME,
1208  supported,
1209  upVoted,
1210  downVoted,
1211  logs_->journal("Amendments"));
1212  }
1213 
1215 
1216  auto const startUp = config_->START_UP;
1217  JLOG(m_journal.debug()) << "startUp: " << startUp;
1218  if (!config_->reporting())
1219  {
1220  if (startUp == Config::FRESH)
1221  {
1222  JLOG(m_journal.info()) << "Starting new Ledger";
1223 
1225  }
1226  else if (
1227  startUp == Config::LOAD || startUp == Config::LOAD_FILE ||
1228  startUp == Config::REPLAY)
1229  {
1230  JLOG(m_journal.info()) << "Loading specified Ledger";
1231 
1232  if (!loadOldLedger(
1233  config_->START_LEDGER,
1234  startUp == Config::REPLAY,
1235  startUp == Config::LOAD_FILE))
1236  {
1237  JLOG(m_journal.error())
1238  << "The specified ledger could not be loaded.";
1239  if (config_->FAST_LOAD)
1240  {
1241  // Fall back to syncing from the network, such as
1242  // when there's no existing data.
1244  }
1245  else
1246  {
1247  return false;
1248  }
1249  }
1250  }
1251  else if (startUp == Config::NETWORK)
1252  {
1253  // This should probably become the default once we have a stable
1254  // network.
1255  if (!config_->standalone())
1256  m_networkOPs->setNeedNetworkLedger();
1257 
1259  }
1260  else
1261  {
1263  }
1264  }
1265 
1266  if (!config().reporting())
1267  m_orderBookDB.setup(getLedgerMaster().getCurrentLedger());
1268 
1269  nodeIdentity_ = getNodeIdentity(*this);
1270 
1271  if (!cluster_->load(config().section(SECTION_CLUSTER_NODES)))
1272  {
1273  JLOG(m_journal.fatal()) << "Invalid entry in cluster configuration.";
1274  return false;
1275  }
1276 
1277  if (!config().reporting())
1278  {
1279  {
1281  return false;
1282 
1283  if (!validatorManifests_->load(
1284  getWalletDB(),
1285  "ValidatorManifests",
1287  config()
1288  .section(SECTION_VALIDATOR_KEY_REVOCATION)
1289  .values()))
1290  {
1291  JLOG(m_journal.fatal())
1292  << "Invalid configured validator manifest.";
1293  return false;
1294  }
1295 
1296  publisherManifests_->load(getWalletDB(), "PublisherManifests");
1297 
1298  // Setup trusted validators
1299  if (!validators_->load(
1301  config().section(SECTION_VALIDATORS).values(),
1302  config().section(SECTION_VALIDATOR_LIST_KEYS).values()))
1303  {
1304  JLOG(m_journal.fatal())
1305  << "Invalid entry in validator configuration.";
1306  return false;
1307  }
1308  }
1309 
1310  if (!validatorSites_->load(
1311  config().section(SECTION_VALIDATOR_LIST_SITES).values()))
1312  {
1313  JLOG(m_journal.fatal())
1314  << "Invalid entry in [" << SECTION_VALIDATOR_LIST_SITES << "]";
1315  return false;
1316  }
1317  }
1318  //----------------------------------------------------------------------
1319  //
1320  // Server
1321  //
1322  //----------------------------------------------------------------------
1323 
1324  // VFALCO NOTE Unfortunately, in stand-alone mode some code still
1325  // foolishly calls overlay(). When this is fixed we can
1326  // move the instantiation inside a conditional:
1327  //
1328  // if (!config_.standalone())
1329  if (!config_->reporting())
1330  {
1332  *this,
1334  *serverHandler_,
1336  *m_resolver,
1337  get_io_service(),
1338  *config_,
1339  m_collectorManager->collector());
1340  add(*overlay_); // add to PropertyStream
1341  }
1342 
1343  if (!config_->standalone())
1344  {
1345  // NodeStore import into the ShardStore requires the SQLite database
1346  if (config_->nodeToShard && !nodeToShards())
1347  return false;
1348  }
1349 
1350  // start first consensus round
1351  if (!config_->reporting() &&
1352  !m_networkOPs->beginConsensus(
1353  m_ledgerMaster->getClosedLedger()->info().hash))
1354  {
1355  JLOG(m_journal.fatal()) << "Unable to start consensus";
1356  return false;
1357  }
1358 
1359  {
1360  try
1361  {
1362  auto setup = setup_ServerHandler(
1364  setup.makeContexts();
1365  serverHandler_->setup(setup, m_journal);
1366  }
1367  catch (std::exception const& e)
1368  {
1369  if (auto stream = m_journal.fatal())
1370  {
1371  stream << "Unable to setup server handler";
1372  if (std::strlen(e.what()) > 0)
1373  stream << ": " << e.what();
1374  }
1375  return false;
1376  }
1377  }
1378 
1379  // Begin connecting to network.
1380  if (!config_->standalone())
1381  {
1382  // Should this message be here, conceptually? In theory this sort
1383  // of message, if displayed, should be displayed from PeerFinder.
1384  if (config_->PEER_PRIVATE && config_->IPS_FIXED.empty())
1385  {
1386  JLOG(m_journal.warn())
1387  << "No outbound peer connections will be made";
1388  }
1389 
1390  // VFALCO NOTE the state timer resets the deadlock detector.
1391  //
1392  m_networkOPs->setStateTimer();
1393  }
1394  else
1395  {
1396  JLOG(m_journal.warn()) << "Running in standalone mode";
1397 
1398  m_networkOPs->setStandAlone();
1399  }
1400 
1401  if (config_->canSign())
1402  {
1403  JLOG(m_journal.warn()) << "*** The server is configured to allow the "
1404  "'sign' and 'sign_for'";
1405  JLOG(m_journal.warn()) << "*** commands. These commands have security "
1406  "implications and have";
1407  JLOG(m_journal.warn()) << "*** been deprecated. They will be removed "
1408  "in a future release of";
1409  JLOG(m_journal.warn()) << "*** rippled.";
1410  JLOG(m_journal.warn()) << "*** If you do not use them to sign "
1411  "transactions please edit your";
1412  JLOG(m_journal.warn())
1413  << "*** configuration file and remove the [enable_signing] stanza.";
1414  JLOG(m_journal.warn()) << "*** If you do use them to sign transactions "
1415  "please migrate to a";
1416  JLOG(m_journal.warn())
1417  << "*** standalone signing solution as soon as possible.";
1418  }
1419 
1420  //
1421  // Execute start up rpc commands.
1422  //
1423  for (auto cmd : config_->section(SECTION_RPC_STARTUP).lines())
1424  {
1425  Json::Reader jrReader;
1426  Json::Value jvCommand;
1427 
1428  if (!jrReader.parse(cmd, jvCommand))
1429  {
1430  JLOG(m_journal.fatal()) << "Couldn't parse entry in ["
1431  << SECTION_RPC_STARTUP << "]: '" << cmd;
1432  }
1433 
1434  if (!config_->quiet())
1435  {
1436  JLOG(m_journal.fatal())
1437  << "Startup RPC: " << jvCommand << std::endl;
1438  }
1439 
1442  RPC::JsonContext context{
1443  {journal("RPCHandler"),
1444  *this,
1445  loadType,
1446  getOPs(),
1447  getLedgerMaster(),
1448  c,
1449  Role::ADMIN,
1450  {},
1451  {},
1453  jvCommand};
1454 
1455  Json::Value jvResult;
1456  RPC::doCommand(context, jvResult);
1457 
1458  if (!config_->quiet())
1459  {
1460  JLOG(m_journal.fatal()) << "Result: " << jvResult << std::endl;
1461  }
1462  }
1463 
1464  RPC::ShardArchiveHandler* shardArchiveHandler = nullptr;
1465  if (shardStore_)
1466  {
1467  try
1468  {
1469  // Create a ShardArchiveHandler if recovery
1470  // is needed (there's a state database left
1471  // over from a previous run).
1472  auto handler = getShardArchiveHandler(true);
1473 
1474  // Recovery is needed.
1475  if (handler)
1476  shardArchiveHandler = handler;
1477  }
1478  catch (std::exception const& e)
1479  {
1480  JLOG(m_journal.fatal())
1481  << "Exception when starting ShardArchiveHandler from "
1482  "state database: "
1483  << e.what();
1484 
1485  return false;
1486  }
1487  }
1488 
1489  if (shardArchiveHandler && !shardArchiveHandler->start())
1490  {
1491  JLOG(m_journal.fatal()) << "Failed to start ShardArchiveHandler.";
1492 
1493  return false;
1494  }
1495 
1496  validatorSites_->start();
1497 
1498  if (reportingETL_)
1499  reportingETL_->start();
1500 
1501  return true;
1502 }
1503 
1504 void
1505 ApplicationImp::start(bool withTimers)
1506 {
1507  JLOG(m_journal.info()) << "Application starting. Version is "
1509 
1510  if (withTimers)
1511  {
1512  setSweepTimer();
1513  setEntropyTimer();
1514  }
1515 
1517  m_resolver->start();
1518  m_loadManager->start();
1519  m_shaMapStore->start();
1520  if (overlay_)
1521  overlay_->start();
1522  grpcServer_->start();
1523  ledgerCleaner_->start();
1524  perfLog_->start();
1525 }
1526 
1527 void
1529 {
1530  if (!config_->standalone())
1531  {
1532  // VFALCO NOTE This seems unnecessary. If we properly refactor the load
1533  // manager then the deadlock detector can just always be
1534  // "armed"
1535  //
1537  }
1538 
1539  {
1541  stoppingCondition_.wait(lk, [this] { return isTimeToStop.load(); });
1542  }
1543 
1544  JLOG(m_journal.debug()) << "Application stopping";
1545 
1547 
1548  // VFALCO Enormous hack, we have to force the probe to cancel
1549  // before we stop the io_service queue or else it never
1550  // unblocks in its destructor. The fix is to make all
1551  // io_objects gracefully handle exit so that we can
1552  // naturally return from io_service::run() instead of
1553  // forcing a call to io_service::stop()
1555 
1556  m_resolver->stop_async();
1557 
1558  // NIKB This is a hack - we need to wait for the resolver to
1559  // stop. before we stop the io_server_queue or weird
1560  // things will happen.
1561  m_resolver->stop();
1562 
1563  {
1564  boost::system::error_code ec;
1565  sweepTimer_.cancel(ec);
1566  if (ec)
1567  {
1568  JLOG(m_journal.error())
1569  << "Application: sweepTimer cancel error: " << ec.message();
1570  }
1571 
1572  ec.clear();
1573  entropyTimer_.cancel(ec);
1574  if (ec)
1575  {
1576  JLOG(m_journal.error())
1577  << "Application: entropyTimer cancel error: " << ec.message();
1578  }
1579  }
1580 
1581  // Make sure that any waitHandlers pending in our timers are done
1582  // before we declare ourselves stopped.
1583  using namespace std::chrono_literals;
1584 
1585  waitHandlerCounter_.join("Application", 1s, m_journal);
1586 
1587  mValidations.flush();
1588 
1589  validatorSites_->stop();
1590 
1591  // TODO Store manifests in manifests.sqlite instead of wallet.db
1592  validatorManifests_->save(
1593  getWalletDB(), "ValidatorManifests", [this](PublicKey const& pubKey) {
1594  return validators().listed(pubKey);
1595  });
1596 
1597  publisherManifests_->save(
1598  getWalletDB(), "PublisherManifests", [this](PublicKey const& pubKey) {
1599  return validators().trustedPublisher(pubKey);
1600  });
1601 
1602  // The order of these stop calls is delicate.
1603  // Re-ordering them risks undefined behavior.
1604  m_loadManager->stop();
1605  m_shaMapStore->stop();
1606  m_jobQueue->stop();
1608  shardArchiveHandler_->stop();
1609  if (overlay_)
1610  overlay_->stop();
1611  if (shardStore_)
1612  shardStore_->stop();
1613  grpcServer_->stop();
1614  m_networkOPs->stop();
1615  serverHandler_->stop();
1616  m_ledgerReplayer->stop();
1617  m_inboundTransactions->stop();
1618  m_inboundLedgers->stop();
1619  ledgerCleaner_->stop();
1620  if (reportingETL_)
1621  reportingETL_->stop();
1622  if (auto pg = dynamic_cast<RelationalDBInterfacePostgres*>(
1624  pg->stop();
1625  m_nodeStore->stop();
1626  perfLog_->stop();
1627 
1628  JLOG(m_journal.info()) << "Done.";
1629 }
1630 
1631 void
1633 {
1634  if (!isTimeToStop.exchange(true))
1636 }
1637 
1638 bool
1640 {
1641  return checkSigs_;
1642 }
1643 
1644 void
1646 {
1647  checkSigs_ = check;
1648 }
1649 
1650 bool
1652 {
1653  return isTimeToStop.load();
1654 }
1655 
1656 int
1658 {
1659  // Standard handles, config file, misc I/O etc:
1660  int needed = 128;
1661 
1662  // 2x the configured peer limit for peer connections:
1663  if (overlay_)
1664  needed += 2 * overlay_->limit();
1665 
1666  // the number of fds needed by the backend (internally
1667  // doubled if online delete is enabled).
1668  needed += std::max(5, m_shaMapStore->fdRequired());
1669 
1670  if (shardStore_)
1671  needed += shardStore_->fdRequired();
1672 
1673  // One fd per incoming connection a port can accept, or
1674  // if no limit is set, assume it'll handle 256 clients.
1675  for (auto const& p : serverHandler_->setup().ports)
1676  needed += std::max(256, p.limit);
1677 
1678  // The minimum number of file descriptors we need is 1024:
1679  return std::max(1024, needed);
1680 }
1681 
1682 //------------------------------------------------------------------------------
1683 
1684 void
1686 {
1687  std::vector<uint256> initialAmendments =
1688  (config_->START_UP == Config::FRESH) ? m_amendmentTable->getDesired()
1690 
1691  std::shared_ptr<Ledger> const genesis = std::make_shared<Ledger>(
1692  create_genesis, *config_, initialAmendments, nodeFamily_);
1693  m_ledgerMaster->storeLedger(genesis);
1694 
1695  auto const next =
1696  std::make_shared<Ledger>(*genesis, timeKeeper().closeTime());
1697  next->updateSkipList();
1698  next->setImmutable(*config_);
1699  openLedger_.emplace(next, cachedSLEs_, logs_->journal("OpenLedger"));
1700  m_ledgerMaster->storeLedger(next);
1701  m_ledgerMaster->switchLCL(next);
1702 }
1703 
1706 {
1707  auto j = journal("Ledger");
1708 
1709  try
1710  {
1711  auto const [ledger, seq, hash] = getLatestLedger(*this);
1712 
1713  if (!ledger)
1714  return ledger;
1715 
1716  ledger->setImmutable(*config_);
1717 
1718  if (getLedgerMaster().haveLedger(seq))
1719  ledger->setValidated();
1720 
1721  if (ledger->info().hash == hash)
1722  {
1723  JLOG(j.trace()) << "Loaded ledger: " << hash;
1724  return ledger;
1725  }
1726 
1727  if (auto stream = j.error())
1728  {
1729  stream << "Failed on ledger";
1730  Json::Value p;
1731  addJson(p, {*ledger, nullptr, LedgerFill::full});
1732  stream << p;
1733  }
1734 
1735  return {};
1736  }
1737  catch (SHAMapMissingNode const& mn)
1738  {
1739  JLOG(j.warn()) << "Ledger in database: " << mn.what();
1740  return {};
1741  }
1742 }
1743 
1746 {
1747  try
1748  {
1749  std::ifstream ledgerFile(name, std::ios::in);
1750 
1751  if (!ledgerFile)
1752  {
1753  JLOG(m_journal.fatal()) << "Unable to open file '" << name << "'";
1754  return nullptr;
1755  }
1756 
1757  Json::Reader reader;
1758  Json::Value jLedger;
1759 
1760  if (!reader.parse(ledgerFile, jLedger))
1761  {
1762  JLOG(m_journal.fatal()) << "Unable to parse ledger JSON";
1763  return nullptr;
1764  }
1765 
1766  std::reference_wrapper<Json::Value> ledger(jLedger);
1767 
1768  // accept a wrapped ledger
1769  if (ledger.get().isMember("result"))
1770  ledger = ledger.get()["result"];
1771 
1772  if (ledger.get().isMember("ledger"))
1773  ledger = ledger.get()["ledger"];
1774 
1775  std::uint32_t seq = 1;
1776  auto closeTime = timeKeeper().closeTime();
1777  using namespace std::chrono_literals;
1778  auto closeTimeResolution = 30s;
1779  bool closeTimeEstimated = false;
1780  std::uint64_t totalDrops = 0;
1781 
1782  if (ledger.get().isMember("accountState"))
1783  {
1784  if (ledger.get().isMember(jss::ledger_index))
1785  {
1786  seq = ledger.get()[jss::ledger_index].asUInt();
1787  }
1788 
1789  if (ledger.get().isMember("close_time"))
1790  {
1791  using tp = NetClock::time_point;
1792  using d = tp::duration;
1793  closeTime = tp{d{ledger.get()["close_time"].asUInt()}};
1794  }
1795  if (ledger.get().isMember("close_time_resolution"))
1796  {
1797  using namespace std::chrono;
1798  closeTimeResolution =
1799  seconds{ledger.get()["close_time_resolution"].asUInt()};
1800  }
1801  if (ledger.get().isMember("close_time_estimated"))
1802  {
1803  closeTimeEstimated =
1804  ledger.get()["close_time_estimated"].asBool();
1805  }
1806  if (ledger.get().isMember("total_coins"))
1807  {
1808  totalDrops = beast::lexicalCastThrow<std::uint64_t>(
1809  ledger.get()["total_coins"].asString());
1810  }
1811 
1812  ledger = ledger.get()["accountState"];
1813  }
1814 
1815  if (!ledger.get().isArrayOrNull())
1816  {
1817  JLOG(m_journal.fatal()) << "State nodes must be an array";
1818  return nullptr;
1819  }
1820 
1821  auto loadLedger =
1822  std::make_shared<Ledger>(seq, closeTime, *config_, nodeFamily_);
1823  loadLedger->setTotalDrops(totalDrops);
1824 
1825  for (Json::UInt index = 0; index < ledger.get().size(); ++index)
1826  {
1827  Json::Value& entry = ledger.get()[index];
1828 
1829  if (!entry.isObjectOrNull())
1830  {
1831  JLOG(m_journal.fatal()) << "Invalid entry in ledger";
1832  return nullptr;
1833  }
1834 
1835  uint256 uIndex;
1836 
1837  if (!uIndex.parseHex(entry[jss::index].asString()))
1838  {
1839  JLOG(m_journal.fatal()) << "Invalid entry in ledger";
1840  return nullptr;
1841  }
1842 
1843  entry.removeMember(jss::index);
1844 
1845  STParsedJSONObject stp("sle", ledger.get()[index]);
1846 
1847  if (!stp.object || uIndex.isZero())
1848  {
1849  JLOG(m_journal.fatal()) << "Invalid entry in ledger";
1850  return nullptr;
1851  }
1852 
1853  // VFALCO TODO This is the only place that
1854  // constructor is used, try to remove it
1855  STLedgerEntry sle(*stp.object, uIndex);
1856 
1857  if (!loadLedger->addSLE(sle))
1858  {
1859  JLOG(m_journal.fatal())
1860  << "Couldn't add serialized ledger: " << uIndex;
1861  return nullptr;
1862  }
1863  }
1864 
1865  loadLedger->stateMap().flushDirty(hotACCOUNT_NODE);
1866 
1867  loadLedger->setAccepted(
1868  closeTime, closeTimeResolution, !closeTimeEstimated, *config_);
1869 
1870  return loadLedger;
1871  }
1872  catch (std::exception const& x)
1873  {
1874  JLOG(m_journal.fatal()) << "Ledger contains invalid data: " << x.what();
1875  return nullptr;
1876  }
1877 }
1878 
1879 bool
1881  std::string const& ledgerID,
1882  bool replay,
1883  bool isFileName)
1884 {
1885  try
1886  {
1887  std::shared_ptr<Ledger const> loadLedger, replayLedger;
1888 
1889  if (isFileName)
1890  {
1891  if (!ledgerID.empty())
1892  loadLedger = loadLedgerFromFile(ledgerID);
1893  }
1894  else if (ledgerID.length() == 64)
1895  {
1896  uint256 hash;
1897 
1898  if (hash.parseHex(ledgerID))
1899  {
1900  loadLedger = loadByHash(hash, *this);
1901 
1902  if (!loadLedger)
1903  {
1904  // Try to build the ledger from the back end
1905  auto il = std::make_shared<InboundLedger>(
1906  *this,
1907  hash,
1908  0,
1910  stopwatch(),
1911  make_DummyPeerSet(*this));
1912  if (il->checkLocal())
1913  loadLedger = il->getLedger();
1914  }
1915  }
1916  }
1917  else if (ledgerID.empty() || boost::iequals(ledgerID, "latest"))
1918  {
1919  loadLedger = getLastFullLedger();
1920  }
1921  else
1922  {
1923  // assume by sequence
1924  std::uint32_t index;
1925 
1926  if (beast::lexicalCastChecked(index, ledgerID))
1927  loadLedger = loadByIndex(index, *this);
1928  }
1929 
1930  if (!loadLedger)
1931  return false;
1932 
1933  if (replay)
1934  {
1935  // Replay a ledger close with same prior ledger and transactions
1936 
1937  // this ledger holds the transactions we want to replay
1938  replayLedger = loadLedger;
1939 
1940  JLOG(m_journal.info()) << "Loading parent ledger";
1941 
1942  loadLedger = loadByHash(replayLedger->info().parentHash, *this);
1943  if (!loadLedger)
1944  {
1945  JLOG(m_journal.info())
1946  << "Loading parent ledger from node store";
1947 
1948  // Try to build the ledger from the back end
1949  auto il = std::make_shared<InboundLedger>(
1950  *this,
1951  replayLedger->info().parentHash,
1952  0,
1954  stopwatch(),
1955  make_DummyPeerSet(*this));
1956 
1957  if (il->checkLocal())
1958  loadLedger = il->getLedger();
1959 
1960  if (!loadLedger)
1961  {
1962  JLOG(m_journal.fatal()) << "Replay ledger missing/damaged";
1963  assert(false);
1964  return false;
1965  }
1966  }
1967  }
1968  using namespace std::chrono_literals;
1969  using namespace date;
1970  static constexpr NetClock::time_point ledgerWarnTimePoint{
1971  sys_days{January / 1 / 2018} - sys_days{January / 1 / 2000}};
1972  if (loadLedger->info().closeTime < ledgerWarnTimePoint)
1973  {
1974  JLOG(m_journal.fatal())
1975  << "\n\n*** WARNING ***\n"
1976  "You are replaying a ledger from before "
1977  << to_string(ledgerWarnTimePoint)
1978  << " UTC.\n"
1979  "This replay will not handle your ledger as it was "
1980  "originally "
1981  "handled.\nConsider running an earlier version of rippled "
1982  "to "
1983  "get the older rules.\n*** CONTINUING ***\n";
1984  }
1985 
1986  JLOG(m_journal.info()) << "Loading ledger " << loadLedger->info().hash
1987  << " seq:" << loadLedger->info().seq;
1988 
1989  if (loadLedger->info().accountHash.isZero())
1990  {
1991  JLOG(m_journal.fatal()) << "Ledger is empty.";
1992  assert(false);
1993  return false;
1994  }
1995 
1996  if (!loadLedger->walkLedger(journal("Ledger"), true))
1997  {
1998  JLOG(m_journal.fatal()) << "Ledger is missing nodes.";
1999  assert(false);
2000  return false;
2001  }
2002 
2003  if (!loadLedger->assertSensible(journal("Ledger")))
2004  {
2005  JLOG(m_journal.fatal()) << "Ledger is not sensible.";
2006  assert(false);
2007  return false;
2008  }
2009 
2010  m_ledgerMaster->setLedgerRangePresent(
2011  loadLedger->info().seq, loadLedger->info().seq);
2012 
2013  m_ledgerMaster->switchLCL(loadLedger);
2014  loadLedger->setValidated();
2015  m_ledgerMaster->setFullLedger(loadLedger, true, false);
2016  openLedger_.emplace(
2017  loadLedger, cachedSLEs_, logs_->journal("OpenLedger"));
2018 
2019  if (replay)
2020  {
2021  // inject transaction(s) from the replayLedger into our open ledger
2022  // and build replay structure
2023  auto replayData =
2024  std::make_unique<LedgerReplay>(loadLedger, replayLedger);
2025 
2026  for (auto const& [_, tx] : replayData->orderedTxns())
2027  {
2028  (void)_;
2029  auto txID = tx->getTransactionID();
2030 
2031  auto s = std::make_shared<Serializer>();
2032  tx->add(*s);
2033 
2035 
2036  openLedger_->modify(
2037  [&txID, &s](OpenView& view, beast::Journal j) {
2038  view.rawTxInsert(txID, std::move(s), nullptr);
2039  return true;
2040  });
2041  }
2042 
2043  m_ledgerMaster->takeReplay(std::move(replayData));
2044  }
2045  }
2046  catch (SHAMapMissingNode const& mn)
2047  {
2048  JLOG(m_journal.fatal())
2049  << "While loading specified ledger: " << mn.what();
2050  return false;
2051  }
2052  catch (boost::bad_lexical_cast&)
2053  {
2054  JLOG(m_journal.fatal())
2055  << "Ledger specified '" << ledgerID << "' is not valid";
2056  return false;
2057  }
2058 
2059  return true;
2060 }
2061 
2062 bool
2064 {
2065  if (!config().ELB_SUPPORT)
2066  return true;
2067 
2068  if (isStopping())
2069  {
2070  reason = "Server is shutting down";
2071  return false;
2072  }
2073 
2074  if (getOPs().isNeedNetworkLedger())
2075  {
2076  reason = "Not synchronized with network yet";
2077  return false;
2078  }
2079 
2080  if (getOPs().isAmendmentBlocked())
2081  {
2082  reason = "Server version too old";
2083  return false;
2084  }
2085 
2086  if (getOPs().isUNLBlocked())
2087  {
2088  reason = "No valid validator list available";
2089  return false;
2090  }
2091 
2092  if (getOPs().getOperatingMode() < OperatingMode::SYNCING)
2093  {
2094  reason = "Not synchronized with network";
2095  return false;
2096  }
2097 
2098  if (!getLedgerMaster().isCaughtUp(reason))
2099  return false;
2100 
2101  if (getFeeTrack().isLoadedLocal())
2102  {
2103  reason = "Too much load";
2104  return false;
2105  }
2106 
2107  return true;
2108 }
2109 
2112 {
2113  return logs_->journal(name);
2114 }
2115 
2116 bool
2118 {
2119  assert(overlay_);
2120  assert(!config_->standalone());
2121 
2122  if (config_->section(ConfigSection::shardDatabase()).empty())
2123  {
2124  JLOG(m_journal.fatal())
2125  << "The [shard_db] configuration setting must be set";
2126  return false;
2127  }
2128  if (!shardStore_)
2129  {
2130  JLOG(m_journal.fatal()) << "Invalid [shard_db] configuration";
2131  return false;
2132  }
2133  shardStore_->importDatabase(getNodeStore());
2134  return true;
2135 }
2136 
2137 void
2139 {
2141  if (seq)
2142  maxDisallowedLedger_ = *seq;
2143 
2144  JLOG(m_journal.trace())
2145  << "Max persisted ledger is " << maxDisallowedLedger_;
2146 }
2147 
2148 //------------------------------------------------------------------------------
2149 
2150 Application::Application() : beast::PropertyStream::Source("app")
2151 {
2152 }
2153 
2154 //------------------------------------------------------------------------------
2155 
2158  std::unique_ptr<Config> config,
2159  std::unique_ptr<Logs> logs,
2160  std::unique_ptr<TimeKeeper> timeKeeper)
2161 {
2162  return std::make_unique<ApplicationImp>(
2163  std::move(config), std::move(logs), std::move(timeKeeper));
2164 }
2165 
2166 } // namespace ripple
ripple::NodeStoreScheduler
A NodeStore::Scheduler which uses the JobQueue.
Definition: NodeStoreScheduler.h:30
beast::PropertyStream::Source::name
std::string const & name() const
Returns the name of this source.
Definition: beast_PropertyStream.cpp:190
ripple::ApplicationImp::m_resourceManager
std::unique_ptr< Resource::Manager > m_resourceManager
Definition: Application.cpp:188
ripple::ValidatorKeys::publicKey
PublicKey publicKey
Definition: ValidatorKeys.h:40
beast::Journal::fatal
Stream fatal() const
Definition: Journal.h:339
ripple::setup_TxQ
TxQ::Setup setup_TxQ(Config const &config)
Build a TxQ::Setup object from application configuration.
Definition: TxQ.cpp:1855
ripple::ApplicationImp::getReportingETL
ReportingETL & getReportingETL() override
Definition: Application.cpp:895
ripple::NodeStore::DummyScheduler
Simple NodeStore Scheduler that just peforms the tasks synchronously.
Definition: DummyScheduler.h:29
ripple::ApplicationImp::getValidationPublicKey
PublicKey const & getValidationPublicKey() const override
Definition: Application.cpp:580
ripple::ApplicationImp::m_tempNodeCache
NodeCache m_tempNodeCache
Definition: Application.cpp:183
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:42
ripple::NetworkOPs
Provides server functionality for clients.
Definition: NetworkOPs.h:86
ripple::ApplicationImp::openLedger_
std::optional< OpenLedger > openLedger_
Definition: Application.cpp:181
ripple::getNodeIdentity
std::pair< PublicKey, SecretKey > getNodeIdentity(Application &app)
The cryptographic credentials identifying this server instance.
Definition: NodeIdentity.cpp:32
ripple::ApplicationImp::m_ledgerReplayer
std::unique_ptr< LedgerReplayer > m_ledgerReplayer
Definition: Application.cpp:202
ripple::ApplicationImp::shardStore_
std::unique_ptr< NodeStore::DatabaseShard > shardStore_
Definition: Application.cpp:192
ripple::make_DummyPeerSet
std::unique_ptr< PeerSet > make_DummyPeerSet(Application &app)
Make a dummy PeerSet that does not do anything.
Definition: PeerSet.cpp:187
ripple::Application
Definition: Application.h:115
sstream
ripple::RPC::JsonContext
Definition: Context.h:53
ripple::ApplicationImp::ledgerCleaner_
std::unique_ptr< LedgerCleaner > ledgerCleaner_
Definition: Application.cpp:199
ripple::LoadManager::activateDeadlockDetector
void activateDeadlockDetector()
Turn on deadlock detection.
Definition: LoadManager.cpp:55
ripple::ApplicationImp::m_inboundTransactions
std::unique_ptr< InboundTransactions > m_inboundTransactions
Definition: Application.cpp:201
ripple::NodeStore::make_ShardStore
std::unique_ptr< DatabaseShard > make_ShardStore(Application &app, Scheduler &scheduler, int readThreads, beast::Journal j)
Definition: DatabaseShardImp.cpp:2231
ripple::NodeFamily::sweep
void sweep() override
Definition: NodeFamily.cpp:49
ripple::ApplicationImp::getShardFamily
Family * getShardFamily() override
Definition: Application.cpp:556
ripple::LoadManager
Manages load sources.
Definition: LoadManager.h:45
ripple::ApplicationImp::validators
ValidatorList & validators() override
Definition: Application.cpp:797
ripple::TaggedCache::sweep
void sweep()
Definition: TaggedCache.h:200
std::strlen
T strlen(T... args)
ripple::STLedgerEntry
Definition: STLedgerEntry.h:30
ripple::NodeStore::Database
Persistency layer for NodeObject.
Definition: Database.h:51
ripple::RPC::ShardArchiveHandler::makeShardArchiveHandler
static std::unique_ptr< ShardArchiveHandler > makeShardArchiveHandler(Application &app)
Definition: ShardArchiveHandler.cpp:49
std::string
STL class.
ripple::ApplicationImp::cachedSLEs
CachedSLEs & cachedSLEs() override
Definition: Application.cpp:767
std::shared_ptr
STL class.
ripple::ApplicationImp::getNodeStore
NodeStore::Database & getNodeStore() override
Definition: Application.cpp:665
ripple::RPC::ShardArchiveHandler::start
bool start()
Starts downloading and importing archives.
Definition: ShardArchiveHandler.cpp:235
ripple::TaggedCache< SHAMapHash, Blob >
ripple::ApplicationImp::serverOkay
bool serverOkay(std::string &reason) override
Definition: Application.cpp:2063
ripple::loadByIndex
std::shared_ptr< Ledger > loadByIndex(std::uint32_t ledgerIndex, Application &app, bool acquire)
Definition: Ledger.cpp:1063
utility
ripple::LedgerMaster::sweep
void sweep()
Definition: LedgerMaster.cpp:1873
ripple::ApplicationImp::mValidations
RCLValidations mValidations
Definition: Application.cpp:215
ripple::TransactionMaster::sweep
void sweep(void)
Definition: TransactionMaster.cpp:156
std::exception
STL class.
ripple::ApplicationImp::getAcceptedLedgerCache
TaggedCache< uint256, AcceptedLedger > & getAcceptedLedgerCache() override
Definition: Application.cpp:634
ripple::make_Overlay
std::unique_ptr< Overlay > make_Overlay(Application &app, Overlay::Setup const &setup, ServerHandler &serverHandler, Resource::Manager &resourceManager, Resolver &resolver, boost::asio::io_service &io_service, BasicConfig const &config, beast::insight::Collector::ptr const &collector)
Creates the implementation of Overlay.
Definition: OverlayImpl.cpp:1642
cstring
ripple::ApplicationImp::getHashRouter
HashRouter & getHashRouter() override
Definition: Application.cpp:785
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
beast::PropertyStream::Map
Definition: PropertyStream.h:236
ripple::ApplicationImp::validatorSites_
std::unique_ptr< ValidatorSite > validatorSites_
Definition: Application.cpp:210
ripple::ApplicationImp::mWalletDB
std::unique_ptr< DatabaseCon > mWalletDB
Definition: Application.cpp:223
ripple::ApplicationImp::getPathRequests
PathRequests & getPathRequests() override
Definition: Application.cpp:761
ripple::ApplicationImp::m_orderBookDB
OrderBookDB m_orderBookDB
Definition: Application.cpp:196
ripple::make_LoadManager
std::unique_ptr< LoadManager > make_LoadManager(Application &app, beast::Journal journal)
Definition: LoadManager.cpp:197
ripple::TransactionMaster
Definition: TransactionMaster.h:36
ripple::ValidatorSite
Definition: ValidatorSite.h:69
std::pair
ripple::ApplicationImp::onWrite
void onWrite(beast::PropertyStream::Map &stream) override
Subclass override.
Definition: Application.cpp:974
ripple::LedgerMaster
Definition: LedgerMaster.h:70
ripple::ApplicationImp::mRelationalDBInterface
std::unique_ptr< RelationalDBInterface > mRelationalDBInterface
Definition: Application.cpp:222
ripple::ApplicationImp::getInboundLedgers
InboundLedgers & getInboundLedgers() override
Definition: Application.cpp:622
ripple::ApplicationImp::accountIDCache
AccountIDCache const & accountIDCache() const override
Definition: Application.cpp:845
ripple::OpenView
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:55
ripple::ApplicationImp::io_latency_sampler::cancel_async
void cancel_async()
Definition: Application.cpp:157
Json::UInt
unsigned int UInt
Definition: json_forwards.h:27
ripple::hotACCOUNT_NODE
@ hotACCOUNT_NODE
Definition: NodeObject.h:35
ripple::setup_DatabaseCon
DatabaseCon::Setup setup_DatabaseCon(Config const &c, std::optional< beast::Journal > j=std::nullopt)
Definition: DatabaseCon.cpp:106
ripple::ApplicationImp::getLedgerReplayer
LedgerReplayer & getLedgerReplayer() override
Definition: Application.cpp:616
ripple::InboundLedger::Reason::GENERIC
@ GENERIC
std::vector
STL class.
ripple::ConfigSection::shardDatabase
static std::string shardDatabase()
Definition: ConfigSections.h:38
std::string::length
T length(T... args)
ripple::ValidatorList::trustedPublisher
bool trustedPublisher(PublicKey const &identity) const
Returns true if public key is a trusted publisher.
Definition: ValidatorList.cpp:1404
ripple::ApplicationImp::waitHandlerCounter_
ClosureCounter< void, boost::system::error_code const & > waitHandlerCounter_
Definition: Application.cpp:218
ripple::ApplicationImp::getOPs
NetworkOPs & getOPs() override
Definition: Application.cpp:586
ripple::ApplicationImp::run
void run() override
Definition: Application.cpp:1528
ripple::make_InboundLedgers
std::unique_ptr< InboundLedgers > make_InboundLedgers(Application &app, InboundLedgers::clock_type &clock, beast::insight::Collector::ptr const &collector)
Definition: InboundLedgers.cpp:434
ripple::CollectorManager
Provides the beast::insight::Collector service.
Definition: CollectorManager.h:29
ripple::ConfigSection::importNodeDatabase
static std::string importNodeDatabase()
Definition: ConfigSections.h:43
std::chrono::milliseconds
ripple::Config::NODE_SIZE
std::size_t NODE_SIZE
Definition: Config.h:197
ripple::ApplicationImp::isTimeToStop
std::atomic< bool > isTimeToStop
Definition: Application.cpp:232
ripple::ApplicationImp::m_acceptedLedgerCache
TaggedCache< uint256, AcceptedLedger > m_acceptedLedgerCache
Definition: Application.cpp:203
ripple::ApplicationImp::setup
bool setup() override
Definition: Application.cpp:1112
ripple::SHAMapStore
class to create database, launch online delete thread, and related SQLite database
Definition: SHAMapStore.h:36
ripple::ApplicationImp::validatorManifests
ManifestCache & validatorManifests() override
Definition: Application.cpp:809
ripple::ApplicationImp::getWalletDB
DatabaseCon & getWalletDB() override
Retrieve the "wallet database".
Definition: Application.cpp:888
ripple::getLatestLedger
std::tuple< std::shared_ptr< Ledger >, std::uint32_t, uint256 > getLatestLedger(Application &app)
Definition: Ledger.cpp:1053
ripple::ApplicationImp::getCollectorManager
CollectorManager & getCollectorManager() override
Definition: Application.cpp:542
ripple::ApplicationImp::sweepTimer_
boost::asio::steady_timer sweepTimer_
Definition: Application.cpp:219
ripple::ApplicationImp::cluster_
std::unique_ptr< Cluster > cluster_
Definition: Application.cpp:205
ripple::ApplicationImp::getShardStore
NodeStore::DatabaseShard * getShardStore() override
Definition: Application.cpp:673
ripple::ApplicationImp::openLedger
OpenLedger const & openLedger() const override
Definition: Application.cpp:859
ripple::ApplicationImp::getIOLatency
std::chrono::milliseconds getIOLatency() override
Definition: Application.cpp:598
ripple::ApplicationImp::m_shaMapStore
std::unique_ptr< SHAMapStore > m_shaMapStore
Definition: Application.cpp:178
ripple::make_CollectorManager
std::unique_ptr< CollectorManager > make_CollectorManager(Section const &params, beast::Journal journal)
Definition: CollectorManager.cpp:72
ripple::Config::LOAD
@ LOAD
Definition: Config.h:132
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
std::recursive_mutex
STL class.
std::reference_wrapper::get
T get(T... args)
ripple::ApplicationImp::getIOService
boost::asio::io_service & getIOService() override
Definition: Application.cpp:592
ripple::ApplicationImp::shardArchiveHandler_
std::unique_ptr< RPC::ShardArchiveHandler > shardArchiveHandler_
Definition: Application.cpp:194
std::lock_guard
STL class.
beast::severities
A namespace for easy access to logging severity values.
Definition: Journal.h:29
ripple::perf::PerfLog
Singleton class that maintains performance counters and optionally writes Json-formatted data to a di...
Definition: PerfLog.h:48
ripple::STParsedJSONObject
Holds the serialized result of parsing an input JSON object.
Definition: STParsedJSON.h:31
ripple::PendingSaves
Keeps track of which ledgers haven't been fully saved.
Definition: PendingSaves.h:36
ripple::Resource::feeReferenceRPC
const Charge feeReferenceRPC
ripple::make_LedgerCleaner
std::unique_ptr< LedgerCleaner > make_LedgerCleaner(Application &app, beast::Journal journal)
Definition: LedgerCleaner.cpp:455
ripple::Pathfinder::initPathTable
static void initPathTable()
Definition: Pathfinder.cpp:1284
std::cerr
ripple::ApplicationImp::ApplicationImp
ApplicationImp(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
Definition: Application.cpp:269
ripple::ApplicationImp::signalStop
void signalStop() override
Definition: Application.cpp:1632
ripple::ApplicationImp::cluster
Cluster & cluster() override
Definition: Application.cpp:821
ripple::stopwatch
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition: chrono.h:88
ripple::RelationalDBInterface
Definition: RelationalDBInterface.h:48
ripple::make_NetworkOPs
std::unique_ptr< NetworkOPs > make_NetworkOPs(Application &app, NetworkOPs::clock_type &clock, bool standalone, std::size_t minPeerCount, bool startvalid, JobQueue &job_queue, LedgerMaster &ledgerMaster, ValidatorKeys const &validatorKeys, boost::asio::io_service &io_svc, beast::Journal journal, beast::insight::Collector::ptr const &collector)
Definition: NetworkOPs.cpp:4511
ripple::make_InboundTransactions
std::unique_ptr< InboundTransactions > make_InboundTransactions(Application &app, beast::insight::Collector::ptr const &collector, std::function< void(std::shared_ptr< SHAMap > const &, bool)> gotSet)
Definition: InboundTransactions.cpp:269
ripple::RelationalDBInterface::init
static std::unique_ptr< RelationalDBInterface > init(Application &app, Config const &config, JobQueue &jobQueue)
init Creates and returns appropriate interface based on config.
Definition: RelationalDBInterface.cpp:40
ripple::ApplicationImp::getLedgerMaster
LedgerMaster & getLedgerMaster() override
Definition: Application.cpp:604
Json::Reader
Unserialize a JSON document into a Value.
Definition: json_reader.h:36
ripple::NodeFamily
Definition: NodeFamily.h:30
ripple::STParsedJSONObject::object
std::optional< STObject > object
The STObject if the parse was successful.
Definition: STParsedJSON.h:50
ripple::ResolverAsio::New
static std::unique_ptr< ResolverAsio > New(boost::asio::io_service &, beast::Journal)
Definition: ResolverAsio.cpp:406
iostream
ripple::ApplicationImp::m_nodeStore
std::unique_ptr< NodeStore::Database > m_nodeStore
Definition: Application.cpp:190
ripple::RelationalDBInterfacePostgres
Definition: RelationalDBInterfacePostgres.h:27
ripple::ApplicationImp::perfLog_
std::unique_ptr< perf::PerfLog > perfLog_
Definition: Application.cpp:169
ripple::AccountIDCache
Caches the base58 representations of AccountIDs.
Definition: AccountID.h:118
ripple::ApplicationImp::nodeIdentity_
std::pair< PublicKey, SecretKey > nodeIdentity_
Definition: Application.cpp:185
ripple::InboundLedgers::sweep
virtual void sweep()=0
ripple::ValidatorKeys
Validator keys and manifest as set in configuration file.
Definition: ValidatorKeys.h:36
ripple::HashRouter
Routing table for objects identified by hash.
Definition: HashRouter.h:53
ripple::forceValidity
void forceValidity(HashRouter &router, uint256 const &txid, Validity validity)
Sets the validity of a given transaction in the cache.
Definition: apply.cpp:89
ripple::ApplicationImp::validatorKeys_
const ValidatorKeys validatorKeys_
Definition: Application.cpp:186
ripple::ApplicationImp::timeKeeper_
std::unique_ptr< TimeKeeper > timeKeeper_
Definition: Application.cpp:166
ripple::OperatingMode::SYNCING
@ SYNCING
fallen slightly behind
ripple::Config::IO_WORKERS
int IO_WORKERS
Definition: Config.h:219
ripple::SHAMapMissingNode
Definition: SHAMapMissingNode.h:55
ripple::Validity::SigGoodOnly
@ SigGoodOnly
Signature is good, but local checks fail.
ripple::ApplicationImp::getShardArchiveHandler
RPC::ShardArchiveHandler * getShardArchiveHandler(bool tryRecovery) override
Definition: Application.cpp:679
ripple::ApplicationImp::m_inboundLedgers
std::unique_ptr< InboundLedgers > m_inboundLedgers
Definition: Application.cpp:200
ripple::ApplicationImp::peerReservations_
std::unique_ptr< PeerReservationTable > peerReservations_
Definition: Application.cpp:206
ripple::setup_ServerHandler
ServerHandler::Setup setup_ServerHandler(Config const &config, std::ostream &&log)
Definition: ServerHandlerImp.cpp:1197
ripple::ApplicationImp::loadLedgerFromFile
std::shared_ptr< Ledger > loadLedgerFromFile(std::string const &ledgerID)
Definition: Application.cpp:1745
ripple::ApplicationImp::checkSigs
bool checkSigs() const override
Definition: Application.cpp:1639
ripple::ApplicationImp::journal
beast::Journal journal(std::string const &name) override
Definition: Application.cpp:2111
ripple::base_uint< 256 >
ripple::ApplicationImp::entropyTimer_
boost::asio::steady_timer entropyTimer_
Definition: Application.cpp:220
ripple::ApplicationImp::getMaxDisallowedLedger
LedgerIndex getMaxDisallowedLedger() override
Ensure that a newly-started validator does not sign proposals older than the last ledger it persisted...
Definition: Application.cpp:1079
ripple::ApplicationImp::nodeToShards
bool nodeToShards()
Definition: Application.cpp:2117
ripple::ApplicationImp::hashRouter_
std::unique_ptr< HashRouter > hashRouter_
Definition: Application.cpp:214
ripple::ApplicationImp::getMasterMutex
Application::MutexType & getMasterMutex() override
Definition: Application.cpp:737
ripple::ApplicationImp::m_ledgerMaster
std::unique_ptr< LedgerMaster > m_ledgerMaster
Definition: Application.cpp:198
ripple::RPC::doCommand
Status doCommand(RPC::JsonContext &context, Json::Value &result)
Execute an RPC command and store the results in a Json::Value.
Definition: RPCHandler.cpp:245
ripple::setup_Overlay
Overlay::Setup setup_Overlay(BasicConfig const &config)
Definition: OverlayImpl.cpp:1537
ripple::ApplicationImp::logs
Logs & logs() override
Definition: Application.cpp:530
ripple::Config::reporting
bool reporting() const
Definition: Config.h:316
ripple::ApplicationImp::getPerfLog
perf::PerfLog & getPerfLog() override
Definition: Application.cpp:653
ripple::ApplicationImp::m_jobQueue
std::unique_ptr< JobQueue > m_jobQueue
Definition: Application.cpp:176
ripple::ApplicationImp::checkSigs_
std::atomic< bool > checkSigs_
Definition: Application.cpp:234
std::reference_wrapper
ripple::make_ServerHandler
std::unique_ptr< ServerHandler > make_ServerHandler(Application &app, boost::asio::io_service &io_service, JobQueue &jobQueue, NetworkOPs &networkOPs, Resource::Manager &resourceManager, CollectorManager &cm)
Definition: ServerHandlerImp.cpp:1209
ripple::RelationalDBInterface::getMaxLedgerSeq
virtual std::optional< LedgerIndex > getMaxLedgerSeq()=0
getMaxLedgerSeq Returns maximum ledger sequence in Ledgers table.
ripple::loadByHash
std::shared_ptr< Ledger > loadByHash(uint256 const &ledgerHash, Application &app, bool acquire)
Definition: Ledger.cpp:1076
ripple::TxQ
Transaction Queue.
Definition: TxQ.h:57
ripple::Config::FORCE_MULTI_THREAD
bool FORCE_MULTI_THREAD
Definition: Config.h:223
ripple::ApplicationImp::numberOfThreads
static std::size_t numberOfThreads(Config const &config)
Definition: Application.cpp:246
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:525
ripple::ApplicationImp::getSHAMapStore
SHAMapStore & getSHAMapStore() override
Definition: Application.cpp:833
ripple::Role::ADMIN
@ ADMIN
ripple::detail::supportedAmendments
std::map< std::string, DefaultVote > const & supportedAmendments()
Amendments that this server supports and the default voting behavior.
Definition: Feature.cpp:314
beast::PropertyStream::Source::add
void add(Source &source)
Add a child source.
Definition: beast_PropertyStream.cpp:196
ripple::ApplicationImp::getAmendmentTable
AmendmentTable & getAmendmentTable() override
Definition: Application.cpp:773
ripple::ApplicationImp::loadOldLedger
bool loadOldLedger(std::string const &ledgerID, bool replay, bool isFilename)
Definition: Application.cpp:1880
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
std::atomic::load
T load(T... args)
ripple::Config
Definition: Config.h:68
ripple::ApplicationImp::io_latency_sampler::cancel
void cancel()
Definition: Application.cpp:151
ripple::PublicKey::size
std::size_t size() const noexcept
Definition: PublicKey.h:87
ripple::Cluster
Definition: Cluster.h:38
std::thread::hardware_concurrency
T hardware_concurrency(T... args)
ripple::ValidatorList
Definition: ValidatorList.h:172
chrono
ripple::ApplicationImp::getResourceManager
Resource::Manager & getResourceManager() override
Definition: Application.cpp:749
ripple::ApplicationImp::peerReservations
PeerReservationTable & peerReservations() override
Definition: Application.cpp:827
ripple::ApplicationImp::publisherManifests
ManifestCache & publisherManifests() override
Definition: Application.cpp:815
ripple::ApplicationImp::m_amendmentTable
std::unique_ptr< AmendmentTable > m_amendmentTable
Definition: Application.cpp:212
ripple::Config::NETWORK
@ NETWORK
Definition: Config.h:132
ripple::ApplicationImp::overlay
Overlay & overlay() override
Definition: Application.cpp:867
ripple::megabytes
constexpr auto megabytes(T value) noexcept
Definition: ByteUtilities.h:34
ripple::ApplicationImp::pendingSaves
PendingSaves & pendingSaves() override
Definition: Application.cpp:839
ripple::ApplicationImp::m_collectorManager
std::unique_ptr< CollectorManager > m_collectorManager
Definition: Application.cpp:175
ripple::Config::standalone
bool standalone() const
Definition: Config.h:311
ripple::ApplicationImp::nodeFamily_
NodeFamily nodeFamily_
Definition: Application.cpp:191
ripple::HashRouter::getDefaultHoldTime
static std::chrono::seconds getDefaultHoldTime()
Definition: HashRouter.h:139
ripple::LedgerFill::full
@ full
Definition: LedgerToJson.h:49
std::unique_lock
STL class.
beast::io_latency_probe::sample
void sample(Handler &&handler)
Initiate continuous i/o latency sampling.
Definition: io_latency_probe.h:119
ripple::ApplicationImp::m_txMaster
TransactionMaster m_txMaster
Definition: Application.cpp:173
ripple::NodeStore::DatabaseShard
A collection of historical shards.
Definition: DatabaseShard.h:37
ripple::LoadFeeTrack
Manages the current fee schedule.
Definition: LoadFeeTrack.h:44
ripple::set
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
Definition: BasicConfig.h:313
ripple::ValidatorList::listed
bool listed(PublicKey const &identity) const
Returns true if public key is included on any lists.
Definition: ValidatorList.cpp:1349
ripple::ApplicationImp::validatorSites
ValidatorSite & validatorSites() override
Definition: Application.cpp:803
ripple::ApplicationImp::nodeIdentity
std::pair< PublicKey, SecretKey > const & nodeIdentity() override
Definition: Application.cpp:574
beast::Journal::error
Stream error() const
Definition: Journal.h:333
beast::Journal::info
Stream info() const
Definition: Journal.h:321
ripple::ApplicationImp::io_latency_sampler::m_event
beast::insight::Event m_event
Definition: Application.cpp:102
std::chrono::time_point
beast::insight::Event
A metric for reporting event timing.
Definition: Event.h:40
ripple::ApplicationImp::config_
std::unique_ptr< Config > config_
Definition: Application.cpp:164
ripple::BuildInfo::getVersionString
std::string const & getVersionString()
Server version.
Definition: BuildInfo.cpp:65
ripple::OrderBookDB::setup
void setup(std::shared_ptr< ReadView const > const &ledger)
Definition: OrderBookDB.cpp:37
beast::basic_logstream
Definition: Journal.h:428
ripple::ReportingETL
This class is responsible for continuously extracting data from a p2p node, and writing that data to ...
Definition: ReportingETL.h:70
ripple::ApplicationImp::getLastFullLedger
std::shared_ptr< Ledger > getLastFullLedger()
Definition: Application.cpp:1705
ripple::TimeKeeper::closeTime
virtual time_point closeTime() const =0
Returns the close time, in network time.
ripple::Family
Definition: Family.h:32
ripple::ValidatorKeys::configInvalid
bool configInvalid() const
Definition: ValidatorKeys.h:49
ripple::ClosureCounter
The role of a ClosureCounter is to assist in shutdown by letting callers wait for the completion of c...
Definition: ClosureCounter.h:54
ripple::ApplicationImp::m_io_latency_sampler
io_latency_sampler m_io_latency_sampler
Definition: Application.cpp:238
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::SizedItem::burstSize
@ burstSize
std::uint32_t
ripple::Config::WORKERS
int WORKERS
Definition: Config.h:218
std::condition_variable::wait
T wait(T... args)
ripple::ApplicationImp::gotTXSet
void gotTXSet(std::shared_ptr< SHAMap > const &set, bool fromAcquire)
Definition: Application.cpp:640
std::atomic< std::chrono::milliseconds >
ripple::ApplicationImp::startGenesisLedger
void startGenesisLedger()
Definition: Application.cpp:1685
ripple::ApplicationImp::m_signals
boost::asio::signal_set m_signals
Definition: Application.cpp:226
ripple::TimeKeeper
Manages various times used by the server.
Definition: TimeKeeper.h:32
ripple::ApplicationImp::timeKeeper
TimeKeeper & timeKeeper() override
Definition: Application.cpp:562
beast::io_latency_probe< std::chrono::steady_clock >
ripple::OrderBookDB
Definition: OrderBookDB.h:30
ripple::ApplicationImp::io_latency_sampler::operator()
void operator()(Duration const &elapsed)
Definition: Application.cpp:128
ripple::NodeStore::Database::sweep
virtual void sweep()=0
Remove expired entries from the positive and negative caches.
ripple::ApplicationImp::getRelationalDBInterface
RelationalDBInterface & getRelationalDBInterface() override
Definition: Application.cpp:881
ripple::InboundLedgers
Manages the lifetime of inbound ledgers.
Definition: InboundLedgers.h:33
ripple::OpenLedger
Represents the open ledger.
Definition: OpenLedger.h:49
ripple::Validations::flush
void flush()
Flush all current validations.
Definition: Validations.h:1100
ripple::JobQueue
A pool of threads to perform work.
Definition: JobQueue.h:55
ripple::Application::Application
Application()
Definition: Application.cpp:2150
std::min
T min(T... args)
ripple::ApplicationImp::setMaxDisallowedLedger
void setMaxDisallowedLedger()
Definition: Application.cpp:2138
ripple::Resource::Manager
Tracks load and resource consumption.
Definition: ResourceManager.h:36
ripple::ApplicationImp::shardFamily_
std::unique_ptr< ShardFamily > shardFamily_
Definition: Application.cpp:193
ripple::ApplicationImp::io_latency_sampler::lastSample_
std::atomic< std::chrono::milliseconds > lastSample_
Definition: Application.cpp:105
ripple::ApplicationImp::setSweepTimer
void setSweepTimer()
Definition: Application.cpp:981
ripple::ApplicationImp::overlay_
std::unique_ptr< Overlay > overlay_
Definition: Application.cpp:224
ripple::BuildInfo::getFullVersionString
std::string const & getFullVersionString()
Full server version string.
Definition: BuildInfo.cpp:78
ripple::ApplicationImp::openLedger
OpenLedger & openLedger() override
Definition: Application.cpp:851
ripple::ApplicationImp::pendingSaves_
PendingSaves pendingSaves_
Definition: Application.cpp:179
ripple::ApplicationImp::m_resolver
std::unique_ptr< ResolverAsio > m_resolver
Definition: Application.cpp:236
ripple::ApplicationImp::getTxQ
TxQ & getTxQ() override
Definition: Application.cpp:874
ripple::PeerReservationTable
Definition: PeerReservationTable.h:79
ripple::ManifestCache
Remembers manifests with the highest sequence number.
Definition: Manifest.h:225
ripple::LedgerReplayer::sweep
void sweep()
Remove completed tasks.
Definition: LedgerReplayer.cpp:219
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Config::FRESH
@ FRESH
Definition: Config.h:132
ripple::Resource::make_Manager
std::unique_ptr< Manager > make_Manager(beast::insight::Collector::ptr const &collector, beast::Journal journal)
Definition: ResourceManager.cpp:175
std::atomic::exchange
T exchange(T... args)
ripple::ApplicationImp::getTempNodeCache
NodeCache & getTempNodeCache() override
Definition: Application.cpp:659
ripple::ApplicationImp::io_latency_sampler::get
std::chrono::milliseconds get() const
Definition: Application.cpp:145
beast::io_latency_probe::cancel
void cancel()
Cancel all pending i/o.
Definition: io_latency_probe.h:84
Json::Value::removeMember
Value removeMember(const char *key)
Remove and return the named member.
Definition: json_value.cpp:907
ripple::ApplicationImp::grpcServer_
std::unique_ptr< GRPCServer > grpcServer_
Definition: Application.cpp:240
std::endl
T endl(T... args)
ripple::ApplicationImp::stoppingCondition_
std::condition_variable stoppingCondition_
Definition: Application.cpp:230
ripple::OpenView::rawTxInsert
void rawTxInsert(key_type const &key, std::shared_ptr< Serializer const > const &txn, std::shared_ptr< Serializer const > const &metaData) override
Add a transaction to the tx map.
Definition: OpenView.cpp:261
ripple::RPC::ShardArchiveHandler::tryMakeRecoveryHandler
static std::unique_ptr< ShardArchiveHandler > tryMakeRecoveryHandler(Application &app)
Definition: ShardArchiveHandler.cpp:55
ripple::ApplicationImp::getJobQueue
JobQueue & getJobQueue() override
Definition: Application.cpp:568
ripple::ApplicationImp::fdRequired
int fdRequired() const override
Definition: Application.cpp:1657
ripple::ApplicationImp::doSweep
void doSweep()
Definition: Application.cpp:1041
beast::PropertyStream::Source::Source
Source(std::string const &name)
Definition: beast_PropertyStream.cpp:176
ripple::Overlay
Manages the set of connected peers.
Definition: Overlay.h:51
ripple::ApplicationImp::io_latency_sampler
Definition: Application.cpp:99
limits
ripple::ApplicationImp::getOrderBookDB
OrderBookDB & getOrderBookDB() override
Definition: Application.cpp:755
ripple::ApplicationImp
Definition: Application.cpp:96
ripple::ApplicationImp::initRDBMS
bool initRDBMS()
Definition: Application.cpp:910
ripple::ApplicationImp::getLoadManager
LoadManager & getLoadManager() override
Definition: Application.cpp:743
beast::lexicalCastChecked
bool lexicalCastChecked(Out &out, In in)
Intelligently convert from one type to another.
Definition: LexicalCast.h:266
ripple::make_PeerSetBuilder
std::unique_ptr< PeerSetBuilder > make_PeerSetBuilder(Application &app)
Definition: PeerSet.cpp:144
ripple::ApplicationImp::io_latency_sampler::m_probe
beast::io_latency_probe< std::chrono::steady_clock > m_probe
Definition: Application.cpp:104
ripple::ApplicationImp::isStopping
bool isStopping() const override
Definition: Application.cpp:1651
ripple::ApplicationImp::accountIDCache_
AccountIDCache accountIDCache_
Definition: Application.cpp:180
std
STL namespace.
ripple::ApplicationImp::m_nodeStoreScheduler
NodeStoreScheduler m_nodeStoreScheduler
Definition: Application.cpp:177
ripple::ApplicationImp::m_loadManager
std::unique_ptr< LoadManager > m_loadManager
Definition: Application.cpp:216
ripple::create_genesis
const create_genesis_t create_genesis
Definition: Ledger.cpp:62
ripple::Config::REPLAY
@ REPLAY
Definition: Config.h:132
ripple::ApplicationImp::getInboundTransactions
InboundTransactions & getInboundTransactions() override
Definition: Application.cpp:628
ripple::makeWalletDB
std::unique_ptr< DatabaseCon > makeWalletDB(DatabaseCon::Setup const &setup)
makeWalletDB Opens wallet DB and returns it.
Definition: RelationalDBInterface_global.cpp:40
Json::Reader::parse
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
Definition: json_reader.cpp:74
condition_variable
ripple::Resource::Consumer
An endpoint that consumes resources.
Definition: Consumer.h:34
ripple::Resource::Charge
A consumption charge.
Definition: Charge.h:30
ripple::SizedItem::sweepInterval
@ sweepInterval
ripple::DatabaseCon
Definition: DatabaseCon.h:81
ripple::RPC::apiMaximumSupportedVersion
constexpr unsigned int apiMaximumSupportedVersion
Definition: RPCHelpers.h:243
ripple::ApplicationImp::mFeeTrack
std::unique_ptr< LoadFeeTrack > mFeeTrack
Definition: Application.cpp:213
ripple::ApplicationImp::getFeeTrack
LoadFeeTrack & getFeeTrack() override
Definition: Application.cpp:779
ripple::addJson
void addJson(Json::Value &json, LedgerFill const &fill)
Given a Ledger and options, fill a Json::Object or Json::Value with a description of the ledger.
Definition: LedgerToJson.cpp:281
ripple::RPC::ShardArchiveHandler
Handles the download and import of one or more shard archives.
Definition: ShardArchiveHandler.h:42
ripple::LedgerReplayer
Manages the lifetime of ledger replay tasks.
Definition: LedgerReplayer.h:72
beast::severities::kDebug
@ kDebug
Definition: Journal.h:35
ripple::ApplicationImp::io_latency_sampler::m_journal
beast::Journal m_journal
Definition: Application.cpp:103
ripple::ApplicationImp::config
Config & config() override
Definition: Application.cpp:536
ripple::ApplicationImp::validators_
std::unique_ptr< ValidatorList > validators_
Definition: Application.cpp:209
std::string::empty
T empty(T... args)
ripple::ApplicationImp::getLedgerCleaner
LedgerCleaner & getLedgerCleaner() override
Definition: Application.cpp:610
ripple::ApplicationImp::m_journal
beast::Journal m_journal
Definition: Application.cpp:168
ripple::Validations< RCLValidationsAdaptor >
ripple::ClosureCounter::join
void join(char const *name, std::chrono::milliseconds wait, beast::Journal j)
Returns once all counted in-flight closures are destroyed.
Definition: ClosureCounter.h:166
optional
beast::io_latency_probe::cancel_async
void cancel_async()
Definition: io_latency_probe.h:91
mutex
ripple::ApplicationImp::stoppingMutex_
std::mutex stoppingMutex_
Definition: Application.cpp:231
ripple::ApplicationImp::io_latency_sampler::io_latency_sampler
io_latency_sampler(beast::insight::Event ev, beast::Journal journal, std::chrono::milliseconds interval, boost::asio::io_service &ios)
Definition: Application.cpp:108
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::ApplicationImp::serverHandler_
std::unique_ptr< ServerHandler > serverHandler_
Definition: Application.cpp:211
std::size_t
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::make_AmendmentTable
std::unique_ptr< AmendmentTable > make_AmendmentTable(Application &app, std::chrono::seconds majorityTime, std::vector< AmendmentTable::FeatureInfo > const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
Definition: AmendmentTable.cpp:789
ripple::ApplicationImp::validatorManifests_
std::unique_ptr< ManifestCache > validatorManifests_
Definition: Application.cpp:207
BasicApp
Definition: BasicApp.h:29
ripple::ApplicationImp::m_pathRequests
std::unique_ptr< PathRequests > m_pathRequests
Definition: Application.cpp:197
ripple::ApplicationImp::m_networkOPs
std::unique_ptr< NetworkOPs > m_networkOPs
Definition: Application.cpp:204
ripple::ApplicationImp::getNodeFamily
Family & getNodeFamily() override
Definition: Application.cpp:548
ripple::PathRequests
Definition: PathRequests.h:33
ripple::ApplicationImp::txQ_
std::unique_ptr< TxQ > txQ_
Definition: Application.cpp:217
ripple::ApplicationImp::cachedSLEs_
CachedSLEs cachedSLEs_
Definition: Application.cpp:184
std::max
T max(T... args)
ripple::base_uint::parseHex
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition: base_uint.h:489
ripple::Validations::expire
void expire(beast::Journal &j)
Expire old validation sets.
Definition: Validations.h:725
ripple::NodeStore::Manager::instance
static Manager & instance()
Returns the instance of the manager singleton.
Definition: ManagerImp.cpp:120
ripple::ApplicationImp::m_masterMutex
Application::MutexType m_masterMutex
Definition: Application.cpp:170
ripple::NodeStore::Manager::make_Database
virtual std::unique_ptr< Database > make_Database(std::size_t burstSize, Scheduler &scheduler, int readThreads, Section const &backendParameters, beast::Journal journal)=0
Construct a NodeStore database.
ripple::getRegisteredFeature
std::optional< uint256 > getRegisteredFeature(std::string const &name)
Definition: Feature.cpp:336
ripple::LedgerCleaner
Check the ledger/transaction databases to make sure they have continuity.
Definition: LedgerCleaner.h:32
BasicApp::get_io_service
boost::asio::io_service & get_io_service()
Definition: BasicApp.h:41
ripple::ApplicationImp::initNodeStore
bool initNodeStore()
Definition: Application.cpp:936
ripple::ApplicationImp::maxDisallowedLedger_
std::atomic< LedgerIndex > maxDisallowedLedger_
Definition: Application.cpp:1087
ripple::make_SHAMapStore
std::unique_ptr< SHAMapStore > make_SHAMapStore(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
Definition: SHAMapStoreImp.cpp:766
ripple::ApplicationImp::publisherManifests_
std::unique_ptr< ManifestCache > publisherManifests_
Definition: Application.cpp:208
ripple::AmendmentTable
The amendment table stores the list of enabled and potential amendments.
Definition: AmendmentTable.h:37
ripple::ApplicationImp::getMasterTransaction
TransactionMaster & getMasterTransaction() override
Definition: Application.cpp:647
std::unique_ptr
STL class.
ripple::NetClock::time_point
std::chrono::time_point< NetClock > time_point
Definition: chrono.h:56
ripple::Config::LOAD_FILE
@ LOAD_FILE
Definition: Config.h:132
ripple::ApplicationImp::io_latency_sampler::start
void start()
Definition: Application.cpp:121
std::condition_variable::notify_all
T notify_all(T... args)
ripple::ApplicationImp::reportingETL_
std::unique_ptr< ReportingETL > reportingETL_
Definition: Application.cpp:241
Json::Value::isObjectOrNull
bool isObjectOrNull() const
Definition: json_value.cpp:1033
ripple::ApplicationImp::getValidations
RCLValidations & getValidations() override
Definition: Application.cpp:791
ripple::ApplicationImp::setEntropyTimer
void setEntropyTimer()
Definition: Application.cpp:1012
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:2157
ripple::ValidatorKeys::manifest
std::string manifest
Definition: ValidatorKeys.h:43
std::ref
T ref(T... args)
std::exception::what
T what(T... args)
ripple::ApplicationImp::start
void start(bool withTimers) override
Definition: Application.cpp:1505
Json::Value
Represents a JSON value.
Definition: json_value.h:145
beast::insight::Event::notify
void notify(std::chrono::duration< Rep, Period > const &value) const
Push an event notification.
Definition: Event.h:64
ripple::ApplicationImp::logs_
std::unique_ptr< Logs > logs_
Definition: Application.cpp:165
ripple::InboundTransactions
Manages the acquisition and lifetime of transaction sets.
Definition: InboundTransactions.h:35
variant
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469
ripple::ClosureCounter::wrap
std::optional< Substitute< Closure > > wrap(Closure &&closure)
Wrap the passed closure with a reference counter.
Definition: ClosureCounter.h:192
std::ifstream
STL class.
beast
Definition: base_uint.h:671
std::chrono