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