rippled
NetworkOPs.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/RCLConsensus.h>
21 #include <ripple/app/consensus/RCLValidations.h>
22 #include <ripple/app/ledger/AcceptedLedger.h>
23 #include <ripple/app/ledger/InboundLedgers.h>
24 #include <ripple/app/ledger/LedgerMaster.h>
25 #include <ripple/app/ledger/LedgerToJson.h>
26 #include <ripple/app/ledger/LocalTxs.h>
27 #include <ripple/app/ledger/OpenLedger.h>
28 #include <ripple/app/ledger/OrderBookDB.h>
29 #include <ripple/app/ledger/TransactionMaster.h>
30 #include <ripple/app/main/LoadManager.h>
31 #include <ripple/app/misc/AmendmentTable.h>
32 #include <ripple/app/misc/HashRouter.h>
33 #include <ripple/app/misc/LoadFeeTrack.h>
34 #include <ripple/app/misc/NetworkOPs.h>
35 #include <ripple/app/misc/Transaction.h>
36 #include <ripple/app/misc/TxQ.h>
37 #include <ripple/app/misc/ValidatorKeys.h>
38 #include <ripple/app/misc/ValidatorList.h>
39 #include <ripple/app/misc/impl/AccountTxPaging.h>
40 #include <ripple/app/rdb/backend/PostgresDatabase.h>
41 #include <ripple/app/rdb/backend/SQLiteDatabase.h>
42 #include <ripple/app/reporting/ReportingETL.h>
43 #include <ripple/app/tx/apply.h>
44 #include <ripple/basics/PerfLog.h>
45 #include <ripple/basics/UptimeClock.h>
46 #include <ripple/basics/mulDiv.h>
47 #include <ripple/basics/safe_cast.h>
48 #include <ripple/beast/rfc2616.h>
49 #include <ripple/beast/utility/rngfill.h>
50 #include <ripple/consensus/Consensus.h>
51 #include <ripple/consensus/ConsensusParms.h>
52 #include <ripple/crypto/RFC1751.h>
53 #include <ripple/crypto/csprng.h>
54 #include <ripple/json/to_string.h>
55 #include <ripple/net/RPCErr.h>
56 #include <ripple/nodestore/DatabaseShard.h>
57 #include <ripple/overlay/Cluster.h>
58 #include <ripple/overlay/Overlay.h>
59 #include <ripple/overlay/predicates.h>
60 #include <ripple/protocol/BuildInfo.h>
61 #include <ripple/protocol/Feature.h>
62 #include <ripple/protocol/STParsedJSON.h>
63 #include <ripple/resource/Fees.h>
64 #include <ripple/resource/ResourceManager.h>
65 #include <ripple/rpc/BookChanges.h>
66 #include <ripple/rpc/DeliveredAmount.h>
67 #include <ripple/rpc/impl/RPCHelpers.h>
68 #include <boost/asio/ip/host_name.hpp>
69 #include <boost/asio/steady_timer.hpp>
70 
71 #include <mutex>
72 #include <string>
73 #include <tuple>
74 #include <unordered_map>
75 #include <utility>
76 
77 namespace ripple {
78 
79 class NetworkOPsImp final : public NetworkOPs
80 {
86  {
87  public:
89  bool const admin;
90  bool const local;
92  bool applied = false;
94 
97  bool a,
98  bool l,
99  FailHard f)
100  : transaction(t), admin(a), local(l), failType(f)
101  {
102  assert(local || failType == FailHard::no);
103  }
104  };
105 
109  enum class DispatchState : unsigned char {
110  none,
111  scheduled,
112  running,
113  };
114 
116 
132  {
133  struct Counters
134  {
135  explicit Counters() = default;
136 
139  };
140 
144  std::chrono::steady_clock::time_point start_ =
146  std::chrono::steady_clock::time_point const processStart_ = start_;
149 
150  public:
151  explicit StateAccounting()
152  {
154  .transitions = 1;
155  }
156 
163  void
164  mode(OperatingMode om);
165 
171  void
172  json(Json::Value& obj) const;
173 
174  struct CounterData
175  {
176  decltype(counters_) counters;
177  decltype(mode_) mode;
178  decltype(start_) start;
180  };
181 
184  {
185  std::lock_guard lock(mutex_);
186  return {counters_, mode_, start_, initialSyncUs_};
187  }
188  };
189 
192  {
193  ServerFeeSummary() = default;
194 
196  XRPAmount fee,
197  TxQ::Metrics&& escalationMetrics,
198  LoadFeeTrack const& loadFeeTrack);
199  bool
200  operator!=(ServerFeeSummary const& b) const;
201 
202  bool
203  operator==(ServerFeeSummary const& b) const
204  {
205  return !(*this != b);
206  }
207 
212  };
213 
214 public:
216  Application& app,
217  NetworkOPs::clock_type& clock,
218  bool standalone,
219  std::size_t minPeerCount,
220  bool start_valid,
221  JobQueue& job_queue,
222  LedgerMaster& ledgerMaster,
223  ValidatorKeys const& validatorKeys,
224  boost::asio::io_service& io_svc,
225  beast::Journal journal,
226  beast::insight::Collector::ptr const& collector)
227  : app_(app)
228  , m_journal(journal)
230  , mMode(start_valid ? OperatingMode::FULL : OperatingMode::DISCONNECTED)
231  , heartbeatTimer_(io_svc)
232  , clusterTimer_(io_svc)
233  , accountHistoryTxTimer_(io_svc)
234  , mConsensus(
235  app,
236  make_FeeVote(
237  setup_FeeVote(app_.config().section("voting")),
238  app_.logs().journal("FeeVote")),
239  ledgerMaster,
240  *m_localTX,
241  app.getInboundTransactions(),
242  beast::get_abstract_clock<std::chrono::steady_clock>(),
243  validatorKeys,
244  app_.logs().journal("LedgerConsensus"))
246  , m_job_queue(job_queue)
247  , m_standalone(standalone)
248  , minPeerCount_(start_valid ? 0 : minPeerCount)
249  , m_stats(std::bind(&NetworkOPsImp::collect_metrics, this), collector)
250  {
251  }
252 
253  ~NetworkOPsImp() override
254  {
255  // This clear() is necessary to ensure the shared_ptrs in this map get
256  // destroyed NOW because the objects in this map invoke methods on this
257  // class when they are destroyed
258  mRpcSubMap.clear();
259  }
260 
261 public:
263  getOperatingMode() const override;
264 
266  strOperatingMode(OperatingMode const mode, bool const admin) const override;
267 
269  strOperatingMode(bool const admin = false) const override;
270 
271  //
272  // Transaction operations.
273  //
274 
275  // Must complete immediately.
276  void
278 
279  void
281  std::shared_ptr<Transaction>& transaction,
282  bool bUnlimited,
283  bool bLocal,
284  FailHard failType) override;
285 
294  void
296  std::shared_ptr<Transaction> transaction,
297  bool bUnlimited,
298  FailHard failType);
299 
309  void
311  std::shared_ptr<Transaction> transaction,
312  bool bUnlimited,
313  FailHard failtype);
314 
318  void
320 
326  void
328 
329  //
330  // Owner functions.
331  //
332 
334  getOwnerInfo(
336  AccountID const& account) override;
337 
338  //
339  // Book functions.
340  //
341 
342  void
343  getBookPage(
345  Book const&,
346  AccountID const& uTakerID,
347  const bool bProof,
348  unsigned int iLimit,
349  Json::Value const& jvMarker,
350  Json::Value& jvResult) override;
351 
352  // Ledger proposal/close functions.
353  bool
354  processTrustedProposal(RCLCxPeerPos proposal) override;
355 
356  bool
359  std::string const& source) override;
360 
361  void
362  mapComplete(std::shared_ptr<SHAMap> const& map, bool fromAcquire) override;
363 
364  // Network state machine.
365 
366  // Used for the "jump" case.
367 private:
368  void
370  bool
371  checkLastClosedLedger(const Overlay::PeerSequence&, uint256& networkClosed);
372 
373 public:
374  bool
375  beginConsensus(uint256 const& networkClosed) override;
376  void
377  endConsensus() override;
378  void
379  setStandAlone() override;
380 
384  void
385  setStateTimer() override;
386 
387  void
388  setNeedNetworkLedger() override;
389  void
390  clearNeedNetworkLedger() override;
391  bool
392  isNeedNetworkLedger() override;
393  bool
394  isFull() override;
395 
396  void
397  setMode(OperatingMode om) override;
398 
399  bool
400  isBlocked() override;
401  bool
402  isAmendmentBlocked() override;
403  void
404  setAmendmentBlocked() override;
405  bool
406  isAmendmentWarned() override;
407  void
408  setAmendmentWarned() override;
409  void
410  clearAmendmentWarned() override;
411  bool
412  isUNLBlocked() override;
413  void
414  setUNLBlocked() override;
415  void
416  clearUNLBlocked() override;
417  void
418  consensusViewChange() override;
419 
421  getConsensusInfo() override;
423  getServerInfo(bool human, bool admin, bool counters) override;
424  void
425  clearLedgerFetch() override;
427  getLedgerFetchInfo() override;
429  acceptLedger(
430  std::optional<std::chrono::milliseconds> consensusDelay) override;
431  void
432  reportFeeChange() override;
433  void
435 
436  void
437  updateLocalTx(ReadView const& view) override;
439  getLocalTxCount() override;
440 
441  //
442  // Monitoring: publisher side.
443  //
444  void
445  pubLedger(std::shared_ptr<ReadView const> const& lpAccepted) override;
446  void
448  std::shared_ptr<ReadView const> const& ledger,
449  std::shared_ptr<STTx const> const& transaction,
450  TER result) override;
451  void
452  pubValidation(std::shared_ptr<STValidation> const& val) override;
453 
454  void
455  forwardValidation(Json::Value const& jvObj) override;
456  void
457  forwardManifest(Json::Value const& jvObj) override;
458  void
459  forwardProposedTransaction(Json::Value const& jvObj) override;
460  void
461  forwardProposedAccountTransaction(Json::Value const& jvObj) override;
462 
463  //--------------------------------------------------------------------------
464  //
465  // InfoSub::Source.
466  //
467  void
468  subAccount(
469  InfoSub::ref ispListener,
470  hash_set<AccountID> const& vnaAccountIDs,
471  bool rt) override;
472  void
473  unsubAccount(
474  InfoSub::ref ispListener,
475  hash_set<AccountID> const& vnaAccountIDs,
476  bool rt) override;
477 
478  // Just remove the subscription from the tracking
479  // not from the InfoSub. Needed for InfoSub destruction
480  void
482  std::uint64_t seq,
483  hash_set<AccountID> const& vnaAccountIDs,
484  bool rt) override;
485 
487  subAccountHistory(InfoSub::ref ispListener, AccountID const& account)
488  override;
489  void
491  InfoSub::ref ispListener,
492  AccountID const& account,
493  bool historyOnly) override;
494 
495  void
497  std::uint64_t seq,
498  AccountID const& account,
499  bool historyOnly) override;
500 
501  bool
502  subLedger(InfoSub::ref ispListener, Json::Value& jvResult) override;
503  bool
504  unsubLedger(std::uint64_t uListener) override;
505 
506  bool
507  subBookChanges(InfoSub::ref ispListener) override;
508  bool
509  unsubBookChanges(std::uint64_t uListener) override;
510 
511  bool
512  subServer(InfoSub::ref ispListener, Json::Value& jvResult, bool admin)
513  override;
514  bool
515  unsubServer(std::uint64_t uListener) override;
516 
517  bool
518  subBook(InfoSub::ref ispListener, Book const&) override;
519  bool
520  unsubBook(std::uint64_t uListener, Book const&) override;
521 
522  bool
523  subManifests(InfoSub::ref ispListener) override;
524  bool
525  unsubManifests(std::uint64_t uListener) override;
526  void
527  pubManifest(Manifest const&) override;
528 
529  bool
530  subTransactions(InfoSub::ref ispListener) override;
531  bool
532  unsubTransactions(std::uint64_t uListener) override;
533 
534  bool
535  subRTTransactions(InfoSub::ref ispListener) override;
536  bool
537  unsubRTTransactions(std::uint64_t uListener) override;
538 
539  bool
540  subValidations(InfoSub::ref ispListener) override;
541  bool
542  unsubValidations(std::uint64_t uListener) override;
543 
544  bool
545  subPeerStatus(InfoSub::ref ispListener) override;
546  bool
547  unsubPeerStatus(std::uint64_t uListener) override;
548  void
549  pubPeerStatus(std::function<Json::Value(void)> const&) override;
550 
551  bool
552  subConsensus(InfoSub::ref ispListener) override;
553  bool
554  unsubConsensus(std::uint64_t uListener) override;
555 
557  findRpcSub(std::string const& strUrl) override;
559  addRpcSub(std::string const& strUrl, InfoSub::ref) override;
560  bool
561  tryRemoveRpcSub(std::string const& strUrl) override;
562 
563  void
564  stop() override
565  {
566  {
567  boost::system::error_code ec;
568  heartbeatTimer_.cancel(ec);
569  if (ec)
570  {
571  JLOG(m_journal.error())
572  << "NetworkOPs: heartbeatTimer cancel error: "
573  << ec.message();
574  }
575 
576  ec.clear();
577  clusterTimer_.cancel(ec);
578  if (ec)
579  {
580  JLOG(m_journal.error())
581  << "NetworkOPs: clusterTimer cancel error: "
582  << ec.message();
583  }
584 
585  ec.clear();
586  accountHistoryTxTimer_.cancel(ec);
587  if (ec)
588  {
589  JLOG(m_journal.error())
590  << "NetworkOPs: accountHistoryTxTimer cancel error: "
591  << ec.message();
592  }
593  }
594  // Make sure that any waitHandlers pending in our timers are done.
595  using namespace std::chrono_literals;
596  waitHandlerCounter_.join("NetworkOPs", 1s, m_journal);
597  }
598 
599  void
600  stateAccounting(Json::Value& obj) override;
601 
602 private:
603  void
604  setTimer(
605  boost::asio::steady_timer& timer,
606  std::chrono::milliseconds const& expiry_time,
607  std::function<void()> onExpire,
608  std::function<void()> onError);
609  void
611  void
612  setClusterTimer();
613  void
615  void
617 
619  transJson(
620  const STTx& transaction,
621  TER result,
622  bool validated,
623  std::shared_ptr<ReadView const> const& ledger);
624 
625  void
627  std::shared_ptr<ReadView const> const& ledger,
628  AcceptedLedgerTx const& transaction);
629 
630  void
632  std::shared_ptr<ReadView const> const& ledger,
633  AcceptedLedgerTx const& transaction);
634 
635  void
637  std::shared_ptr<ReadView const> const& ledger,
638  std::shared_ptr<STTx const> const& transaction,
639  TER result);
640 
641  void
642  pubServer();
643  void
645 
647  getHostId(bool forAdmin);
648 
649 private:
653 
654  /*
655  * With a validated ledger to separate history and future, the node
656  * streams historical txns with negative indexes starting from -1,
657  * and streams future txns starting from index 0.
658  * The SubAccountHistoryIndex struct maintains these indexes.
659  * It also has a flag stopHistorical_ for stopping streaming
660  * the historical txns.
661  */
663  {
665  // forward
667  // separate backward and forward
669  // history, backward
674 
676  : accountId_(accountId)
677  , forwardTxIndex_(0)
680  , historyTxIndex_(-1)
681  , haveHistorical_(false)
682  , stopHistorical_(false)
683  {
684  }
685  };
687  {
690  };
692  {
695  };
698 
702  void
704  std::shared_ptr<ReadView const> const& ledger,
705  SubAccountHistoryInfoWeak& subInfo);
706  void
708  void
710 
713 
715 
717 
719 
724 
726  boost::asio::steady_timer heartbeatTimer_;
727  boost::asio::steady_timer clusterTimer_;
728  boost::asio::steady_timer accountHistoryTxTimer_;
729 
731 
733 
735 
738 
740 
742 
743  enum SubTypes {
744  sLedger, // Accepted ledgers.
745  sManifests, // Received validator manifests.
746  sServer, // When server changes connectivity state.
747  sTransactions, // All accepted transactions.
748  sRTTransactions, // All proposed and accepted transactions.
749  sValidations, // Received validations.
750  sPeerStatus, // Peer status changes.
751  sConsensusPhase, // Consensus phase
752  sBookChanges, // Per-ledger order book changes
753 
754  sLastEntry = sBookChanges // as this name implies, any new entry
755  // must be ADDED ABOVE this one
756  };
758 
760 
762 
763  // Whether we are in standalone mode.
764  bool const m_standalone;
765 
766  // The number of nodes that we need to consider ourselves connected.
768 
769  // Transaction batching.
774 
776 
777 private:
778  struct Stats
779  {
780  template <class Handler>
782  Handler const& handler,
783  beast::insight::Collector::ptr const& collector)
784  : hook(collector->make_hook(handler))
785  , disconnected_duration(collector->make_gauge(
786  "State_Accounting",
787  "Disconnected_duration"))
788  , connected_duration(collector->make_gauge(
789  "State_Accounting",
790  "Connected_duration"))
792  collector->make_gauge("State_Accounting", "Syncing_duration"))
793  , tracking_duration(collector->make_gauge(
794  "State_Accounting",
795  "Tracking_duration"))
796  , full_duration(
797  collector->make_gauge("State_Accounting", "Full_duration"))
798  , disconnected_transitions(collector->make_gauge(
799  "State_Accounting",
800  "Disconnected_transitions"))
801  , connected_transitions(collector->make_gauge(
802  "State_Accounting",
803  "Connected_transitions"))
804  , syncing_transitions(collector->make_gauge(
805  "State_Accounting",
806  "Syncing_transitions"))
807  , tracking_transitions(collector->make_gauge(
808  "State_Accounting",
809  "Tracking_transitions"))
811  collector->make_gauge("State_Accounting", "Full_transitions"))
812  {
813  }
814 
821 
827  };
828 
829  std::mutex m_statsMutex; // Mutex to lock m_stats
831 
832 private:
833  void
834  collect_metrics();
835 };
836 
837 //------------------------------------------------------------------------------
838 
840  {"disconnected", "connected", "syncing", "tracking", "full"}};
841 
843 
851 
852 static auto const genesisAccountId = calcAccountID(
853  generateKeyPair(KeyType::secp256k1, generateSeed("masterpassphrase"))
854  .first);
855 
856 //------------------------------------------------------------------------------
857 inline OperatingMode
859 {
860  return mMode;
861 }
862 
863 inline std::string
864 NetworkOPsImp::strOperatingMode(bool const admin /* = false */) const
865 {
866  return strOperatingMode(mMode, admin);
867 }
868 
869 inline void
871 {
873 }
874 
875 inline void
877 {
878  needNetworkLedger_ = true;
879 }
880 
881 inline void
883 {
884  needNetworkLedger_ = false;
885 }
886 
887 inline bool
889 {
890  return needNetworkLedger_;
891 }
892 
893 inline bool
895 {
897 }
898 
901 {
902  static std::string const hostname = boost::asio::ip::host_name();
903 
904  if (forAdmin)
905  return hostname;
906 
907  // For non-admin uses hash the node public key into a
908  // single RFC1751 word:
909  static std::string const shroudedHostId = [this]() {
910  auto const& id = app_.nodeIdentity();
911 
912  return RFC1751::getWordFromBlob(id.first.data(), id.first.size());
913  }();
914 
915  return shroudedHostId;
916 }
917 
918 void
920 {
922  setClusterTimer();
923 }
924 
925 void
927  boost::asio::steady_timer& timer,
928  const std::chrono::milliseconds& expiry_time,
929  std::function<void()> onExpire,
930  std::function<void()> onError)
931 {
932  // Only start the timer if waitHandlerCounter_ is not yet joined.
933  if (auto optionalCountedHandler = waitHandlerCounter_.wrap(
934  [this, onExpire, onError](boost::system::error_code const& e) {
935  if ((e.value() == boost::system::errc::success) &&
936  (!m_job_queue.isStopped()))
937  {
938  onExpire();
939  }
940  // Recover as best we can if an unexpected error occurs.
941  if (e.value() != boost::system::errc::success &&
942  e.value() != boost::asio::error::operation_aborted)
943  {
944  // Try again later and hope for the best.
945  JLOG(m_journal.error())
946  << "Timer got error '" << e.message()
947  << "'. Restarting timer.";
948  onError();
949  }
950  }))
951  {
952  timer.expires_from_now(expiry_time);
953  timer.async_wait(std::move(*optionalCountedHandler));
954  }
955 }
956 
957 void
959 {
960  setTimer(
963  [this]() {
964  m_job_queue.addJob(jtNETOP_TIMER, "NetOPs.heartbeat", [this]() {
965  processHeartbeatTimer();
966  });
967  },
968  [this]() { setHeartbeatTimer(); });
969 }
970 
971 void
972 NetworkOPsImp::setClusterTimer()
973 {
974  using namespace std::chrono_literals;
975  setTimer(
976  clusterTimer_,
977  10s,
978  [this]() {
979  m_job_queue.addJob(jtNETOP_CLUSTER, "NetOPs.cluster", [this]() {
980  processClusterTimer();
981  });
982  },
983  [this]() { setClusterTimer(); });
984 }
985 
986 void
987 NetworkOPsImp::setAccountHistoryJobTimer(SubAccountHistoryInfoWeak subInfo)
988 {
989  JLOG(m_journal.debug()) << "Scheduling AccountHistory job for account "
990  << toBase58(subInfo.index_->accountId_);
991  using namespace std::chrono_literals;
992  setTimer(
993  accountHistoryTxTimer_,
994  4s,
995  [this, subInfo]() { addAccountHistoryJob(subInfo); },
996  [this, subInfo]() { setAccountHistoryJobTimer(subInfo); });
997 }
998 
999 void
1000 NetworkOPsImp::processHeartbeatTimer()
1001 {
1002  {
1003  std::unique_lock lock{app_.getMasterMutex()};
1004 
1005  // VFALCO NOTE This is for diagnosing a crash on exit
1006  LoadManager& mgr(app_.getLoadManager());
1007  mgr.resetDeadlockDetector();
1008 
1009  std::size_t const numPeers = app_.overlay().size();
1010 
1011  // do we have sufficient peers? If not, we are disconnected.
1012  if (numPeers < minPeerCount_)
1013  {
1014  if (mMode != OperatingMode::DISCONNECTED)
1015  {
1016  setMode(OperatingMode::DISCONNECTED);
1017  JLOG(m_journal.warn())
1018  << "Node count (" << numPeers << ") has fallen "
1019  << "below required minimum (" << minPeerCount_ << ").";
1020  }
1021 
1022  // MasterMutex lock need not be held to call setHeartbeatTimer()
1023  lock.unlock();
1024  // We do not call mConsensus.timerEntry until there are enough
1025  // peers providing meaningful inputs to consensus
1026  setHeartbeatTimer();
1027  return;
1028  }
1029 
1030  if (mMode == OperatingMode::DISCONNECTED)
1031  {
1032  setMode(OperatingMode::CONNECTED);
1033  JLOG(m_journal.info())
1034  << "Node count (" << numPeers << ") is sufficient.";
1035  }
1036 
1037  // Check if the last validated ledger forces a change between these
1038  // states.
1039  if (mMode == OperatingMode::SYNCING)
1040  setMode(OperatingMode::SYNCING);
1041  else if (mMode == OperatingMode::CONNECTED)
1042  setMode(OperatingMode::CONNECTED);
1043  }
1044 
1045  mConsensus.timerEntry(app_.timeKeeper().closeTime());
1046 
1047  const ConsensusPhase currPhase = mConsensus.phase();
1048  if (mLastConsensusPhase != currPhase)
1049  {
1050  reportConsensusStateChange(currPhase);
1051  mLastConsensusPhase = currPhase;
1052  }
1053 
1054  setHeartbeatTimer();
1055 }
1056 
1057 void
1058 NetworkOPsImp::processClusterTimer()
1059 {
1060  using namespace std::chrono_literals;
1061  bool const update = app_.cluster().update(
1062  app_.nodeIdentity().first,
1063  "",
1064  (m_ledgerMaster.getValidatedLedgerAge() <= 4min)
1065  ? app_.getFeeTrack().getLocalFee()
1066  : 0,
1067  app_.timeKeeper().now());
1068 
1069  if (!update)
1070  {
1071  JLOG(m_journal.debug()) << "Too soon to send cluster update";
1072  setClusterTimer();
1073  return;
1074  }
1075 
1076  protocol::TMCluster cluster;
1077  app_.cluster().for_each([&cluster](ClusterNode const& node) {
1078  protocol::TMClusterNode& n = *cluster.add_clusternodes();
1079  n.set_publickey(toBase58(TokenType::NodePublic, node.identity()));
1080  n.set_reporttime(node.getReportTime().time_since_epoch().count());
1081  n.set_nodeload(node.getLoadFee());
1082  if (!node.name().empty())
1083  n.set_nodename(node.name());
1084  });
1085 
1086  Resource::Gossip gossip = app_.getResourceManager().exportConsumers();
1087  for (auto& item : gossip.items)
1088  {
1089  protocol::TMLoadSource& node = *cluster.add_loadsources();
1090  node.set_name(to_string(item.address));
1091  node.set_cost(item.balance);
1092  }
1093  app_.overlay().foreach(send_if(
1094  std::make_shared<Message>(cluster, protocol::mtCLUSTER),
1095  peer_in_cluster()));
1096  setClusterTimer();
1097 }
1098 
1099 //------------------------------------------------------------------------------
1100 
1102 NetworkOPsImp::strOperatingMode(OperatingMode const mode, bool const admin)
1103  const
1104 {
1105  if (mode == OperatingMode::FULL && admin)
1106  {
1107  auto const consensusMode = mConsensus.mode();
1108  if (consensusMode != ConsensusMode::wrongLedger)
1109  {
1110  if (consensusMode == ConsensusMode::proposing)
1111  return "proposing";
1112 
1113  if (mConsensus.validating())
1114  return "validating";
1115  }
1116  }
1117 
1118  return states_[static_cast<std::size_t>(mode)];
1119 }
1120 
1121 void
1122 NetworkOPsImp::submitTransaction(std::shared_ptr<STTx const> const& iTrans)
1123 {
1124  if (isNeedNetworkLedger())
1125  {
1126  // Nothing we can do if we've never been in sync
1127  return;
1128  }
1129 
1130  // this is an asynchronous interface
1131  auto const trans = sterilize(*iTrans);
1132 
1133  auto const txid = trans->getTransactionID();
1134  auto const flags = app_.getHashRouter().getFlags(txid);
1135 
1136  if ((flags & SF_BAD) != 0)
1137  {
1138  JLOG(m_journal.warn()) << "Submitted transaction cached bad";
1139  return;
1140  }
1141 
1142  try
1143  {
1144  auto const [validity, reason] = checkValidity(
1145  app_.getHashRouter(),
1146  *trans,
1147  m_ledgerMaster.getValidatedRules(),
1148  app_.config());
1149 
1150  if (validity != Validity::Valid)
1151  {
1152  JLOG(m_journal.warn())
1153  << "Submitted transaction invalid: " << reason;
1154  return;
1155  }
1156  }
1157  catch (std::exception const&)
1158  {
1159  JLOG(m_journal.warn()) << "Exception checking transaction" << txid;
1160 
1161  return;
1162  }
1163 
1164  std::string reason;
1165 
1166  auto tx = std::make_shared<Transaction>(trans, reason, app_);
1167 
1168  m_job_queue.addJob(jtTRANSACTION, "submitTxn", [this, tx]() {
1169  auto t = tx;
1170  processTransaction(t, false, false, FailHard::no);
1171  });
1172 }
1173 
1174 void
1175 NetworkOPsImp::processTransaction(
1176  std::shared_ptr<Transaction>& transaction,
1177  bool bUnlimited,
1178  bool bLocal,
1179  FailHard failType)
1180 {
1181  auto ev = m_job_queue.makeLoadEvent(jtTXN_PROC, "ProcessTXN");
1182  auto const newFlags = app_.getHashRouter().getFlags(transaction->getID());
1183 
1184  if ((newFlags & SF_BAD) != 0)
1185  {
1186  // cached bad
1187  JLOG(m_journal.warn()) << transaction->getID() << ": cached bad!\n";
1188  transaction->setStatus(INVALID);
1189  transaction->setResult(temBAD_SIGNATURE);
1190  return;
1191  }
1192 
1193  // NOTE eahennis - I think this check is redundant,
1194  // but I'm not 100% sure yet.
1195  // If so, only cost is looking up HashRouter flags.
1196  auto const view = m_ledgerMaster.getCurrentLedger();
1197  auto const [validity, reason] = checkValidity(
1198  app_.getHashRouter(),
1199  *transaction->getSTransaction(),
1200  view->rules(),
1201  app_.config());
1202  assert(validity == Validity::Valid);
1203 
1204  // Not concerned with local checks at this point.
1205  if (validity == Validity::SigBad)
1206  {
1207  JLOG(m_journal.info()) << "Transaction has bad signature: " << reason;
1208  transaction->setStatus(INVALID);
1209  transaction->setResult(temBAD_SIGNATURE);
1210  app_.getHashRouter().setFlags(transaction->getID(), SF_BAD);
1211  return;
1212  }
1213 
1214  // canonicalize can change our pointer
1215  app_.getMasterTransaction().canonicalize(&transaction);
1216 
1217  if (bLocal)
1218  doTransactionSync(transaction, bUnlimited, failType);
1219  else
1220  doTransactionAsync(transaction, bUnlimited, failType);
1221 }
1222 
1223 void
1224 NetworkOPsImp::doTransactionAsync(
1225  std::shared_ptr<Transaction> transaction,
1226  bool bUnlimited,
1227  FailHard failType)
1228 {
1229  std::lock_guard lock(mMutex);
1230 
1231  if (transaction->getApplying())
1232  return;
1233 
1234  mTransactions.push_back(
1235  TransactionStatus(transaction, bUnlimited, false, failType));
1236  transaction->setApplying();
1237 
1238  if (mDispatchState == DispatchState::none)
1239  {
1240  if (m_job_queue.addJob(
1241  jtBATCH, "transactionBatch", [this]() { transactionBatch(); }))
1242  {
1243  mDispatchState = DispatchState::scheduled;
1244  }
1245  }
1246 }
1247 
1248 void
1249 NetworkOPsImp::doTransactionSync(
1250  std::shared_ptr<Transaction> transaction,
1251  bool bUnlimited,
1252  FailHard failType)
1253 {
1254  std::unique_lock<std::mutex> lock(mMutex);
1255 
1256  if (!transaction->getApplying())
1257  {
1258  mTransactions.push_back(
1259  TransactionStatus(transaction, bUnlimited, true, failType));
1260  transaction->setApplying();
1261  }
1262 
1263  do
1264  {
1265  if (mDispatchState == DispatchState::running)
1266  {
1267  // A batch processing job is already running, so wait.
1268  mCond.wait(lock);
1269  }
1270  else
1271  {
1272  apply(lock);
1273 
1274  if (mTransactions.size())
1275  {
1276  // More transactions need to be applied, but by another job.
1277  if (m_job_queue.addJob(jtBATCH, "transactionBatch", [this]() {
1278  transactionBatch();
1279  }))
1280  {
1281  mDispatchState = DispatchState::scheduled;
1282  }
1283  }
1284  }
1285  } while (transaction->getApplying());
1286 }
1287 
1288 void
1289 NetworkOPsImp::transactionBatch()
1290 {
1291  std::unique_lock<std::mutex> lock(mMutex);
1292 
1293  if (mDispatchState == DispatchState::running)
1294  return;
1295 
1296  while (mTransactions.size())
1297  {
1298  apply(lock);
1299  }
1300 }
1301 
1302 void
1303 NetworkOPsImp::apply(std::unique_lock<std::mutex>& batchLock)
1304 {
1305  std::vector<TransactionStatus> submit_held;
1306  std::vector<TransactionStatus> transactions;
1307  mTransactions.swap(transactions);
1308  assert(!transactions.empty());
1309 
1310  assert(mDispatchState != DispatchState::running);
1311  mDispatchState = DispatchState::running;
1312 
1313  batchLock.unlock();
1314 
1315  {
1316  std::unique_lock masterLock{app_.getMasterMutex(), std::defer_lock};
1317  bool changed = false;
1318  {
1319  std::unique_lock ledgerLock{
1320  m_ledgerMaster.peekMutex(), std::defer_lock};
1321  std::lock(masterLock, ledgerLock);
1322 
1323  app_.openLedger().modify([&](OpenView& view, beast::Journal j) {
1324  for (TransactionStatus& e : transactions)
1325  {
1326  // we check before adding to the batch
1327  ApplyFlags flags = tapNONE;
1328  if (e.admin)
1329  flags |= tapUNLIMITED;
1330 
1331  if (e.failType == FailHard::yes)
1332  flags |= tapFAIL_HARD;
1333 
1334  auto const result = app_.getTxQ().apply(
1335  app_, view, e.transaction->getSTransaction(), flags, j);
1336  e.result = result.first;
1337  e.applied = result.second;
1338  changed = changed || result.second;
1339  }
1340  return changed;
1341  });
1342  }
1343  if (changed)
1344  reportFeeChange();
1345 
1346  std::optional<LedgerIndex> validatedLedgerIndex;
1347  if (auto const l = m_ledgerMaster.getValidatedLedger())
1348  validatedLedgerIndex = l->info().seq;
1349 
1350  auto newOL = app_.openLedger().current();
1351  for (TransactionStatus& e : transactions)
1352  {
1353  e.transaction->clearSubmitResult();
1354 
1355  if (e.applied)
1356  {
1357  pubProposedTransaction(
1358  newOL, e.transaction->getSTransaction(), e.result);
1359  e.transaction->setApplied();
1360  }
1361 
1362  e.transaction->setResult(e.result);
1363 
1364  if (isTemMalformed(e.result))
1365  app_.getHashRouter().setFlags(e.transaction->getID(), SF_BAD);
1366 
1367 #ifdef DEBUG
1368  if (e.result != tesSUCCESS)
1369  {
1370  std::string token, human;
1371 
1372  if (transResultInfo(e.result, token, human))
1373  {
1374  JLOG(m_journal.info())
1375  << "TransactionResult: " << token << ": " << human;
1376  }
1377  }
1378 #endif
1379 
1380  bool addLocal = e.local;
1381 
1382  if (e.result == tesSUCCESS)
1383  {
1384  JLOG(m_journal.debug())
1385  << "Transaction is now included in open ledger";
1386  e.transaction->setStatus(INCLUDED);
1387 
1388  auto const& txCur = e.transaction->getSTransaction();
1389  auto const txNext = m_ledgerMaster.popAcctTransaction(txCur);
1390  if (txNext)
1391  {
1392  std::string reason;
1393  auto const trans = sterilize(*txNext);
1394  auto t = std::make_shared<Transaction>(trans, reason, app_);
1395  submit_held.emplace_back(t, false, false, FailHard::no);
1396  t->setApplying();
1397  }
1398  }
1399  else if (e.result == tefPAST_SEQ)
1400  {
1401  // duplicate or conflict
1402  JLOG(m_journal.info()) << "Transaction is obsolete";
1403  e.transaction->setStatus(OBSOLETE);
1404  }
1405  else if (e.result == terQUEUED)
1406  {
1407  JLOG(m_journal.debug())
1408  << "Transaction is likely to claim a"
1409  << " fee, but is queued until fee drops";
1410 
1411  e.transaction->setStatus(HELD);
1412  // Add to held transactions, because it could get
1413  // kicked out of the queue, and this will try to
1414  // put it back.
1415  m_ledgerMaster.addHeldTransaction(e.transaction);
1416  e.transaction->setQueued();
1417  e.transaction->setKept();
1418  }
1419  else if (isTerRetry(e.result))
1420  {
1421  if (e.failType != FailHard::yes)
1422  {
1423  // transaction should be held
1424  JLOG(m_journal.debug())
1425  << "Transaction should be held: " << e.result;
1426  e.transaction->setStatus(HELD);
1427  m_ledgerMaster.addHeldTransaction(e.transaction);
1428  e.transaction->setKept();
1429  }
1430  }
1431  else
1432  {
1433  JLOG(m_journal.debug())
1434  << "Status other than success " << e.result;
1435  e.transaction->setStatus(INVALID);
1436  }
1437 
1438  auto const enforceFailHard =
1439  e.failType == FailHard::yes && !isTesSuccess(e.result);
1440 
1441  if (addLocal && !enforceFailHard)
1442  {
1443  m_localTX->push_back(
1444  m_ledgerMaster.getCurrentLedgerIndex(),
1445  e.transaction->getSTransaction());
1446  e.transaction->setKept();
1447  }
1448 
1449  if ((e.applied ||
1450  ((mMode != OperatingMode::FULL) &&
1451  (e.failType != FailHard::yes) && e.local) ||
1452  (e.result == terQUEUED)) &&
1453  !enforceFailHard)
1454  {
1455  auto const toSkip =
1456  app_.getHashRouter().shouldRelay(e.transaction->getID());
1457 
1458  if (toSkip)
1459  {
1460  protocol::TMTransaction tx;
1461  Serializer s;
1462 
1463  e.transaction->getSTransaction()->add(s);
1464  tx.set_rawtransaction(s.data(), s.size());
1465  tx.set_status(protocol::tsCURRENT);
1466  tx.set_receivetimestamp(
1467  app_.timeKeeper().now().time_since_epoch().count());
1468  tx.set_deferred(e.result == terQUEUED);
1469  // FIXME: This should be when we received it
1470  app_.overlay().relay(e.transaction->getID(), tx, *toSkip);
1471  e.transaction->setBroadcast();
1472  }
1473  }
1474 
1475  if (validatedLedgerIndex)
1476  {
1477  auto [fee, accountSeq, availableSeq] =
1478  app_.getTxQ().getTxRequiredFeeAndSeq(
1479  *newOL, e.transaction->getSTransaction());
1480  e.transaction->setCurrentLedgerState(
1481  *validatedLedgerIndex, fee, accountSeq, availableSeq);
1482  }
1483  }
1484  }
1485 
1486  batchLock.lock();
1487 
1488  for (TransactionStatus& e : transactions)
1489  e.transaction->clearApplying();
1490 
1491  if (!submit_held.empty())
1492  {
1493  if (mTransactions.empty())
1494  mTransactions.swap(submit_held);
1495  else
1496  for (auto& e : submit_held)
1497  mTransactions.push_back(std::move(e));
1498  }
1499 
1500  mCond.notify_all();
1501 
1502  mDispatchState = DispatchState::none;
1503 }
1504 
1505 //
1506 // Owner functions
1507 //
1508 
1510 NetworkOPsImp::getOwnerInfo(
1512  AccountID const& account)
1513 {
1514  Json::Value jvObjects(Json::objectValue);
1515  auto root = keylet::ownerDir(account);
1516  auto sleNode = lpLedger->read(keylet::page(root));
1517  if (sleNode)
1518  {
1519  std::uint64_t uNodeDir;
1520 
1521  do
1522  {
1523  for (auto const& uDirEntry : sleNode->getFieldV256(sfIndexes))
1524  {
1525  auto sleCur = lpLedger->read(keylet::child(uDirEntry));
1526  assert(sleCur);
1527 
1528  switch (sleCur->getType())
1529  {
1530  case ltOFFER:
1531  if (!jvObjects.isMember(jss::offers))
1532  jvObjects[jss::offers] =
1534 
1535  jvObjects[jss::offers].append(
1536  sleCur->getJson(JsonOptions::none));
1537  break;
1538 
1539  case ltRIPPLE_STATE:
1540  if (!jvObjects.isMember(jss::ripple_lines))
1541  {
1542  jvObjects[jss::ripple_lines] =
1544  }
1545 
1546  jvObjects[jss::ripple_lines].append(
1547  sleCur->getJson(JsonOptions::none));
1548  break;
1549 
1550  case ltACCOUNT_ROOT:
1551  case ltDIR_NODE:
1552  default:
1553  assert(false);
1554  break;
1555  }
1556  }
1557 
1558  uNodeDir = sleNode->getFieldU64(sfIndexNext);
1559 
1560  if (uNodeDir)
1561  {
1562  sleNode = lpLedger->read(keylet::page(root, uNodeDir));
1563  assert(sleNode);
1564  }
1565  } while (uNodeDir);
1566  }
1567 
1568  return jvObjects;
1569 }
1570 
1571 //
1572 // Other
1573 //
1574 
1575 inline bool
1576 NetworkOPsImp::isBlocked()
1577 {
1578  return isAmendmentBlocked() || isUNLBlocked();
1579 }
1580 
1581 inline bool
1582 NetworkOPsImp::isAmendmentBlocked()
1583 {
1584  return amendmentBlocked_;
1585 }
1586 
1587 void
1588 NetworkOPsImp::setAmendmentBlocked()
1589 {
1590  amendmentBlocked_ = true;
1591  setMode(OperatingMode::CONNECTED);
1592 }
1593 
1594 inline bool
1595 NetworkOPsImp::isAmendmentWarned()
1596 {
1597  return !amendmentBlocked_ && amendmentWarned_;
1598 }
1599 
1600 inline void
1601 NetworkOPsImp::setAmendmentWarned()
1602 {
1603  amendmentWarned_ = true;
1604 }
1605 
1606 inline void
1607 NetworkOPsImp::clearAmendmentWarned()
1608 {
1609  amendmentWarned_ = false;
1610 }
1611 
1612 inline bool
1613 NetworkOPsImp::isUNLBlocked()
1614 {
1615  return unlBlocked_;
1616 }
1617 
1618 void
1619 NetworkOPsImp::setUNLBlocked()
1620 {
1621  unlBlocked_ = true;
1622  setMode(OperatingMode::CONNECTED);
1623 }
1624 
1625 inline void
1626 NetworkOPsImp::clearUNLBlocked()
1627 {
1628  unlBlocked_ = false;
1629 }
1630 
1631 bool
1632 NetworkOPsImp::checkLastClosedLedger(
1633  const Overlay::PeerSequence& peerList,
1634  uint256& networkClosed)
1635 {
1636  // Returns true if there's an *abnormal* ledger issue, normal changing in
1637  // TRACKING mode should return false. Do we have sufficient validations for
1638  // our last closed ledger? Or do sufficient nodes agree? And do we have no
1639  // better ledger available? If so, we are either tracking or full.
1640 
1641  JLOG(m_journal.trace()) << "NetworkOPsImp::checkLastClosedLedger";
1642 
1643  auto const ourClosed = m_ledgerMaster.getClosedLedger();
1644 
1645  if (!ourClosed)
1646  return false;
1647 
1648  uint256 closedLedger = ourClosed->info().hash;
1649  uint256 prevClosedLedger = ourClosed->info().parentHash;
1650  JLOG(m_journal.trace()) << "OurClosed: " << closedLedger;
1651  JLOG(m_journal.trace()) << "PrevClosed: " << prevClosedLedger;
1652 
1653  //-------------------------------------------------------------------------
1654  // Determine preferred last closed ledger
1655 
1656  auto& validations = app_.getValidations();
1657  JLOG(m_journal.debug())
1658  << "ValidationTrie " << Json::Compact(validations.getJsonTrie());
1659 
1660  // Will rely on peer LCL if no trusted validations exist
1662  peerCounts[closedLedger] = 0;
1663  if (mMode >= OperatingMode::TRACKING)
1664  peerCounts[closedLedger]++;
1665 
1666  for (auto& peer : peerList)
1667  {
1668  uint256 peerLedger = peer->getClosedLedgerHash();
1669 
1670  if (peerLedger.isNonZero())
1671  ++peerCounts[peerLedger];
1672  }
1673 
1674  for (auto const& it : peerCounts)
1675  JLOG(m_journal.debug()) << "L: " << it.first << " n=" << it.second;
1676 
1677  uint256 preferredLCL = validations.getPreferredLCL(
1678  RCLValidatedLedger{ourClosed, validations.adaptor().journal()},
1679  m_ledgerMaster.getValidLedgerIndex(),
1680  peerCounts);
1681 
1682  bool switchLedgers = preferredLCL != closedLedger;
1683  if (switchLedgers)
1684  closedLedger = preferredLCL;
1685  //-------------------------------------------------------------------------
1686  if (switchLedgers && (closedLedger == prevClosedLedger))
1687  {
1688  // don't switch to our own previous ledger
1689  JLOG(m_journal.info()) << "We won't switch to our own previous ledger";
1690  networkClosed = ourClosed->info().hash;
1691  switchLedgers = false;
1692  }
1693  else
1694  networkClosed = closedLedger;
1695 
1696  if (!switchLedgers)
1697  return false;
1698 
1699  auto consensus = m_ledgerMaster.getLedgerByHash(closedLedger);
1700 
1701  if (!consensus)
1702  consensus = app_.getInboundLedgers().acquire(
1703  closedLedger, 0, InboundLedger::Reason::CONSENSUS);
1704 
1705  if (consensus &&
1706  (!m_ledgerMaster.canBeCurrent(consensus) ||
1707  !m_ledgerMaster.isCompatible(
1708  *consensus, m_journal.debug(), "Not switching")))
1709  {
1710  // Don't switch to a ledger not on the validated chain
1711  // or with an invalid close time or sequence
1712  networkClosed = ourClosed->info().hash;
1713  return false;
1714  }
1715 
1716  JLOG(m_journal.warn()) << "We are not running on the consensus ledger";
1717  JLOG(m_journal.info()) << "Our LCL: " << getJson({*ourClosed, {}});
1718  JLOG(m_journal.info()) << "Net LCL " << closedLedger;
1719 
1720  if ((mMode == OperatingMode::TRACKING) || (mMode == OperatingMode::FULL))
1721  {
1722  setMode(OperatingMode::CONNECTED);
1723  }
1724 
1725  if (consensus)
1726  {
1727  // FIXME: If this rewinds the ledger sequence, or has the same
1728  // sequence, we should update the status on any stored transactions
1729  // in the invalidated ledgers.
1730  switchLastClosedLedger(consensus);
1731  }
1732 
1733  return true;
1734 }
1735 
1736 void
1737 NetworkOPsImp::switchLastClosedLedger(
1738  std::shared_ptr<Ledger const> const& newLCL)
1739 {
1740  // set the newLCL as our last closed ledger -- this is abnormal code
1741  JLOG(m_journal.error())
1742  << "JUMP last closed ledger to " << newLCL->info().hash;
1743 
1744  clearNeedNetworkLedger();
1745 
1746  // Update fee computations.
1747  app_.getTxQ().processClosedLedger(app_, *newLCL, true);
1748 
1749  // Caller must own master lock
1750  {
1751  // Apply tx in old open ledger to new
1752  // open ledger. Then apply local tx.
1753 
1754  auto retries = m_localTX->getTxSet();
1755  auto const lastVal = app_.getLedgerMaster().getValidatedLedger();
1756  std::optional<Rules> rules;
1757  if (lastVal)
1758  rules = makeRulesGivenLedger(*lastVal, app_.config().features);
1759  else
1760  rules.emplace(app_.config().features);
1761  app_.openLedger().accept(
1762  app_,
1763  *rules,
1764  newLCL,
1765  OrderedTxs({}),
1766  false,
1767  retries,
1768  tapNONE,
1769  "jump",
1770  [&](OpenView& view, beast::Journal j) {
1771  // Stuff the ledger with transactions from the queue.
1772  return app_.getTxQ().accept(app_, view);
1773  });
1774  }
1775 
1776  m_ledgerMaster.switchLCL(newLCL);
1777 
1778  protocol::TMStatusChange s;
1779  s.set_newevent(protocol::neSWITCHED_LEDGER);
1780  s.set_ledgerseq(newLCL->info().seq);
1781  s.set_networktime(app_.timeKeeper().now().time_since_epoch().count());
1782  s.set_ledgerhashprevious(
1783  newLCL->info().parentHash.begin(), newLCL->info().parentHash.size());
1784  s.set_ledgerhash(newLCL->info().hash.begin(), newLCL->info().hash.size());
1785 
1786  app_.overlay().foreach(
1787  send_always(std::make_shared<Message>(s, protocol::mtSTATUS_CHANGE)));
1788 }
1789 
1790 bool
1791 NetworkOPsImp::beginConsensus(uint256 const& networkClosed)
1792 {
1793  assert(networkClosed.isNonZero());
1794 
1795  auto closingInfo = m_ledgerMaster.getCurrentLedger()->info();
1796 
1797  JLOG(m_journal.info()) << "Consensus time for #" << closingInfo.seq
1798  << " with LCL " << closingInfo.parentHash;
1799 
1800  auto prevLedger = m_ledgerMaster.getLedgerByHash(closingInfo.parentHash);
1801 
1802  if (!prevLedger)
1803  {
1804  // this shouldn't happen unless we jump ledgers
1805  if (mMode == OperatingMode::FULL)
1806  {
1807  JLOG(m_journal.warn()) << "Don't have LCL, going to tracking";
1808  setMode(OperatingMode::TRACKING);
1809  }
1810 
1811  return false;
1812  }
1813 
1814  assert(prevLedger->info().hash == closingInfo.parentHash);
1815  assert(
1816  closingInfo.parentHash ==
1817  m_ledgerMaster.getClosedLedger()->info().hash);
1818 
1819  if (prevLedger->rules().enabled(featureNegativeUNL))
1820  app_.validators().setNegativeUNL(prevLedger->negativeUNL());
1821  TrustChanges const changes = app_.validators().updateTrusted(
1822  app_.getValidations().getCurrentNodeIDs(),
1823  closingInfo.parentCloseTime,
1824  *this,
1825  app_.overlay(),
1826  app_.getHashRouter());
1827 
1828  if (!changes.added.empty() || !changes.removed.empty())
1829  app_.getValidations().trustChanged(changes.added, changes.removed);
1830 
1831  mConsensus.startRound(
1832  app_.timeKeeper().closeTime(),
1833  networkClosed,
1834  prevLedger,
1835  changes.removed,
1836  changes.added);
1837 
1838  const ConsensusPhase currPhase = mConsensus.phase();
1839  if (mLastConsensusPhase != currPhase)
1840  {
1841  reportConsensusStateChange(currPhase);
1842  mLastConsensusPhase = currPhase;
1843  }
1844 
1845  JLOG(m_journal.debug()) << "Initiating consensus engine";
1846  return true;
1847 }
1848 
1849 bool
1850 NetworkOPsImp::processTrustedProposal(RCLCxPeerPos peerPos)
1851 {
1852  return mConsensus.peerProposal(app_.timeKeeper().closeTime(), peerPos);
1853 }
1854 
1855 void
1856 NetworkOPsImp::mapComplete(std::shared_ptr<SHAMap> const& map, bool fromAcquire)
1857 {
1858  // We now have an additional transaction set
1859  // either created locally during the consensus process
1860  // or acquired from a peer
1861 
1862  // Inform peers we have this set
1863  protocol::TMHaveTransactionSet msg;
1864  msg.set_hash(map->getHash().as_uint256().begin(), 256 / 8);
1865  msg.set_status(protocol::tsHAVE);
1866  app_.overlay().foreach(
1867  send_always(std::make_shared<Message>(msg, protocol::mtHAVE_SET)));
1868 
1869  // We acquired it because consensus asked us to
1870  if (fromAcquire)
1871  mConsensus.gotTxSet(app_.timeKeeper().closeTime(), RCLTxSet{map});
1872 }
1873 
1874 void
1875 NetworkOPsImp::endConsensus()
1876 {
1877  uint256 deadLedger = m_ledgerMaster.getClosedLedger()->info().parentHash;
1878 
1879  for (auto const& it : app_.overlay().getActivePeers())
1880  {
1881  if (it && (it->getClosedLedgerHash() == deadLedger))
1882  {
1883  JLOG(m_journal.trace()) << "Killing obsolete peer status";
1884  it->cycleStatus();
1885  }
1886  }
1887 
1888  uint256 networkClosed;
1889  bool ledgerChange =
1890  checkLastClosedLedger(app_.overlay().getActivePeers(), networkClosed);
1891 
1892  if (networkClosed.isZero())
1893  return;
1894 
1895  // WRITEME: Unless we are in FULL and in the process of doing a consensus,
1896  // we must count how many nodes share our LCL, how many nodes disagree with
1897  // our LCL, and how many validations our LCL has. We also want to check
1898  // timing to make sure there shouldn't be a newer LCL. We need this
1899  // information to do the next three tests.
1900 
1901  if (((mMode == OperatingMode::CONNECTED) ||
1902  (mMode == OperatingMode::SYNCING)) &&
1903  !ledgerChange)
1904  {
1905  // Count number of peers that agree with us and UNL nodes whose
1906  // validations we have for LCL. If the ledger is good enough, go to
1907  // TRACKING - TODO
1908  if (!needNetworkLedger_)
1909  setMode(OperatingMode::TRACKING);
1910  }
1911 
1912  if (((mMode == OperatingMode::CONNECTED) ||
1913  (mMode == OperatingMode::TRACKING)) &&
1914  !ledgerChange)
1915  {
1916  // check if the ledger is good enough to go to FULL
1917  // Note: Do not go to FULL if we don't have the previous ledger
1918  // check if the ledger is bad enough to go to CONNECTE D -- TODO
1919  auto current = m_ledgerMaster.getCurrentLedger();
1920  if (app_.timeKeeper().now() < (current->info().parentCloseTime +
1921  2 * current->info().closeTimeResolution))
1922  {
1923  setMode(OperatingMode::FULL);
1924  }
1925  }
1926 
1927  beginConsensus(networkClosed);
1928 }
1929 
1930 void
1931 NetworkOPsImp::consensusViewChange()
1932 {
1933  if ((mMode == OperatingMode::FULL) || (mMode == OperatingMode::TRACKING))
1934  {
1935  setMode(OperatingMode::CONNECTED);
1936  }
1937 }
1938 
1939 void
1940 NetworkOPsImp::pubManifest(Manifest const& mo)
1941 {
1942  // VFALCO consider std::shared_mutex
1943  std::lock_guard sl(mSubLock);
1944 
1945  if (!mStreamMaps[sManifests].empty())
1946  {
1948 
1949  jvObj[jss::type] = "manifestReceived";
1950  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, mo.masterKey);
1951  if (!mo.signingKey.empty())
1952  jvObj[jss::signing_key] =
1953  toBase58(TokenType::NodePublic, mo.signingKey);
1954  jvObj[jss::seq] = Json::UInt(mo.sequence);
1955  if (auto sig = mo.getSignature())
1956  jvObj[jss::signature] = strHex(*sig);
1957  jvObj[jss::master_signature] = strHex(mo.getMasterSignature());
1958  if (!mo.domain.empty())
1959  jvObj[jss::domain] = mo.domain;
1960  jvObj[jss::manifest] = strHex(mo.serialized);
1961 
1962  for (auto i = mStreamMaps[sManifests].begin();
1963  i != mStreamMaps[sManifests].end();)
1964  {
1965  if (auto p = i->second.lock())
1966  {
1967  p->send(jvObj, true);
1968  ++i;
1969  }
1970  else
1971  {
1972  i = mStreamMaps[sManifests].erase(i);
1973  }
1974  }
1975  }
1976 }
1977 
1978 NetworkOPsImp::ServerFeeSummary::ServerFeeSummary(
1979  XRPAmount fee,
1980  TxQ::Metrics&& escalationMetrics,
1981  LoadFeeTrack const& loadFeeTrack)
1982  : loadFactorServer{loadFeeTrack.getLoadFactor()}
1983  , loadBaseServer{loadFeeTrack.getLoadBase()}
1984  , baseFee{fee}
1985  , em{std::move(escalationMetrics)}
1986 {
1987 }
1988 
1989 bool
1991  NetworkOPsImp::ServerFeeSummary const& b) const
1992 {
1993  if (loadFactorServer != b.loadFactorServer ||
1994  loadBaseServer != b.loadBaseServer || baseFee != b.baseFee ||
1995  em.has_value() != b.em.has_value())
1996  return true;
1997 
1998  if (em && b.em)
1999  {
2000  return (
2001  em->minProcessingFeeLevel != b.em->minProcessingFeeLevel ||
2002  em->openLedgerFeeLevel != b.em->openLedgerFeeLevel ||
2003  em->referenceFeeLevel != b.em->referenceFeeLevel);
2004  }
2005 
2006  return false;
2007 }
2008 
2009 // Need to cap to uint64 to uint32 due to JSON limitations
2010 static std::uint32_t
2012 {
2014 
2015  return std::min(max32, v);
2016 };
2017 
2018 void
2020 {
2021  // VFALCO TODO Don't hold the lock across calls to send...make a copy of the
2022  // list into a local array while holding the lock then release
2023  // the lock and call send on everyone.
2024  //
2026 
2027  if (!mStreamMaps[sServer].empty())
2028  {
2030 
2031  ServerFeeSummary f{
2032  app_.openLedger().current()->fees().base,
2034  app_.getFeeTrack()};
2035 
2036  jvObj[jss::type] = "serverStatus";
2037  jvObj[jss::server_status] = strOperatingMode();
2038  jvObj[jss::load_base] = f.loadBaseServer;
2039  jvObj[jss::load_factor_server] = f.loadFactorServer;
2040  jvObj[jss::base_fee] = f.baseFee.jsonClipped();
2041 
2042  if (f.em)
2043  {
2044  auto const loadFactor = std::max(
2045  safe_cast<std::uint64_t>(f.loadFactorServer),
2046  mulDiv(
2047  f.em->openLedgerFeeLevel,
2048  f.loadBaseServer,
2049  f.em->referenceFeeLevel)
2050  .second);
2051 
2052  jvObj[jss::load_factor] = trunc32(loadFactor);
2053  jvObj[jss::load_factor_fee_escalation] =
2054  f.em->openLedgerFeeLevel.jsonClipped();
2055  jvObj[jss::load_factor_fee_queue] =
2056  f.em->minProcessingFeeLevel.jsonClipped();
2057  jvObj[jss::load_factor_fee_reference] =
2058  f.em->referenceFeeLevel.jsonClipped();
2059  }
2060  else
2061  jvObj[jss::load_factor] = f.loadFactorServer;
2062 
2063  mLastFeeSummary = f;
2064 
2065  for (auto i = mStreamMaps[sServer].begin();
2066  i != mStreamMaps[sServer].end();)
2067  {
2068  InfoSub::pointer p = i->second.lock();
2069 
2070  // VFALCO TODO research the possibility of using thread queues and
2071  // linearizing the deletion of subscribers with the
2072  // sending of JSON data.
2073  if (p)
2074  {
2075  p->send(jvObj, true);
2076  ++i;
2077  }
2078  else
2079  {
2080  i = mStreamMaps[sServer].erase(i);
2081  }
2082  }
2083  }
2084 }
2085 
2086 void
2088 {
2090 
2091  auto& streamMap = mStreamMaps[sConsensusPhase];
2092  if (!streamMap.empty())
2093  {
2095  jvObj[jss::type] = "consensusPhase";
2096  jvObj[jss::consensus] = to_string(phase);
2097 
2098  for (auto i = streamMap.begin(); i != streamMap.end();)
2099  {
2100  if (auto p = i->second.lock())
2101  {
2102  p->send(jvObj, true);
2103  ++i;
2104  }
2105  else
2106  {
2107  i = streamMap.erase(i);
2108  }
2109  }
2110  }
2111 }
2112 
2113 void
2115 {
2116  // VFALCO consider std::shared_mutex
2118 
2119  if (!mStreamMaps[sValidations].empty())
2120  {
2122 
2123  auto const signerPublic = val->getSignerPublic();
2124 
2125  jvObj[jss::type] = "validationReceived";
2126  jvObj[jss::validation_public_key] =
2127  toBase58(TokenType::NodePublic, signerPublic);
2128  jvObj[jss::ledger_hash] = to_string(val->getLedgerHash());
2129  jvObj[jss::signature] = strHex(val->getSignature());
2130  jvObj[jss::full] = val->isFull();
2131  jvObj[jss::flags] = val->getFlags();
2132  jvObj[jss::signing_time] = *(*val)[~sfSigningTime];
2133  jvObj[jss::data] = strHex(val->getSerializer().slice());
2134 
2135  if (auto version = (*val)[~sfServerVersion])
2136  jvObj[jss::server_version] = std::to_string(*version);
2137 
2138  if (auto cookie = (*val)[~sfCookie])
2139  jvObj[jss::cookie] = std::to_string(*cookie);
2140 
2141  if (auto hash = (*val)[~sfValidatedHash])
2142  jvObj[jss::validated_hash] = strHex(*hash);
2143 
2144  auto const masterKey =
2145  app_.validatorManifests().getMasterKey(signerPublic);
2146 
2147  if (masterKey != signerPublic)
2148  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, masterKey);
2149 
2150  if (auto const seq = (*val)[~sfLedgerSequence])
2151  jvObj[jss::ledger_index] = to_string(*seq);
2152 
2153  if (val->isFieldPresent(sfAmendments))
2154  {
2155  jvObj[jss::amendments] = Json::Value(Json::arrayValue);
2156  for (auto const& amendment : val->getFieldV256(sfAmendments))
2157  jvObj[jss::amendments].append(to_string(amendment));
2158  }
2159 
2160  if (auto const closeTime = (*val)[~sfCloseTime])
2161  jvObj[jss::close_time] = *closeTime;
2162 
2163  if (auto const loadFee = (*val)[~sfLoadFee])
2164  jvObj[jss::load_fee] = *loadFee;
2165 
2166  if (auto const baseFee = (*val)[~sfBaseFee])
2167  jvObj[jss::base_fee] = static_cast<double>(*baseFee);
2168 
2169  if (auto const reserveBase = (*val)[~sfReserveBase])
2170  jvObj[jss::reserve_base] = *reserveBase;
2171 
2172  if (auto const reserveInc = (*val)[~sfReserveIncrement])
2173  jvObj[jss::reserve_inc] = *reserveInc;
2174 
2175  for (auto i = mStreamMaps[sValidations].begin();
2176  i != mStreamMaps[sValidations].end();)
2177  {
2178  if (auto p = i->second.lock())
2179  {
2180  p->send(jvObj, true);
2181  ++i;
2182  }
2183  else
2184  {
2185  i = mStreamMaps[sValidations].erase(i);
2186  }
2187  }
2188  }
2189 }
2190 
2191 void
2193 {
2195 
2196  if (!mStreamMaps[sPeerStatus].empty())
2197  {
2198  Json::Value jvObj(func());
2199 
2200  jvObj[jss::type] = "peerStatusChange";
2201 
2202  for (auto i = mStreamMaps[sPeerStatus].begin();
2203  i != mStreamMaps[sPeerStatus].end();)
2204  {
2205  InfoSub::pointer p = i->second.lock();
2206 
2207  if (p)
2208  {
2209  p->send(jvObj, true);
2210  ++i;
2211  }
2212  else
2213  {
2214  i = mStreamMaps[sPeerStatus].erase(i);
2215  }
2216  }
2217  }
2218 }
2219 
2220 void
2222 {
2223  using namespace std::chrono_literals;
2224  if (om == OperatingMode::CONNECTED)
2225  {
2228  }
2229  else if (om == OperatingMode::SYNCING)
2230  {
2231  if (app_.getLedgerMaster().getValidatedLedgerAge() >= 1min)
2233  }
2234 
2235  if ((om > OperatingMode::CONNECTED) && isBlocked())
2237 
2238  if (mMode == om)
2239  return;
2240 
2241  mMode = om;
2242 
2243  accounting_.mode(om);
2244 
2245  JLOG(m_journal.info()) << "STATE->" << strOperatingMode();
2246  pubServer();
2247 }
2248 
2249 bool
2251  std::shared_ptr<STValidation> const& val,
2252  std::string const& source)
2253 {
2254  JLOG(m_journal.trace())
2255  << "recvValidation " << val->getLedgerHash() << " from " << source;
2256 
2257  handleNewValidation(app_, val, source);
2258 
2259  pubValidation(val);
2260 
2261  // We will always relay trusted validations; if configured, we will
2262  // also relay all untrusted validations.
2263  return app_.config().RELAY_UNTRUSTED_VALIDATIONS == 1 || val->isTrusted();
2264 }
2265 
2268 {
2269  return mConsensus.getJson(true);
2270 }
2271 
2273 NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
2274 {
2276 
2277  // System-level warnings
2278  {
2279  Json::Value warnings{Json::arrayValue};
2280  if (isAmendmentBlocked())
2281  {
2282  Json::Value& w = warnings.append(Json::objectValue);
2283  w[jss::id] = warnRPC_AMENDMENT_BLOCKED;
2284  w[jss::message] =
2285  "This server is amendment blocked, and must be updated to be "
2286  "able to stay in sync with the network.";
2287  }
2288  if (isUNLBlocked())
2289  {
2290  Json::Value& w = warnings.append(Json::objectValue);
2291  w[jss::id] = warnRPC_EXPIRED_VALIDATOR_LIST;
2292  w[jss::message] =
2293  "This server has an expired validator list. validators.txt "
2294  "may be incorrectly configured or some [validator_list_sites] "
2295  "may be unreachable.";
2296  }
2297  if (admin && isAmendmentWarned())
2298  {
2299  Json::Value& w = warnings.append(Json::objectValue);
2300  w[jss::id] = warnRPC_UNSUPPORTED_MAJORITY;
2301  w[jss::message] =
2302  "One or more unsupported amendments have reached majority. "
2303  "Upgrade to the latest version before they are activated "
2304  "to avoid being amendment blocked.";
2305  if (auto const expected =
2307  {
2308  auto& d = w[jss::details] = Json::objectValue;
2309  d[jss::expected_date] = expected->time_since_epoch().count();
2310  d[jss::expected_date_UTC] = to_string(*expected);
2311  }
2312  }
2313 
2314  if (warnings.size())
2315  info[jss::warnings] = std::move(warnings);
2316  }
2317 
2318  // hostid: unique string describing the machine
2319  if (human)
2320  info[jss::hostid] = getHostId(admin);
2321 
2322  // domain: if configured with a domain, report it:
2323  if (!app_.config().SERVER_DOMAIN.empty())
2324  info[jss::server_domain] = app_.config().SERVER_DOMAIN;
2325 
2326  if (!app_.config().reporting())
2327  if (auto const netid = app_.overlay().networkID())
2328  info[jss::network_id] = static_cast<Json::UInt>(*netid);
2329 
2330  info[jss::build_version] = BuildInfo::getVersionString();
2331 
2332  info[jss::server_state] = strOperatingMode(admin);
2333 
2334  info[jss::time] = to_string(std::chrono::floor<std::chrono::microseconds>(
2336 
2337  if (needNetworkLedger_)
2338  info[jss::network_ledger] = "waiting";
2339 
2340  info[jss::validation_quorum] =
2341  static_cast<Json::UInt>(app_.validators().quorum());
2342 
2343  if (admin)
2344  {
2345  switch (app_.config().NODE_SIZE)
2346  {
2347  case 0:
2348  info[jss::node_size] = "tiny";
2349  break;
2350  case 1:
2351  info[jss::node_size] = "small";
2352  break;
2353  case 2:
2354  info[jss::node_size] = "medium";
2355  break;
2356  case 3:
2357  info[jss::node_size] = "large";
2358  break;
2359  case 4:
2360  info[jss::node_size] = "huge";
2361  break;
2362  }
2363 
2364  auto when = app_.validators().expires();
2365 
2366  if (!human)
2367  {
2368  if (when)
2369  info[jss::validator_list_expires] =
2370  safe_cast<Json::UInt>(when->time_since_epoch().count());
2371  else
2372  info[jss::validator_list_expires] = 0;
2373  }
2374  else
2375  {
2376  auto& x = (info[jss::validator_list] = Json::objectValue);
2377 
2378  x[jss::count] = static_cast<Json::UInt>(app_.validators().count());
2379 
2380  if (when)
2381  {
2382  if (*when == TimeKeeper::time_point::max())
2383  {
2384  x[jss::expiration] = "never";
2385  x[jss::status] = "active";
2386  }
2387  else
2388  {
2389  x[jss::expiration] = to_string(*when);
2390 
2391  if (*when > app_.timeKeeper().now())
2392  x[jss::status] = "active";
2393  else
2394  x[jss::status] = "expired";
2395  }
2396  }
2397  else
2398  {
2399  x[jss::status] = "unknown";
2400  x[jss::expiration] = "unknown";
2401  }
2402  }
2403  }
2404  info[jss::io_latency_ms] =
2405  static_cast<Json::UInt>(app_.getIOLatency().count());
2406 
2407  if (admin)
2408  {
2410  {
2411  info[jss::pubkey_validator] = toBase58(
2413  }
2414  else
2415  {
2416  info[jss::pubkey_validator] = "none";
2417  }
2418  }
2419 
2420  if (counters)
2421  {
2422  info[jss::counters] = app_.getPerfLog().countersJson();
2423 
2424  Json::Value nodestore(Json::objectValue);
2425  if (app_.getShardStore())
2426  app_.getShardStore()->getCountsJson(nodestore);
2427  else
2428  app_.getNodeStore().getCountsJson(nodestore);
2429  info[jss::counters][jss::nodestore] = nodestore;
2430  info[jss::current_activities] = app_.getPerfLog().currentJson();
2431  }
2432 
2433  info[jss::pubkey_node] =
2435 
2436  info[jss::complete_ledgers] = app_.getLedgerMaster().getCompleteLedgers();
2437 
2438  if (amendmentBlocked_)
2439  info[jss::amendment_blocked] = true;
2440 
2441  auto const fp = m_ledgerMaster.getFetchPackCacheSize();
2442 
2443  if (fp != 0)
2444  info[jss::fetch_pack] = Json::UInt(fp);
2445 
2446  if (!app_.config().reporting())
2447  info[jss::peers] = Json::UInt(app_.overlay().size());
2448 
2449  Json::Value lastClose = Json::objectValue;
2450  lastClose[jss::proposers] = Json::UInt(mConsensus.prevProposers());
2451 
2452  if (human)
2453  {
2454  lastClose[jss::converge_time_s] =
2456  }
2457  else
2458  {
2459  lastClose[jss::converge_time] =
2461  }
2462 
2463  info[jss::last_close] = lastClose;
2464 
2465  // info[jss::consensus] = mConsensus.getJson();
2466 
2467  if (admin)
2468  info[jss::load] = m_job_queue.getJson();
2469 
2470  if (!app_.config().reporting())
2471  {
2472  auto const escalationMetrics =
2474 
2475  auto const loadFactorServer = app_.getFeeTrack().getLoadFactor();
2476  auto const loadBaseServer = app_.getFeeTrack().getLoadBase();
2477  /* Scale the escalated fee level to unitless "load factor".
2478  In practice, this just strips the units, but it will continue
2479  to work correctly if either base value ever changes. */
2480  auto const loadFactorFeeEscalation =
2481  mulDiv(
2482  escalationMetrics.openLedgerFeeLevel,
2483  loadBaseServer,
2484  escalationMetrics.referenceFeeLevel)
2485  .second;
2486 
2487  auto const loadFactor = std::max(
2488  safe_cast<std::uint64_t>(loadFactorServer),
2489  loadFactorFeeEscalation);
2490 
2491  if (!human)
2492  {
2493  info[jss::load_base] = loadBaseServer;
2494  info[jss::load_factor] = trunc32(loadFactor);
2495  info[jss::load_factor_server] = loadFactorServer;
2496 
2497  /* Json::Value doesn't support uint64, so clamp to max
2498  uint32 value. This is mostly theoretical, since there
2499  probably isn't enough extant XRP to drive the factor
2500  that high.
2501  */
2502  info[jss::load_factor_fee_escalation] =
2503  escalationMetrics.openLedgerFeeLevel.jsonClipped();
2504  info[jss::load_factor_fee_queue] =
2505  escalationMetrics.minProcessingFeeLevel.jsonClipped();
2506  info[jss::load_factor_fee_reference] =
2507  escalationMetrics.referenceFeeLevel.jsonClipped();
2508  }
2509  else
2510  {
2511  info[jss::load_factor] =
2512  static_cast<double>(loadFactor) / loadBaseServer;
2513 
2514  if (loadFactorServer != loadFactor)
2515  info[jss::load_factor_server] =
2516  static_cast<double>(loadFactorServer) / loadBaseServer;
2517 
2518  if (admin)
2519  {
2521  if (fee != loadBaseServer)
2522  info[jss::load_factor_local] =
2523  static_cast<double>(fee) / loadBaseServer;
2524  fee = app_.getFeeTrack().getRemoteFee();
2525  if (fee != loadBaseServer)
2526  info[jss::load_factor_net] =
2527  static_cast<double>(fee) / loadBaseServer;
2528  fee = app_.getFeeTrack().getClusterFee();
2529  if (fee != loadBaseServer)
2530  info[jss::load_factor_cluster] =
2531  static_cast<double>(fee) / loadBaseServer;
2532  }
2533  if (escalationMetrics.openLedgerFeeLevel !=
2534  escalationMetrics.referenceFeeLevel &&
2535  (admin || loadFactorFeeEscalation != loadFactor))
2536  info[jss::load_factor_fee_escalation] =
2537  escalationMetrics.openLedgerFeeLevel.decimalFromReference(
2538  escalationMetrics.referenceFeeLevel);
2539  if (escalationMetrics.minProcessingFeeLevel !=
2540  escalationMetrics.referenceFeeLevel)
2541  info[jss::load_factor_fee_queue] =
2542  escalationMetrics.minProcessingFeeLevel
2543  .decimalFromReference(
2544  escalationMetrics.referenceFeeLevel);
2545  }
2546  }
2547 
2548  bool valid = false;
2549  auto lpClosed = m_ledgerMaster.getValidatedLedger();
2550 
2551  if (lpClosed)
2552  valid = true;
2553  else if (!app_.config().reporting())
2554  lpClosed = m_ledgerMaster.getClosedLedger();
2555 
2556  if (lpClosed)
2557  {
2558  XRPAmount const baseFee = lpClosed->fees().base;
2560  l[jss::seq] = Json::UInt(lpClosed->info().seq);
2561  l[jss::hash] = to_string(lpClosed->info().hash);
2562 
2563  if (!human)
2564  {
2565  l[jss::base_fee] = baseFee.jsonClipped();
2566  l[jss::reserve_base] =
2567  lpClosed->fees().accountReserve(0).jsonClipped();
2568  l[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
2569  l[jss::close_time] = Json::Value::UInt(
2570  lpClosed->info().closeTime.time_since_epoch().count());
2571  }
2572  else
2573  {
2574  l[jss::base_fee_xrp] = baseFee.decimalXRP();
2575  l[jss::reserve_base_xrp] =
2576  lpClosed->fees().accountReserve(0).decimalXRP();
2577  l[jss::reserve_inc_xrp] = lpClosed->fees().increment.decimalXRP();
2578 
2579  auto const nowOffset = app_.timeKeeper().nowOffset();
2580  if (std::abs(nowOffset.count()) >= 60)
2581  l[jss::system_time_offset] = nowOffset.count();
2582 
2583  auto const closeOffset = app_.timeKeeper().closeOffset();
2584  if (std::abs(closeOffset.count()) >= 60)
2585  l[jss::close_time_offset] = closeOffset.count();
2586 
2587 #if RIPPLED_REPORTING
2588  std::int64_t const dbAge =
2590  l[jss::age] = Json::UInt(dbAge);
2591 #else
2592  constexpr std::chrono::seconds highAgeThreshold{1000000};
2594  {
2595  auto const age = m_ledgerMaster.getValidatedLedgerAge();
2596  l[jss::age] =
2597  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2598  }
2599  else
2600  {
2601  auto lCloseTime = lpClosed->info().closeTime;
2602  auto closeTime = app_.timeKeeper().closeTime();
2603  if (lCloseTime <= closeTime)
2604  {
2605  using namespace std::chrono_literals;
2606  auto age = closeTime - lCloseTime;
2607  l[jss::age] =
2608  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2609  }
2610  }
2611 #endif
2612  }
2613 
2614  if (valid)
2615  info[jss::validated_ledger] = l;
2616  else
2617  info[jss::closed_ledger] = l;
2618 
2619  auto lpPublished = m_ledgerMaster.getPublishedLedger();
2620  if (!lpPublished)
2621  info[jss::published_ledger] = "none";
2622  else if (lpPublished->info().seq != lpClosed->info().seq)
2623  info[jss::published_ledger] = lpPublished->info().seq;
2624  }
2625 
2626  accounting_.json(info);
2627  info[jss::uptime] = UptimeClock::now().time_since_epoch().count();
2628  if (!app_.config().reporting())
2629  {
2630  info[jss::jq_trans_overflow] =
2632  info[jss::peer_disconnects] =
2634  info[jss::peer_disconnects_resources] =
2636  }
2637  else
2638  {
2639  info["reporting"] = app_.getReportingETL().getInfo();
2640  }
2641 
2642  return info;
2643 }
2644 
2645 void
2647 {
2649 }
2650 
2653 {
2654  return app_.getInboundLedgers().getInfo();
2655 }
2656 
2657 void
2659  std::shared_ptr<ReadView const> const& ledger,
2660  std::shared_ptr<STTx const> const& transaction,
2661  TER result)
2662 {
2663  Json::Value jvObj = transJson(*transaction, result, false, ledger);
2664 
2665  {
2667 
2668  auto it = mStreamMaps[sRTTransactions].begin();
2669  while (it != mStreamMaps[sRTTransactions].end())
2670  {
2671  InfoSub::pointer p = it->second.lock();
2672 
2673  if (p)
2674  {
2675  p->send(jvObj, true);
2676  ++it;
2677  }
2678  else
2679  {
2680  it = mStreamMaps[sRTTransactions].erase(it);
2681  }
2682  }
2683  }
2684 
2685  pubProposedAccountTransaction(ledger, transaction, result);
2686 }
2687 
2688 void
2690 {
2691  // reporting does not forward validated transactions
2692  // validated transactions will be published to the proper streams when the
2693  // etl process writes a validated ledger
2694  if (jvObj[jss::validated].asBool())
2695  return;
2696  {
2698 
2699  auto it = mStreamMaps[sRTTransactions].begin();
2700  while (it != mStreamMaps[sRTTransactions].end())
2701  {
2702  InfoSub::pointer p = it->second.lock();
2703 
2704  if (p)
2705  {
2706  p->send(jvObj, true);
2707  ++it;
2708  }
2709  else
2710  {
2711  it = mStreamMaps[sRTTransactions].erase(it);
2712  }
2713  }
2714  }
2715 
2717 }
2718 
2719 void
2721 {
2723 
2724  for (auto i = mStreamMaps[sValidations].begin();
2725  i != mStreamMaps[sValidations].end();)
2726  {
2727  if (auto p = i->second.lock())
2728  {
2729  p->send(jvObj, true);
2730  ++i;
2731  }
2732  else
2733  {
2734  i = mStreamMaps[sValidations].erase(i);
2735  }
2736  }
2737 }
2738 
2739 void
2741 {
2743 
2744  for (auto i = mStreamMaps[sManifests].begin();
2745  i != mStreamMaps[sManifests].end();)
2746  {
2747  if (auto p = i->second.lock())
2748  {
2749  p->send(jvObj, true);
2750  ++i;
2751  }
2752  else
2753  {
2754  i = mStreamMaps[sManifests].erase(i);
2755  }
2756  }
2757 }
2758 
2759 static void
2761 {
2762  for (auto& jv : jvObj)
2763  {
2764  if (jv.isObject())
2765  {
2766  getAccounts(jv, accounts);
2767  }
2768  else if (jv.isString())
2769  {
2770  auto account = RPC::accountFromStringStrict(jv.asString());
2771  if (account)
2772  accounts.push_back(*account);
2773  }
2774  }
2775 }
2776 
2777 void
2779 {
2781  int iProposed = 0;
2782  // check if there are any subscribers before attempting to parse the JSON
2783  {
2785 
2786  if (mSubRTAccount.empty())
2787  return;
2788  }
2789 
2790  // parse the JSON outside of the lock
2791  std::vector<AccountID> accounts;
2792  if (jvObj.isMember(jss::transaction))
2793  {
2794  try
2795  {
2796  getAccounts(jvObj[jss::transaction], accounts);
2797  }
2798  catch (...)
2799  {
2800  JLOG(m_journal.debug())
2801  << __func__ << " : "
2802  << "error parsing json for accounts affected";
2803  return;
2804  }
2805  }
2806  {
2808 
2809  if (!mSubRTAccount.empty())
2810  {
2811  for (auto const& affectedAccount : accounts)
2812  {
2813  auto simiIt = mSubRTAccount.find(affectedAccount);
2814  if (simiIt != mSubRTAccount.end())
2815  {
2816  auto it = simiIt->second.begin();
2817 
2818  while (it != simiIt->second.end())
2819  {
2820  InfoSub::pointer p = it->second.lock();
2821 
2822  if (p)
2823  {
2824  notify.insert(p);
2825  ++it;
2826  ++iProposed;
2827  }
2828  else
2829  it = simiIt->second.erase(it);
2830  }
2831  }
2832  }
2833  }
2834  }
2835  JLOG(m_journal.trace()) << "forwardProposedAccountTransaction:"
2836  << " iProposed=" << iProposed;
2837 
2838  if (!notify.empty())
2839  {
2840  for (InfoSub::ref isrListener : notify)
2841  isrListener->send(jvObj, true);
2842  }
2843 }
2844 
2845 void
2847 {
2848  // Ledgers are published only when they acquire sufficient validations
2849  // Holes are filled across connection loss or other catastrophe
2850 
2851  std::shared_ptr<AcceptedLedger> alpAccepted =
2852  app_.getAcceptedLedgerCache().fetch(lpAccepted->info().hash);
2853  if (!alpAccepted)
2854  {
2855  alpAccepted = std::make_shared<AcceptedLedger>(lpAccepted, app_);
2856  app_.getAcceptedLedgerCache().canonicalize_replace_client(
2857  lpAccepted->info().hash, alpAccepted);
2858  }
2859 
2860  assert(alpAccepted->getLedger().get() == lpAccepted.get());
2861 
2862  {
2863  JLOG(m_journal.debug())
2864  << "Publishing ledger " << lpAccepted->info().seq << " "
2865  << lpAccepted->info().hash;
2866 
2868 
2869  if (!mStreamMaps[sLedger].empty())
2870  {
2872 
2873  jvObj[jss::type] = "ledgerClosed";
2874  jvObj[jss::ledger_index] = lpAccepted->info().seq;
2875  jvObj[jss::ledger_hash] = to_string(lpAccepted->info().hash);
2876  jvObj[jss::ledger_time] = Json::Value::UInt(
2877  lpAccepted->info().closeTime.time_since_epoch().count());
2878 
2879  jvObj[jss::fee_ref] = lpAccepted->fees().units.jsonClipped();
2880  jvObj[jss::fee_base] = lpAccepted->fees().base.jsonClipped();
2881  jvObj[jss::reserve_base] =
2882  lpAccepted->fees().accountReserve(0).jsonClipped();
2883  jvObj[jss::reserve_inc] =
2884  lpAccepted->fees().increment.jsonClipped();
2885 
2886  jvObj[jss::txn_count] = Json::UInt(alpAccepted->size());
2887 
2889  {
2890  jvObj[jss::validated_ledgers] =
2892  }
2893 
2894  auto it = mStreamMaps[sLedger].begin();
2895  while (it != mStreamMaps[sLedger].end())
2896  {
2897  InfoSub::pointer p = it->second.lock();
2898  if (p)
2899  {
2900  p->send(jvObj, true);
2901  ++it;
2902  }
2903  else
2904  it = mStreamMaps[sLedger].erase(it);
2905  }
2906  }
2907 
2908  if (!mStreamMaps[sBookChanges].empty())
2909  {
2910  Json::Value jvObj = ripple::RPC::computeBookChanges(lpAccepted);
2911 
2912  auto it = mStreamMaps[sBookChanges].begin();
2913  while (it != mStreamMaps[sBookChanges].end())
2914  {
2915  InfoSub::pointer p = it->second.lock();
2916  if (p)
2917  {
2918  p->send(jvObj, true);
2919  ++it;
2920  }
2921  else
2922  it = mStreamMaps[sBookChanges].erase(it);
2923  }
2924  }
2925 
2926  {
2927  static bool firstTime = true;
2928  if (firstTime)
2929  {
2930  // First validated ledger, start delayed SubAccountHistory
2931  firstTime = false;
2932  for (auto& outer : mSubAccountHistory)
2933  {
2934  for (auto& inner : outer.second)
2935  {
2936  auto& subInfo = inner.second;
2937  if (subInfo.index_->separationLedgerSeq_ == 0)
2938  {
2940  alpAccepted->getLedger(), subInfo);
2941  }
2942  }
2943  }
2944  }
2945  }
2946  }
2947 
2948  // Don't lock since pubAcceptedTransaction is locking.
2949  for (auto const& accTx : *alpAccepted)
2950  {
2951  JLOG(m_journal.trace()) << "pubAccepted: " << accTx->getJson();
2952  pubValidatedTransaction(lpAccepted, *accTx);
2953  }
2954 }
2955 
2956 void
2958 {
2959  if (app_.config().reporting())
2960  return;
2961  ServerFeeSummary f{
2962  app_.openLedger().current()->fees().base,
2964  app_.getFeeTrack()};
2965 
2966  // only schedule the job if something has changed
2967  if (f != mLastFeeSummary)
2968  {
2970  jtCLIENT_FEE_CHANGE, "reportFeeChange->pubServer", [this]() {
2971  pubServer();
2972  });
2973  }
2974 }
2975 
2976 void
2978 {
2981  "reportConsensusStateChange->pubConsensus",
2982  [this, phase]() { pubConsensus(phase); });
2983 }
2984 
2985 inline void
2987 {
2988  m_localTX->sweep(view);
2989 }
2990 inline std::size_t
2992 {
2993  return m_localTX->size();
2994 }
2995 
2996 // This routine should only be used to publish accepted or validated
2997 // transactions.
3000  const STTx& transaction,
3001  TER result,
3002  bool validated,
3003  std::shared_ptr<ReadView const> const& ledger)
3004 {
3006  std::string sToken;
3007  std::string sHuman;
3008 
3009  transResultInfo(result, sToken, sHuman);
3010 
3011  jvObj[jss::type] = "transaction";
3012  jvObj[jss::transaction] = transaction.getJson(JsonOptions::none);
3013 
3014  if (validated)
3015  {
3016  jvObj[jss::ledger_index] = ledger->info().seq;
3017  jvObj[jss::ledger_hash] = to_string(ledger->info().hash);
3018  jvObj[jss::transaction][jss::date] =
3019  ledger->info().closeTime.time_since_epoch().count();
3020  jvObj[jss::validated] = true;
3021 
3022  // WRITEME: Put the account next seq here
3023  }
3024  else
3025  {
3026  jvObj[jss::validated] = false;
3027  jvObj[jss::ledger_current_index] = ledger->info().seq;
3028  }
3029 
3030  jvObj[jss::status] = validated ? "closed" : "proposed";
3031  jvObj[jss::engine_result] = sToken;
3032  jvObj[jss::engine_result_code] = result;
3033  jvObj[jss::engine_result_message] = sHuman;
3034 
3035  if (transaction.getTxnType() == ttOFFER_CREATE)
3036  {
3037  auto const account = transaction.getAccountID(sfAccount);
3038  auto const amount = transaction.getFieldAmount(sfTakerGets);
3039 
3040  // If the offer create is not self funded then add the owner balance
3041  if (account != amount.issue().account)
3042  {
3043  auto const ownerFunds = accountFunds(
3044  *ledger,
3045  account,
3046  amount,
3048  app_.journal("View"));
3049  jvObj[jss::transaction][jss::owner_funds] = ownerFunds.getText();
3050  }
3051  }
3052 
3053  return jvObj;
3054 }
3055 
3056 void
3058  std::shared_ptr<ReadView const> const& ledger,
3059  const AcceptedLedgerTx& transaction)
3060 {
3061  auto const& stTxn = transaction.getTxn();
3062 
3063  Json::Value jvObj =
3064  transJson(*stTxn, transaction.getResult(), true, ledger);
3065 
3066  {
3067  auto const& meta = transaction.getMeta();
3068  jvObj[jss::meta] = meta.getJson(JsonOptions::none);
3069  RPC::insertDeliveredAmount(jvObj[jss::meta], *ledger, stTxn, meta);
3070  }
3071 
3072  {
3074 
3075  auto it = mStreamMaps[sTransactions].begin();
3076  while (it != mStreamMaps[sTransactions].end())
3077  {
3078  InfoSub::pointer p = it->second.lock();
3079 
3080  if (p)
3081  {
3082  p->send(jvObj, true);
3083  ++it;
3084  }
3085  else
3086  it = mStreamMaps[sTransactions].erase(it);
3087  }
3088 
3089  it = mStreamMaps[sRTTransactions].begin();
3090 
3091  while (it != mStreamMaps[sRTTransactions].end())
3092  {
3093  InfoSub::pointer p = it->second.lock();
3094 
3095  if (p)
3096  {
3097  p->send(jvObj, true);
3098  ++it;
3099  }
3100  else
3101  it = mStreamMaps[sRTTransactions].erase(it);
3102  }
3103  }
3104 
3105  if (transaction.getResult() == tesSUCCESS)
3106  app_.getOrderBookDB().processTxn(ledger, transaction, jvObj);
3107 
3108  pubAccountTransaction(ledger, transaction);
3109 }
3110 
3111 void
3113  std::shared_ptr<ReadView const> const& ledger,
3114  AcceptedLedgerTx const& transaction)
3115 {
3117  int iProposed = 0;
3118  int iAccepted = 0;
3119 
3120  std::vector<SubAccountHistoryInfo> accountHistoryNotify;
3121  auto const currLedgerSeq = ledger->seq();
3122  {
3124 
3125  if (!mSubAccount.empty() || !mSubRTAccount.empty() ||
3127  {
3128  for (auto const& affectedAccount : transaction.getAffected())
3129  {
3130  if (auto simiIt = mSubRTAccount.find(affectedAccount);
3131  simiIt != mSubRTAccount.end())
3132  {
3133  auto it = simiIt->second.begin();
3134 
3135  while (it != simiIt->second.end())
3136  {
3137  InfoSub::pointer p = it->second.lock();
3138 
3139  if (p)
3140  {
3141  notify.insert(p);
3142  ++it;
3143  ++iProposed;
3144  }
3145  else
3146  it = simiIt->second.erase(it);
3147  }
3148  }
3149 
3150  if (auto simiIt = mSubAccount.find(affectedAccount);
3151  simiIt != mSubAccount.end())
3152  {
3153  auto it = simiIt->second.begin();
3154  while (it != simiIt->second.end())
3155  {
3156  InfoSub::pointer p = it->second.lock();
3157 
3158  if (p)
3159  {
3160  notify.insert(p);
3161  ++it;
3162  ++iAccepted;
3163  }
3164  else
3165  it = simiIt->second.erase(it);
3166  }
3167  }
3168 
3169  if (auto histoIt = mSubAccountHistory.find(affectedAccount);
3170  histoIt != mSubAccountHistory.end())
3171  {
3172  auto& subs = histoIt->second;
3173  auto it = subs.begin();
3174  while (it != subs.end())
3175  {
3176  SubAccountHistoryInfoWeak const& info = it->second;
3177  if (currLedgerSeq <= info.index_->separationLedgerSeq_)
3178  {
3179  ++it;
3180  continue;
3181  }
3182 
3183  if (auto isSptr = info.sinkWptr_.lock(); isSptr)
3184  {
3185  accountHistoryNotify.emplace_back(
3186  SubAccountHistoryInfo{isSptr, info.index_});
3187  ++it;
3188  }
3189  else
3190  {
3191  it = subs.erase(it);
3192  }
3193  }
3194  if (subs.empty())
3195  mSubAccountHistory.erase(histoIt);
3196  }
3197  }
3198  }
3199  }
3200 
3201  JLOG(m_journal.trace())
3202  << "pubAccountTransaction: "
3203  << "proposed=" << iProposed << ", accepted=" << iAccepted;
3204 
3205  if (!notify.empty() || !accountHistoryNotify.empty())
3206  {
3207  auto const& stTxn = transaction.getTxn();
3208 
3209  Json::Value jvObj =
3210  transJson(*stTxn, transaction.getResult(), true, ledger);
3211 
3212  {
3213  auto const& meta = transaction.getMeta();
3214 
3215  jvObj[jss::meta] = meta.getJson(JsonOptions::none);
3216  RPC::insertDeliveredAmount(jvObj[jss::meta], *ledger, stTxn, meta);
3217  }
3218 
3219  for (InfoSub::ref isrListener : notify)
3220  isrListener->send(jvObj, true);
3221 
3222  assert(!jvObj.isMember(jss::account_history_tx_stream));
3223  for (auto& info : accountHistoryNotify)
3224  {
3225  auto& index = info.index_;
3226  if (index->forwardTxIndex_ == 0 && !index->haveHistorical_)
3227  jvObj[jss::account_history_tx_first] = true;
3228  jvObj[jss::account_history_tx_index] = index->forwardTxIndex_++;
3229  info.sink_->send(jvObj, true);
3230  }
3231  }
3232 }
3233 
3234 void
3236  std::shared_ptr<ReadView const> const& ledger,
3237  std::shared_ptr<STTx const> const& tx,
3238  TER result)
3239 {
3241  int iProposed = 0;
3242 
3243  std::vector<SubAccountHistoryInfo> accountHistoryNotify;
3244 
3245  {
3247 
3248  if (mSubRTAccount.empty())
3249  return;
3250 
3251  if (!mSubAccount.empty() || !mSubRTAccount.empty() ||
3253  {
3254  for (auto const& affectedAccount : tx->getMentionedAccounts())
3255  {
3256  if (auto simiIt = mSubRTAccount.find(affectedAccount);
3257  simiIt != mSubRTAccount.end())
3258  {
3259  auto it = simiIt->second.begin();
3260 
3261  while (it != simiIt->second.end())
3262  {
3263  InfoSub::pointer p = it->second.lock();
3264 
3265  if (p)
3266  {
3267  notify.insert(p);
3268  ++it;
3269  ++iProposed;
3270  }
3271  else
3272  it = simiIt->second.erase(it);
3273  }
3274  }
3275  }
3276  }
3277  }
3278 
3279  JLOG(m_journal.trace()) << "pubProposedAccountTransaction: " << iProposed;
3280 
3281  if (!notify.empty() || !accountHistoryNotify.empty())
3282  {
3283  Json::Value jvObj = transJson(*tx, result, false, ledger);
3284 
3285  for (InfoSub::ref isrListener : notify)
3286  isrListener->send(jvObj, true);
3287 
3288  assert(!jvObj.isMember(jss::account_history_tx_stream));
3289  for (auto& info : accountHistoryNotify)
3290  {
3291  auto& index = info.index_;
3292  if (index->forwardTxIndex_ == 0 && !index->haveHistorical_)
3293  jvObj[jss::account_history_tx_first] = true;
3294  jvObj[jss::account_history_tx_index] = index->forwardTxIndex_++;
3295  info.sink_->send(jvObj, true);
3296  }
3297  }
3298 }
3299 
3300 //
3301 // Monitoring
3302 //
3303 
3304 void
3306  InfoSub::ref isrListener,
3307  hash_set<AccountID> const& vnaAccountIDs,
3308  bool rt)
3309 {
3310  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3311 
3312  for (auto const& naAccountID : vnaAccountIDs)
3313  {
3314  JLOG(m_journal.trace())
3315  << "subAccount: account: " << toBase58(naAccountID);
3316 
3317  isrListener->insertSubAccountInfo(naAccountID, rt);
3318  }
3319 
3321 
3322  for (auto const& naAccountID : vnaAccountIDs)
3323  {
3324  auto simIterator = subMap.find(naAccountID);
3325  if (simIterator == subMap.end())
3326  {
3327  // Not found, note that account has a new single listner.
3328  SubMapType usisElement;
3329  usisElement[isrListener->getSeq()] = isrListener;
3330  // VFALCO NOTE This is making a needless copy of naAccountID
3331  subMap.insert(simIterator, make_pair(naAccountID, usisElement));
3332  }
3333  else
3334  {
3335  // Found, note that the account has another listener.
3336  simIterator->second[isrListener->getSeq()] = isrListener;
3337  }
3338  }
3339 }
3340 
3341 void
3343  InfoSub::ref isrListener,
3344  hash_set<AccountID> const& vnaAccountIDs,
3345  bool rt)
3346 {
3347  for (auto const& naAccountID : vnaAccountIDs)
3348  {
3349  // Remove from the InfoSub
3350  isrListener->deleteSubAccountInfo(naAccountID, rt);
3351  }
3352 
3353  // Remove from the server
3354  unsubAccountInternal(isrListener->getSeq(), vnaAccountIDs, rt);
3355 }
3356 
3357 void
3359  std::uint64_t uSeq,
3360  hash_set<AccountID> const& vnaAccountIDs,
3361  bool rt)
3362 {
3364 
3365  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3366 
3367  for (auto const& naAccountID : vnaAccountIDs)
3368  {
3369  auto simIterator = subMap.find(naAccountID);
3370 
3371  if (simIterator != subMap.end())
3372  {
3373  // Found
3374  simIterator->second.erase(uSeq);
3375 
3376  if (simIterator->second.empty())
3377  {
3378  // Don't need hash entry.
3379  subMap.erase(simIterator);
3380  }
3381  }
3382  }
3383 }
3384 
3385 void
3387 {
3388  enum DatabaseType { Postgres, Sqlite, None };
3389  static const auto databaseType = [&]() -> DatabaseType {
3390 #ifdef RIPPLED_REPORTING
3391  if (app_.config().reporting())
3392  {
3393  // Use a dynamic_cast to return DatabaseType::None
3394  // on failure.
3395  if (dynamic_cast<PostgresDatabase*>(&app_.getRelationalDatabase()))
3396  {
3397  return DatabaseType::Postgres;
3398  }
3399  return DatabaseType::None;
3400  }
3401  else
3402  {
3403  // Use a dynamic_cast to return DatabaseType::None
3404  // on failure.
3405  if (dynamic_cast<SQLiteDatabase*>(&app_.getRelationalDatabase()))
3406  {
3407  return DatabaseType::Sqlite;
3408  }
3409  return DatabaseType::None;
3410  }
3411 #else
3412  // Use a dynamic_cast to return DatabaseType::None
3413  // on failure.
3414  if (dynamic_cast<SQLiteDatabase*>(&app_.getRelationalDatabase()))
3415  {
3416  return DatabaseType::Sqlite;
3417  }
3418  return DatabaseType::None;
3419 #endif
3420  }();
3421 
3422  if (databaseType == DatabaseType::None)
3423  {
3424  JLOG(m_journal.error())
3425  << "AccountHistory job for account "
3426  << toBase58(subInfo.index_->accountId_) << " no database";
3427  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3428  {
3429  sptr->send(rpcError(rpcINTERNAL), true);
3430  unsubAccountHistory(sptr, subInfo.index_->accountId_, false);
3431  }
3432  return;
3433  }
3434 
3437  "AccountHistoryTxStream",
3438  [this, dbType = databaseType, subInfo]() {
3439  auto const& accountId = subInfo.index_->accountId_;
3440  auto& lastLedgerSeq = subInfo.index_->historyLastLedgerSeq_;
3441  auto& txHistoryIndex = subInfo.index_->historyTxIndex_;
3442 
3443  JLOG(m_journal.trace())
3444  << "AccountHistory job for account " << toBase58(accountId)
3445  << " started. lastLedgerSeq=" << lastLedgerSeq;
3446 
3447  auto isFirstTx = [&](std::shared_ptr<Transaction> const& tx,
3448  std::shared_ptr<TxMeta> const& meta) -> bool {
3449  /*
3450  * genesis account: first tx is the one with seq 1
3451  * other account: first tx is the one created the account
3452  */
3453  if (accountId == genesisAccountId)
3454  {
3455  auto stx = tx->getSTransaction();
3456  if (stx->getAccountID(sfAccount) == accountId &&
3457  stx->getSeqProxy().value() == 1)
3458  return true;
3459  }
3460 
3461  for (auto& node : meta->getNodes())
3462  {
3463  if (node.getFieldU16(sfLedgerEntryType) != ltACCOUNT_ROOT)
3464  continue;
3465 
3466  if (node.isFieldPresent(sfNewFields))
3467  {
3468  if (auto inner = dynamic_cast<const STObject*>(
3469  node.peekAtPField(sfNewFields));
3470  inner)
3471  {
3472  if (inner->isFieldPresent(sfAccount) &&
3473  inner->getAccountID(sfAccount) == accountId)
3474  {
3475  return true;
3476  }
3477  }
3478  }
3479  }
3480 
3481  return false;
3482  };
3483 
3484  auto send = [&](Json::Value const& jvObj,
3485  bool unsubscribe) -> bool {
3486  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3487  {
3488  sptr->send(jvObj, true);
3489  if (unsubscribe)
3490  unsubAccountHistory(sptr, accountId, false);
3491  return true;
3492  }
3493 
3494  return false;
3495  };
3496 
3497  auto getMoreTxns =
3498  [&](std::uint32_t minLedger,
3499  std::uint32_t maxLedger,
3504  switch (dbType)
3505  {
3506  case Postgres: {
3507  auto db = static_cast<PostgresDatabase*>(
3510  args.account = accountId;
3511  LedgerRange range{minLedger, maxLedger};
3512  args.ledger = range;
3513  args.marker = marker;
3514  auto [txResult, status] = db->getAccountTx(args);
3515  if (status != rpcSUCCESS)
3516  {
3517  JLOG(m_journal.debug())
3518  << "AccountHistory job for account "
3519  << toBase58(accountId)
3520  << " getAccountTx failed";
3521  return {};
3522  }
3523 
3524  if (auto txns =
3525  std::get_if<RelationalDatabase::AccountTxs>(
3526  &txResult.transactions);
3527  txns)
3528  {
3529  return std::make_pair(*txns, txResult.marker);
3530  }
3531  else
3532  {
3533  JLOG(m_journal.debug())
3534  << "AccountHistory job for account "
3535  << toBase58(accountId)
3536  << " getAccountTx wrong data";
3537  return {};
3538  }
3539  }
3540  case Sqlite: {
3541  auto db = static_cast<SQLiteDatabase*>(
3544  accountId, minLedger, maxLedger, marker, 0, true};
3545  return db->newestAccountTxPage(options);
3546  }
3547  default: {
3548  assert(false);
3549  return {};
3550  }
3551  }
3552  };
3553 
3554  /*
3555  * search backward until the genesis ledger or asked to stop
3556  */
3557  while (lastLedgerSeq >= 2 && !subInfo.index_->stopHistorical_)
3558  {
3559  int feeChargeCount = 0;
3560  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3561  {
3562  sptr->getConsumer().charge(Resource::feeMediumBurdenRPC);
3563  ++feeChargeCount;
3564  }
3565  else
3566  {
3567  JLOG(m_journal.trace())
3568  << "AccountHistory job for account "
3569  << toBase58(accountId) << " no InfoSub. Fee charged "
3570  << feeChargeCount << " times.";
3571  return;
3572  }
3573 
3574  // try to search in 1024 ledgers till reaching genesis ledgers
3575  auto startLedgerSeq =
3576  (lastLedgerSeq > 1024 + 2 ? lastLedgerSeq - 1024 : 2);
3577  JLOG(m_journal.trace())
3578  << "AccountHistory job for account " << toBase58(accountId)
3579  << ", working on ledger range [" << startLedgerSeq << ","
3580  << lastLedgerSeq << "]";
3581 
3582  auto haveRange = [&]() -> bool {
3583  std::uint32_t validatedMin = UINT_MAX;
3584  std::uint32_t validatedMax = 0;
3585  auto haveSomeValidatedLedgers =
3587  validatedMin, validatedMax);
3588 
3589  return haveSomeValidatedLedgers &&
3590  validatedMin <= startLedgerSeq &&
3591  lastLedgerSeq <= validatedMax;
3592  }();
3593 
3594  if (!haveRange)
3595  {
3596  JLOG(m_journal.debug())
3597  << "AccountHistory reschedule job for account "
3598  << toBase58(accountId) << ", incomplete ledger range ["
3599  << startLedgerSeq << "," << lastLedgerSeq << "]";
3600  setAccountHistoryJobTimer(subInfo);
3601  return;
3602  }
3603 
3605  while (!subInfo.index_->stopHistorical_)
3606  {
3607  auto dbResult =
3608  getMoreTxns(startLedgerSeq, lastLedgerSeq, marker);
3609  if (!dbResult)
3610  {
3611  JLOG(m_journal.debug())
3612  << "AccountHistory job for account "
3613  << toBase58(accountId) << " getMoreTxns failed.";
3614  send(rpcError(rpcINTERNAL), true);
3615  return;
3616  }
3617 
3618  auto const& txns = dbResult->first;
3619  marker = dbResult->second;
3620  for (auto const& [tx, meta] : txns)
3621  {
3622  if (!tx || !meta)
3623  {
3624  JLOG(m_journal.debug())
3625  << "AccountHistory job for account "
3626  << toBase58(accountId) << " empty tx or meta.";
3627  send(rpcError(rpcINTERNAL), true);
3628  return;
3629  }
3630  auto curTxLedger =
3632  tx->getLedger());
3633  if (!curTxLedger)
3634  {
3635  JLOG(m_journal.debug())
3636  << "AccountHistory job for account "
3637  << toBase58(accountId) << " no ledger.";
3638  send(rpcError(rpcINTERNAL), true);
3639  return;
3640  }
3642  tx->getSTransaction();
3643  if (!stTxn)
3644  {
3645  JLOG(m_journal.debug())
3646  << "AccountHistory job for account "
3647  << toBase58(accountId)
3648  << " getSTransaction failed.";
3649  send(rpcError(rpcINTERNAL), true);
3650  return;
3651  }
3652  Json::Value jvTx = transJson(
3653  *stTxn, meta->getResultTER(), true, curTxLedger);
3654  jvTx[jss::meta] = meta->getJson(JsonOptions::none);
3655  jvTx[jss::account_history_tx_index] = txHistoryIndex--;
3657  jvTx[jss::meta], *curTxLedger, stTxn, *meta);
3658  if (isFirstTx(tx, meta))
3659  {
3660  jvTx[jss::account_history_tx_first] = true;
3661  send(jvTx, false);
3662 
3663  JLOG(m_journal.trace())
3664  << "AccountHistory job for account "
3665  << toBase58(accountId)
3666  << " done, found last tx.";
3667  return;
3668  }
3669  else
3670  {
3671  send(jvTx, false);
3672  }
3673  }
3674 
3675  if (marker)
3676  {
3677  JLOG(m_journal.trace())
3678  << "AccountHistory job for account "
3679  << toBase58(accountId)
3680  << " paging, marker=" << marker->ledgerSeq << ":"
3681  << marker->txnSeq;
3682  }
3683  else
3684  {
3685  break;
3686  }
3687  }
3688 
3689  if (!subInfo.index_->stopHistorical_)
3690  {
3691  lastLedgerSeq = startLedgerSeq - 1;
3692  if (lastLedgerSeq <= 1)
3693  {
3694  JLOG(m_journal.trace())
3695  << "AccountHistory job for account "
3696  << toBase58(accountId)
3697  << " done, reached genesis ledger.";
3698  return;
3699  }
3700  }
3701  }
3702  });
3703 }
3704 
3705 void
3707  std::shared_ptr<ReadView const> const& ledger,
3708  SubAccountHistoryInfoWeak& subInfo)
3709 {
3710  subInfo.index_->separationLedgerSeq_ = ledger->seq();
3711  auto const& accountId = subInfo.index_->accountId_;
3712  auto const accountKeylet = keylet::account(accountId);
3713  if (!ledger->exists(accountKeylet))
3714  {
3715  JLOG(m_journal.debug())
3716  << "subAccountHistoryStart, no account " << toBase58(accountId)
3717  << ", no need to add AccountHistory job.";
3718  return;
3719  }
3720  if (accountId == genesisAccountId)
3721  {
3722  if (auto const sleAcct = ledger->read(accountKeylet); sleAcct)
3723  {
3724  if (sleAcct->getFieldU32(sfSequence) == 1)
3725  {
3726  JLOG(m_journal.debug())
3727  << "subAccountHistoryStart, genesis account "
3728  << toBase58(accountId)
3729  << " does not have tx, no need to add AccountHistory job.";
3730  return;
3731  }
3732  }
3733  else
3734  {
3735  assert(false);
3736  return;
3737  }
3738  }
3739  subInfo.index_->historyLastLedgerSeq_ = ledger->seq();
3740  subInfo.index_->haveHistorical_ = true;
3741 
3742  JLOG(m_journal.debug())
3743  << "subAccountHistoryStart, add AccountHistory job: accountId="
3744  << toBase58(accountId) << ", currentLedgerSeq=" << ledger->seq();
3745 
3746  addAccountHistoryJob(subInfo);
3747 }
3748 
3751  InfoSub::ref isrListener,
3752  AccountID const& accountId)
3753 {
3754  if (!isrListener->insertSubAccountHistory(accountId))
3755  {
3756  JLOG(m_journal.debug())
3757  << "subAccountHistory, already subscribed to account "
3758  << toBase58(accountId);
3759  return rpcINVALID_PARAMS;
3760  }
3761 
3764  isrListener, std::make_shared<SubAccountHistoryIndex>(accountId)};
3765  auto simIterator = mSubAccountHistory.find(accountId);
3766  if (simIterator == mSubAccountHistory.end())
3767  {
3769  inner.emplace(isrListener->getSeq(), ahi);
3771  simIterator, std::make_pair(accountId, inner));
3772  }
3773  else
3774  {
3775  simIterator->second.emplace(isrListener->getSeq(), ahi);
3776  }
3777 
3778  auto const ledger = app_.getLedgerMaster().getValidatedLedger();
3779  if (ledger)
3780  {
3781  subAccountHistoryStart(ledger, ahi);
3782  }
3783  else
3784  {
3785  // The node does not have validated ledgers, so wait for
3786  // one before start streaming.
3787  // In this case, the subscription is also considered successful.
3788  JLOG(m_journal.debug())
3789  << "subAccountHistory, no validated ledger yet, delay start";
3790  }
3791 
3792  return rpcSUCCESS;
3793 }
3794 
3795 void
3797  InfoSub::ref isrListener,
3798  AccountID const& account,
3799  bool historyOnly)
3800 {
3801  if (!historyOnly)
3802  isrListener->deleteSubAccountHistory(account);
3803  unsubAccountHistoryInternal(isrListener->getSeq(), account, historyOnly);
3804 }
3805 
3806 void
3808  std::uint64_t seq,
3809  const AccountID& account,
3810  bool historyOnly)
3811 {
3813  auto simIterator = mSubAccountHistory.find(account);
3814  if (simIterator != mSubAccountHistory.end())
3815  {
3816  auto& subInfoMap = simIterator->second;
3817  auto subInfoIter = subInfoMap.find(seq);
3818  if (subInfoIter != subInfoMap.end())
3819  {
3820  subInfoIter->second.index_->stopHistorical_ = true;
3821  }
3822 
3823  if (!historyOnly)
3824  {
3825  simIterator->second.erase(seq);
3826  if (simIterator->second.empty())
3827  {
3828  mSubAccountHistory.erase(simIterator);
3829  }
3830  }
3831  JLOG(m_journal.debug())
3832  << "unsubAccountHistory, account " << toBase58(account)
3833  << ", historyOnly = " << (historyOnly ? "true" : "false");
3834  }
3835 }
3836 
3837 bool
3838 NetworkOPsImp::subBook(InfoSub::ref isrListener, Book const& book)
3839 {
3840  if (auto listeners = app_.getOrderBookDB().makeBookListeners(book))
3841  listeners->addSubscriber(isrListener);
3842  else
3843  assert(false);
3844  return true;
3845 }
3846 
3847 bool
3849 {
3850  if (auto listeners = app_.getOrderBookDB().getBookListeners(book))
3851  listeners->removeSubscriber(uSeq);
3852 
3853  return true;
3854 }
3855 
3859 {
3860  // This code-path is exclusively used when the server is in standalone
3861  // mode via `ledger_accept`
3862  assert(m_standalone);
3863 
3864  if (!m_standalone)
3865  Throw<std::runtime_error>(
3866  "Operation only possible in STANDALONE mode.");
3867 
3868  // FIXME Could we improve on this and remove the need for a specialized
3869  // API in Consensus?
3871  mConsensus.simulate(app_.timeKeeper().closeTime(), consensusDelay);
3872  return m_ledgerMaster.getCurrentLedger()->info().seq;
3873 }
3874 
3875 // <-- bool: true=added, false=already there
3876 bool
3878 {
3879  if (auto lpClosed = m_ledgerMaster.getValidatedLedger())
3880  {
3881  jvResult[jss::ledger_index] = lpClosed->info().seq;
3882  jvResult[jss::ledger_hash] = to_string(lpClosed->info().hash);
3883  jvResult[jss::ledger_time] = Json::Value::UInt(
3884  lpClosed->info().closeTime.time_since_epoch().count());
3885  jvResult[jss::fee_ref] = lpClosed->fees().units.jsonClipped();
3886  jvResult[jss::fee_base] = lpClosed->fees().base.jsonClipped();
3887  jvResult[jss::reserve_base] =
3888  lpClosed->fees().accountReserve(0).jsonClipped();
3889  jvResult[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
3890  }
3891 
3893  {
3894  jvResult[jss::validated_ledgers] =
3896  }
3897 
3899  return mStreamMaps[sLedger]
3900  .emplace(isrListener->getSeq(), isrListener)
3901  .second;
3902 }
3903 
3904 // <-- bool: true=added, false=already there
3905 bool
3907 {
3909  return mStreamMaps[sBookChanges]
3910  .emplace(isrListener->getSeq(), isrListener)
3911  .second;
3912 }
3913 
3914 // <-- bool: true=erased, false=was not there
3915 bool
3917 {
3919  return mStreamMaps[sLedger].erase(uSeq);
3920 }
3921 
3922 // <-- bool: true=erased, false=was not there
3923 bool
3925 {
3927  return mStreamMaps[sBookChanges].erase(uSeq);
3928 }
3929 
3930 // <-- bool: true=added, false=already there
3931 bool
3933 {
3935  return mStreamMaps[sManifests]
3936  .emplace(isrListener->getSeq(), isrListener)
3937  .second;
3938 }
3939 
3940 // <-- bool: true=erased, false=was not there
3941 bool
3943 {
3945  return mStreamMaps[sManifests].erase(uSeq);
3946 }
3947 
3948 // <-- bool: true=added, false=already there
3949 bool
3951  InfoSub::ref isrListener,
3952  Json::Value& jvResult,
3953  bool admin)
3954 {
3955  uint256 uRandom;
3956 
3957  if (m_standalone)
3958  jvResult[jss::stand_alone] = m_standalone;
3959 
3960  // CHECKME: is it necessary to provide a random number here?
3961  beast::rngfill(uRandom.begin(), uRandom.size(), crypto_prng());
3962 
3963  auto const& feeTrack = app_.getFeeTrack();
3964  jvResult[jss::random] = to_string(uRandom);
3965  jvResult[jss::server_status] = strOperatingMode(admin);
3966  jvResult[jss::load_base] = feeTrack.getLoadBase();
3967  jvResult[jss::load_factor] = feeTrack.getLoadFactor();
3968  jvResult[jss::hostid] = getHostId(admin);
3969  jvResult[jss::pubkey_node] =
3971 
3973  return mStreamMaps[sServer]
3974  .emplace(isrListener->getSeq(), isrListener)
3975  .second;
3976 }
3977 
3978 // <-- bool: true=erased, false=was not there
3979 bool
3981 {
3983  return mStreamMaps[sServer].erase(uSeq);
3984 }
3985 
3986 // <-- bool: true=added, false=already there
3987 bool
3989 {
3991  return mStreamMaps[sTransactions]
3992  .emplace(isrListener->getSeq(), isrListener)
3993  .second;
3994 }
3995 
3996 // <-- bool: true=erased, false=was not there
3997 bool
3999 {
4001  return mStreamMaps[sTransactions].erase(uSeq);
4002 }
4003 
4004 // <-- bool: true=added, false=already there
4005 bool
4007 {
4010  .emplace(isrListener->getSeq(), isrListener)
4011  .second;
4012 }
4013 
4014 // <-- bool: true=erased, false=was not there
4015 bool
4017 {
4019  return mStreamMaps[sRTTransactions].erase(uSeq);
4020 }
4021 
4022 // <-- bool: true=added, false=already there
4023 bool
4025 {
4027  return mStreamMaps[sValidations]
4028  .emplace(isrListener->getSeq(), isrListener)
4029  .second;
4030 }
4031 
4032 void
4034 {
4035  accounting_.json(obj);
4036 }
4037 
4038 // <-- bool: true=erased, false=was not there
4039 bool
4041 {
4043  return mStreamMaps[sValidations].erase(uSeq);
4044 }
4045 
4046 // <-- bool: true=added, false=already there
4047 bool
4049 {
4051  return mStreamMaps[sPeerStatus]
4052  .emplace(isrListener->getSeq(), isrListener)
4053  .second;
4054 }
4055 
4056 // <-- bool: true=erased, false=was not there
4057 bool
4059 {
4061  return mStreamMaps[sPeerStatus].erase(uSeq);
4062 }
4063 
4064 // <-- bool: true=added, false=already there
4065 bool
4067 {
4070  .emplace(isrListener->getSeq(), isrListener)
4071  .second;
4072 }
4073 
4074 // <-- bool: true=erased, false=was not there
4075 bool
4077 {
4079  return mStreamMaps[sConsensusPhase].erase(uSeq);
4080 }
4081 
4084 {
4086 
4087  subRpcMapType::iterator it = mRpcSubMap.find(strUrl);
4088 
4089  if (it != mRpcSubMap.end())
4090  return it->second;
4091 
4092  return InfoSub::pointer();
4093 }
4094 
4097 {
4099 
4100  mRpcSubMap.emplace(strUrl, rspEntry);
4101 
4102  return rspEntry;
4103 }
4104 
4105 bool
4107 {
4109  auto pInfo = findRpcSub(strUrl);
4110 
4111  if (!pInfo)
4112  return false;
4113 
4114  // check to see if any of the stream maps still hold a weak reference to
4115  // this entry before removing
4116  for (SubMapType const& map : mStreamMaps)
4117  {
4118  if (map.find(pInfo->getSeq()) != map.end())
4119  return false;
4120  }
4121  mRpcSubMap.erase(strUrl);
4122  return true;
4123 }
4124 
4125 #ifndef USE_NEW_BOOK_PAGE
4126 
4127 // NIKB FIXME this should be looked at. There's no reason why this shouldn't
4128 // work, but it demonstrated poor performance.
4129 //
4130 void
4133  Book const& book,
4134  AccountID const& uTakerID,
4135  bool const bProof,
4136  unsigned int iLimit,
4137  Json::Value const& jvMarker,
4138  Json::Value& jvResult)
4139 { // CAUTION: This is the old get book page logic
4140  Json::Value& jvOffers =
4141  (jvResult[jss::offers] = Json::Value(Json::arrayValue));
4142 
4144  const uint256 uBookBase = getBookBase(book);
4145  const uint256 uBookEnd = getQualityNext(uBookBase);
4146  uint256 uTipIndex = uBookBase;
4147 
4148  if (auto stream = m_journal.trace())
4149  {
4150  stream << "getBookPage:" << book;
4151  stream << "getBookPage: uBookBase=" << uBookBase;
4152  stream << "getBookPage: uBookEnd=" << uBookEnd;
4153  stream << "getBookPage: uTipIndex=" << uTipIndex;
4154  }
4155 
4156  ReadView const& view = *lpLedger;
4157 
4158  bool const bGlobalFreeze = isGlobalFrozen(view, book.out.account) ||
4159  isGlobalFrozen(view, book.in.account);
4160 
4161  bool bDone = false;
4162  bool bDirectAdvance = true;
4163 
4164  std::shared_ptr<SLE const> sleOfferDir;
4165  uint256 offerIndex;
4166  unsigned int uBookEntry;
4167  STAmount saDirRate;
4168 
4169  auto const rate = transferRate(view, book.out.account);
4170  auto viewJ = app_.journal("View");
4171 
4172  while (!bDone && iLimit-- > 0)
4173  {
4174  if (bDirectAdvance)
4175  {
4176  bDirectAdvance = false;
4177 
4178  JLOG(m_journal.trace()) << "getBookPage: bDirectAdvance";
4179 
4180  auto const ledgerIndex = view.succ(uTipIndex, uBookEnd);
4181  if (ledgerIndex)
4182  sleOfferDir = view.read(keylet::page(*ledgerIndex));
4183  else
4184  sleOfferDir.reset();
4185 
4186  if (!sleOfferDir)
4187  {
4188  JLOG(m_journal.trace()) << "getBookPage: bDone";
4189  bDone = true;
4190  }
4191  else
4192  {
4193  uTipIndex = sleOfferDir->key();
4194  saDirRate = amountFromQuality(getQuality(uTipIndex));
4195 
4196  cdirFirst(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex);
4197 
4198  JLOG(m_journal.trace())
4199  << "getBookPage: uTipIndex=" << uTipIndex;
4200  JLOG(m_journal.trace())
4201  << "getBookPage: offerIndex=" << offerIndex;
4202  }
4203  }
4204 
4205  if (!bDone)
4206  {
4207  auto sleOffer = view.read(keylet::offer(offerIndex));
4208 
4209  if (sleOffer)
4210  {
4211  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
4212  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
4213  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
4214  STAmount saOwnerFunds;
4215  bool firstOwnerOffer(true);
4216 
4217  if (book.out.account == uOfferOwnerID)
4218  {
4219  // If an offer is selling issuer's own IOUs, it is fully
4220  // funded.
4221  saOwnerFunds = saTakerGets;
4222  }
4223  else if (bGlobalFreeze)
4224  {
4225  // If either asset is globally frozen, consider all offers
4226  // that aren't ours to be totally unfunded
4227  saOwnerFunds.clear(book.out);
4228  }
4229  else
4230  {
4231  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
4232  if (umBalanceEntry != umBalance.end())
4233  {
4234  // Found in running balance table.
4235 
4236  saOwnerFunds = umBalanceEntry->second;
4237  firstOwnerOffer = false;
4238  }
4239  else
4240  {
4241  // Did not find balance in table.
4242 
4243  saOwnerFunds = accountHolds(
4244  view,
4245  uOfferOwnerID,
4246  book.out.currency,
4247  book.out.account,
4249  viewJ);
4250 
4251  if (saOwnerFunds < beast::zero)
4252  {
4253  // Treat negative funds as zero.
4254 
4255  saOwnerFunds.clear();
4256  }
4257  }
4258  }
4259 
4260  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
4261 
4262  STAmount saTakerGetsFunded;
4263  STAmount saOwnerFundsLimit = saOwnerFunds;
4264  Rate offerRate = parityRate;
4265 
4266  if (rate != parityRate
4267  // Have a tranfer fee.
4268  && uTakerID != book.out.account
4269  // Not taking offers of own IOUs.
4270  && book.out.account != uOfferOwnerID)
4271  // Offer owner not issuing ownfunds
4272  {
4273  // Need to charge a transfer fee to offer owner.
4274  offerRate = rate;
4275  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
4276  }
4277 
4278  if (saOwnerFundsLimit >= saTakerGets)
4279  {
4280  // Sufficient funds no shenanigans.
4281  saTakerGetsFunded = saTakerGets;
4282  }
4283  else
4284  {
4285  // Only provide, if not fully funded.
4286 
4287  saTakerGetsFunded = saOwnerFundsLimit;
4288 
4289  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
4290  std::min(
4291  saTakerPays,
4292  multiply(
4293  saTakerGetsFunded, saDirRate, saTakerPays.issue()))
4294  .setJson(jvOffer[jss::taker_pays_funded]);
4295  }
4296 
4297  STAmount saOwnerPays = (parityRate == offerRate)
4298  ? saTakerGetsFunded
4299  : std::min(
4300  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
4301 
4302  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
4303 
4304  // Include all offers funded and unfunded
4305  Json::Value& jvOf = jvOffers.append(jvOffer);
4306  jvOf[jss::quality] = saDirRate.getText();
4307 
4308  if (firstOwnerOffer)
4309  jvOf[jss::owner_funds] = saOwnerFunds.getText();
4310  }
4311  else
4312  {
4313  JLOG(m_journal.warn()) << "Missing offer";
4314  }
4315 
4316  if (!cdirNext(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex))
4317  {
4318  bDirectAdvance = true;
4319  }
4320  else
4321  {
4322  JLOG(m_journal.trace())
4323  << "getBookPage: offerIndex=" << offerIndex;
4324  }
4325  }
4326  }
4327 
4328  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
4329  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
4330 }
4331 
4332 #else
4333 
4334 // This is the new code that uses the book iterators
4335 // It has temporarily been disabled
4336 
4337 void
4340  Book const& book,
4341  AccountID const& uTakerID,
4342  bool const bProof,
4343  unsigned int iLimit,
4344  Json::Value const& jvMarker,
4345  Json::Value& jvResult)
4346 {
4347  auto& jvOffers = (jvResult[jss::offers] = Json::Value(Json::arrayValue));
4348 
4350 
4351  MetaView lesActive(lpLedger, tapNONE, true);
4352  OrderBookIterator obIterator(lesActive, book);
4353 
4354  auto const rate = transferRate(lesActive, book.out.account);
4355 
4356  const bool bGlobalFreeze = lesActive.isGlobalFrozen(book.out.account) ||
4357  lesActive.isGlobalFrozen(book.in.account);
4358 
4359  while (iLimit-- > 0 && obIterator.nextOffer())
4360  {
4361  SLE::pointer sleOffer = obIterator.getCurrentOffer();
4362  if (sleOffer)
4363  {
4364  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
4365  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
4366  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
4367  STAmount saDirRate = obIterator.getCurrentRate();
4368  STAmount saOwnerFunds;
4369 
4370  if (book.out.account == uOfferOwnerID)
4371  {
4372  // If offer is selling issuer's own IOUs, it is fully funded.
4373  saOwnerFunds = saTakerGets;
4374  }
4375  else if (bGlobalFreeze)
4376  {
4377  // If either asset is globally frozen, consider all offers
4378  // that aren't ours to be totally unfunded
4379  saOwnerFunds.clear(book.out);
4380  }
4381  else
4382  {
4383  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
4384 
4385  if (umBalanceEntry != umBalance.end())
4386  {
4387  // Found in running balance table.
4388 
4389  saOwnerFunds = umBalanceEntry->second;
4390  }
4391  else
4392  {
4393  // Did not find balance in table.
4394 
4395  saOwnerFunds = lesActive.accountHolds(
4396  uOfferOwnerID,
4397  book.out.currency,
4398  book.out.account,
4400 
4401  if (saOwnerFunds.isNegative())
4402  {
4403  // Treat negative funds as zero.
4404 
4405  saOwnerFunds.zero();
4406  }
4407  }
4408  }
4409 
4410  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
4411 
4412  STAmount saTakerGetsFunded;
4413  STAmount saOwnerFundsLimit = saOwnerFunds;
4414  Rate offerRate = parityRate;
4415 
4416  if (rate != parityRate
4417  // Have a tranfer fee.
4418  && uTakerID != book.out.account
4419  // Not taking offers of own IOUs.
4420  && book.out.account != uOfferOwnerID)
4421  // Offer owner not issuing ownfunds
4422  {
4423  // Need to charge a transfer fee to offer owner.
4424  offerRate = rate;
4425  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
4426  }
4427 
4428  if (saOwnerFundsLimit >= saTakerGets)
4429  {
4430  // Sufficient funds no shenanigans.
4431  saTakerGetsFunded = saTakerGets;
4432  }
4433  else
4434  {
4435  // Only provide, if not fully funded.
4436  saTakerGetsFunded = saOwnerFundsLimit;
4437 
4438  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
4439 
4440  // TOOD(tom): The result of this expression is not used - what's
4441  // going on here?
4442  std::min(
4443  saTakerPays,
4444  multiply(saTakerGetsFunded, saDirRate, saTakerPays.issue()))
4445  .setJson(jvOffer[jss::taker_pays_funded]);
4446  }
4447 
4448  STAmount saOwnerPays = (parityRate == offerRate)
4449  ? saTakerGetsFunded
4450  : std::min(
4451  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
4452 
4453  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
4454 
4455  if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID)
4456  {
4457  // Only provide funded offers and offers of the taker.
4458  Json::Value& jvOf = jvOffers.append(jvOffer);
4459  jvOf[jss::quality] = saDirRate.getText();
4460  }
4461  }
4462  }
4463 
4464  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
4465  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
4466 }
4467 
4468 #endif
4469 
4470 inline void
4472 {
4473  auto [counters, mode, start, initialSync] = accounting_.getCounterData();
4474  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
4475  std::chrono::steady_clock::now() - start);
4476  counters[static_cast<std::size_t>(mode)].dur += current;
4477 
4480  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
4481  .dur.count());
4483  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
4484  .dur.count());
4486  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].dur.count());
4488  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
4489  .dur.count());
4491  counters[static_cast<std::size_t>(OperatingMode::FULL)].dur.count());
4492 
4494  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
4495  .transitions);
4497  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
4498  .transitions);
4500  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].transitions);
4502  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
4503  .transitions);
4505  counters[static_cast<std::size_t>(OperatingMode::FULL)].transitions);
4506 }
4507 
4508 void
4510 {
4511  auto now = std::chrono::steady_clock::now();
4512 
4513  std::lock_guard lock(mutex_);
4514  ++counters_[static_cast<std::size_t>(om)].transitions;
4515  if (om == OperatingMode::FULL &&
4516  counters_[static_cast<std::size_t>(om)].transitions == 1)
4517  {
4518  initialSyncUs_ = std::chrono::duration_cast<std::chrono::microseconds>(
4519  now - processStart_)
4520  .count();
4521  }
4522  counters_[static_cast<std::size_t>(mode_)].dur +=
4523  std::chrono::duration_cast<std::chrono::microseconds>(now - start_);
4524 
4525  mode_ = om;
4526  start_ = now;
4527 }
4528 
4529 void
4531 {
4532  auto [counters, mode, start, initialSync] = getCounterData();
4533  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
4534  std::chrono::steady_clock::now() - start);
4535  counters[static_cast<std::size_t>(mode)].dur += current;
4536 
4537  obj[jss::state_accounting] = Json::objectValue;
4538  for (std::size_t i = static_cast<std::size_t>(OperatingMode::DISCONNECTED);
4539  i <= static_cast<std::size_t>(OperatingMode::FULL);
4540  ++i)
4541  {
4542  obj[jss::state_accounting][states_[i]] = Json::objectValue;
4543  auto& state = obj[jss::state_accounting][states_[i]];
4544  state[jss::transitions] = std::to_string(counters[i].transitions);
4545  state[jss::duration_us] = std::to_string(counters[i].dur.count());
4546  }
4547  obj[jss::server_state_duration_us] = std::to_string(current.count());
4548  if (initialSync)
4549  obj[jss::initial_sync_duration_us] = std::to_string(initialSync);
4550 }
4551 
4552 //------------------------------------------------------------------------------
4553 
4556  Application& app,
4557  NetworkOPs::clock_type& clock,
4558  bool standalone,
4559  std::size_t minPeerCount,
4560  bool startvalid,
4561  JobQueue& job_queue,
4562  LedgerMaster& ledgerMaster,
4563  ValidatorKeys const& validatorKeys,
4564  boost::asio::io_service& io_svc,
4565  beast::Journal journal,
4566  beast::insight::Collector::ptr const& collector)
4567 {
4568  return std::make_unique<NetworkOPsImp>(
4569  app,
4570  clock,
4571  standalone,
4572  minPeerCount,
4573  startvalid,
4574  job_queue,
4575  ledgerMaster,
4576  validatorKeys,
4577  io_svc,
4578  journal,
4579  collector);
4580 }
4581 
4582 } // namespace ripple
ripple::SQLiteDatabase
Definition: SQLiteDatabase.h:27
ripple::NetworkOPsImp::forwardManifest
void forwardManifest(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2740
ripple::NetworkOPsImp::unsubValidations
bool unsubValidations(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4040
ripple::NetworkOPsImp::Stats::hook
beast::insight::Hook hook
Definition: NetworkOPs.cpp:815
ripple::STTx::getTxnType
TxType getTxnType() const
Definition: STTx.h:179
ripple::setup_FeeVote
FeeVote::Setup setup_FeeVote(Section const &section)
Build FeeVote::Setup from a config section.
Definition: FeeVoteImpl.cpp:259
ripple::NetworkOPsImp::subValidations
bool subValidations(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4024
ripple::NetworkOPsImp::processHeartbeatTimer
void processHeartbeatTimer()
Definition: NetworkOPs.cpp:1000
ripple::NetworkOPs
Provides server functionality for clients.
Definition: NetworkOPs.h:86
ripple::sfIndexNext
const SF_UINT64 sfIndexNext
ripple::NetworkOPsImp::SubAccountHistoryIndex::historyLastLedgerSeq_
std::uint32_t historyLastLedgerSeq_
Definition: NetworkOPs.cpp:670
ripple::LedgerMaster::getValidatedRange
bool getValidatedRange(std::uint32_t &minVal, std::uint32_t &maxVal)
Definition: LedgerMaster.cpp:629
ripple::NetworkOPsImp::mapComplete
void mapComplete(std::shared_ptr< SHAMap > const &map, bool fromAcquire) override
Definition: NetworkOPs.cpp:1856
ripple::NetworkOPsImp::setClusterTimer
void setClusterTimer()
Definition: NetworkOPs.cpp:972
ripple::Application
Definition: Application.h:115
ripple::transferRate
Rate transferRate(ReadView const &view, AccountID const &issuer)
Definition: View.cpp:471
ripple::TimeKeeper::nowOffset
virtual std::chrono::duration< std::int32_t > nowOffset() const =0
ripple::cdirNext
bool cdirNext(ReadView const &view, uint256 const &root, std::shared_ptr< SLE const > &page, unsigned int &index, uint256 &entry)
Returns the next entry in the directory, advancing the index.
Definition: View.cpp:145
ripple::ClusterNode
Definition: ClusterNode.h:30
ripple::NetworkOPsImp::SubTypes
SubTypes
Definition: NetworkOPs.cpp:743
ripple::NetworkOPsImp::unsubConsensus
bool unsubConsensus(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4076
ripple::jtTRANSACTION
@ jtTRANSACTION
Definition: Job.h:63
ripple::Manifest::domain
std::string domain
The domain, if one was specified in the manifest; empty otherwise.
Definition: Manifest.h:95
ripple::Application::getOrderBookDB
virtual OrderBookDB & getOrderBookDB()=0
ripple::NetworkOPsImp::SubAccountHistoryIndex::haveHistorical_
bool haveHistorical_
Definition: NetworkOPs.cpp:672
ripple::RCLCxPeerPos
A peer's signed, proposed position for use in RCLConsensus.
Definition: RCLCxPeerPos.h:42
ripple::HashPrefix::ledgerMaster
@ ledgerMaster
ledger master data for signing
ripple::NetworkOPsImp::processTrustedProposal
bool processTrustedProposal(RCLCxPeerPos proposal) override
Definition: NetworkOPs.cpp:1850
std::lock
T lock(T... args)
ripple::NetworkOPsImp::setAccountHistoryJobTimer
void setAccountHistoryJobTimer(SubAccountHistoryInfoWeak subInfo)
Definition: NetworkOPs.cpp:987
ripple::NetworkOPsImp::pubAccountTransaction
void pubAccountTransaction(std::shared_ptr< ReadView const > const &ledger, AcceptedLedgerTx const &transaction)
Definition: NetworkOPs.cpp:3112
ripple::InboundLedgers::getInfo
virtual Json::Value getInfo()=0
ripple::NetworkOPsImp::stateAccounting
void stateAccounting(Json::Value &obj) override
Definition: NetworkOPs.cpp:4033
ripple::LoadManager
Manages load sources.
Definition: LoadManager.h:45
ripple::sfReserveBase
const SF_UINT32 sfReserveBase
ripple::NetworkOPsImp::m_journal
beast::Journal m_journal
Definition: NetworkOPs.cpp:712
ripple::LedgerMaster::getPublishedLedger
std::shared_ptr< ReadView const > getPublishedLedger()
Definition: LedgerMaster.cpp:1690
ripple::NetworkOPsImp::sLastEntry
@ sLastEntry
Definition: NetworkOPs.cpp:754
ripple::Application::getAcceptedLedgerCache
virtual TaggedCache< uint256, AcceptedLedger > & getAcceptedLedgerCache()=0
ripple::OpenLedger::current
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
Definition: OpenLedger.cpp:50
ripple::NetworkOPsImp::TransactionStatus::applied
bool applied
Definition: NetworkOPs.cpp:92
ripple::NetworkOPsImp::mLastFeeSummary
ServerFeeSummary mLastFeeSummary
Definition: NetworkOPs.cpp:759
ripple::ValidatorList::localPublicKey
PublicKey localPublicKey() const
Returns local validator public key.
Definition: ValidatorList.cpp:1412
ripple::NetworkOPsImp::StateAccounting::processStart_
const std::chrono::steady_clock::time_point processStart_
Definition: NetworkOPs.cpp:146
std::string
STL class.
std::shared_ptr< Transaction >
ripple::NetworkOPsImp::heartbeatTimer_
boost::asio::steady_timer heartbeatTimer_
Definition: NetworkOPs.cpp:726
ripple::ManifestCache::getMasterKey
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
Definition: app/misc/impl/Manifest.cpp:299
ripple::RCLConsensus::getJson
Json::Value getJson(bool full) const
Definition: RCLConsensus.cpp:890
ripple::NetworkOPsImp::minPeerCount_
const std::size_t minPeerCount_
Definition: NetworkOPs.cpp:767
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
ripple::rpcError
Json::Value rpcError(int iError)
Definition: RPCErr.cpp:29
ripple::fhZERO_IF_FROZEN
@ fhZERO_IF_FROZEN
Definition: View.h:76
utility
ripple::Rate
Represents a transfer rate.
Definition: Rate.h:37
std::exception
STL class.
ripple::NetworkOPsImp::setStateTimer
void setStateTimer() override
Called to initially start our timers.
Definition: NetworkOPs.cpp:919
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:530
ripple::NetworkOPsImp::StateAccounting::json
void json(Json::Value &obj) const
Output state counters in JSON format.
Definition: NetworkOPs.cpp:4530
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::STAmount::clear
void clear()
Definition: STAmount.h:394
ripple::sfLedgerSequence
const SF_UINT32 sfLedgerSequence
ripple::AcceptedLedgerTx::getTxn
std::shared_ptr< STTx const > const & getTxn() const
Definition: AcceptedLedgerTx.h:53
ripple::NetworkOPsImp::m_stats
Stats m_stats
Definition: NetworkOPs.cpp:830
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:339
ripple::Book::out
Issue out
Definition: Book.h:37
ripple::make_FeeVote
std::unique_ptr< FeeVote > make_FeeVote(FeeVote::Setup const &setup, beast::Journal journal)
Create an instance of the FeeVote logic.
Definition: FeeVoteImpl.cpp:279
ripple::Resource::feeMediumBurdenRPC
const Charge feeMediumBurdenRPC
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:594
ripple::TrustChanges
Changes in trusted nodes after updating validator list.
Definition: ValidatorList.h:107
ripple::Resource::Gossip
Data format for exchanging consumption information across peers.
Definition: Gossip.h:29
ripple::NetworkOPsImp::setAmendmentWarned
void setAmendmentWarned() override
Definition: NetworkOPs.cpp:1601
ripple::NetworkOPsImp::pubManifest
void pubManifest(Manifest const &) override
Definition: NetworkOPs.cpp:1940
ripple::RelationalDatabase::AccountTxArgs
Definition: RelationalDatabase.h:96
ripple::Manifest
Definition: Manifest.h:80
ripple::NetworkOPsImp::collect_metrics
void collect_metrics()
Definition: NetworkOPs.cpp:4471
ripple::NetworkOPsImp::subPeerStatus
bool subPeerStatus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4048
std::unordered_set
STL class.
ripple::NetworkOPsImp::mDispatchState
DispatchState mDispatchState
Definition: NetworkOPs.cpp:772
ripple::NetworkOPsImp::DispatchState::none
@ none
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
ripple::NetworkOPs::FailHard::no
@ no
ripple::NetworkOPsImp::stop
void stop() override
Definition: NetworkOPs.cpp:564
std::pair
ripple::Overlay::getJqTransOverflow
virtual std::uint64_t getJqTransOverflow() const =0
ripple::NetworkOPsImp::mSubRTAccount
SubInfoMapType mSubRTAccount
Definition: NetworkOPs.cpp:737
ripple::NetworkOPsImp::amendmentWarned_
std::atomic< bool > amendmentWarned_
Definition: NetworkOPs.cpp:722
ripple::NetworkOPsImp::states_
static const std::array< char const *, 5 > states_
Definition: NetworkOPs.cpp:115
ripple::sfSequence
const SF_UINT32 sfSequence
ripple::LedgerMaster
Definition: LedgerMaster.h:70
ripple::Application::getAmendmentTable
virtual AmendmentTable & getAmendmentTable()=0
ripple::NetworkOPsImp::setMode
void setMode(OperatingMode om) override
Definition: NetworkOPs.cpp:2221
ripple::ClusterNode::name
std::string const & name() const
Definition: ClusterNode.h:45
ripple::OpenView
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:55
Json::UInt
unsigned int UInt
Definition: json_forwards.h:27
Json::Compact
Decorator for streaming out compact json.
Definition: json_writer.h:316
ripple::getBookBase
uint256 getBookBase(Book const &book)
Definition: Indexes.cpp:82
ripple::NetworkOPsImp::StateAccounting::Counters::dur
std::chrono::microseconds dur
Definition: NetworkOPs.cpp:138
ripple::Manifest::signingKey
PublicKey signingKey
The ephemeral key associated with this manifest.
Definition: Manifest.h:89
ripple::NetworkOPsImp::pubProposedAccountTransaction
void pubProposedAccountTransaction(std::shared_ptr< ReadView const > const &ledger, std::shared_ptr< STTx const > const &transaction, TER result)
Definition: NetworkOPs.cpp:3235
std::vector
STL class.
ripple::NetworkOPsImp::isUNLBlocked
bool isUNLBlocked() override
Definition: NetworkOPs.cpp:1613
std::unordered_map::find
T find(T... args)
ripple::ReportingETL::getInfo
Json::Value getInfo()
Definition: ReportingETL.h:310
ripple::Manifest::serialized
std::string serialized
The manifest in serialized form.
Definition: Manifest.h:83
ripple::NetworkOPsImp::setNeedNetworkLedger
void setNeedNetworkLedger() override
Definition: NetworkOPs.cpp:876
ripple::NetworkOPsImp::tryRemoveRpcSub
bool tryRemoveRpcSub(std::string const &strUrl) override
Definition: NetworkOPs.cpp:4106
ripple::Manifest::masterKey
PublicKey masterKey
The master key associated with this manifest.
Definition: Manifest.h:86
ripple::accountHolds
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
Definition: View.cpp:223
ripple::PublicKey::empty
bool empty() const noexcept
Definition: PublicKey.h:117
ripple::STAmount::getText
std::string getText() const override
Definition: STAmount.cpp:530
ripple::NetworkOPsImp::recvValidation
bool recvValidation(std::shared_ptr< STValidation > const &val, std::string const &source) override
Definition: NetworkOPs.cpp:2250
ripple::jtNETOP_CLUSTER
@ jtNETOP_CLUSTER
Definition: Job.h:76
ripple::NetworkOPsImp::getHostId
std::string getHostId(bool forAdmin)
Definition: NetworkOPs.cpp:900
ripple::NetworkOPsImp::forwardProposedTransaction
void forwardProposedTransaction(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2689
ripple::NetworkOPsImp::sValidations
@ sValidations
Definition: NetworkOPs.cpp:749
std::chrono::microseconds
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:29
ripple::Config::NODE_SIZE
std::size_t NODE_SIZE
Definition: Config.h:197
ripple::crypto_prng
csprng_engine & crypto_prng()
The default cryptographically secure PRNG.
Definition: csprng.cpp:108
ripple::keylet::offer
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
Definition: Indexes.cpp:222
ripple::Issue::currency
Currency currency
Definition: Issue.h:37
ripple::JobQueue::getJson
Json::Value getJson(int c=0)
Definition: JobQueue.cpp:196
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:29
ripple::NetworkOPsImp::Stats::disconnected_duration
beast::insight::Gauge disconnected_duration
Definition: NetworkOPs.cpp:816
ripple::NetworkOPsImp::StateAccounting::Counters
Definition: NetworkOPs.cpp:133
std::optional::emplace
T emplace(T... args)
ripple::makeRulesGivenLedger
Rules makeRulesGivenLedger(DigestAwareReadView const &ledger, std::unordered_set< uint256, beast::uhash<>> const &presets)
Definition: ReadView.cpp:69
ripple::HELD
@ HELD
Definition: Transaction.h:51
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
std::recursive_mutex
STL class.
std::shared_ptr::get
T get(T... args)
ripple::NetworkOPsImp::consensusViewChange
void consensusViewChange() override
Definition: NetworkOPs.cpp:1931
std::lock_guard
STL class.
ripple::RPC::computeBookChanges
Json::Value computeBookChanges(std::shared_ptr< L const > const &lpAccepted)
Definition: BookChanges.h:38
ripple::NetworkOPsImp::accounting_
StateAccounting accounting_
Definition: NetworkOPs.cpp:775
ripple::ConsensusParms::ledgerGRANULARITY
std::chrono::milliseconds ledgerGRANULARITY
How often we check state or change positions.
Definition: ConsensusParms.h:95
ripple::NetworkOPsImp::unsubAccountHistoryInternal
void unsubAccountHistoryInternal(std::uint64_t seq, AccountID const &account, bool historyOnly) override
Definition: NetworkOPs.cpp:3807
ripple::Application::getShardStore
virtual NodeStore::DatabaseShard * getShardStore()=0
ripple::NetworkOPsImp::DispatchState::scheduled
@ scheduled
ripple::sfCloseTime
const SF_UINT32 sfCloseTime
tuple
ripple::NetworkOPsImp::SubAccountHistoryInfo::index_
std::shared_ptr< SubAccountHistoryIndex > index_
Definition: NetworkOPs.cpp:689
ripple::Overlay::size
virtual std::size_t size() const =0
Returns the number of active peers.
ripple::NetworkOPsImp::apply
void apply(std::unique_lock< std::mutex > &batchLock)
Attempt to apply transactions and post-process based on the results.
Definition: NetworkOPs.cpp:1303
ripple::JobQueue::addJob
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
Definition: JobQueue.h:166
ripple::jtCLIENT_CONSENSUS
@ jtCLIENT_CONSENSUS
Definition: Job.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:4555
ripple::NetworkOPsImp::Stats::syncing_transitions
beast::insight::Gauge syncing_transitions
Definition: NetworkOPs.cpp:824
std::function
ripple::LoadFeeTrack::getLoadBase
std::uint32_t getLoadBase() const
Definition: LoadFeeTrack.h:89
ripple::NetworkOPsImp::unlBlocked_
std::atomic< bool > unlBlocked_
Definition: NetworkOPs.cpp:723
ripple::NetworkOPsImp::SubAccountHistoryIndex::SubAccountHistoryIndex
SubAccountHistoryIndex(AccountID const &accountId)
Definition: NetworkOPs.cpp:675
ripple::getQualityNext
uint256 getQualityNext(uint256 const &uBase)
Definition: Indexes.cpp:100
ripple::Application::timeKeeper
virtual TimeKeeper & timeKeeper()=0
ripple::NetworkOPsImp::forwardProposedAccountTransaction
void forwardProposedAccountTransaction(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2778
ripple::Application::openLedger
virtual OpenLedger & openLedger()=0
ripple::NetworkOPsImp::pubLedger
void pubLedger(std::shared_ptr< ReadView const > const &lpAccepted) override
Definition: NetworkOPs.cpp:2846
ripple::RelationalDatabase::AccountTxArgs::account
AccountID account
Definition: RelationalDatabase.h:98
ripple::NetworkOPsImp::switchLastClosedLedger
void switchLastClosedLedger(std::shared_ptr< Ledger const > const &newLCL)
Definition: NetworkOPs.cpp:1737
ripple::tapNONE
@ tapNONE
Definition: ApplyView.h:30
ripple::NetworkOPsImp::setUNLBlocked
void setUNLBlocked() override
Definition: NetworkOPs.cpp:1619
ripple::NetworkOPsImp::SubAccountHistoryInfo
Definition: NetworkOPs.cpp:686
ripple::NetworkOPsImp::doTransactionAsync
void doTransactionAsync(std::shared_ptr< Transaction > transaction, bool bUnlimited, FailHard failtype)
For transactions not submitted by a locally connected client, fire and forget.
Definition: NetworkOPs.cpp:1224
ripple::TxQ::Metrics
Structure returned by TxQ::getMetrics, expressed in reference fee level units.
Definition: TxQ.h:161
ripple::RCLValidatedLedger
Wraps a ledger instance for use in generic Validations LedgerTrie.
Definition: RCLValidations.h:153
ripple::parityRate
const Rate parityRate(QUALITY_ONE)
A transfer rate signifying a 1:1 exchange.
Definition: Rate.h:101
std::shared_ptr::reset
T reset(T... args)
ripple::NetworkOPsImp::TransactionStatus::result
TER result
Definition: NetworkOPs.cpp:93
ripple::generateKeyPair
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
Definition: SecretKey.cpp:351
ripple::error_code_i
error_code_i
Definition: ErrorCodes.h:40
ripple::ValidatorKeys
Validator keys and manifest as set in configuration file.
Definition: ValidatorKeys.h:36
std::unordered_map::clear
T clear(T... args)
ripple::CanonicalTXSet
Holds transactions which were deferred to the next pass of consensus.
Definition: CanonicalTXSet.h:38
ripple::Application::getInboundLedgers
virtual InboundLedgers & getInboundLedgers()=0
ripple::Application::getFeeTrack
virtual LoadFeeTrack & getFeeTrack()=0
ripple::base_uint::size
constexpr static std::size_t size()
Definition: base_uint.h:512
ripple::LedgerMaster::getCompleteLedgers
std::string getCompleteLedgers()
Definition: LedgerMaster.cpp:1697
ripple::ltDIR_NODE
@ ltDIR_NODE
A ledger object which contains a list of object identifiers.
Definition: LedgerFormats.h:66
ripple::send_always
Sends a message to all peers.
Definition: predicates.h:31
ripple::OperatingMode::SYNCING
@ SYNCING
fallen slightly behind
ripple::NetworkOPsImp::processClusterTimer
void processClusterTimer()
Definition: NetworkOPs.cpp:1058
ripple::NetworkOPsImp::unsubTransactions
bool unsubTransactions(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3998
std::unique_lock::unlock
T unlock(T... args)
ripple::Serializer::data
void const * data() const noexcept
Definition: Serializer.h:75
ripple::terQUEUED
@ terQUEUED
Definition: TER.h:203
ripple::sfIndexes
const SF_VECTOR256 sfIndexes
ripple::NetworkOPsImp::StateAccounting::mutex_
std::mutex mutex_
Definition: NetworkOPs.cpp:143
ripple::RCLConsensus::simulate
void simulate(NetClock::time_point const &now, std::optional< std::chrono::milliseconds > consensusDelay)
Definition: RCLConsensus.cpp:936
std::vector::push_back
T push_back(T... args)
ripple::NetworkOPsImp::ServerFeeSummary::loadFactorServer
std::uint32_t loadFactorServer
Definition: NetworkOPs.cpp:208
ripple::divide
STAmount divide(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:86
ripple::NetworkOPsImp::~NetworkOPsImp
~NetworkOPsImp() override
Definition: NetworkOPs.cpp:253
ripple::isTerRetry
bool isTerRetry(TER x)
Definition: TER.h:588
ripple::LoadFeeTrack::getRemoteFee
std::uint32_t getRemoteFee() const
Definition: LoadFeeTrack.h:68
ripple::jtBATCH
@ jtBATCH
Definition: Job.h:66
ripple::sfValidatedHash
const SF_UINT256 sfValidatedHash
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:75
ripple::sfTakerPays
const SF_AMOUNT sfTakerPays
ripple::INCLUDED
@ INCLUDED
Definition: Transaction.h:48
ripple::getAccounts
static void getAccounts(Json::Value const &jvObj, std::vector< AccountID > &accounts)
Definition: NetworkOPs.cpp:2760
ripple::RCLConsensus
Manages the generic consensus algorithm for use by the RCL.
Definition: RCLConsensus.h:50
ripple::warnRPC_AMENDMENT_BLOCKED
@ warnRPC_AMENDMENT_BLOCKED
Definition: ErrorCodes.h:155
ripple::NetworkOPsImp::SubAccountHistoryIndex
Definition: NetworkOPs.cpp:662
ripple::NetworkOPsImp::m_statsMutex
std::mutex m_statsMutex
Definition: NetworkOPs.cpp:829
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::isGlobalFrozen
bool isGlobalFrozen(ReadView const &view, AccountID const &issuer)
Definition: View.cpp:188
ripple::NetworkOPsImp::Stats::syncing_duration
beast::insight::Gauge syncing_duration
Definition: NetworkOPs.cpp:818
ripple::NetworkOPsImp::isAmendmentBlocked
bool isAmendmentBlocked() override
Definition: NetworkOPs.cpp:1582
ripple::NetworkOPsImp::addRpcSub
InfoSub::pointer addRpcSub(std::string const &strUrl, InfoSub::ref) override
Definition: NetworkOPs.cpp:4096
ripple::rpcSUCCESS
@ rpcSUCCESS
Definition: ErrorCodes.h:44
ripple::NetworkOPsImp::forwardValidation
void forwardValidation(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2720
ripple::NetworkOPsImp::TransactionStatus::failType
const FailHard failType
Definition: NetworkOPs.cpp:91
ripple::ltOFFER
@ ltOFFER
A ledger object which describes an offer on the DEX.
Definition: LedgerFormats.h:92
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
ripple::Config::reporting
bool reporting() const
Definition: Config.h:316
ripple::Application::getReportingETL
virtual ReportingETL & getReportingETL()=0
ripple::OperatingMode::DISCONNECTED
@ DISCONNECTED
not ready to process requests
ripple::NetworkOPsImp::TransactionStatus::local
const bool local
Definition: NetworkOPs.cpp:90
ripple::NetworkOPsImp::clearAmendmentWarned
void clearAmendmentWarned() override
Definition: NetworkOPs.cpp:1607
ripple::STAmount::setJson
void setJson(Json::Value &) const
Definition: STAmount.cpp:476
ripple::UptimeClock::now
static time_point now()
Definition: UptimeClock.cpp:63
ripple::NetworkOPsImp::subAccountHistoryStart
void subAccountHistoryStart(std::shared_ptr< ReadView const > const &ledger, SubAccountHistoryInfoWeak &subInfo)
Definition: NetworkOPs.cpp:3706
ripple::jtTXN_PROC
@ jtTXN_PROC
Definition: Job.h:83
ripple::OrderBookDB::processTxn
void processTxn(std::shared_ptr< ReadView const > const &ledger, const AcceptedLedgerTx &alTx, Json::Value const &jvObj)
Definition: OrderBookDB.cpp:234
ripple::Application::getIOLatency
virtual std::chrono::milliseconds getIOLatency()=0
ripple::NetworkOPsImp::SubAccountHistoryInfo::sink_
InfoSub::pointer sink_
Definition: NetworkOPs.cpp:688
ripple::NetworkOPsImp::getOwnerInfo
Json::Value getOwnerInfo(std::shared_ptr< ReadView const > lpLedger, AccountID const &account) override
Definition: NetworkOPs.cpp:1510
ripple::sfServerVersion
const SF_UINT64 sfServerVersion
ripple::checkValidity
std::pair< Validity, std::string > checkValidity(HashRouter &router, STTx const &tx, Rules const &rules, Config const &config)
Checks transaction signature and local checks.
Definition: apply.cpp:37
ripple::NetworkOPsImp::reportFeeChange
void reportFeeChange() override
Definition: NetworkOPs.cpp:2957
ripple::LoadFeeTrack::getLocalFee
std::uint32_t getLocalFee() const
Definition: LoadFeeTrack.h:75
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:525
ripple::OperatingMode::CONNECTED
@ CONNECTED
convinced we are talking to the network
ripple::OBSOLETE
@ OBSOLETE
Definition: Transaction.h:53
ripple::NetworkOPsImp::StateAccounting::Counters::transitions
std::uint64_t transitions
Definition: NetworkOPs.cpp:137
ripple::InfoSub::pointer
std::shared_ptr< InfoSub > pointer
Definition: InfoSub.h:54
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::XRPAmount::decimalXRP
constexpr double decimalXRP() const
Definition: XRPAmount.h:253
ripple::sfLoadFee
const SF_UINT32 sfLoadFee
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::NetworkOPsImp::addAccountHistoryJob
void addAccountHistoryJob(SubAccountHistoryInfoWeak subInfo)
Definition: NetworkOPs.cpp:3386
ripple::NetworkOPsImp::isBlocked
bool isBlocked() override
Definition: NetworkOPs.cpp:1576
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:133
ripple::OperatingMode::TRACKING
@ TRACKING
convinced we agree with the network
ripple::NetworkOPsImp::SubAccountHistoryIndex::separationLedgerSeq_
std::uint32_t separationLedgerSeq_
Definition: NetworkOPs.cpp:668
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:589
ripple::sfNewFields
const SField sfNewFields
ripple::NetworkOPsImp::SubAccountHistoryInfoWeak::sinkWptr_
InfoSub::wptr sinkWptr_
Definition: NetworkOPs.cpp:693
ripple::sfReserveIncrement
const SF_UINT32 sfReserveIncrement
ripple::NetworkOPsImp::setTimer
void setTimer(boost::asio::steady_timer &timer, std::chrono::milliseconds const &expiry_time, std::function< void()> onExpire, std::function< void()> onError)
Definition: NetworkOPs.cpp:926
ripple::JsonOptions::none
@ none
ripple::NetworkOPsImp::DispatchState
DispatchState
Synchronization states for transaction batches.
Definition: NetworkOPs.cpp:109
ripple::NetworkOPsImp::sServer
@ sServer
Definition: NetworkOPs.cpp:746
ripple::Application::config
virtual Config & config()=0
ripple::peer_in_cluster
Select all peers (except optional excluded) that are in our cluster.
Definition: predicates.h:136
ripple::NetworkOPsImp::StateAccounting::start_
std::chrono::steady_clock::time_point start_
Definition: NetworkOPs.cpp:144
ripple::TERSubset< CanCvtToTER >
ripple::TrustChanges::removed
hash_set< NodeID > removed
Definition: ValidatorList.h:112
ripple::RCLTxSet
Represents a set of transactions in RCLConsensus.
Definition: RCLCxTx.h:65
ripple::keylet::page
Keylet page(uint256 const &key, std::uint64_t index) noexcept
A page in a directory.
Definition: Indexes.cpp:309
ripple::NetworkOPsImp::endConsensus
void endConsensus() override
Definition: NetworkOPs.cpp:1875
ripple::RelationalDatabase::AccountTxArgs::marker
std::optional< AccountTxMarker > marker
Definition: RelationalDatabase.h:103
std::unique_lock
STL class.
ripple::sfCookie
const SF_UINT64 sfCookie
ripple::calcAccountID
AccountID calcAccountID(PublicKey const &pk)
Definition: AccountID.cpp:80
ripple::NetworkOPsImp::unsubAccount
void unsubAccount(InfoSub::ref ispListener, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
Definition: NetworkOPs.cpp:3342
ripple::Application::getRelationalDatabase
virtual RelationalDatabase & getRelationalDatabase()=0
ripple::Application::nodeIdentity
virtual std::pair< PublicKey, SecretKey > const & nodeIdentity()=0
ripple::NetworkOPsImp::unsubRTTransactions
bool unsubRTTransactions(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4016
ripple::Application::getTxQ
virtual TxQ & getTxQ()=0
ripple::LoadFeeTrack
Manages the current fee schedule.
Definition: LoadFeeTrack.h:44
ripple::Manifest::getSignature
std::optional< Blob > getSignature() const
Returns manifest signature.
Definition: app/misc/impl/Manifest.cpp:222
ripple::NetworkOPsImp::pubValidatedTransaction
void pubValidatedTransaction(std::shared_ptr< ReadView const > const &ledger, AcceptedLedgerTx const &transaction)
Definition: NetworkOPs.cpp:3057
std::to_string
T to_string(T... args)
ripple::Application::getJobQueue
virtual JobQueue & getJobQueue()=0
ripple::NetworkOPsImp::subManifests
bool subManifests(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3932
ripple::AcceptedLedgerTx
A transaction that is in a closed ledger.
Definition: AcceptedLedgerTx.h:43
ripple::AmendmentTable::firstUnsupportedExpected
virtual std::optional< NetClock::time_point > firstUnsupportedExpected() const =0
ripple::Resource::Gossip::items
std::vector< Item > items
Definition: Gossip.h:42
ripple::NetworkOPsImp::TransactionStatus::transaction
const std::shared_ptr< Transaction > transaction
Definition: NetworkOPs.cpp:88
std::array
STL class.
ripple::NetworkOPsImp::clearUNLBlocked
void clearUNLBlocked() override
Definition: NetworkOPs.cpp:1626
ripple::NetworkOPsImp::ServerFeeSummary
Server fees published on server subscription.
Definition: NetworkOPs.cpp:191
ripple::NetworkOPsImp::m_localTX
std::unique_ptr< LocalTxs > m_localTX
Definition: NetworkOPs.cpp:714
ripple::NetworkOPsImp::NetworkOPsImp
NetworkOPsImp(Application &app, NetworkOPs::clock_type &clock, bool standalone, std::size_t minPeerCount, bool start_valid, 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:215
ripple::NetworkOPsImp::DispatchState::running
@ running
ripple::NetworkOPsImp::StateAccounting::CounterData::start
decltype(start_) start
Definition: NetworkOPs.cpp:178
ripple::ConsensusPhase
ConsensusPhase
Phases of consensus for a single ledger round.
Definition: ConsensusTypes.h:103
ripple::STAmount
Definition: STAmount.h:44
ripple::NetworkOPsImp::StateAccounting::Counters::Counters
Counters()=default
ripple::warnRPC_EXPIRED_VALIDATOR_LIST
@ warnRPC_EXPIRED_VALIDATOR_LIST
Definition: ErrorCodes.h:156
beast::Journal::error
Stream error() const
Definition: Journal.h:333
beast::Journal::info
Stream info() const
Definition: Journal.h:321
ripple::NetworkOPsImp::m_job_queue
JobQueue & m_job_queue
Definition: NetworkOPs.cpp:761
std::unordered_map::erase
T erase(T... args)
ripple::BuildInfo::getVersionString
std::string const & getVersionString()
Server version.
Definition: BuildInfo.cpp:65
ripple::sfTakerGets
const SF_AMOUNT sfTakerGets
ripple::NetworkOPsImp::subBookChanges
bool subBookChanges(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3906
ripple::STTx
Definition: STTx.h:45
ripple::LedgerMaster::getLedgerBySeq
std::shared_ptr< Ledger const > getLedgerBySeq(std::uint32_t index)
Definition: LedgerMaster.cpp:1814
ripple::AcceptedLedgerTx::getAffected
boost::container::flat_set< AccountID > const & getAffected() const
Definition: AcceptedLedgerTx.h:64
ripple::NetworkOPsImp::StateAccounting::CounterData::counters
decltype(counters_) counters
Definition: NetworkOPs.cpp:176
ripple::NetworkOPsImp::Stats::tracking_duration
beast::insight::Gauge tracking_duration
Definition: NetworkOPs.cpp:819
ripple::warnRPC_UNSUPPORTED_MAJORITY
@ warnRPC_UNSUPPORTED_MAJORITY
Definition: ErrorCodes.h:154
ripple::NetworkOPsImp::subTransactions
bool subTransactions(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3988
ripple::TimeKeeper::closeTime
virtual time_point closeTime() const =0
Returns the close time, in network time.
ripple::ValStatus::current
@ current
This was a new validation and was added.
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::NetworkOPsImp::StateAccounting::counters_
std::array< Counters, 5 > counters_
Definition: NetworkOPs.cpp:142
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
ripple::NetworkOPsImp::unsubLedger
bool unsubLedger(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3916
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::NetworkOPsImp::isAmendmentWarned
bool isAmendmentWarned() override
Definition: NetworkOPs.cpp:1595
std::uint64_t
ripple::NetworkOPsImp::needNetworkLedger_
std::atomic< bool > needNetworkLedger_
Definition: NetworkOPs.cpp:720
ripple::temBAD_SIGNATURE
@ temBAD_SIGNATURE
Definition: TER.h:100
ripple::ReadView::succ
virtual std::optional< key_type > succ(key_type const &key, std::optional< key_type > const &last=std::nullopt) const =0
Return the key of the next state item.
ripple::Manifest::getMasterSignature
Blob getMasterSignature() const
Returns manifest master key signature.
Definition: app/misc/impl/Manifest.cpp:233
std::atomic< bool >
ripple::NetworkOPsImp::ServerFeeSummary::ServerFeeSummary
ServerFeeSummary()=default
ripple::NetworkOPsImp::StateAccounting::mode_
OperatingMode mode_
Definition: NetworkOPs.cpp:141
std::map
STL class.
ripple::LoadFeeTrack::getClusterFee
std::uint32_t getClusterFee() const
Definition: LoadFeeTrack.h:82
ripple::range
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition: RangeSet.h:53
ripple::Application::getValidationPublicKey
virtual PublicKey const & getValidationPublicKey() const =0
ripple::NetworkOPsImp::pubValidation
void pubValidation(std::shared_ptr< STValidation > const &val) override
Definition: NetworkOPs.cpp:2114
ripple::amountFromQuality
STAmount amountFromQuality(std::uint64_t rate)
Definition: STAmount.cpp:793
ripple::OrderBookDB::makeBookListeners
BookListeners::pointer makeBookListeners(Book const &)
Definition: OrderBookDB.cpp:202
ripple::NetworkOPs::FailHard
FailHard
Definition: NetworkOPs.h:91
ripple::NetworkOPsImp::subAccount
void subAccount(InfoSub::ref ispListener, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
Definition: NetworkOPs.cpp:3305
ripple::NetworkOPsImp::m_standalone
const bool m_standalone
Definition: NetworkOPs.cpp:764
ripple::ReadView::read
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
ripple::LedgerMaster::getCurrentLedger
std::shared_ptr< ReadView const > getCurrentLedger()
Definition: LedgerMaster.cpp:1650
Json::Int
int Int
Definition: json_forwards.h:26
ripple::NetworkOPsImp::Stats
Definition: NetworkOPs.cpp:778
ripple::AcceptedLedgerTx::getResult
TER getResult() const
Definition: AcceptedLedgerTx.h:80
ripple::RCLConsensus::parms
ConsensusParms const & parms() const
Definition: RCLConsensus.h:518
ripple::NetworkOPsImp::StateAccounting::CounterData::initialSyncUs
decltype(initialSyncUs_) initialSyncUs
Definition: NetworkOPs.cpp:179
ripple::STTx::getJson
Json::Value getJson(JsonOptions options) const override
Definition: STTx.cpp:229
beast::abstract_clock< std::chrono::steady_clock >
ripple::NetworkOPsImp::StateAccounting::CounterData::mode
decltype(mode_) mode
Definition: NetworkOPs.cpp:177
ripple::NetworkOPsImp::StateAccounting::CounterData
Definition: NetworkOPs.cpp:174
ripple::accountFunds
STAmount accountFunds(ReadView const &view, AccountID const &id, STAmount const &saDefault, FreezeHandling freezeHandling, beast::Journal j)
Definition: View.cpp:267
ripple::ttOFFER_CREATE
@ ttOFFER_CREATE
This transaction type creates an offer to trade one asset for another.
Definition: TxFormats.h:80
Json::Value::UInt
Json::UInt UInt
Definition: json_value.h:153
ripple::NetworkOPsImp::SubAccountHistoryIndex::historyTxIndex_
std::int32_t historyTxIndex_
Definition: NetworkOPs.cpp:671
ripple::NetworkOPsImp::TransactionStatus
Transaction with input flags and results to be applied in batches.
Definition: NetworkOPs.cpp:85
ripple::jtCLIENT_ACCT_HIST
@ jtCLIENT_ACCT_HIST
Definition: Job.h:49
ripple::Application::validators
virtual ValidatorList & validators()=0
beast::insight::Gauge
A metric for measuring an integral value.
Definition: Gauge.h:39
ripple::NetworkOPsImp::transactionBatch
void transactionBatch()
Apply transactions in batches.
Definition: NetworkOPs.cpp:1289
ripple::NetworkOPsImp::isNeedNetworkLedger
bool isNeedNetworkLedger() override
Definition: NetworkOPs.cpp:888
ripple::LoadManager::resetDeadlockDetector
void resetDeadlockDetector()
Reset the deadlock detection timer.
Definition: LoadManager.cpp:63
ripple::NetworkOPsImp::ServerFeeSummary::operator!=
bool operator!=(ServerFeeSummary const &b) const
Definition: NetworkOPs.cpp:1990
ripple::jtCLIENT_FEE_CHANGE
@ jtCLIENT_FEE_CHANGE
Definition: Job.h:47
ripple::NetworkOPsImp::TransactionStatus::TransactionStatus
TransactionStatus(std::shared_ptr< Transaction > t, bool a, bool l, FailHard f)
Definition: NetworkOPs.cpp:95
ripple::KeyType::secp256k1
@ secp256k1
ripple::NetworkOPsImp::setStandAlone
void setStandAlone() override
Definition: NetworkOPs.cpp:870
ripple::JobQueue
A pool of threads to perform work.
Definition: JobQueue.h:55
ripple::NetworkOPsImp::mSubLock
std::recursive_mutex mSubLock
Definition: NetworkOPs.cpp:716
std::vector::swap
T swap(T... args)
ripple::ValidatorList::expires
std::optional< TimeKeeper::time_point > expires() const
Return the time when the validator list will expire.
Definition: ValidatorList.cpp:1500
ripple::NetworkOPsImp::ServerFeeSummary::operator==
bool operator==(ServerFeeSummary const &b) const
Definition: NetworkOPs.cpp:203
std::weak_ptr< InfoSub >
ripple::rpcINTERNAL
@ rpcINTERNAL
Definition: ErrorCodes.h:130
ripple::multiply
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:47
std::min
T min(T... args)
ripple::OrderBookDB::getBookListeners
BookListeners::pointer getBookListeners(Book const &)
Definition: OrderBookDB.cpp:219
ripple::NetworkOPsImp::SubAccountHistoryIndex::forwardTxIndex_
std::uint32_t forwardTxIndex_
Definition: NetworkOPs.cpp:666
ripple::Serializer
Definition: Serializer.h:39
ripple::Manifest::sequence
std::uint32_t sequence
The sequence number of this manifest.
Definition: Manifest.h:92
ripple::LedgerMaster::getFetchPackCacheSize
std::size_t getFetchPackCacheSize() const
Definition: LedgerMaster.cpp:2354
ripple::getJson
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
Definition: LedgerToJson.cpp:291
ripple::NetworkOPsImp::sConsensusPhase
@ sConsensusPhase
Definition: NetworkOPs.cpp:751
ripple::NetworkOPsImp::mMutex
std::mutex mMutex
Definition: NetworkOPs.cpp:771
ripple::sfBaseFee
const SF_UINT64 sfBaseFee
ripple::NetworkOPsImp::Stats::tracking_transitions
beast::insight::Gauge tracking_transitions
Definition: NetworkOPs.cpp:825
ripple::LedgerMaster::haveValidated
bool haveValidated()
Whether we have ever fully validated a ledger.
Definition: LedgerMaster.h:286
ripple::LedgerMaster::getValidatedLedgerAge
std::chrono::seconds getValidatedLedgerAge()
Definition: LedgerMaster.cpp:274
ripple::generateSeed
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition: Seed.cpp:69
ripple::LedgerMaster::getClosedLedger
std::shared_ptr< Ledger const > getClosedLedger()
Definition: LedgerMaster.h:98
ripple::NetworkOPsImp::Stats::connected_transitions
beast::insight::Gauge connected_transitions
Definition: NetworkOPs.cpp:823
ripple::NetworkOPsImp::clusterTimer_
boost::asio::steady_timer clusterTimer_
Definition: NetworkOPs.cpp:727
ripple::STObject
Definition: STObject.h:51
ripple::perf::PerfLog::countersJson
virtual Json::Value countersJson() const =0
Render performance counters in Json.
ripple::NetworkOPsImp::mTransactions
std::vector< TransactionStatus > mTransactions
Definition: NetworkOPs.cpp:773
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:135
ripple::NetworkOPsImp::reportConsensusStateChange
void reportConsensusStateChange(ConsensusPhase phase)
Definition: NetworkOPs.cpp:2977
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::transResultInfo
bool transResultInfo(TER code, std::string &token, std::string &text)
Definition: TER.cpp:192
ripple::NetworkOPsImp::unsubServer
bool unsubServer(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3980
ripple::RCLConsensus::prevRoundTime
std::chrono::milliseconds prevRoundTime() const
Get duration of the previous round.
Definition: RCLConsensus.h:456
ripple::sterilize
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Definition: STTx.cpp:551
ripple::NetworkOPsImp::Stats::Stats
Stats(Handler const &handler, beast::insight::Collector::ptr const &collector)
Definition: NetworkOPs.cpp:781
ripple::NetworkOPsImp::setHeartbeatTimer
void setHeartbeatTimer()
Definition: NetworkOPs.cpp:958
ripple::NetworkOPsImp::unsubBookChanges
bool unsubBookChanges(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3924
ripple::Application::getNodeStore
virtual NodeStore::Database & getNodeStore()=0
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::Application::validatorManifests
virtual ManifestCache & validatorManifests()=0
ripple::NetworkOPsImp::getLocalTxCount
std::size_t getLocalTxCount() override
Definition: NetworkOPs.cpp:2991
ripple::NetworkOPsImp::StateAccounting::initialSyncUs_
std::uint64_t initialSyncUs_
Definition: NetworkOPs.cpp:147
ripple::NetworkOPsImp::mStreamMaps
std::array< SubMapType, SubTypes::sLastEntry+1 > mStreamMaps
Definition: NetworkOPs.cpp:757
ripple::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:69
ripple::LoadFeeTrack::getLoadFactor
std::uint32_t getLoadFactor() const
Definition: LoadFeeTrack.h:95
ripple::NetworkOPsImp::getLedgerFetchInfo
Json::Value getLedgerFetchInfo() override
Definition: NetworkOPs.cpp:2652
ripple::tapUNLIMITED
@ tapUNLIMITED
Definition: ApplyView.h:41
ripple::NetworkOPsImp::sManifests
@ sManifests
Definition: NetworkOPs.cpp:745
ripple::sfLedgerEntryType
const SF_UINT16 sfLedgerEntryType
ripple::NetworkOPsImp::StateAccounting::StateAccounting
StateAccounting()
Definition: NetworkOPs.cpp:151
ripple::NetworkOPsImp::SubAccountHistoryInfoWeak
Definition: NetworkOPs.cpp:691
ripple::INVALID
@ INVALID
Definition: Transaction.h:47
ripple::NetworkOPsImp::pubServer
void pubServer()
Definition: NetworkOPs.cpp:2019
ripple::base_uint::begin
iterator begin()
Definition: base_uint.h:126
ripple::tefPAST_SEQ
@ tefPAST_SEQ
Definition: TER.h:154
ripple::NetworkOPsImp::unsubBook
bool unsubBook(std::uint64_t uListener, Book const &) override
Definition: NetworkOPs.cpp:3848
ripple::NetworkOPsImp::acceptLedger
std::uint32_t acceptLedger(std::optional< std::chrono::milliseconds > consensusDelay) override
Accepts the current transaction tree, return the new ledger's sequence.
Definition: NetworkOPs.cpp:3857
ripple::NetworkOPsImp::sTransactions
@ sTransactions
Definition: NetworkOPs.cpp:747
ripple::NetworkOPsImp::mSubAccount
SubInfoMapType mSubAccount
Definition: NetworkOPs.cpp:736
ripple::Config::SERVER_DOMAIN
std::string SERVER_DOMAIN
Definition: Config.h:263
ripple::AcceptedLedgerTx::getMeta
TxMeta const & getMeta() const
Definition: AcceptedLedgerTx.h:58
ripple::NetworkOPsImp::clearNeedNetworkLedger
void clearNeedNetworkLedger() override
Definition: NetworkOPs.cpp:882
ripple::NetworkOPsImp::sBookChanges
@ sBookChanges
Definition: NetworkOPs.cpp:752
beast::rngfill
void rngfill(void *buffer, std::size_t bytes, Generator &g)
Definition: rngfill.h:33
Json::StaticString
Lightweight wrapper to tag static string.
Definition: json_value.h:60
ripple::NetworkOPsImp::TransactionStatus::admin
const bool admin
Definition: NetworkOPs.cpp:89
std
STL namespace.
ripple::featureNegativeUNL
const uint256 featureNegativeUNL
ripple::ltACCOUNT_ROOT
@ ltACCOUNT_ROOT
A ledger object which describes an account.
Definition: LedgerFormats.h:59
ripple::NetworkOPsImp::checkLastClosedLedger
bool checkLastClosedLedger(const Overlay::PeerSequence &, uint256 &networkClosed)
Definition: NetworkOPs.cpp:1632
std::unordered_set::insert
T insert(T... args)
ripple::NetworkOPsImp::strOperatingMode
std::string strOperatingMode(OperatingMode const mode, bool const admin) const override
Definition: NetworkOPs.cpp:1102
ripple::NetworkOPsImp::getBookPage
void getBookPage(std::shared_ptr< ReadView const > &lpLedger, Book const &, AccountID const &uTakerID, const bool bProof, unsigned int iLimit, Json::Value const &jvMarker, Json::Value &jvResult) override
Definition: NetworkOPs.cpp:4131
ripple::NetworkOPsImp::ServerFeeSummary::baseFee
XRPAmount baseFee
Definition: NetworkOPs.cpp:210
ripple::RPC::insertDeliveredAmount
void insertDeliveredAmount(Json::Value &meta, ReadView const &, std::shared_ptr< STTx const > const &serializedTx, TxMeta const &)
Add a delivered_amount field to the meta input/output parameter.
Definition: DeliveredAmount.cpp:143
ripple::NetworkOPsImp::pubPeerStatus
void pubPeerStatus(std::function< Json::Value(void)> const &) override
Definition: NetworkOPs.cpp:2192
ripple::NetworkOPsImp::mCond
std::condition_variable mCond
Definition: NetworkOPs.cpp:770
ripple::NetworkOPsImp::isFull
bool isFull() override
Definition: NetworkOPs.cpp:894
ripple::PostgresDatabase
Definition: PostgresDatabase.h:27
ripple::NodeStore::Database::getCountsJson
void getCountsJson(Json::Value &obj)
Definition: Database.cpp:352
ripple::NetworkOPsImp::subLedger
bool subLedger(InfoSub::ref ispListener, Json::Value &jvResult) override
Definition: NetworkOPs.cpp:3877
std::condition_variable
ripple::NetworkOPsImp::Stats::full_transitions
beast::insight::Gauge full_transitions
Definition: NetworkOPs.cpp:826
ripple::Config::RELAY_UNTRUSTED_VALIDATIONS
int RELAY_UNTRUSTED_VALIDATIONS
Definition: Config.h:151
ripple::stateNames
static const std::array< char const *, 5 > stateNames
Definition: NetworkOPs.cpp:839
ripple::NetworkOPsImp::sLedger
@ sLedger
Definition: NetworkOPs.cpp:744
ripple::TimeKeeper::now
virtual time_point now() const override=0
Returns the estimate of wall time, in network time.
ripple::NetworkOPsImp::subAccountHistory
error_code_i subAccountHistory(InfoSub::ref ispListener, AccountID const &account) override
subscribe an account's new transactions and retrieve the account's historical transactions
Definition: NetworkOPs.cpp:3750
ripple::NetworkOPsImp::mConsensus
RCLConsensus mConsensus
Definition: NetworkOPs.cpp:730
ripple::RCLConsensus::prevProposers
std::size_t prevProposers() const
Get the number of proposing peers that participated in the previous round.
Definition: RCLConsensus.h:443
ripple::Application::overlay
virtual Overlay & overlay()=0
ripple::NetworkOPsImp::sPeerStatus
@ sPeerStatus
Definition: NetworkOPs.cpp:750
std::chrono::milliseconds::count
T count(T... args)
ripple::NetworkOPsImp::mMode
std::atomic< OperatingMode > mMode
Definition: NetworkOPs.cpp:718
ripple::LedgerMaster::getValidatedLedger
std::shared_ptr< Ledger const > getValidatedLedger()
Definition: LedgerMaster.cpp:1660
ripple::NetworkOPsImp::unsubManifests
bool unsubManifests(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3942
ripple::tapFAIL_HARD
@ tapFAIL_HARD
Definition: ApplyView.h:34
ripple::TrustChanges::added
hash_set< NodeID > added
Definition: ValidatorList.h:111
ripple::NetworkOPsImp::amendmentBlocked_
std::atomic< bool > amendmentBlocked_
Definition: NetworkOPs.cpp:721
ripple::NetworkOPsImp::submitTransaction
void submitTransaction(std::shared_ptr< STTx const > const &) override
Definition: NetworkOPs.cpp:1122
std::string::empty
T empty(T... args)
ripple::OperatingMode
OperatingMode
Specifies the mode under which the server believes it's operating.
Definition: NetworkOPs.h:66
ripple::fhIGNORE_FREEZE
@ fhIGNORE_FREEZE
Definition: View.h:76
ripple::Overlay::networkID
virtual std::optional< std::uint32_t > networkID() const =0
Returns the ID of the network this server is configured for, if any.
ripple::InboundLedgers::clearFailures
virtual void clearFailures()=0
ripple::TokenType::NodePublic
@ NodePublic
ripple::NetworkOPsImp::transJson
Json::Value transJson(const STTx &transaction, TER result, bool validated, std::shared_ptr< ReadView const > const &ledger)
Definition: NetworkOPs.cpp:2999
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
ripple::NetworkOPsImp::mLastConsensusPhase
ConsensusPhase mLastConsensusPhase
Definition: NetworkOPs.cpp:732
ripple::NetworkOPsImp::updateLocalTx
void updateLocalTx(ReadView const &view) override
Definition: NetworkOPs.cpp:2986
std::optional
mutex
ripple::NetworkOPsImp::sRTTransactions
@ sRTTransactions
Definition: NetworkOPs.cpp:748
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::NetworkOPsImp::pubConsensus
void pubConsensus(ConsensusPhase phase)
Definition: NetworkOPs.cpp:2087
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::NetworkOPsImp::subRTTransactions
bool subRTTransactions(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4006
ripple::Book
Specifies an order book.
Definition: Book.h:33
ripple::ClusterNode::getReportTime
NetClock::time_point getReportTime() const
Definition: ClusterNode.h:57
ripple::NetworkOPsImp::Stats::disconnected_transitions
beast::insight::Gauge disconnected_transitions
Definition: NetworkOPs.cpp:822
ripple::genesisAccountId
static const auto genesisAccountId
Definition: NetworkOPs.cpp:852
std::make_pair
T make_pair(T... args)
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::NetworkOPsImp::pubProposedTransaction
void pubProposedTransaction(std::shared_ptr< ReadView const > const &ledger, std::shared_ptr< STTx const > const &transaction, TER result) override
Definition: NetworkOPs.cpp:2658
ripple::ltRIPPLE_STATE
@ ltRIPPLE_STATE
A ledger object which describes a bidirectional trust line.
Definition: LedgerFormats.h:74
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:45
std::unordered_map::end
T end(T... args)
ripple::mulDiv
std::pair< bool, Dest > mulDiv(Source1 value, Dest mul, Source2 div)
Definition: FeeUnits.h:473
ripple::NetworkOPsImp::getServerInfo
Json::Value getServerInfo(bool human, bool admin, bool counters) override
Definition: NetworkOPs.cpp:2273
ripple::perf::PerfLog::currentJson
virtual Json::Value currentJson() const =0
Render currently executing jobs and RPC calls and durations in Json.
ripple::NetworkOPsImp::m_ledgerMaster
LedgerMaster & m_ledgerMaster
Definition: NetworkOPs.cpp:734
ripple::NetworkOPsImp::subServer
bool subServer(InfoSub::ref ispListener, Json::Value &jvResult, bool admin) override
Definition: NetworkOPs.cpp:3950
ripple::NetworkOPsImp::SubAccountHistoryInfoWeak::index_
std::shared_ptr< SubAccountHistoryIndex > index_
Definition: NetworkOPs.cpp:694
ripple::RelationalDatabase::AccountTxArgs::ledger
std::optional< LedgerSpecifier > ledger
Definition: RelationalDatabase.h:99
ripple::LedgerRange
Definition: RelationalDatabase.h:42
std::numeric_limits::max
T max(T... args)
ripple::NetworkOPsImp::accountHistoryTxTimer_
boost::asio::steady_timer accountHistoryTxTimer_
Definition: NetworkOPs.cpp:728
ripple::make_LocalTxs
std::unique_ptr< LocalTxs > make_LocalTxs()
Definition: LocalTxs.cpp:197
ripple::TxQ::getMetrics
Metrics getMetrics(OpenView const &view) const
Returns fee metrics in reference fee level units.
Definition: TxQ.cpp:1732
ripple::NetworkOPsImp::doTransactionSync
void doTransactionSync(std::shared_ptr< Transaction > transaction, bool bUnlimited, FailHard failType)
For transactions submitted directly by a client, apply batch of transactions and wait for this transa...
Definition: NetworkOPs.cpp:1249
ripple::NetworkOPsImp::StateAccounting::getCounterData
CounterData getCounterData() const
Definition: NetworkOPs.cpp:183
ripple::NetworkOPsImp::Stats::full_duration
beast::insight::Gauge full_duration
Definition: NetworkOPs.cpp:820
ripple::Application::getPerfLog
virtual perf::PerfLog & getPerfLog()=0
ripple::send_if
send_if_pred< Predicate > send_if(std::shared_ptr< Message > const &m, Predicate const &f)
Helper function to aid in type deduction.
Definition: predicates.h:75
ripple::Overlay::getPeerDisconnect
virtual std::uint64_t getPeerDisconnect() const =0
ripple::NetworkOPsImp::subBook
bool subBook(InfoSub::ref ispListener, Book const &) override
Definition: NetworkOPs.cpp:3838
ripple::NetworkOPsImp::subConsensus
bool subConsensus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4066
ripple::NetworkOPsImp::getConsensusInfo
Json::Value getConsensusInfo() override
Definition: NetworkOPs.cpp:2267
ripple::NetworkOPsImp::Stats::connected_duration
beast::insight::Gauge connected_duration
Definition: NetworkOPs.cpp:817
ripple::ValidatorList::count
std::size_t count() const
Return the number of configured validator list sites.
Definition: ValidatorList.cpp:1459
ripple::NetworkOPsImp::waitHandlerCounter_
ClosureCounter< void, boost::system::error_code const & > waitHandlerCounter_
Definition: NetworkOPs.cpp:725
std::unique_ptr
STL class.
ripple::cdirFirst
bool cdirFirst(ReadView const &view, uint256 const &root, std::shared_ptr< SLE const > &page, unsigned int &index, uint256 &entry)
Returns the first entry in the directory, advancing the index.
Definition: View.cpp:134
ripple::NetworkOPsImp::SubAccountHistoryIndex::stopHistorical_
std::atomic< bool > stopHistorical_
Definition: NetworkOPs.cpp:673
ripple::NetworkOPsImp
Definition: NetworkOPs.cpp:79
ripple::NetworkOPsImp::mSubAccountHistory
SubAccountHistoryMapType mSubAccountHistory
Definition: NetworkOPs.cpp:741
ripple::NetworkOPsImp::StateAccounting::mode
void mode(OperatingMode om)
Record state transition.
Definition: NetworkOPs.cpp:4509
ripple::RPC::accountFromStringStrict
std::optional< AccountID > accountFromStringStrict(std::string const &account)
Get an AccountID from an account ID or public key.
Definition: RPCHelpers.cpp:42
unordered_map
ripple::NetworkOPsImp::StateAccounting::states_
static const std::array< Json::StaticString const, 5 > states_
Definition: NetworkOPs.cpp:148
ripple::RFC1751::getWordFromBlob
static std::string getWordFromBlob(void const *blob, size_t bytes)
Chooses a single dictionary word from the data.
Definition: RFC1751.cpp:494
ripple::NetworkOPsImp::unsubAccountInternal
void unsubAccountInternal(std::uint64_t seq, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
Definition: NetworkOPs.cpp:3358
ripple::sfSigningTime
const SF_UINT32 sfSigningTime
ripple::NetworkOPsImp::unsubAccountHistory
void unsubAccountHistory(InfoSub::ref ispListener, AccountID const &account, bool historyOnly) override
unsubscribe an account's transactions
Definition: NetworkOPs.cpp:3796
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:219
ripple::NetworkOPsImp::StateAccounting
State accounting records two attributes for each possible server state: 1) Amount of time spent in ea...
Definition: NetworkOPs.cpp:131
beast::insight::Hook
A reference to a handler for performing polled collection.
Definition: Hook.h:31
ripple::getQuality
std::uint64_t getQuality(uint256 const &uBase)
Definition: Indexes.cpp:108
ripple::Overlay::getPeerDisconnectCharges
virtual std::uint64_t getPeerDisconnectCharges() const =0
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:603
ripple::NetworkOPsImp::unsubPeerStatus
bool unsubPeerStatus(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4058
ripple::NetworkOPsImp::app_
Application & app_
Definition: NetworkOPs.cpp:711
ripple::handleNewValidation
void handleNewValidation(Application &app, std::shared_ptr< STValidation > const &val, std::string const &source)
Handle a new validation.
Definition: RCLValidations.cpp:152
ripple::NetworkOPsImp::SubAccountHistoryIndex::accountId_
const AccountID accountId_
Definition: NetworkOPs.cpp:664
ripple::isTemMalformed
bool isTemMalformed(TER x)
Definition: TER.h:576
ripple::trunc32
static std::uint32_t trunc32(std::uint64_t v)
Definition: NetworkOPs.cpp:2011
ripple::XRPAmount::jsonClipped
Json::Value jsonClipped() const
Definition: XRPAmount.h:209
ripple::Book::in
Issue in
Definition: Book.h:36
ripple::RelationalDatabase::AccountTxPageOptions
Definition: RelationalDatabase.h:74
ripple::NetworkOPsImp::getOperatingMode
OperatingMode getOperatingMode() const override
Definition: NetworkOPs.cpp:858
ripple::Issue::account
AccountID account
Definition: Issue.h:38
ripple::ClusterNode::identity
PublicKey const & identity() const
Definition: ClusterNode.h:63
ripple::NetworkOPsImp::ServerFeeSummary::em
std::optional< TxQ::Metrics > em
Definition: NetworkOPs.cpp:211
ripple::NetworkOPsImp::mRpcSubMap
subRpcMapType mRpcSubMap
Definition: NetworkOPs.cpp:739
ripple::ValidatorList::quorum
std::size_t quorum() const
Get quorum value for current trusted key set.
Definition: ValidatorList.h:492
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::sfAmendments
const SF_VECTOR256 sfAmendments
ripple::TimeKeeper::closeOffset
virtual std::chrono::duration< std::int32_t > closeOffset() const =0
ripple::NetworkOPsImp::findRpcSub
InfoSub::pointer findRpcSub(std::string const &strUrl) override
Definition: NetworkOPs.cpp:4083
beast::insight::Gauge::set
void set(value_type value) const
Set the value on the gauge.
Definition: Gauge.h:68
ripple::NetworkOPsImp::ServerFeeSummary::loadBaseServer
std::uint32_t loadBaseServer
Definition: NetworkOPs.cpp:209
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NetworkOPsImp::clearLedgerFetch
void clearLedgerFetch() override
Definition: NetworkOPs.cpp:2646
ripple::ClusterNode::getLoadFee
std::uint32_t getLoadFee() const
Definition: ClusterNode.h:51
ripple::ClosureCounter::wrap
std::optional< Substitute< Closure > > wrap(Closure &&closure)
Wrap the passed closure with a reference counter.
Definition: ClosureCounter.h:192
ripple::test::jtx::rate
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
Definition: rate.cpp:30
ripple::NetworkOPsImp::beginConsensus
bool beginConsensus(uint256 const &networkClosed) override
Definition: NetworkOPs.cpp:1791
ripple::NetworkOPsImp::setAmendmentBlocked
void setAmendmentBlocked() override
Definition: NetworkOPs.cpp:1588
ripple::NetworkOPsImp::processTransaction
void processTransaction(std::shared_ptr< Transaction > &transaction, bool bUnlimited, bool bLocal, FailHard failType) override
Process transactions as they arrive from the network or which are submitted by clients.
Definition: NetworkOPs.cpp:1175
beast
Definition: base_uint.h:671
string
ripple::OperatingMode::FULL
@ FULL
we have the ledger and can even validate
std::chrono::steady_clock::now
T now(T... args)