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]() {
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]() {
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]() {
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(
1228  jtBATCH, "transactionBatch", [this]() { transactionBatch(); }))
1229  {
1230  mDispatchState = DispatchState::scheduled;
1231  }
1232  }
1233 }
1234 
1235 void
1236 NetworkOPsImp::doTransactionSync(
1237  std::shared_ptr<Transaction> transaction,
1238  bool bUnlimited,
1239  FailHard failType)
1240 {
1241  std::unique_lock<std::mutex> lock(mMutex);
1242 
1243  if (!transaction->getApplying())
1244  {
1245  mTransactions.push_back(
1246  TransactionStatus(transaction, bUnlimited, true, failType));
1247  transaction->setApplying();
1248  }
1249 
1250  do
1251  {
1252  if (mDispatchState == DispatchState::running)
1253  {
1254  // A batch processing job is already running, so wait.
1255  mCond.wait(lock);
1256  }
1257  else
1258  {
1259  apply(lock);
1260 
1261  if (mTransactions.size())
1262  {
1263  // More transactions need to be applied, but by another job.
1264  if (m_job_queue.addJob(jtBATCH, "transactionBatch", [this]() {
1265  transactionBatch();
1266  }))
1267  {
1268  mDispatchState = DispatchState::scheduled;
1269  }
1270  }
1271  }
1272  } while (transaction->getApplying());
1273 }
1274 
1275 void
1276 NetworkOPsImp::transactionBatch()
1277 {
1278  std::unique_lock<std::mutex> lock(mMutex);
1279 
1280  if (mDispatchState == DispatchState::running)
1281  return;
1282 
1283  while (mTransactions.size())
1284  {
1285  apply(lock);
1286  }
1287 }
1288 
1289 void
1290 NetworkOPsImp::apply(std::unique_lock<std::mutex>& batchLock)
1291 {
1292  std::vector<TransactionStatus> submit_held;
1293  std::vector<TransactionStatus> transactions;
1294  mTransactions.swap(transactions);
1295  assert(!transactions.empty());
1296 
1297  assert(mDispatchState != DispatchState::running);
1298  mDispatchState = DispatchState::running;
1299 
1300  batchLock.unlock();
1301 
1302  {
1303  std::unique_lock masterLock{app_.getMasterMutex(), std::defer_lock};
1304  bool changed = false;
1305  {
1306  std::unique_lock ledgerLock{
1307  m_ledgerMaster.peekMutex(), std::defer_lock};
1308  std::lock(masterLock, ledgerLock);
1309 
1310  app_.openLedger().modify([&](OpenView& view, beast::Journal j) {
1311  for (TransactionStatus& e : transactions)
1312  {
1313  // we check before adding to the batch
1314  ApplyFlags flags = tapNONE;
1315  if (e.admin)
1316  flags |= tapUNLIMITED;
1317 
1318  if (e.failType == FailHard::yes)
1319  flags |= tapFAIL_HARD;
1320 
1321  auto const result = app_.getTxQ().apply(
1322  app_, view, e.transaction->getSTransaction(), flags, j);
1323  e.result = result.first;
1324  e.applied = result.second;
1325  changed = changed || result.second;
1326  }
1327  return changed;
1328  });
1329  }
1330  if (changed)
1331  reportFeeChange();
1332 
1333  std::optional<LedgerIndex> validatedLedgerIndex;
1334  if (auto const l = m_ledgerMaster.getValidatedLedger())
1335  validatedLedgerIndex = l->info().seq;
1336 
1337  auto newOL = app_.openLedger().current();
1338  for (TransactionStatus& e : transactions)
1339  {
1340  e.transaction->clearSubmitResult();
1341 
1342  if (e.applied)
1343  {
1344  pubProposedTransaction(
1345  newOL, e.transaction->getSTransaction(), e.result);
1346  e.transaction->setApplied();
1347  }
1348 
1349  e.transaction->setResult(e.result);
1350 
1351  if (isTemMalformed(e.result))
1352  app_.getHashRouter().setFlags(e.transaction->getID(), SF_BAD);
1353 
1354 #ifdef DEBUG
1355  if (e.result != tesSUCCESS)
1356  {
1357  std::string token, human;
1358 
1359  if (transResultInfo(e.result, token, human))
1360  {
1361  JLOG(m_journal.info())
1362  << "TransactionResult: " << token << ": " << human;
1363  }
1364  }
1365 #endif
1366 
1367  bool addLocal = e.local;
1368 
1369  if (e.result == tesSUCCESS)
1370  {
1371  JLOG(m_journal.debug())
1372  << "Transaction is now included in open ledger";
1373  e.transaction->setStatus(INCLUDED);
1374 
1375  auto const& txCur = e.transaction->getSTransaction();
1376  auto const txNext = m_ledgerMaster.popAcctTransaction(txCur);
1377  if (txNext)
1378  {
1379  std::string reason;
1380  auto const trans = sterilize(*txNext);
1381  auto t = std::make_shared<Transaction>(trans, reason, app_);
1382  submit_held.emplace_back(t, false, false, FailHard::no);
1383  t->setApplying();
1384  }
1385  }
1386  else if (e.result == tefPAST_SEQ)
1387  {
1388  // duplicate or conflict
1389  JLOG(m_journal.info()) << "Transaction is obsolete";
1390  e.transaction->setStatus(OBSOLETE);
1391  }
1392  else if (e.result == terQUEUED)
1393  {
1394  JLOG(m_journal.debug())
1395  << "Transaction is likely to claim a"
1396  << " fee, but is queued until fee drops";
1397 
1398  e.transaction->setStatus(HELD);
1399  // Add to held transactions, because it could get
1400  // kicked out of the queue, and this will try to
1401  // put it back.
1402  m_ledgerMaster.addHeldTransaction(e.transaction);
1403  e.transaction->setQueued();
1404  e.transaction->setKept();
1405  }
1406  else if (isTerRetry(e.result))
1407  {
1408  if (e.failType != FailHard::yes)
1409  {
1410  // transaction should be held
1411  JLOG(m_journal.debug())
1412  << "Transaction should be held: " << e.result;
1413  e.transaction->setStatus(HELD);
1414  m_ledgerMaster.addHeldTransaction(e.transaction);
1415  e.transaction->setKept();
1416  }
1417  }
1418  else
1419  {
1420  JLOG(m_journal.debug())
1421  << "Status other than success " << e.result;
1422  e.transaction->setStatus(INVALID);
1423  }
1424 
1425  auto const enforceFailHard =
1426  e.failType == FailHard::yes && !isTesSuccess(e.result);
1427 
1428  if (addLocal && !enforceFailHard)
1429  {
1430  m_localTX->push_back(
1431  m_ledgerMaster.getCurrentLedgerIndex(),
1432  e.transaction->getSTransaction());
1433  e.transaction->setKept();
1434  }
1435 
1436  if ((e.applied ||
1437  ((mMode != OperatingMode::FULL) &&
1438  (e.failType != FailHard::yes) && e.local) ||
1439  (e.result == terQUEUED)) &&
1440  !enforceFailHard)
1441  {
1442  auto const toSkip =
1443  app_.getHashRouter().shouldRelay(e.transaction->getID());
1444 
1445  if (toSkip)
1446  {
1447  protocol::TMTransaction tx;
1448  Serializer s;
1449 
1450  e.transaction->getSTransaction()->add(s);
1451  tx.set_rawtransaction(s.data(), s.size());
1452  tx.set_status(protocol::tsCURRENT);
1453  tx.set_receivetimestamp(
1454  app_.timeKeeper().now().time_since_epoch().count());
1455  tx.set_deferred(e.result == terQUEUED);
1456  // FIXME: This should be when we received it
1457  app_.overlay().relay(e.transaction->getID(), tx, *toSkip);
1458  e.transaction->setBroadcast();
1459  }
1460  }
1461 
1462  if (validatedLedgerIndex)
1463  {
1464  auto [fee, accountSeq, availableSeq] =
1465  app_.getTxQ().getTxRequiredFeeAndSeq(
1466  *newOL, e.transaction->getSTransaction());
1467  e.transaction->setCurrentLedgerState(
1468  *validatedLedgerIndex, fee, accountSeq, availableSeq);
1469  }
1470  }
1471  }
1472 
1473  batchLock.lock();
1474 
1475  for (TransactionStatus& e : transactions)
1476  e.transaction->clearApplying();
1477 
1478  if (!submit_held.empty())
1479  {
1480  if (mTransactions.empty())
1481  mTransactions.swap(submit_held);
1482  else
1483  for (auto& e : submit_held)
1484  mTransactions.push_back(std::move(e));
1485  }
1486 
1487  mCond.notify_all();
1488 
1489  mDispatchState = DispatchState::none;
1490 }
1491 
1492 //
1493 // Owner functions
1494 //
1495 
1497 NetworkOPsImp::getOwnerInfo(
1499  AccountID const& account)
1500 {
1501  Json::Value jvObjects(Json::objectValue);
1502  auto root = keylet::ownerDir(account);
1503  auto sleNode = lpLedger->read(keylet::page(root));
1504  if (sleNode)
1505  {
1506  std::uint64_t uNodeDir;
1507 
1508  do
1509  {
1510  for (auto const& uDirEntry : sleNode->getFieldV256(sfIndexes))
1511  {
1512  auto sleCur = lpLedger->read(keylet::child(uDirEntry));
1513  assert(sleCur);
1514 
1515  switch (sleCur->getType())
1516  {
1517  case ltOFFER:
1518  if (!jvObjects.isMember(jss::offers))
1519  jvObjects[jss::offers] =
1521 
1522  jvObjects[jss::offers].append(
1523  sleCur->getJson(JsonOptions::none));
1524  break;
1525 
1526  case ltRIPPLE_STATE:
1527  if (!jvObjects.isMember(jss::ripple_lines))
1528  {
1529  jvObjects[jss::ripple_lines] =
1531  }
1532 
1533  jvObjects[jss::ripple_lines].append(
1534  sleCur->getJson(JsonOptions::none));
1535  break;
1536 
1537  case ltACCOUNT_ROOT:
1538  case ltDIR_NODE:
1539  default:
1540  assert(false);
1541  break;
1542  }
1543  }
1544 
1545  uNodeDir = sleNode->getFieldU64(sfIndexNext);
1546 
1547  if (uNodeDir)
1548  {
1549  sleNode = lpLedger->read(keylet::page(root, uNodeDir));
1550  assert(sleNode);
1551  }
1552  } while (uNodeDir);
1553  }
1554 
1555  return jvObjects;
1556 }
1557 
1558 //
1559 // Other
1560 //
1561 
1562 inline bool
1563 NetworkOPsImp::isBlocked()
1564 {
1565  return isAmendmentBlocked() || isUNLBlocked();
1566 }
1567 
1568 inline bool
1569 NetworkOPsImp::isAmendmentBlocked()
1570 {
1571  return amendmentBlocked_;
1572 }
1573 
1574 void
1575 NetworkOPsImp::setAmendmentBlocked()
1576 {
1577  amendmentBlocked_ = true;
1578  setMode(OperatingMode::CONNECTED);
1579 }
1580 
1581 inline bool
1582 NetworkOPsImp::isAmendmentWarned()
1583 {
1584  return !amendmentBlocked_ && amendmentWarned_;
1585 }
1586 
1587 inline void
1588 NetworkOPsImp::setAmendmentWarned()
1589 {
1590  amendmentWarned_ = true;
1591 }
1592 
1593 inline void
1594 NetworkOPsImp::clearAmendmentWarned()
1595 {
1596  amendmentWarned_ = false;
1597 }
1598 
1599 inline bool
1600 NetworkOPsImp::isUNLBlocked()
1601 {
1602  return unlBlocked_;
1603 }
1604 
1605 void
1606 NetworkOPsImp::setUNLBlocked()
1607 {
1608  unlBlocked_ = true;
1609  setMode(OperatingMode::CONNECTED);
1610 }
1611 
1612 inline void
1613 NetworkOPsImp::clearUNLBlocked()
1614 {
1615  unlBlocked_ = false;
1616 }
1617 
1618 bool
1619 NetworkOPsImp::checkLastClosedLedger(
1620  const Overlay::PeerSequence& peerList,
1621  uint256& networkClosed)
1622 {
1623  // Returns true if there's an *abnormal* ledger issue, normal changing in
1624  // TRACKING mode should return false. Do we have sufficient validations for
1625  // our last closed ledger? Or do sufficient nodes agree? And do we have no
1626  // better ledger available? If so, we are either tracking or full.
1627 
1628  JLOG(m_journal.trace()) << "NetworkOPsImp::checkLastClosedLedger";
1629 
1630  auto const ourClosed = m_ledgerMaster.getClosedLedger();
1631 
1632  if (!ourClosed)
1633  return false;
1634 
1635  uint256 closedLedger = ourClosed->info().hash;
1636  uint256 prevClosedLedger = ourClosed->info().parentHash;
1637  JLOG(m_journal.trace()) << "OurClosed: " << closedLedger;
1638  JLOG(m_journal.trace()) << "PrevClosed: " << prevClosedLedger;
1639 
1640  //-------------------------------------------------------------------------
1641  // Determine preferred last closed ledger
1642 
1643  auto& validations = app_.getValidations();
1644  JLOG(m_journal.debug())
1645  << "ValidationTrie " << Json::Compact(validations.getJsonTrie());
1646 
1647  // Will rely on peer LCL if no trusted validations exist
1649  peerCounts[closedLedger] = 0;
1650  if (mMode >= OperatingMode::TRACKING)
1651  peerCounts[closedLedger]++;
1652 
1653  for (auto& peer : peerList)
1654  {
1655  uint256 peerLedger = peer->getClosedLedgerHash();
1656 
1657  if (peerLedger.isNonZero())
1658  ++peerCounts[peerLedger];
1659  }
1660 
1661  for (auto const& it : peerCounts)
1662  JLOG(m_journal.debug()) << "L: " << it.first << " n=" << it.second;
1663 
1664  uint256 preferredLCL = validations.getPreferredLCL(
1665  RCLValidatedLedger{ourClosed, validations.adaptor().journal()},
1666  m_ledgerMaster.getValidLedgerIndex(),
1667  peerCounts);
1668 
1669  bool switchLedgers = preferredLCL != closedLedger;
1670  if (switchLedgers)
1671  closedLedger = preferredLCL;
1672  //-------------------------------------------------------------------------
1673  if (switchLedgers && (closedLedger == prevClosedLedger))
1674  {
1675  // don't switch to our own previous ledger
1676  JLOG(m_journal.info()) << "We won't switch to our own previous ledger";
1677  networkClosed = ourClosed->info().hash;
1678  switchLedgers = false;
1679  }
1680  else
1681  networkClosed = closedLedger;
1682 
1683  if (!switchLedgers)
1684  return false;
1685 
1686  auto consensus = m_ledgerMaster.getLedgerByHash(closedLedger);
1687 
1688  if (!consensus)
1689  consensus = app_.getInboundLedgers().acquire(
1690  closedLedger, 0, InboundLedger::Reason::CONSENSUS);
1691 
1692  if (consensus &&
1693  (!m_ledgerMaster.canBeCurrent(consensus) ||
1694  !m_ledgerMaster.isCompatible(
1695  *consensus, m_journal.debug(), "Not switching")))
1696  {
1697  // Don't switch to a ledger not on the validated chain
1698  // or with an invalid close time or sequence
1699  networkClosed = ourClosed->info().hash;
1700  return false;
1701  }
1702 
1703  JLOG(m_journal.warn()) << "We are not running on the consensus ledger";
1704  JLOG(m_journal.info()) << "Our LCL: " << getJson({*ourClosed, {}});
1705  JLOG(m_journal.info()) << "Net LCL " << closedLedger;
1706 
1707  if ((mMode == OperatingMode::TRACKING) || (mMode == OperatingMode::FULL))
1708  {
1709  setMode(OperatingMode::CONNECTED);
1710  }
1711 
1712  if (consensus)
1713  {
1714  // FIXME: If this rewinds the ledger sequence, or has the same
1715  // sequence, we should update the status on any stored transactions
1716  // in the invalidated ledgers.
1717  switchLastClosedLedger(consensus);
1718  }
1719 
1720  return true;
1721 }
1722 
1723 void
1724 NetworkOPsImp::switchLastClosedLedger(
1725  std::shared_ptr<Ledger const> const& newLCL)
1726 {
1727  // set the newLCL as our last closed ledger -- this is abnormal code
1728  JLOG(m_journal.error())
1729  << "JUMP last closed ledger to " << newLCL->info().hash;
1730 
1731  clearNeedNetworkLedger();
1732 
1733  // Update fee computations.
1734  app_.getTxQ().processClosedLedger(app_, *newLCL, true);
1735 
1736  // Caller must own master lock
1737  {
1738  // Apply tx in old open ledger to new
1739  // open ledger. Then apply local tx.
1740 
1741  auto retries = m_localTX->getTxSet();
1742  auto const lastVal = app_.getLedgerMaster().getValidatedLedger();
1743  std::optional<Rules> rules;
1744  if (lastVal)
1745  rules.emplace(*lastVal, app_.config().features);
1746  else
1747  rules.emplace(app_.config().features);
1748  app_.openLedger().accept(
1749  app_,
1750  *rules,
1751  newLCL,
1752  OrderedTxs({}),
1753  false,
1754  retries,
1755  tapNONE,
1756  "jump",
1757  [&](OpenView& view, beast::Journal j) {
1758  // Stuff the ledger with transactions from the queue.
1759  return app_.getTxQ().accept(app_, view);
1760  });
1761  }
1762 
1763  m_ledgerMaster.switchLCL(newLCL);
1764 
1765  protocol::TMStatusChange s;
1766  s.set_newevent(protocol::neSWITCHED_LEDGER);
1767  s.set_ledgerseq(newLCL->info().seq);
1768  s.set_networktime(app_.timeKeeper().now().time_since_epoch().count());
1769  s.set_ledgerhashprevious(
1770  newLCL->info().parentHash.begin(), newLCL->info().parentHash.size());
1771  s.set_ledgerhash(newLCL->info().hash.begin(), newLCL->info().hash.size());
1772 
1773  app_.overlay().foreach(
1774  send_always(std::make_shared<Message>(s, protocol::mtSTATUS_CHANGE)));
1775 }
1776 
1777 bool
1778 NetworkOPsImp::beginConsensus(uint256 const& networkClosed)
1779 {
1780  assert(networkClosed.isNonZero());
1781 
1782  auto closingInfo = m_ledgerMaster.getCurrentLedger()->info();
1783 
1784  JLOG(m_journal.info()) << "Consensus time for #" << closingInfo.seq
1785  << " with LCL " << closingInfo.parentHash;
1786 
1787  auto prevLedger = m_ledgerMaster.getLedgerByHash(closingInfo.parentHash);
1788 
1789  if (!prevLedger)
1790  {
1791  // this shouldn't happen unless we jump ledgers
1792  if (mMode == OperatingMode::FULL)
1793  {
1794  JLOG(m_journal.warn()) << "Don't have LCL, going to tracking";
1795  setMode(OperatingMode::TRACKING);
1796  }
1797 
1798  return false;
1799  }
1800 
1801  assert(prevLedger->info().hash == closingInfo.parentHash);
1802  assert(
1803  closingInfo.parentHash ==
1804  m_ledgerMaster.getClosedLedger()->info().hash);
1805 
1806  if (prevLedger->rules().enabled(featureNegativeUNL))
1807  app_.validators().setNegativeUNL(prevLedger->negativeUNL());
1808  TrustChanges const changes = app_.validators().updateTrusted(
1809  app_.getValidations().getCurrentNodeIDs(),
1810  closingInfo.parentCloseTime,
1811  *this,
1812  app_.overlay(),
1813  app_.getHashRouter());
1814 
1815  if (!changes.added.empty() || !changes.removed.empty())
1816  app_.getValidations().trustChanged(changes.added, changes.removed);
1817 
1818  mConsensus.startRound(
1819  app_.timeKeeper().closeTime(),
1820  networkClosed,
1821  prevLedger,
1822  changes.removed,
1823  changes.added);
1824 
1825  const ConsensusPhase currPhase = mConsensus.phase();
1826  if (mLastConsensusPhase != currPhase)
1827  {
1828  reportConsensusStateChange(currPhase);
1829  mLastConsensusPhase = currPhase;
1830  }
1831 
1832  JLOG(m_journal.debug()) << "Initiating consensus engine";
1833  return true;
1834 }
1835 
1836 bool
1837 NetworkOPsImp::processTrustedProposal(RCLCxPeerPos peerPos)
1838 {
1839  return mConsensus.peerProposal(app_.timeKeeper().closeTime(), peerPos);
1840 }
1841 
1842 void
1843 NetworkOPsImp::mapComplete(std::shared_ptr<SHAMap> const& map, bool fromAcquire)
1844 {
1845  // We now have an additional transaction set
1846  // either created locally during the consensus process
1847  // or acquired from a peer
1848 
1849  // Inform peers we have this set
1850  protocol::TMHaveTransactionSet msg;
1851  msg.set_hash(map->getHash().as_uint256().begin(), 256 / 8);
1852  msg.set_status(protocol::tsHAVE);
1853  app_.overlay().foreach(
1854  send_always(std::make_shared<Message>(msg, protocol::mtHAVE_SET)));
1855 
1856  // We acquired it because consensus asked us to
1857  if (fromAcquire)
1858  mConsensus.gotTxSet(app_.timeKeeper().closeTime(), RCLTxSet{map});
1859 }
1860 
1861 void
1862 NetworkOPsImp::endConsensus()
1863 {
1864  uint256 deadLedger = m_ledgerMaster.getClosedLedger()->info().parentHash;
1865 
1866  for (auto const& it : app_.overlay().getActivePeers())
1867  {
1868  if (it && (it->getClosedLedgerHash() == deadLedger))
1869  {
1870  JLOG(m_journal.trace()) << "Killing obsolete peer status";
1871  it->cycleStatus();
1872  }
1873  }
1874 
1875  uint256 networkClosed;
1876  bool ledgerChange =
1877  checkLastClosedLedger(app_.overlay().getActivePeers(), networkClosed);
1878 
1879  if (networkClosed.isZero())
1880  return;
1881 
1882  // WRITEME: Unless we are in FULL and in the process of doing a consensus,
1883  // we must count how many nodes share our LCL, how many nodes disagree with
1884  // our LCL, and how many validations our LCL has. We also want to check
1885  // timing to make sure there shouldn't be a newer LCL. We need this
1886  // information to do the next three tests.
1887 
1888  if (((mMode == OperatingMode::CONNECTED) ||
1889  (mMode == OperatingMode::SYNCING)) &&
1890  !ledgerChange)
1891  {
1892  // Count number of peers that agree with us and UNL nodes whose
1893  // validations we have for LCL. If the ledger is good enough, go to
1894  // TRACKING - TODO
1895  if (!needNetworkLedger_)
1896  setMode(OperatingMode::TRACKING);
1897  }
1898 
1899  if (((mMode == OperatingMode::CONNECTED) ||
1900  (mMode == OperatingMode::TRACKING)) &&
1901  !ledgerChange)
1902  {
1903  // check if the ledger is good enough to go to FULL
1904  // Note: Do not go to FULL if we don't have the previous ledger
1905  // check if the ledger is bad enough to go to CONNECTE D -- TODO
1906  auto current = m_ledgerMaster.getCurrentLedger();
1907  if (app_.timeKeeper().now() < (current->info().parentCloseTime +
1908  2 * current->info().closeTimeResolution))
1909  {
1910  setMode(OperatingMode::FULL);
1911  }
1912  }
1913 
1914  beginConsensus(networkClosed);
1915 }
1916 
1917 void
1918 NetworkOPsImp::consensusViewChange()
1919 {
1920  if ((mMode == OperatingMode::FULL) || (mMode == OperatingMode::TRACKING))
1921  {
1922  setMode(OperatingMode::CONNECTED);
1923  }
1924 }
1925 
1926 void
1927 NetworkOPsImp::pubManifest(Manifest const& mo)
1928 {
1929  // VFALCO consider std::shared_mutex
1930  std::lock_guard sl(mSubLock);
1931 
1932  if (!mStreamMaps[sManifests].empty())
1933  {
1935 
1936  jvObj[jss::type] = "manifestReceived";
1937  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, mo.masterKey);
1938  if (!mo.signingKey.empty())
1939  jvObj[jss::signing_key] =
1940  toBase58(TokenType::NodePublic, mo.signingKey);
1941  jvObj[jss::seq] = Json::UInt(mo.sequence);
1942  if (auto sig = mo.getSignature())
1943  jvObj[jss::signature] = strHex(*sig);
1944  jvObj[jss::master_signature] = strHex(mo.getMasterSignature());
1945  if (!mo.domain.empty())
1946  jvObj[jss::domain] = mo.domain;
1947  jvObj[jss::manifest] = strHex(mo.serialized);
1948 
1949  for (auto i = mStreamMaps[sManifests].begin();
1950  i != mStreamMaps[sManifests].end();)
1951  {
1952  if (auto p = i->second.lock())
1953  {
1954  p->send(jvObj, true);
1955  ++i;
1956  }
1957  else
1958  {
1959  i = mStreamMaps[sManifests].erase(i);
1960  }
1961  }
1962  }
1963 }
1964 
1965 NetworkOPsImp::ServerFeeSummary::ServerFeeSummary(
1966  XRPAmount fee,
1967  TxQ::Metrics&& escalationMetrics,
1968  LoadFeeTrack const& loadFeeTrack)
1969  : loadFactorServer{loadFeeTrack.getLoadFactor()}
1970  , loadBaseServer{loadFeeTrack.getLoadBase()}
1971  , baseFee{fee}
1972  , em{std::move(escalationMetrics)}
1973 {
1974 }
1975 
1976 bool
1978  NetworkOPsImp::ServerFeeSummary const& b) const
1979 {
1980  if (loadFactorServer != b.loadFactorServer ||
1981  loadBaseServer != b.loadBaseServer || baseFee != b.baseFee ||
1982  em.has_value() != b.em.has_value())
1983  return true;
1984 
1985  if (em && b.em)
1986  {
1987  return (
1988  em->minProcessingFeeLevel != b.em->minProcessingFeeLevel ||
1989  em->openLedgerFeeLevel != b.em->openLedgerFeeLevel ||
1990  em->referenceFeeLevel != b.em->referenceFeeLevel);
1991  }
1992 
1993  return false;
1994 }
1995 
1996 // Need to cap to uint64 to uint32 due to JSON limitations
1997 static std::uint32_t
1999 {
2001 
2002  return std::min(max32, v);
2003 };
2004 
2005 void
2007 {
2008  // VFALCO TODO Don't hold the lock across calls to send...make a copy of the
2009  // list into a local array while holding the lock then release
2010  // the lock and call send on everyone.
2011  //
2013 
2014  if (!mStreamMaps[sServer].empty())
2015  {
2017 
2018  ServerFeeSummary f{
2019  app_.openLedger().current()->fees().base,
2021  app_.getFeeTrack()};
2022 
2023  jvObj[jss::type] = "serverStatus";
2024  jvObj[jss::server_status] = strOperatingMode();
2025  jvObj[jss::load_base] = f.loadBaseServer;
2026  jvObj[jss::load_factor_server] = f.loadFactorServer;
2027  jvObj[jss::base_fee] = f.baseFee.jsonClipped();
2028 
2029  if (f.em)
2030  {
2031  auto const loadFactor = std::max(
2032  safe_cast<std::uint64_t>(f.loadFactorServer),
2033  mulDiv(
2034  f.em->openLedgerFeeLevel,
2035  f.loadBaseServer,
2036  f.em->referenceFeeLevel)
2037  .second);
2038 
2039  jvObj[jss::load_factor] = trunc32(loadFactor);
2040  jvObj[jss::load_factor_fee_escalation] =
2041  f.em->openLedgerFeeLevel.jsonClipped();
2042  jvObj[jss::load_factor_fee_queue] =
2043  f.em->minProcessingFeeLevel.jsonClipped();
2044  jvObj[jss::load_factor_fee_reference] =
2045  f.em->referenceFeeLevel.jsonClipped();
2046  }
2047  else
2048  jvObj[jss::load_factor] = f.loadFactorServer;
2049 
2050  mLastFeeSummary = f;
2051 
2052  for (auto i = mStreamMaps[sServer].begin();
2053  i != mStreamMaps[sServer].end();)
2054  {
2055  InfoSub::pointer p = i->second.lock();
2056 
2057  // VFALCO TODO research the possibility of using thread queues and
2058  // linearizing the deletion of subscribers with the
2059  // sending of JSON data.
2060  if (p)
2061  {
2062  p->send(jvObj, true);
2063  ++i;
2064  }
2065  else
2066  {
2067  i = mStreamMaps[sServer].erase(i);
2068  }
2069  }
2070  }
2071 }
2072 
2073 void
2075 {
2077 
2078  auto& streamMap = mStreamMaps[sConsensusPhase];
2079  if (!streamMap.empty())
2080  {
2082  jvObj[jss::type] = "consensusPhase";
2083  jvObj[jss::consensus] = to_string(phase);
2084 
2085  for (auto i = streamMap.begin(); i != streamMap.end();)
2086  {
2087  if (auto p = i->second.lock())
2088  {
2089  p->send(jvObj, true);
2090  ++i;
2091  }
2092  else
2093  {
2094  i = streamMap.erase(i);
2095  }
2096  }
2097  }
2098 }
2099 
2100 void
2102 {
2103  // VFALCO consider std::shared_mutex
2105 
2106  if (!mStreamMaps[sValidations].empty())
2107  {
2109 
2110  auto const signerPublic = val->getSignerPublic();
2111 
2112  jvObj[jss::type] = "validationReceived";
2113  jvObj[jss::validation_public_key] =
2114  toBase58(TokenType::NodePublic, signerPublic);
2115  jvObj[jss::ledger_hash] = to_string(val->getLedgerHash());
2116  jvObj[jss::signature] = strHex(val->getSignature());
2117  jvObj[jss::full] = val->isFull();
2118  jvObj[jss::flags] = val->getFlags();
2119  jvObj[jss::signing_time] = *(*val)[~sfSigningTime];
2120  jvObj[jss::data] = strHex(val->getSerializer().slice());
2121 
2122  if (auto version = (*val)[~sfServerVersion])
2123  jvObj[jss::server_version] = std::to_string(*version);
2124 
2125  if (auto cookie = (*val)[~sfCookie])
2126  jvObj[jss::cookie] = std::to_string(*cookie);
2127 
2128  if (auto hash = (*val)[~sfValidatedHash])
2129  jvObj[jss::validated_hash] = strHex(*hash);
2130 
2131  auto const masterKey =
2132  app_.validatorManifests().getMasterKey(signerPublic);
2133 
2134  if (masterKey != signerPublic)
2135  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, masterKey);
2136 
2137  if (auto const seq = (*val)[~sfLedgerSequence])
2138  jvObj[jss::ledger_index] = to_string(*seq);
2139 
2140  if (val->isFieldPresent(sfAmendments))
2141  {
2142  jvObj[jss::amendments] = Json::Value(Json::arrayValue);
2143  for (auto const& amendment : val->getFieldV256(sfAmendments))
2144  jvObj[jss::amendments].append(to_string(amendment));
2145  }
2146 
2147  if (auto const closeTime = (*val)[~sfCloseTime])
2148  jvObj[jss::close_time] = *closeTime;
2149 
2150  if (auto const loadFee = (*val)[~sfLoadFee])
2151  jvObj[jss::load_fee] = *loadFee;
2152 
2153  if (auto const baseFee = (*val)[~sfBaseFee])
2154  jvObj[jss::base_fee] = static_cast<double>(*baseFee);
2155 
2156  if (auto const reserveBase = (*val)[~sfReserveBase])
2157  jvObj[jss::reserve_base] = *reserveBase;
2158 
2159  if (auto const reserveInc = (*val)[~sfReserveIncrement])
2160  jvObj[jss::reserve_inc] = *reserveInc;
2161 
2162  for (auto i = mStreamMaps[sValidations].begin();
2163  i != mStreamMaps[sValidations].end();)
2164  {
2165  if (auto p = i->second.lock())
2166  {
2167  p->send(jvObj, true);
2168  ++i;
2169  }
2170  else
2171  {
2172  i = mStreamMaps[sValidations].erase(i);
2173  }
2174  }
2175  }
2176 }
2177 
2178 void
2180 {
2182 
2183  if (!mStreamMaps[sPeerStatus].empty())
2184  {
2185  Json::Value jvObj(func());
2186 
2187  jvObj[jss::type] = "peerStatusChange";
2188 
2189  for (auto i = mStreamMaps[sPeerStatus].begin();
2190  i != mStreamMaps[sPeerStatus].end();)
2191  {
2192  InfoSub::pointer p = i->second.lock();
2193 
2194  if (p)
2195  {
2196  p->send(jvObj, true);
2197  ++i;
2198  }
2199  else
2200  {
2201  i = mStreamMaps[sPeerStatus].erase(i);
2202  }
2203  }
2204  }
2205 }
2206 
2207 void
2209 {
2210  using namespace std::chrono_literals;
2211  if (om == OperatingMode::CONNECTED)
2212  {
2215  }
2216  else if (om == OperatingMode::SYNCING)
2217  {
2218  if (app_.getLedgerMaster().getValidatedLedgerAge() >= 1min)
2220  }
2221 
2222  if ((om > OperatingMode::CONNECTED) && isBlocked())
2224 
2225  if (mMode == om)
2226  return;
2227 
2228  mMode = om;
2229 
2230  accounting_.mode(om);
2231 
2232  JLOG(m_journal.info()) << "STATE->" << strOperatingMode();
2233  pubServer();
2234 }
2235 
2236 bool
2238  std::shared_ptr<STValidation> const& val,
2239  std::string const& source)
2240 {
2241  JLOG(m_journal.trace())
2242  << "recvValidation " << val->getLedgerHash() << " from " << source;
2243 
2244  handleNewValidation(app_, val, source);
2245 
2246  pubValidation(val);
2247 
2248  // We will always relay trusted validations; if configured, we will
2249  // also relay all untrusted validations.
2250  return app_.config().RELAY_UNTRUSTED_VALIDATIONS == 1 || val->isTrusted();
2251 }
2252 
2255 {
2256  return mConsensus.getJson(true);
2257 }
2258 
2260 NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
2261 {
2263 
2264  // System-level warnings
2265  {
2266  Json::Value warnings{Json::arrayValue};
2267  if (isAmendmentBlocked())
2268  {
2269  Json::Value& w = warnings.append(Json::objectValue);
2270  w[jss::id] = warnRPC_AMENDMENT_BLOCKED;
2271  w[jss::message] =
2272  "This server is amendment blocked, and must be updated to be "
2273  "able to stay in sync with the network.";
2274  }
2275  if (isUNLBlocked())
2276  {
2277  Json::Value& w = warnings.append(Json::objectValue);
2278  w[jss::id] = warnRPC_EXPIRED_VALIDATOR_LIST;
2279  w[jss::message] =
2280  "This server has an expired validator list. validators.txt "
2281  "may be incorrectly configured or some [validator_list_sites] "
2282  "may be unreachable.";
2283  }
2284  if (admin && isAmendmentWarned())
2285  {
2286  Json::Value& w = warnings.append(Json::objectValue);
2287  w[jss::id] = warnRPC_UNSUPPORTED_MAJORITY;
2288  w[jss::message] =
2289  "One or more unsupported amendments have reached majority. "
2290  "Upgrade to the latest version before they are activated "
2291  "to avoid being amendment blocked.";
2292  if (auto const expected =
2294  {
2295  auto& d = w[jss::details] = Json::objectValue;
2296  d[jss::expected_date] = expected->time_since_epoch().count();
2297  d[jss::expected_date_UTC] = to_string(*expected);
2298  }
2299  }
2300 
2301  if (warnings.size())
2302  info[jss::warnings] = std::move(warnings);
2303  }
2304 
2305  // hostid: unique string describing the machine
2306  if (human)
2307  info[jss::hostid] = getHostId(admin);
2308 
2309  // domain: if configured with a domain, report it:
2310  if (!app_.config().SERVER_DOMAIN.empty())
2311  info[jss::server_domain] = app_.config().SERVER_DOMAIN;
2312 
2313  if (!app_.config().reporting())
2314  if (auto const netid = app_.overlay().networkID())
2315  info[jss::network_id] = static_cast<Json::UInt>(*netid);
2316 
2317  info[jss::build_version] = BuildInfo::getVersionString();
2318 
2319  info[jss::server_state] = strOperatingMode(admin);
2320 
2321  info[jss::time] = to_string(std::chrono::floor<std::chrono::microseconds>(
2323 
2324  if (needNetworkLedger_)
2325  info[jss::network_ledger] = "waiting";
2326 
2327  info[jss::validation_quorum] =
2328  static_cast<Json::UInt>(app_.validators().quorum());
2329 
2330  if (admin)
2331  {
2332  switch (app_.config().NODE_SIZE)
2333  {
2334  case 0:
2335  info[jss::node_size] = "tiny";
2336  break;
2337  case 1:
2338  info[jss::node_size] = "small";
2339  break;
2340  case 2:
2341  info[jss::node_size] = "medium";
2342  break;
2343  case 3:
2344  info[jss::node_size] = "large";
2345  break;
2346  case 4:
2347  info[jss::node_size] = "huge";
2348  break;
2349  }
2350 
2351  auto when = app_.validators().expires();
2352 
2353  if (!human)
2354  {
2355  if (when)
2356  info[jss::validator_list_expires] =
2357  safe_cast<Json::UInt>(when->time_since_epoch().count());
2358  else
2359  info[jss::validator_list_expires] = 0;
2360  }
2361  else
2362  {
2363  auto& x = (info[jss::validator_list] = Json::objectValue);
2364 
2365  x[jss::count] = static_cast<Json::UInt>(app_.validators().count());
2366 
2367  if (when)
2368  {
2369  if (*when == TimeKeeper::time_point::max())
2370  {
2371  x[jss::expiration] = "never";
2372  x[jss::status] = "active";
2373  }
2374  else
2375  {
2376  x[jss::expiration] = to_string(*when);
2377 
2378  if (*when > app_.timeKeeper().now())
2379  x[jss::status] = "active";
2380  else
2381  x[jss::status] = "expired";
2382  }
2383  }
2384  else
2385  {
2386  x[jss::status] = "unknown";
2387  x[jss::expiration] = "unknown";
2388  }
2389  }
2390  }
2391  info[jss::io_latency_ms] =
2392  static_cast<Json::UInt>(app_.getIOLatency().count());
2393 
2394  if (admin)
2395  {
2397  {
2398  info[jss::pubkey_validator] = toBase58(
2400  }
2401  else
2402  {
2403  info[jss::pubkey_validator] = "none";
2404  }
2405  }
2406 
2407  if (counters)
2408  {
2409  info[jss::counters] = app_.getPerfLog().countersJson();
2410 
2411  Json::Value nodestore(Json::objectValue);
2412  if (app_.getShardStore())
2413  app_.getShardStore()->getCountsJson(nodestore);
2414  else
2415  app_.getNodeStore().getCountsJson(nodestore);
2416  info[jss::counters][jss::nodestore] = nodestore;
2417  info[jss::current_activities] = app_.getPerfLog().currentJson();
2418  }
2419 
2420  info[jss::pubkey_node] =
2422 
2423  info[jss::complete_ledgers] = app_.getLedgerMaster().getCompleteLedgers();
2424 
2425  if (amendmentBlocked_)
2426  info[jss::amendment_blocked] = true;
2427 
2428  auto const fp = m_ledgerMaster.getFetchPackCacheSize();
2429 
2430  if (fp != 0)
2431  info[jss::fetch_pack] = Json::UInt(fp);
2432 
2433  if (!app_.config().reporting())
2434  info[jss::peers] = Json::UInt(app_.overlay().size());
2435 
2436  Json::Value lastClose = Json::objectValue;
2437  lastClose[jss::proposers] = Json::UInt(mConsensus.prevProposers());
2438 
2439  if (human)
2440  {
2441  lastClose[jss::converge_time_s] =
2443  }
2444  else
2445  {
2446  lastClose[jss::converge_time] =
2448  }
2449 
2450  info[jss::last_close] = lastClose;
2451 
2452  // info[jss::consensus] = mConsensus.getJson();
2453 
2454  if (admin)
2455  info[jss::load] = m_job_queue.getJson();
2456 
2457  if (!app_.config().reporting())
2458  {
2459  auto const escalationMetrics =
2461 
2462  auto const loadFactorServer = app_.getFeeTrack().getLoadFactor();
2463  auto const loadBaseServer = app_.getFeeTrack().getLoadBase();
2464  /* Scale the escalated fee level to unitless "load factor".
2465  In practice, this just strips the units, but it will continue
2466  to work correctly if either base value ever changes. */
2467  auto const loadFactorFeeEscalation =
2468  mulDiv(
2469  escalationMetrics.openLedgerFeeLevel,
2470  loadBaseServer,
2471  escalationMetrics.referenceFeeLevel)
2472  .second;
2473 
2474  auto const loadFactor = std::max(
2475  safe_cast<std::uint64_t>(loadFactorServer),
2476  loadFactorFeeEscalation);
2477 
2478  if (!human)
2479  {
2480  info[jss::load_base] = loadBaseServer;
2481  info[jss::load_factor] = trunc32(loadFactor);
2482  info[jss::load_factor_server] = loadFactorServer;
2483 
2484  /* Json::Value doesn't support uint64, so clamp to max
2485  uint32 value. This is mostly theoretical, since there
2486  probably isn't enough extant XRP to drive the factor
2487  that high.
2488  */
2489  info[jss::load_factor_fee_escalation] =
2490  escalationMetrics.openLedgerFeeLevel.jsonClipped();
2491  info[jss::load_factor_fee_queue] =
2492  escalationMetrics.minProcessingFeeLevel.jsonClipped();
2493  info[jss::load_factor_fee_reference] =
2494  escalationMetrics.referenceFeeLevel.jsonClipped();
2495  }
2496  else
2497  {
2498  info[jss::load_factor] =
2499  static_cast<double>(loadFactor) / loadBaseServer;
2500 
2501  if (loadFactorServer != loadFactor)
2502  info[jss::load_factor_server] =
2503  static_cast<double>(loadFactorServer) / loadBaseServer;
2504 
2505  if (admin)
2506  {
2508  if (fee != loadBaseServer)
2509  info[jss::load_factor_local] =
2510  static_cast<double>(fee) / loadBaseServer;
2511  fee = app_.getFeeTrack().getRemoteFee();
2512  if (fee != loadBaseServer)
2513  info[jss::load_factor_net] =
2514  static_cast<double>(fee) / loadBaseServer;
2515  fee = app_.getFeeTrack().getClusterFee();
2516  if (fee != loadBaseServer)
2517  info[jss::load_factor_cluster] =
2518  static_cast<double>(fee) / loadBaseServer;
2519  }
2520  if (escalationMetrics.openLedgerFeeLevel !=
2521  escalationMetrics.referenceFeeLevel &&
2522  (admin || loadFactorFeeEscalation != loadFactor))
2523  info[jss::load_factor_fee_escalation] =
2524  escalationMetrics.openLedgerFeeLevel.decimalFromReference(
2525  escalationMetrics.referenceFeeLevel);
2526  if (escalationMetrics.minProcessingFeeLevel !=
2527  escalationMetrics.referenceFeeLevel)
2528  info[jss::load_factor_fee_queue] =
2529  escalationMetrics.minProcessingFeeLevel
2530  .decimalFromReference(
2531  escalationMetrics.referenceFeeLevel);
2532  }
2533  }
2534 
2535  bool valid = false;
2536  auto lpClosed = m_ledgerMaster.getValidatedLedger();
2537 
2538  if (lpClosed)
2539  valid = true;
2540  else if (!app_.config().reporting())
2541  lpClosed = m_ledgerMaster.getClosedLedger();
2542 
2543  if (lpClosed)
2544  {
2545  XRPAmount const baseFee = lpClosed->fees().base;
2547  l[jss::seq] = Json::UInt(lpClosed->info().seq);
2548  l[jss::hash] = to_string(lpClosed->info().hash);
2549 
2550  if (!human)
2551  {
2552  l[jss::base_fee] = baseFee.jsonClipped();
2553  l[jss::reserve_base] =
2554  lpClosed->fees().accountReserve(0).jsonClipped();
2555  l[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
2556  l[jss::close_time] = Json::Value::UInt(
2557  lpClosed->info().closeTime.time_since_epoch().count());
2558  }
2559  else
2560  {
2561  l[jss::base_fee_xrp] = baseFee.decimalXRP();
2562  l[jss::reserve_base_xrp] =
2563  lpClosed->fees().accountReserve(0).decimalXRP();
2564  l[jss::reserve_inc_xrp] = lpClosed->fees().increment.decimalXRP();
2565 
2566  auto const nowOffset = app_.timeKeeper().nowOffset();
2567  if (std::abs(nowOffset.count()) >= 60)
2568  l[jss::system_time_offset] = nowOffset.count();
2569 
2570  auto const closeOffset = app_.timeKeeper().closeOffset();
2571  if (std::abs(closeOffset.count()) >= 60)
2572  l[jss::close_time_offset] = closeOffset.count();
2573 
2574 #if RIPPLED_REPORTING
2575  std::int64_t const dbAge =
2577  l[jss::age] = Json::UInt(dbAge);
2578 #else
2579  constexpr std::chrono::seconds highAgeThreshold{1000000};
2581  {
2582  auto const age = m_ledgerMaster.getValidatedLedgerAge();
2583  l[jss::age] =
2584  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2585  }
2586  else
2587  {
2588  auto lCloseTime = lpClosed->info().closeTime;
2589  auto closeTime = app_.timeKeeper().closeTime();
2590  if (lCloseTime <= closeTime)
2591  {
2592  using namespace std::chrono_literals;
2593  auto age = closeTime - lCloseTime;
2594  l[jss::age] =
2595  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2596  }
2597  }
2598 #endif
2599  }
2600 
2601  if (valid)
2602  info[jss::validated_ledger] = l;
2603  else
2604  info[jss::closed_ledger] = l;
2605 
2606  auto lpPublished = m_ledgerMaster.getPublishedLedger();
2607  if (!lpPublished)
2608  info[jss::published_ledger] = "none";
2609  else if (lpPublished->info().seq != lpClosed->info().seq)
2610  info[jss::published_ledger] = lpPublished->info().seq;
2611  }
2612 
2613  accounting_.json(info);
2614  info[jss::uptime] = UptimeClock::now().time_since_epoch().count();
2615  if (!app_.config().reporting())
2616  {
2617  info[jss::jq_trans_overflow] =
2619  info[jss::peer_disconnects] =
2621  info[jss::peer_disconnects_resources] =
2623  }
2624  else
2625  {
2626  info["reporting"] = app_.getReportingETL().getInfo();
2627  }
2628 
2629  return info;
2630 }
2631 
2632 void
2634 {
2636 }
2637 
2640 {
2641  return app_.getInboundLedgers().getInfo();
2642 }
2643 
2644 void
2646  std::shared_ptr<ReadView const> const& lpCurrent,
2647  std::shared_ptr<STTx const> const& stTxn,
2648  TER terResult)
2649 {
2650  Json::Value jvObj = transJson(*stTxn, terResult, false, lpCurrent);
2651 
2652  {
2654 
2655  auto it = mStreamMaps[sRTTransactions].begin();
2656  while (it != mStreamMaps[sRTTransactions].end())
2657  {
2658  InfoSub::pointer p = it->second.lock();
2659 
2660  if (p)
2661  {
2662  p->send(jvObj, true);
2663  ++it;
2664  }
2665  else
2666  {
2667  it = mStreamMaps[sRTTransactions].erase(it);
2668  }
2669  }
2670  }
2671  AcceptedLedgerTx alt(
2672  lpCurrent, stTxn, terResult, app_.accountIDCache(), app_.logs());
2673  JLOG(m_journal.trace()) << "pubProposed: " << alt.getJson();
2674  pubAccountTransaction(lpCurrent, alt, false);
2675 }
2676 
2677 void
2679 {
2680  // reporting does not forward validated transactions
2681  // validated transactions will be published to the proper streams when the
2682  // etl process writes a validated ledger
2683  if (jvObj[jss::validated].asBool())
2684  return;
2685  {
2687 
2688  auto it = mStreamMaps[sRTTransactions].begin();
2689  while (it != mStreamMaps[sRTTransactions].end())
2690  {
2691  InfoSub::pointer p = it->second.lock();
2692 
2693  if (p)
2694  {
2695  p->send(jvObj, true);
2696  ++it;
2697  }
2698  else
2699  {
2700  it = mStreamMaps[sRTTransactions].erase(it);
2701  }
2702  }
2703  }
2704 
2706 }
2707 
2708 void
2710 {
2712 
2713  for (auto i = mStreamMaps[sValidations].begin();
2714  i != mStreamMaps[sValidations].end();)
2715  {
2716  if (auto p = i->second.lock())
2717  {
2718  p->send(jvObj, true);
2719  ++i;
2720  }
2721  else
2722  {
2723  i = mStreamMaps[sValidations].erase(i);
2724  }
2725  }
2726 }
2727 
2728 void
2730 {
2732 
2733  for (auto i = mStreamMaps[sManifests].begin();
2734  i != mStreamMaps[sManifests].end();)
2735  {
2736  if (auto p = i->second.lock())
2737  {
2738  p->send(jvObj, true);
2739  ++i;
2740  }
2741  else
2742  {
2743  i = mStreamMaps[sManifests].erase(i);
2744  }
2745  }
2746 }
2747 
2748 static void
2750 {
2751  for (auto& jv : jvObj)
2752  {
2753  if (jv.isObject())
2754  {
2755  getAccounts(jv, accounts);
2756  }
2757  else if (jv.isString())
2758  {
2759  auto account = RPC::accountFromStringStrict(jv.asString());
2760  if (account)
2761  accounts.push_back(*account);
2762  }
2763  }
2764 }
2765 
2766 void
2768 {
2770  int iProposed = 0;
2771  // check if there are any subscribers before attempting to parse the JSON
2772  {
2774 
2775  if (mSubRTAccount.empty())
2776  return;
2777  }
2778 
2779  // parse the JSON outside of the lock
2780  std::vector<AccountID> accounts;
2781  if (jvObj.isMember(jss::transaction))
2782  {
2783  try
2784  {
2785  getAccounts(jvObj[jss::transaction], accounts);
2786  }
2787  catch (...)
2788  {
2789  JLOG(m_journal.debug())
2790  << __func__ << " : "
2791  << "error parsing json for accounts affected";
2792  return;
2793  }
2794  }
2795  {
2797 
2798  if (!mSubRTAccount.empty())
2799  {
2800  for (auto const& affectedAccount : accounts)
2801  {
2802  auto simiIt = mSubRTAccount.find(affectedAccount);
2803  if (simiIt != mSubRTAccount.end())
2804  {
2805  auto it = simiIt->second.begin();
2806 
2807  while (it != simiIt->second.end())
2808  {
2809  InfoSub::pointer p = it->second.lock();
2810 
2811  if (p)
2812  {
2813  notify.insert(p);
2814  ++it;
2815  ++iProposed;
2816  }
2817  else
2818  it = simiIt->second.erase(it);
2819  }
2820  }
2821  }
2822  }
2823  }
2824  JLOG(m_journal.trace()) << "forwardProposedAccountTransaction:"
2825  << " iProposed=" << iProposed;
2826 
2827  if (!notify.empty())
2828  {
2829  for (InfoSub::ref isrListener : notify)
2830  isrListener->send(jvObj, true);
2831  }
2832 }
2833 
2834 void
2836 {
2837  // Ledgers are published only when they acquire sufficient validations
2838  // Holes are filled across connection loss or other catastrophe
2839 
2840  std::shared_ptr<AcceptedLedger> alpAccepted =
2841  app_.getAcceptedLedgerCache().fetch(lpAccepted->info().hash);
2842  if (!alpAccepted)
2843  {
2844  alpAccepted = std::make_shared<AcceptedLedger>(lpAccepted, app_);
2845  app_.getAcceptedLedgerCache().canonicalize_replace_client(
2846  lpAccepted->info().hash, alpAccepted);
2847  }
2848 
2849  {
2850  JLOG(m_journal.debug())
2851  << "Publishing ledger = " << lpAccepted->info().seq;
2853 
2854  if (!mStreamMaps[sLedger].empty())
2855  {
2857 
2858  jvObj[jss::type] = "ledgerClosed";
2859  jvObj[jss::ledger_index] = lpAccepted->info().seq;
2860  jvObj[jss::ledger_hash] = to_string(lpAccepted->info().hash);
2861  jvObj[jss::ledger_time] = Json::Value::UInt(
2862  lpAccepted->info().closeTime.time_since_epoch().count());
2863 
2864  jvObj[jss::fee_ref] = lpAccepted->fees().units.jsonClipped();
2865  jvObj[jss::fee_base] = lpAccepted->fees().base.jsonClipped();
2866  jvObj[jss::reserve_base] =
2867  lpAccepted->fees().accountReserve(0).jsonClipped();
2868  jvObj[jss::reserve_inc] =
2869  lpAccepted->fees().increment.jsonClipped();
2870 
2871  jvObj[jss::txn_count] = Json::UInt(alpAccepted->getTxnCount());
2872 
2874  {
2875  jvObj[jss::validated_ledgers] =
2877  }
2878 
2879  auto it = mStreamMaps[sLedger].begin();
2880  while (it != mStreamMaps[sLedger].end())
2881  {
2882  InfoSub::pointer p = it->second.lock();
2883  if (p)
2884  {
2885  JLOG(m_journal.debug())
2886  << "Publishing ledger = " << lpAccepted->info().seq
2887  << " : consumer = " << p->getConsumer()
2888  << " : obj = " << jvObj;
2889  p->send(jvObj, true);
2890  ++it;
2891  }
2892  else
2893  it = mStreamMaps[sLedger].erase(it);
2894  }
2895  }
2896 
2897  {
2898  static bool firstTime = true;
2899  if (firstTime)
2900  {
2901  // First validated ledger, start delayed SubAccountHistory
2902  firstTime = false;
2903  for (auto& outer : mSubAccountHistory)
2904  {
2905  for (auto& inner : outer.second)
2906  {
2907  auto& subInfo = inner.second;
2908  if (subInfo.index_->separationLedgerSeq_ == 0)
2909  {
2911  alpAccepted->getLedger(), subInfo);
2912  }
2913  }
2914  }
2915  }
2916  }
2917  }
2918 
2919  // Don't lock since pubAcceptedTransaction is locking.
2920  for (auto const& [_, accTx] : alpAccepted->getMap())
2921  {
2922  (void)_;
2923  JLOG(m_journal.trace()) << "pubAccepted: " << accTx->getJson();
2924  pubValidatedTransaction(lpAccepted, *accTx);
2925  }
2926 }
2927 
2928 void
2930 {
2931  if (app_.config().reporting())
2932  return;
2933  ServerFeeSummary f{
2934  app_.openLedger().current()->fees().base,
2936  app_.getFeeTrack()};
2937 
2938  // only schedule the job if something has changed
2939  if (f != mLastFeeSummary)
2940  {
2942  jtCLIENT_FEE_CHANGE, "reportFeeChange->pubServer", [this]() {
2943  pubServer();
2944  });
2945  }
2946 }
2947 
2948 void
2950 {
2953  "reportConsensusStateChange->pubConsensus",
2954  [this, phase]() { pubConsensus(phase); });
2955 }
2956 
2957 inline void
2959 {
2960  m_localTX->sweep(view);
2961 }
2962 inline std::size_t
2964 {
2965  return m_localTX->size();
2966 }
2967 
2968 // This routine should only be used to publish accepted or validated
2969 // transactions.
2972  const STTx& stTxn,
2973  TER terResult,
2974  bool bValidated,
2975  std::shared_ptr<ReadView const> const& lpCurrent)
2976 {
2978  std::string sToken;
2979  std::string sHuman;
2980 
2981  transResultInfo(terResult, sToken, sHuman);
2982 
2983  jvObj[jss::type] = "transaction";
2984  jvObj[jss::transaction] = stTxn.getJson(JsonOptions::none);
2985 
2986  if (bValidated)
2987  {
2988  jvObj[jss::ledger_index] = lpCurrent->info().seq;
2989  jvObj[jss::ledger_hash] = to_string(lpCurrent->info().hash);
2990  jvObj[jss::transaction][jss::date] =
2991  lpCurrent->info().closeTime.time_since_epoch().count();
2992  jvObj[jss::validated] = true;
2993 
2994  // WRITEME: Put the account next seq here
2995  }
2996  else
2997  {
2998  jvObj[jss::validated] = false;
2999  jvObj[jss::ledger_current_index] = lpCurrent->info().seq;
3000  }
3001 
3002  jvObj[jss::status] = bValidated ? "closed" : "proposed";
3003  jvObj[jss::engine_result] = sToken;
3004  jvObj[jss::engine_result_code] = terResult;
3005  jvObj[jss::engine_result_message] = sHuman;
3006 
3007  if (stTxn.getTxnType() == ttOFFER_CREATE)
3008  {
3009  auto const account = stTxn.getAccountID(sfAccount);
3010  auto const amount = stTxn.getFieldAmount(sfTakerGets);
3011 
3012  // If the offer create is not self funded then add the owner balance
3013  if (account != amount.issue().account)
3014  {
3015  auto const ownerFunds = accountFunds(
3016  *lpCurrent,
3017  account,
3018  amount,
3020  app_.journal("View"));
3021  jvObj[jss::transaction][jss::owner_funds] = ownerFunds.getText();
3022  }
3023  }
3024 
3025  return jvObj;
3026 }
3027 
3028 void
3030  std::shared_ptr<ReadView const> const& alAccepted,
3031  const AcceptedLedgerTx& alTx)
3032 {
3033  std::shared_ptr<STTx const> stTxn = alTx.getTxn();
3034  Json::Value jvObj = transJson(*stTxn, alTx.getResult(), true, alAccepted);
3035 
3036  if (auto const txMeta = alTx.getMeta())
3037  {
3038  jvObj[jss::meta] = txMeta->getJson(JsonOptions::none);
3040  jvObj[jss::meta], *alAccepted, stTxn, *txMeta);
3041  }
3042 
3043  {
3045 
3046  auto it = mStreamMaps[sTransactions].begin();
3047  while (it != mStreamMaps[sTransactions].end())
3048  {
3049  InfoSub::pointer p = it->second.lock();
3050 
3051  if (p)
3052  {
3053  p->send(jvObj, true);
3054  ++it;
3055  }
3056  else
3057  it = mStreamMaps[sTransactions].erase(it);
3058  }
3059 
3060  it = mStreamMaps[sRTTransactions].begin();
3061 
3062  while (it != mStreamMaps[sRTTransactions].end())
3063  {
3064  InfoSub::pointer p = it->second.lock();
3065 
3066  if (p)
3067  {
3068  p->send(jvObj, true);
3069  ++it;
3070  }
3071  else
3072  it = mStreamMaps[sRTTransactions].erase(it);
3073  }
3074  }
3075  app_.getOrderBookDB().processTxn(alAccepted, alTx, jvObj);
3076  pubAccountTransaction(alAccepted, alTx, true);
3077 }
3078 
3079 void
3081  std::shared_ptr<ReadView const> const& lpCurrent,
3082  const AcceptedLedgerTx& alTx,
3083  bool bAccepted)
3084 {
3086  int iProposed = 0;
3087  int iAccepted = 0;
3088 
3089  std::vector<SubAccountHistoryInfo> accountHistoryNotify;
3090  auto const currLedgerSeq = lpCurrent->seq();
3091  {
3093 
3094  if (!bAccepted && mSubRTAccount.empty())
3095  return;
3096 
3097  if (!mSubAccount.empty() || (!mSubRTAccount.empty()) ||
3099  {
3100  for (auto const& affectedAccount : alTx.getAffected())
3101  {
3102  if (auto simiIt = mSubRTAccount.find(affectedAccount);
3103  simiIt != mSubRTAccount.end())
3104  {
3105  auto it = simiIt->second.begin();
3106 
3107  while (it != simiIt->second.end())
3108  {
3109  InfoSub::pointer p = it->second.lock();
3110 
3111  if (p)
3112  {
3113  notify.insert(p);
3114  ++it;
3115  ++iProposed;
3116  }
3117  else
3118  it = simiIt->second.erase(it);
3119  }
3120  }
3121 
3122  if (bAccepted)
3123  {
3124  if (auto simiIt = mSubAccount.find(affectedAccount);
3125  simiIt != mSubAccount.end())
3126  {
3127  auto it = simiIt->second.begin();
3128  while (it != simiIt->second.end())
3129  {
3130  InfoSub::pointer p = it->second.lock();
3131 
3132  if (p)
3133  {
3134  notify.insert(p);
3135  ++it;
3136  ++iAccepted;
3137  }
3138  else
3139  it = simiIt->second.erase(it);
3140  }
3141  }
3142 
3143  if (auto histoIt = mSubAccountHistory.find(affectedAccount);
3144  histoIt != mSubAccountHistory.end())
3145  {
3146  auto& subs = histoIt->second;
3147  auto it = subs.begin();
3148  while (it != subs.end())
3149  {
3150  SubAccountHistoryInfoWeak const& info = it->second;
3151  if (currLedgerSeq <=
3152  info.index_->separationLedgerSeq_)
3153  {
3154  ++it;
3155  continue;
3156  }
3157 
3158  if (auto isSptr = info.sinkWptr_.lock(); isSptr)
3159  {
3160  accountHistoryNotify.emplace_back(
3161  SubAccountHistoryInfo{isSptr, info.index_});
3162  ++it;
3163  }
3164  else
3165  {
3166  it = subs.erase(it);
3167  }
3168  }
3169  if (subs.empty())
3170  mSubAccountHistory.erase(histoIt);
3171  }
3172  }
3173  }
3174  }
3175  }
3176 
3177  JLOG(m_journal.trace())
3178  << "pubAccountTransaction:"
3179  << " iProposed=" << iProposed << " iAccepted=" << iAccepted;
3180 
3181  if (!notify.empty() || !accountHistoryNotify.empty())
3182  {
3183  std::shared_ptr<STTx const> stTxn = alTx.getTxn();
3184  Json::Value jvObj =
3185  transJson(*stTxn, alTx.getResult(), bAccepted, lpCurrent);
3186 
3187  if (alTx.isApplied())
3188  {
3189  if (auto const txMeta = alTx.getMeta())
3190  {
3191  jvObj[jss::meta] = txMeta->getJson(JsonOptions::none);
3193  jvObj[jss::meta], *lpCurrent, stTxn, *txMeta);
3194  }
3195  }
3196 
3197  for (InfoSub::ref isrListener : notify)
3198  isrListener->send(jvObj, true);
3199 
3200  assert(!jvObj.isMember(jss::account_history_tx_stream));
3201  for (auto& info : accountHistoryNotify)
3202  {
3203  auto& index = info.index_;
3204  if (index->forwardTxIndex_ == 0 && !index->haveHistorical_)
3205  jvObj[jss::account_history_tx_first] = true;
3206  jvObj[jss::account_history_tx_index] = index->forwardTxIndex_++;
3207  info.sink_->send(jvObj, true);
3208  }
3209  }
3210 }
3211 
3212 //
3213 // Monitoring
3214 //
3215 
3216 void
3218  InfoSub::ref isrListener,
3219  hash_set<AccountID> const& vnaAccountIDs,
3220  bool rt)
3221 {
3222  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3223 
3224  for (auto const& naAccountID : vnaAccountIDs)
3225  {
3226  JLOG(m_journal.trace())
3227  << "subAccount: account: " << toBase58(naAccountID);
3228 
3229  isrListener->insertSubAccountInfo(naAccountID, rt);
3230  }
3231 
3233 
3234  for (auto const& naAccountID : vnaAccountIDs)
3235  {
3236  auto simIterator = subMap.find(naAccountID);
3237  if (simIterator == subMap.end())
3238  {
3239  // Not found, note that account has a new single listner.
3240  SubMapType usisElement;
3241  usisElement[isrListener->getSeq()] = isrListener;
3242  // VFALCO NOTE This is making a needless copy of naAccountID
3243  subMap.insert(simIterator, make_pair(naAccountID, usisElement));
3244  }
3245  else
3246  {
3247  // Found, note that the account has another listener.
3248  simIterator->second[isrListener->getSeq()] = isrListener;
3249  }
3250  }
3251 }
3252 
3253 void
3255  InfoSub::ref isrListener,
3256  hash_set<AccountID> const& vnaAccountIDs,
3257  bool rt)
3258 {
3259  for (auto const& naAccountID : vnaAccountIDs)
3260  {
3261  // Remove from the InfoSub
3262  isrListener->deleteSubAccountInfo(naAccountID, rt);
3263  }
3264 
3265  // Remove from the server
3266  unsubAccountInternal(isrListener->getSeq(), vnaAccountIDs, rt);
3267 }
3268 
3269 void
3271  std::uint64_t uSeq,
3272  hash_set<AccountID> const& vnaAccountIDs,
3273  bool rt)
3274 {
3276 
3277  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3278 
3279  for (auto const& naAccountID : vnaAccountIDs)
3280  {
3281  auto simIterator = subMap.find(naAccountID);
3282 
3283  if (simIterator != subMap.end())
3284  {
3285  // Found
3286  simIterator->second.erase(uSeq);
3287 
3288  if (simIterator->second.empty())
3289  {
3290  // Don't need hash entry.
3291  subMap.erase(simIterator);
3292  }
3293  }
3294  }
3295 }
3296 
3297 void
3299 {
3300  enum DatabaseType { Postgres, Sqlite, None };
3301  static const auto databaseType = [&]() -> DatabaseType {
3302 #ifdef RIPPLED_REPORTING
3303  if (app_.config().reporting())
3304  {
3305  if (dynamic_cast<RelationalDBInterfacePostgres*>(
3307  {
3308  return DatabaseType::Postgres;
3309  }
3310  return DatabaseType::None;
3311  }
3312  else
3313  {
3314  if (dynamic_cast<RelationalDBInterfaceSqlite*>(
3316  {
3317  return DatabaseType::Sqlite;
3318  }
3319  return DatabaseType::None;
3320  }
3321 #else
3322  if (dynamic_cast<RelationalDBInterfaceSqlite*>(
3324  {
3325  return DatabaseType::Sqlite;
3326  }
3327  return DatabaseType::None;
3328 #endif
3329  }();
3330 
3331  if (databaseType == DatabaseType::None)
3332  {
3333  JLOG(m_journal.error())
3334  << "AccountHistory job for account "
3335  << toBase58(subInfo.index_->accountId_) << " no database";
3336  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3337  {
3338  sptr->send(rpcError(rpcINTERNAL), true);
3339  unsubAccountHistory(sptr, subInfo.index_->accountId_, false);
3340  }
3341  return;
3342  }
3343 
3346  "AccountHistoryTxStream",
3347  [this, dbType = databaseType, subInfo]() {
3348  auto const& accountId = subInfo.index_->accountId_;
3349  auto& lastLedgerSeq = subInfo.index_->historyLastLedgerSeq_;
3350  auto& txHistoryIndex = subInfo.index_->historyTxIndex_;
3351 
3352  JLOG(m_journal.trace())
3353  << "AccountHistory job for account " << toBase58(accountId)
3354  << " started. lastLedgerSeq=" << lastLedgerSeq;
3355 
3356  auto isFirstTx = [&](std::shared_ptr<Transaction> const& tx,
3357  std::shared_ptr<TxMeta> const& meta) -> bool {
3358  /*
3359  * genesis account: first tx is the one with seq 1
3360  * other account: first tx is the one created the account
3361  */
3362  if (accountId == genesisAccountId)
3363  {
3364  auto stx = tx->getSTransaction();
3365  if (stx->getAccountID(sfAccount) == accountId &&
3366  stx->getSeqProxy().value() == 1)
3367  return true;
3368  }
3369 
3370  for (auto& node : meta->getNodes())
3371  {
3372  if (node.getFieldU16(sfLedgerEntryType) != ltACCOUNT_ROOT)
3373  continue;
3374 
3375  if (node.isFieldPresent(sfNewFields))
3376  {
3377  if (auto inner = dynamic_cast<const STObject*>(
3378  node.peekAtPField(sfNewFields));
3379  inner)
3380  {
3381  if (inner->isFieldPresent(sfAccount) &&
3382  inner->getAccountID(sfAccount) == accountId)
3383  {
3384  return true;
3385  }
3386  }
3387  }
3388  }
3389 
3390  return false;
3391  };
3392 
3393  auto send = [&](Json::Value const& jvObj,
3394  bool unsubscribe) -> bool {
3395  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3396  {
3397  sptr->send(jvObj, true);
3398  if (unsubscribe)
3399  unsubAccountHistory(sptr, accountId, false);
3400  return true;
3401  }
3402 
3403  return false;
3404  };
3405 
3406  auto getMoreTxns =
3407  [&](std::uint32_t minLedger,
3408  std::uint32_t maxLedger,
3410  marker)
3414  switch (dbType)
3415  {
3416  case Postgres: {
3417  auto db = static_cast<RelationalDBInterfacePostgres*>(
3420  args.account = accountId;
3421  LedgerRange range{minLedger, maxLedger};
3422  args.ledger = range;
3423  args.marker = marker;
3424  auto [txResult, status] = db->getAccountTx(args);
3425  if (status != rpcSUCCESS)
3426  {
3427  JLOG(m_journal.debug())
3428  << "AccountHistory job for account "
3429  << toBase58(accountId)
3430  << " getAccountTx failed";
3431  return {};
3432  }
3433 
3434  if (auto txns =
3435  std::get_if<RelationalDBInterface::AccountTxs>(
3436  &txResult.transactions);
3437  txns)
3438  {
3439  return std::make_pair(*txns, txResult.marker);
3440  }
3441  else
3442  {
3443  JLOG(m_journal.debug())
3444  << "AccountHistory job for account "
3445  << toBase58(accountId)
3446  << " getAccountTx wrong data";
3447  return {};
3448  }
3449  }
3450  case Sqlite: {
3451  auto db = static_cast<RelationalDBInterfaceSqlite*>(
3454  accountId, minLedger, maxLedger, marker, 0, true};
3455  return db->newestAccountTxPage(options);
3456  }
3457  default: {
3458  assert(false);
3459  return {};
3460  }
3461  }
3462  };
3463 
3464  /*
3465  * search backward until the genesis ledger or asked to stop
3466  */
3467  while (lastLedgerSeq >= 2 && !subInfo.index_->stopHistorical_)
3468  {
3469  int feeChargeCount = 0;
3470  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3471  {
3472  sptr->getConsumer().charge(Resource::feeMediumBurdenRPC);
3473  ++feeChargeCount;
3474  }
3475  else
3476  {
3477  JLOG(m_journal.trace())
3478  << "AccountHistory job for account "
3479  << toBase58(accountId) << " no InfoSub. Fee charged "
3480  << feeChargeCount << " times.";
3481  return;
3482  }
3483 
3484  // try to search in 1024 ledgers till reaching genesis ledgers
3485  auto startLedgerSeq =
3486  (lastLedgerSeq > 1024 + 2 ? lastLedgerSeq - 1024 : 2);
3487  JLOG(m_journal.trace())
3488  << "AccountHistory job for account " << toBase58(accountId)
3489  << ", working on ledger range [" << startLedgerSeq << ","
3490  << lastLedgerSeq << "]";
3491 
3492  auto haveRange = [&]() -> bool {
3493  std::uint32_t validatedMin = UINT_MAX;
3494  std::uint32_t validatedMax = 0;
3495  auto haveSomeValidatedLedgers =
3497  validatedMin, validatedMax);
3498 
3499  return haveSomeValidatedLedgers &&
3500  validatedMin <= startLedgerSeq &&
3501  lastLedgerSeq <= validatedMax;
3502  }();
3503 
3504  if (!haveRange)
3505  {
3506  JLOG(m_journal.debug())
3507  << "AccountHistory reschedule job for account "
3508  << toBase58(accountId) << ", incomplete ledger range ["
3509  << startLedgerSeq << "," << lastLedgerSeq << "]";
3510  setAccountHistoryJobTimer(subInfo);
3511  return;
3512  }
3513 
3515  while (!subInfo.index_->stopHistorical_)
3516  {
3517  auto dbResult =
3518  getMoreTxns(startLedgerSeq, lastLedgerSeq, marker);
3519  if (!dbResult)
3520  {
3521  JLOG(m_journal.debug())
3522  << "AccountHistory job for account "
3523  << toBase58(accountId) << " getMoreTxns failed.";
3524  send(rpcError(rpcINTERNAL), true);
3525  return;
3526  }
3527 
3528  auto const& txns = dbResult->first;
3529  marker = dbResult->second;
3530  for (auto const& [tx, meta] : txns)
3531  {
3532  if (!tx || !meta)
3533  {
3534  JLOG(m_journal.debug())
3535  << "AccountHistory job for account "
3536  << toBase58(accountId) << " empty tx or meta.";
3537  send(rpcError(rpcINTERNAL), true);
3538  return;
3539  }
3540  auto curTxLedger =
3542  tx->getLedger());
3543  if (!curTxLedger)
3544  {
3545  JLOG(m_journal.debug())
3546  << "AccountHistory job for account "
3547  << toBase58(accountId) << " no ledger.";
3548  send(rpcError(rpcINTERNAL), true);
3549  return;
3550  }
3552  tx->getSTransaction();
3553  if (!stTxn)
3554  {
3555  JLOG(m_journal.debug())
3556  << "AccountHistory job for account "
3557  << toBase58(accountId)
3558  << " getSTransaction failed.";
3559  send(rpcError(rpcINTERNAL), true);
3560  return;
3561  }
3562  Json::Value jvTx = transJson(
3563  *stTxn, meta->getResultTER(), true, curTxLedger);
3564  jvTx[jss::meta] = meta->getJson(JsonOptions::none);
3565  jvTx[jss::account_history_tx_index] = txHistoryIndex--;
3567  jvTx[jss::meta], *curTxLedger, stTxn, *meta);
3568  if (isFirstTx(tx, meta))
3569  {
3570  jvTx[jss::account_history_tx_first] = true;
3571  send(jvTx, false);
3572 
3573  JLOG(m_journal.trace())
3574  << "AccountHistory job for account "
3575  << toBase58(accountId)
3576  << " done, found last tx.";
3577  return;
3578  }
3579  else
3580  {
3581  send(jvTx, false);
3582  }
3583  }
3584 
3585  if (marker)
3586  {
3587  JLOG(m_journal.trace())
3588  << "AccountHistory job for account "
3589  << toBase58(accountId)
3590  << " paging, marker=" << marker->ledgerSeq << ":"
3591  << marker->txnSeq;
3592  }
3593  else
3594  {
3595  break;
3596  }
3597  }
3598 
3599  if (!subInfo.index_->stopHistorical_)
3600  {
3601  lastLedgerSeq = startLedgerSeq - 1;
3602  if (lastLedgerSeq <= 1)
3603  {
3604  JLOG(m_journal.trace())
3605  << "AccountHistory job for account "
3606  << toBase58(accountId)
3607  << " done, reached genesis ledger.";
3608  return;
3609  }
3610  }
3611  }
3612  });
3613 }
3614 
3615 void
3617  std::shared_ptr<ReadView const> const& ledger,
3618  SubAccountHistoryInfoWeak& subInfo)
3619 {
3620  subInfo.index_->separationLedgerSeq_ = ledger->seq();
3621  auto const& accountId = subInfo.index_->accountId_;
3622  auto const accountKeylet = keylet::account(accountId);
3623  if (!ledger->exists(accountKeylet))
3624  {
3625  JLOG(m_journal.debug())
3626  << "subAccountHistoryStart, no account " << toBase58(accountId)
3627  << ", no need to add AccountHistory job.";
3628  return;
3629  }
3630  if (accountId == genesisAccountId)
3631  {
3632  if (auto const sleAcct = ledger->read(accountKeylet); sleAcct)
3633  {
3634  if (sleAcct->getFieldU32(sfSequence) == 1)
3635  {
3636  JLOG(m_journal.debug())
3637  << "subAccountHistoryStart, genesis account "
3638  << toBase58(accountId)
3639  << " does not have tx, no need to add AccountHistory job.";
3640  return;
3641  }
3642  }
3643  else
3644  {
3645  assert(false);
3646  return;
3647  }
3648  }
3649  subInfo.index_->historyLastLedgerSeq_ = ledger->seq();
3650  subInfo.index_->haveHistorical_ = true;
3651 
3652  JLOG(m_journal.debug())
3653  << "subAccountHistoryStart, add AccountHistory job: accountId="
3654  << toBase58(accountId) << ", currentLedgerSeq=" << ledger->seq();
3655 
3656  addAccountHistoryJob(subInfo);
3657 }
3658 
3661  InfoSub::ref isrListener,
3662  AccountID const& accountId)
3663 {
3664  if (!isrListener->insertSubAccountHistory(accountId))
3665  {
3666  JLOG(m_journal.debug())
3667  << "subAccountHistory, already subscribed to account "
3668  << toBase58(accountId);
3669  return rpcINVALID_PARAMS;
3670  }
3671 
3674  isrListener, std::make_shared<SubAccountHistoryIndex>(accountId)};
3675  auto simIterator = mSubAccountHistory.find(accountId);
3676  if (simIterator == mSubAccountHistory.end())
3677  {
3679  inner.emplace(isrListener->getSeq(), ahi);
3681  simIterator, std::make_pair(accountId, inner));
3682  }
3683  else
3684  {
3685  simIterator->second.emplace(isrListener->getSeq(), ahi);
3686  }
3687 
3688  auto const ledger = app_.getLedgerMaster().getValidatedLedger();
3689  if (ledger)
3690  {
3691  subAccountHistoryStart(ledger, ahi);
3692  }
3693  else
3694  {
3695  // The node does not have validated ledgers, so wait for
3696  // one before start streaming.
3697  // In this case, the subscription is also considered successful.
3698  JLOG(m_journal.debug())
3699  << "subAccountHistory, no validated ledger yet, delay start";
3700  }
3701 
3702  return rpcSUCCESS;
3703 }
3704 
3705 void
3707  InfoSub::ref isrListener,
3708  AccountID const& account,
3709  bool historyOnly)
3710 {
3711  if (!historyOnly)
3712  isrListener->deleteSubAccountHistory(account);
3713  unsubAccountHistoryInternal(isrListener->getSeq(), account, historyOnly);
3714 }
3715 
3716 void
3718  std::uint64_t seq,
3719  const AccountID& account,
3720  bool historyOnly)
3721 {
3723  auto simIterator = mSubAccountHistory.find(account);
3724  if (simIterator != mSubAccountHistory.end())
3725  {
3726  auto& subInfoMap = simIterator->second;
3727  auto subInfoIter = subInfoMap.find(seq);
3728  if (subInfoIter != subInfoMap.end())
3729  {
3730  subInfoIter->second.index_->stopHistorical_ = true;
3731  }
3732 
3733  if (!historyOnly)
3734  {
3735  simIterator->second.erase(seq);
3736  if (simIterator->second.empty())
3737  {
3738  mSubAccountHistory.erase(simIterator);
3739  }
3740  }
3741  JLOG(m_journal.debug())
3742  << "unsubAccountHistory, account " << toBase58(account)
3743  << ", historyOnly = " << (historyOnly ? "true" : "false");
3744  }
3745 }
3746 
3747 bool
3748 NetworkOPsImp::subBook(InfoSub::ref isrListener, Book const& book)
3749 {
3750  if (auto listeners = app_.getOrderBookDB().makeBookListeners(book))
3751  listeners->addSubscriber(isrListener);
3752  else
3753  assert(false);
3754  return true;
3755 }
3756 
3757 bool
3759 {
3760  if (auto listeners = app_.getOrderBookDB().getBookListeners(book))
3761  listeners->removeSubscriber(uSeq);
3762 
3763  return true;
3764 }
3765 
3769 {
3770  // This code-path is exclusively used when the server is in standalone
3771  // mode via `ledger_accept`
3772  assert(m_standalone);
3773 
3774  if (!m_standalone)
3775  Throw<std::runtime_error>(
3776  "Operation only possible in STANDALONE mode.");
3777 
3778  // FIXME Could we improve on this and remove the need for a specialized
3779  // API in Consensus?
3781  mConsensus.simulate(app_.timeKeeper().closeTime(), consensusDelay);
3782  return m_ledgerMaster.getCurrentLedger()->info().seq;
3783 }
3784 
3785 // <-- bool: true=added, false=already there
3786 bool
3788 {
3789  if (auto lpClosed = m_ledgerMaster.getValidatedLedger())
3790  {
3791  jvResult[jss::ledger_index] = lpClosed->info().seq;
3792  jvResult[jss::ledger_hash] = to_string(lpClosed->info().hash);
3793  jvResult[jss::ledger_time] = Json::Value::UInt(
3794  lpClosed->info().closeTime.time_since_epoch().count());
3795  jvResult[jss::fee_ref] = lpClosed->fees().units.jsonClipped();
3796  jvResult[jss::fee_base] = lpClosed->fees().base.jsonClipped();
3797  jvResult[jss::reserve_base] =
3798  lpClosed->fees().accountReserve(0).jsonClipped();
3799  jvResult[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
3800  }
3801 
3803  {
3804  jvResult[jss::validated_ledgers] =
3806  }
3807 
3809  return mStreamMaps[sLedger]
3810  .emplace(isrListener->getSeq(), isrListener)
3811  .second;
3812 }
3813 
3814 // <-- bool: true=erased, false=was not there
3815 bool
3817 {
3819  return mStreamMaps[sLedger].erase(uSeq);
3820 }
3821 
3822 // <-- bool: true=added, false=already there
3823 bool
3825 {
3827  return mStreamMaps[sManifests]
3828  .emplace(isrListener->getSeq(), isrListener)
3829  .second;
3830 }
3831 
3832 // <-- bool: true=erased, false=was not there
3833 bool
3835 {
3837  return mStreamMaps[sManifests].erase(uSeq);
3838 }
3839 
3840 // <-- bool: true=added, false=already there
3841 bool
3843  InfoSub::ref isrListener,
3844  Json::Value& jvResult,
3845  bool admin)
3846 {
3847  uint256 uRandom;
3848 
3849  if (m_standalone)
3850  jvResult[jss::stand_alone] = m_standalone;
3851 
3852  // CHECKME: is it necessary to provide a random number here?
3853  beast::rngfill(uRandom.begin(), uRandom.size(), crypto_prng());
3854 
3855  auto const& feeTrack = app_.getFeeTrack();
3856  jvResult[jss::random] = to_string(uRandom);
3857  jvResult[jss::server_status] = strOperatingMode(admin);
3858  jvResult[jss::load_base] = feeTrack.getLoadBase();
3859  jvResult[jss::load_factor] = feeTrack.getLoadFactor();
3860  jvResult[jss::hostid] = getHostId(admin);
3861  jvResult[jss::pubkey_node] =
3863 
3865  return mStreamMaps[sServer]
3866  .emplace(isrListener->getSeq(), isrListener)
3867  .second;
3868 }
3869 
3870 // <-- bool: true=erased, false=was not there
3871 bool
3873 {
3875  return mStreamMaps[sServer].erase(uSeq);
3876 }
3877 
3878 // <-- bool: true=added, false=already there
3879 bool
3881 {
3883  return mStreamMaps[sTransactions]
3884  .emplace(isrListener->getSeq(), isrListener)
3885  .second;
3886 }
3887 
3888 // <-- bool: true=erased, false=was not there
3889 bool
3891 {
3893  return mStreamMaps[sTransactions].erase(uSeq);
3894 }
3895 
3896 // <-- bool: true=added, false=already there
3897 bool
3899 {
3902  .emplace(isrListener->getSeq(), isrListener)
3903  .second;
3904 }
3905 
3906 // <-- bool: true=erased, false=was not there
3907 bool
3909 {
3911  return mStreamMaps[sRTTransactions].erase(uSeq);
3912 }
3913 
3914 // <-- bool: true=added, false=already there
3915 bool
3917 {
3919  return mStreamMaps[sValidations]
3920  .emplace(isrListener->getSeq(), isrListener)
3921  .second;
3922 }
3923 
3924 void
3926 {
3927  accounting_.json(obj);
3928 }
3929 
3930 // <-- bool: true=erased, false=was not there
3931 bool
3933 {
3935  return mStreamMaps[sValidations].erase(uSeq);
3936 }
3937 
3938 // <-- bool: true=added, false=already there
3939 bool
3941 {
3943  return mStreamMaps[sPeerStatus]
3944  .emplace(isrListener->getSeq(), isrListener)
3945  .second;
3946 }
3947 
3948 // <-- bool: true=erased, false=was not there
3949 bool
3951 {
3953  return mStreamMaps[sPeerStatus].erase(uSeq);
3954 }
3955 
3956 // <-- bool: true=added, false=already there
3957 bool
3959 {
3962  .emplace(isrListener->getSeq(), isrListener)
3963  .second;
3964 }
3965 
3966 // <-- bool: true=erased, false=was not there
3967 bool
3969 {
3971  return mStreamMaps[sConsensusPhase].erase(uSeq);
3972 }
3973 
3976 {
3978 
3979  subRpcMapType::iterator it = mRpcSubMap.find(strUrl);
3980 
3981  if (it != mRpcSubMap.end())
3982  return it->second;
3983 
3984  return InfoSub::pointer();
3985 }
3986 
3989 {
3991 
3992  mRpcSubMap.emplace(strUrl, rspEntry);
3993 
3994  return rspEntry;
3995 }
3996 
3997 bool
3999 {
4001  auto pInfo = findRpcSub(strUrl);
4002 
4003  if (!pInfo)
4004  return false;
4005 
4006  // check to see if any of the stream maps still hold a weak reference to
4007  // this entry before removing
4008  for (SubMapType const& map : mStreamMaps)
4009  {
4010  if (map.find(pInfo->getSeq()) != map.end())
4011  return false;
4012  }
4013  mRpcSubMap.erase(strUrl);
4014  return true;
4015 }
4016 
4017 #ifndef USE_NEW_BOOK_PAGE
4018 
4019 // NIKB FIXME this should be looked at. There's no reason why this shouldn't
4020 // work, but it demonstrated poor performance.
4021 //
4022 void
4025  Book const& book,
4026  AccountID const& uTakerID,
4027  bool const bProof,
4028  unsigned int iLimit,
4029  Json::Value const& jvMarker,
4030  Json::Value& jvResult)
4031 { // CAUTION: This is the old get book page logic
4032  Json::Value& jvOffers =
4033  (jvResult[jss::offers] = Json::Value(Json::arrayValue));
4034 
4036  const uint256 uBookBase = getBookBase(book);
4037  const uint256 uBookEnd = getQualityNext(uBookBase);
4038  uint256 uTipIndex = uBookBase;
4039 
4040  if (auto stream = m_journal.trace())
4041  {
4042  stream << "getBookPage:" << book;
4043  stream << "getBookPage: uBookBase=" << uBookBase;
4044  stream << "getBookPage: uBookEnd=" << uBookEnd;
4045  stream << "getBookPage: uTipIndex=" << uTipIndex;
4046  }
4047 
4048  ReadView const& view = *lpLedger;
4049 
4050  bool const bGlobalFreeze = isGlobalFrozen(view, book.out.account) ||
4051  isGlobalFrozen(view, book.in.account);
4052 
4053  bool bDone = false;
4054  bool bDirectAdvance = true;
4055 
4056  std::shared_ptr<SLE const> sleOfferDir;
4057  uint256 offerIndex;
4058  unsigned int uBookEntry;
4059  STAmount saDirRate;
4060 
4061  auto const rate = transferRate(view, book.out.account);
4062  auto viewJ = app_.journal("View");
4063 
4064  while (!bDone && iLimit-- > 0)
4065  {
4066  if (bDirectAdvance)
4067  {
4068  bDirectAdvance = false;
4069 
4070  JLOG(m_journal.trace()) << "getBookPage: bDirectAdvance";
4071 
4072  auto const ledgerIndex = view.succ(uTipIndex, uBookEnd);
4073  if (ledgerIndex)
4074  sleOfferDir = view.read(keylet::page(*ledgerIndex));
4075  else
4076  sleOfferDir.reset();
4077 
4078  if (!sleOfferDir)
4079  {
4080  JLOG(m_journal.trace()) << "getBookPage: bDone";
4081  bDone = true;
4082  }
4083  else
4084  {
4085  uTipIndex = sleOfferDir->key();
4086  saDirRate = amountFromQuality(getQuality(uTipIndex));
4087 
4088  cdirFirst(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex);
4089 
4090  JLOG(m_journal.trace())
4091  << "getBookPage: uTipIndex=" << uTipIndex;
4092  JLOG(m_journal.trace())
4093  << "getBookPage: offerIndex=" << offerIndex;
4094  }
4095  }
4096 
4097  if (!bDone)
4098  {
4099  auto sleOffer = view.read(keylet::offer(offerIndex));
4100 
4101  if (sleOffer)
4102  {
4103  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
4104  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
4105  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
4106  STAmount saOwnerFunds;
4107  bool firstOwnerOffer(true);
4108 
4109  if (book.out.account == uOfferOwnerID)
4110  {
4111  // If an offer is selling issuer's own IOUs, it is fully
4112  // funded.
4113  saOwnerFunds = saTakerGets;
4114  }
4115  else if (bGlobalFreeze)
4116  {
4117  // If either asset is globally frozen, consider all offers
4118  // that aren't ours to be totally unfunded
4119  saOwnerFunds.clear(book.out);
4120  }
4121  else
4122  {
4123  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
4124  if (umBalanceEntry != umBalance.end())
4125  {
4126  // Found in running balance table.
4127 
4128  saOwnerFunds = umBalanceEntry->second;
4129  firstOwnerOffer = false;
4130  }
4131  else
4132  {
4133  // Did not find balance in table.
4134 
4135  saOwnerFunds = accountHolds(
4136  view,
4137  uOfferOwnerID,
4138  book.out.currency,
4139  book.out.account,
4141  viewJ);
4142 
4143  if (saOwnerFunds < beast::zero)
4144  {
4145  // Treat negative funds as zero.
4146 
4147  saOwnerFunds.clear();
4148  }
4149  }
4150  }
4151 
4152  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
4153 
4154  STAmount saTakerGetsFunded;
4155  STAmount saOwnerFundsLimit = saOwnerFunds;
4156  Rate offerRate = parityRate;
4157 
4158  if (rate != parityRate
4159  // Have a tranfer fee.
4160  && uTakerID != book.out.account
4161  // Not taking offers of own IOUs.
4162  && book.out.account != uOfferOwnerID)
4163  // Offer owner not issuing ownfunds
4164  {
4165  // Need to charge a transfer fee to offer owner.
4166  offerRate = rate;
4167  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
4168  }
4169 
4170  if (saOwnerFundsLimit >= saTakerGets)
4171  {
4172  // Sufficient funds no shenanigans.
4173  saTakerGetsFunded = saTakerGets;
4174  }
4175  else
4176  {
4177  // Only provide, if not fully funded.
4178 
4179  saTakerGetsFunded = saOwnerFundsLimit;
4180 
4181  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
4182  std::min(
4183  saTakerPays,
4184  multiply(
4185  saTakerGetsFunded, saDirRate, saTakerPays.issue()))
4186  .setJson(jvOffer[jss::taker_pays_funded]);
4187  }
4188 
4189  STAmount saOwnerPays = (parityRate == offerRate)
4190  ? saTakerGetsFunded
4191  : std::min(
4192  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
4193 
4194  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
4195 
4196  // Include all offers funded and unfunded
4197  Json::Value& jvOf = jvOffers.append(jvOffer);
4198  jvOf[jss::quality] = saDirRate.getText();
4199 
4200  if (firstOwnerOffer)
4201  jvOf[jss::owner_funds] = saOwnerFunds.getText();
4202  }
4203  else
4204  {
4205  JLOG(m_journal.warn()) << "Missing offer";
4206  }
4207 
4208  if (!cdirNext(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex))
4209  {
4210  bDirectAdvance = true;
4211  }
4212  else
4213  {
4214  JLOG(m_journal.trace())
4215  << "getBookPage: offerIndex=" << offerIndex;
4216  }
4217  }
4218  }
4219 
4220  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
4221  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
4222 }
4223 
4224 #else
4225 
4226 // This is the new code that uses the book iterators
4227 // It has temporarily been disabled
4228 
4229 void
4232  Book const& book,
4233  AccountID const& uTakerID,
4234  bool const bProof,
4235  unsigned int iLimit,
4236  Json::Value const& jvMarker,
4237  Json::Value& jvResult)
4238 {
4239  auto& jvOffers = (jvResult[jss::offers] = Json::Value(Json::arrayValue));
4240 
4242 
4243  MetaView lesActive(lpLedger, tapNONE, true);
4244  OrderBookIterator obIterator(lesActive, book);
4245 
4246  auto const rate = transferRate(lesActive, book.out.account);
4247 
4248  const bool bGlobalFreeze = lesActive.isGlobalFrozen(book.out.account) ||
4249  lesActive.isGlobalFrozen(book.in.account);
4250 
4251  while (iLimit-- > 0 && obIterator.nextOffer())
4252  {
4253  SLE::pointer sleOffer = obIterator.getCurrentOffer();
4254  if (sleOffer)
4255  {
4256  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
4257  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
4258  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
4259  STAmount saDirRate = obIterator.getCurrentRate();
4260  STAmount saOwnerFunds;
4261 
4262  if (book.out.account == uOfferOwnerID)
4263  {
4264  // If offer is selling issuer's own IOUs, it is fully funded.
4265  saOwnerFunds = saTakerGets;
4266  }
4267  else if (bGlobalFreeze)
4268  {
4269  // If either asset is globally frozen, consider all offers
4270  // that aren't ours to be totally unfunded
4271  saOwnerFunds.clear(book.out);
4272  }
4273  else
4274  {
4275  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
4276 
4277  if (umBalanceEntry != umBalance.end())
4278  {
4279  // Found in running balance table.
4280 
4281  saOwnerFunds = umBalanceEntry->second;
4282  }
4283  else
4284  {
4285  // Did not find balance in table.
4286 
4287  saOwnerFunds = lesActive.accountHolds(
4288  uOfferOwnerID,
4289  book.out.currency,
4290  book.out.account,
4292 
4293  if (saOwnerFunds.isNegative())
4294  {
4295  // Treat negative funds as zero.
4296 
4297  saOwnerFunds.zero();
4298  }
4299  }
4300  }
4301 
4302  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
4303 
4304  STAmount saTakerGetsFunded;
4305  STAmount saOwnerFundsLimit = saOwnerFunds;
4306  Rate offerRate = parityRate;
4307 
4308  if (rate != parityRate
4309  // Have a tranfer fee.
4310  && uTakerID != book.out.account
4311  // Not taking offers of own IOUs.
4312  && book.out.account != uOfferOwnerID)
4313  // Offer owner not issuing ownfunds
4314  {
4315  // Need to charge a transfer fee to offer owner.
4316  offerRate = rate;
4317  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
4318  }
4319 
4320  if (saOwnerFundsLimit >= saTakerGets)
4321  {
4322  // Sufficient funds no shenanigans.
4323  saTakerGetsFunded = saTakerGets;
4324  }
4325  else
4326  {
4327  // Only provide, if not fully funded.
4328  saTakerGetsFunded = saOwnerFundsLimit;
4329 
4330  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
4331 
4332  // TOOD(tom): The result of this expression is not used - what's
4333  // going on here?
4334  std::min(
4335  saTakerPays,
4336  multiply(saTakerGetsFunded, saDirRate, saTakerPays.issue()))
4337  .setJson(jvOffer[jss::taker_pays_funded]);
4338  }
4339 
4340  STAmount saOwnerPays = (parityRate == offerRate)
4341  ? saTakerGetsFunded
4342  : std::min(
4343  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
4344 
4345  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
4346 
4347  if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID)
4348  {
4349  // Only provide funded offers and offers of the taker.
4350  Json::Value& jvOf = jvOffers.append(jvOffer);
4351  jvOf[jss::quality] = saDirRate.getText();
4352  }
4353  }
4354  }
4355 
4356  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
4357  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
4358 }
4359 
4360 #endif
4361 
4362 inline void
4364 {
4365  auto [counters, mode, start, initialSync] = accounting_.getCounterData();
4366  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
4367  std::chrono::steady_clock::now() - start);
4368  counters[static_cast<std::size_t>(mode)].dur += current;
4369 
4372  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
4373  .dur.count());
4375  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
4376  .dur.count());
4378  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].dur.count());
4380  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
4381  .dur.count());
4383  counters[static_cast<std::size_t>(OperatingMode::FULL)].dur.count());
4384 
4386  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
4387  .transitions);
4389  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
4390  .transitions);
4392  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].transitions);
4394  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
4395  .transitions);
4397  counters[static_cast<std::size_t>(OperatingMode::FULL)].transitions);
4398 }
4399 
4400 void
4402 {
4403  auto now = std::chrono::steady_clock::now();
4404 
4405  std::lock_guard lock(mutex_);
4406  ++counters_[static_cast<std::size_t>(om)].transitions;
4407  if (om == OperatingMode::FULL &&
4408  counters_[static_cast<std::size_t>(om)].transitions == 1)
4409  {
4410  initialSyncUs_ = std::chrono::duration_cast<std::chrono::microseconds>(
4411  now - processStart_)
4412  .count();
4413  }
4414  counters_[static_cast<std::size_t>(mode_)].dur +=
4415  std::chrono::duration_cast<std::chrono::microseconds>(now - start_);
4416 
4417  mode_ = om;
4418  start_ = now;
4419 }
4420 
4421 void
4423 {
4424  auto [counters, mode, start, initialSync] = getCounterData();
4425  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
4426  std::chrono::steady_clock::now() - start);
4427  counters[static_cast<std::size_t>(mode)].dur += current;
4428 
4429  obj[jss::state_accounting] = Json::objectValue;
4430  for (std::size_t i = static_cast<std::size_t>(OperatingMode::DISCONNECTED);
4431  i <= static_cast<std::size_t>(OperatingMode::FULL);
4432  ++i)
4433  {
4434  obj[jss::state_accounting][states_[i]] = Json::objectValue;
4435  auto& state = obj[jss::state_accounting][states_[i]];
4436  state[jss::transitions] = std::to_string(counters[i].transitions);
4437  state[jss::duration_us] = std::to_string(counters[i].dur.count());
4438  }
4439  obj[jss::server_state_duration_us] = std::to_string(current.count());
4440  if (initialSync)
4441  obj[jss::initial_sync_duration_us] = std::to_string(initialSync);
4442 }
4443 
4444 //------------------------------------------------------------------------------
4445 
4448  Application& app,
4449  NetworkOPs::clock_type& clock,
4450  bool standalone,
4451  std::size_t minPeerCount,
4452  bool startvalid,
4453  JobQueue& job_queue,
4454  LedgerMaster& ledgerMaster,
4455  ValidatorKeys const& validatorKeys,
4456  boost::asio::io_service& io_svc,
4457  beast::Journal journal,
4458  beast::insight::Collector::ptr const& collector)
4459 {
4460  return std::make_unique<NetworkOPsImp>(
4461  app,
4462  clock,
4463  standalone,
4464  minPeerCount,
4465  startvalid,
4466  job_queue,
4467  ledgerMaster,
4468  validatorKeys,
4469  io_svc,
4470  journal,
4471  collector);
4472 }
4473 
4474 } // namespace ripple
ripple::NetworkOPsImp::forwardManifest
void forwardManifest(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2729
ripple::NetworkOPsImp::unsubValidations
bool unsubValidations(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3932
ripple::NetworkOPsImp::Stats::hook
beast::insight::Hook hook
Definition: NetworkOPs.cpp:803
ripple::STTx::getTxnType
TxType getTxnType() const
Definition: STTx.h:165
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:3916
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:1843
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:3968
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:1837
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:3925
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:1651
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:2645
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:890
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:4422
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::STAmount::clear
void clear()
Definition: STAmount.h:393
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::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:338
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:1588
ripple::NetworkOPsImp::pubManifest
void pubManifest(Manifest const &) override
Definition: NetworkOPs.cpp:1927
ripple::Manifest
Definition: Manifest.h:78
ripple::NetworkOPsImp::collect_metrics
void collect_metrics()
Definition: NetworkOPs.cpp:4363
ripple::NetworkOPsImp::subPeerStatus
bool subPeerStatus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3940
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:2208
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:1600
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:3998
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:530
ripple::NetworkOPsImp::recvValidation
bool recvValidation(std::shared_ptr< STValidation > const &val, std::string const &source) override
Definition: NetworkOPs.cpp:2237
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:2678
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:196
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:29
ripple::NetworkOPsImp::Stats::disconnected_duration
beast::insight::Gauge disconnected_duration
Definition: NetworkOPs.cpp: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:1918
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:3717
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:1290
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:4447
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:2767
ripple::Application::openLedger
virtual OpenLedger & openLedger()=0
ripple::NetworkOPsImp::pubLedger
void pubLedger(std::shared_ptr< ReadView const > const &lpAccepted) override
Definition: NetworkOPs.cpp:2835
ripple::NetworkOPsImp::switchLastClosedLedger
void switchLastClosedLedger(std::shared_ptr< Ledger const > const &newLCL)
Definition: NetworkOPs.cpp:1724
ripple::tapNONE
@ tapNONE
Definition: ApplyView.h:30
ripple::NetworkOPsImp::setUNLBlocked
void setUNLBlocked() override
Definition: NetworkOPs.cpp:1606
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:1658
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:3890
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:936
std::vector::push_back
T push_back(T... args)
ripple::NetworkOPsImp::ServerFeeSummary::loadFactorServer
std::uint32_t loadFactorServer
Definition: NetworkOPs.cpp:208
ripple::divide
STAmount divide(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp: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:2749
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:1569
ripple::NetworkOPsImp::addRpcSub
InfoSub::pointer addRpcSub(std::string const &strUrl, InfoSub::ref) override
Definition: NetworkOPs.cpp:3988
ripple::rpcSUCCESS
@ rpcSUCCESS
Definition: ErrorCodes.h:44
ripple::NetworkOPsImp::forwardValidation
void forwardValidation(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2709
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:1594
ripple::STAmount::setJson
void setJson(Json::Value &) const
Definition: STAmount.cpp:476
ripple::UptimeClock::now
static time_point now()
Definition: UptimeClock.cpp:63
ripple::NetworkOPsImp::subAccountHistoryStart
void subAccountHistoryStart(std::shared_ptr< ReadView const > const &ledger, SubAccountHistoryInfoWeak &subInfo)
Definition: NetworkOPs.cpp:3616
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:1497
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:2929
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:3298
ripple::NetworkOPsImp::isBlocked
bool isBlocked() override
Definition: NetworkOPs.cpp:1563
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:3029
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:589
ripple::sfNewFields
const SField sfNewFields
ripple::NetworkOPsImp::SubAccountHistoryInfoWeak::sinkWptr_
InfoSub::wptr sinkWptr_
Definition: NetworkOPs.cpp: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:1862
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:3254
ripple::Application::nodeIdentity
virtual std::pair< PublicKey, SecretKey > const & nodeIdentity()=0
ripple::NetworkOPsImp::unsubRTTransactions
bool unsubRTTransactions(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3908
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:3824
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:1613
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:2971
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:65
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:3080
ripple::LedgerMaster::getLedgerBySeq
std::shared_ptr< Ledger const > getLedgerBySeq(std::uint32_t index)
Definition: LedgerMaster.cpp:1776
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:3880
ripple::TimeKeeper::closeTime
virtual time_point closeTime() const =0
Returns the close time, in network time.
ripple::ValStatus::current
@ current
This was a new validation and was added.
ripple::ClosureCounter
The role of a ClosureCounter is to assist in shutdown by letting callers wait for the completion of c...
Definition: ClosureCounter.h:54
ripple::NetworkOPsImp::StateAccounting::counters_
std::array< Counters, 5 > counters_
Definition: NetworkOPs.cpp:142
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
ripple::NetworkOPsImp::unsubLedger
bool unsubLedger(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3816
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::NetworkOPsImp::isAmendmentWarned
bool isAmendmentWarned() override
Definition: NetworkOPs.cpp:1582
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:2101
ripple::amountFromQuality
STAmount amountFromQuality(std::uint64_t rate)
Definition: STAmount.cpp:793
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:3217
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:1611
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:226
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:1276
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:1977
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:2322
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:2949
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:3872
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:545
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:2963
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:2639
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:2006
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:3758
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:3767
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
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:1619
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:4023
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:2179
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:3787
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:3660
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:1621
ripple::NetworkOPsImp::unsubManifests
bool unsubManifests(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3834
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:2958
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:2074
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:3898
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:2260
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:3842
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:1236
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:3748
ripple::NetworkOPsImp::subConsensus
bool subConsensus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3958
ripple::NetworkOPsImp::getConsensusInfo
Json::Value getConsensusInfo() override
Definition: NetworkOPs.cpp:2254
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:4401
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:3270
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:3706
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:603
ripple::NetworkOPsImp::unsubPeerStatus
bool unsubPeerStatus(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3950
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:1998
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:3975
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:2633
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:1778
ripple::NetworkOPsImp::setAmendmentBlocked
void setAmendmentBlocked() override
Definition: NetworkOPs.cpp:1575
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)