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/reporting/ReportingETL.h>
42 #include <ripple/app/tx/apply.h>
43 #include <ripple/basics/PerfLog.h>
44 #include <ripple/basics/UptimeClock.h>
45 #include <ripple/basics/mulDiv.h>
46 #include <ripple/basics/safe_cast.h>
47 #include <ripple/beast/rfc2616.h>
48 #include <ripple/beast/utility/rngfill.h>
49 #include <ripple/consensus/Consensus.h>
50 #include <ripple/consensus/ConsensusParms.h>
51 #include <ripple/crypto/RFC1751.h>
52 #include <ripple/crypto/csprng.h>
53 #include <ripple/json/to_string.h>
54 #include <ripple/nodestore/DatabaseShard.h>
55 #include <ripple/overlay/Cluster.h>
56 #include <ripple/overlay/Overlay.h>
57 #include <ripple/overlay/predicates.h>
58 #include <ripple/protocol/BuildInfo.h>
59 #include <ripple/protocol/Feature.h>
60 #include <ripple/protocol/STParsedJSON.h>
61 #include <ripple/resource/ResourceManager.h>
62 #include <ripple/rpc/DeliveredAmount.h>
63 #include <ripple/rpc/impl/RPCHelpers.h>
64 #include <boost/asio/ip/host_name.hpp>
65 #include <boost/asio/steady_timer.hpp>
66 
67 #include <mutex>
68 #include <string>
69 #include <tuple>
70 #include <utility>
71 
72 namespace ripple {
73 
74 class NetworkOPsImp final : public NetworkOPs
75 {
81  {
82  public:
84  bool const admin;
85  bool const local;
87  bool applied = false;
89 
92  bool a,
93  bool l,
94  FailHard f)
95  : transaction(t), admin(a), local(l), failType(f)
96  {
97  assert(local || failType == FailHard::no);
98  }
99  };
100 
104  enum class DispatchState : unsigned char {
105  none,
106  scheduled,
107  running,
108  };
109 
111 
127  {
128  struct Counters
129  {
130  explicit Counters() = default;
131 
134  };
135 
139  std::chrono::system_clock::time_point start_ =
142 
143  public:
144  explicit StateAccounting()
145  {
147  .transitions = 1;
148  }
149 
156  void
157  mode(OperatingMode om);
158 
165 
172  json() const;
173 
174  struct CounterData
175  {
176  decltype(counters_) counters;
177  decltype(mode_) mode;
178  decltype(start_) start;
179  };
180 
183  {
184  std::lock_guard lock(mutex_);
185  return {counters_, mode_, start_};
186  }
187  };
188 
191  {
192  ServerFeeSummary() = default;
193 
195  XRPAmount fee,
196  TxQ::Metrics&& escalationMetrics,
197  LoadFeeTrack const& loadFeeTrack);
198  bool
199  operator!=(ServerFeeSummary const& b) const;
200 
201  bool
202  operator==(ServerFeeSummary const& b) const
203  {
204  return !(*this != b);
205  }
206 
211  };
212 
213 public:
215  Application& app,
216  NetworkOPs::clock_type& clock,
217  bool standalone,
218  std::size_t minPeerCount,
219  bool start_valid,
220  JobQueue& job_queue,
221  LedgerMaster& ledgerMaster,
222  ValidatorKeys const& validatorKeys,
223  boost::asio::io_service& io_svc,
224  beast::Journal journal,
225  beast::insight::Collector::ptr const& collector)
226  : app_(app)
227  , m_journal(journal)
229  , mMode(start_valid ? OperatingMode::FULL : OperatingMode::DISCONNECTED)
230  , heartbeatTimer_(io_svc)
231  , clusterTimer_(io_svc)
232  , mConsensus(
233  app,
234  make_FeeVote(
235  setup_FeeVote(app_.config().section("voting")),
236  app_.logs().journal("FeeVote")),
237  ledgerMaster,
238  *m_localTX,
239  app.getInboundTransactions(),
240  beast::get_abstract_clock<std::chrono::steady_clock>(),
241  validatorKeys,
242  app_.logs().journal("LedgerConsensus"))
244  , m_job_queue(job_queue)
245  , m_standalone(standalone)
246  , minPeerCount_(start_valid ? 0 : minPeerCount)
247  , m_stats(std::bind(&NetworkOPsImp::collect_metrics, this), collector)
248  {
249  }
250 
251  ~NetworkOPsImp() override
252  {
253  // This clear() is necessary to ensure the shared_ptrs in this map get
254  // destroyed NOW because the objects in this map invoke methods on this
255  // class when they are destroyed
256  mRpcSubMap.clear();
257  }
258 
259 public:
261  getOperatingMode() const override;
262 
264  strOperatingMode(OperatingMode const mode, bool const admin) const override;
265 
267  strOperatingMode(bool const admin = false) const override;
268 
269  //
270  // Transaction operations.
271  //
272 
273  // Must complete immediately.
274  void
276 
277  void
279  std::shared_ptr<Transaction>& transaction,
280  bool bUnlimited,
281  bool bLocal,
282  FailHard failType) override;
283 
292  void
294  std::shared_ptr<Transaction> transaction,
295  bool bUnlimited,
296  FailHard failType);
297 
307  void
309  std::shared_ptr<Transaction> transaction,
310  bool bUnlimited,
311  FailHard failtype);
312 
316  void
318 
324  void
326 
327  //
328  // Owner functions.
329  //
330 
332  getOwnerInfo(
334  AccountID const& account) override;
335 
336  //
337  // Book functions.
338  //
339 
340  void
341  getBookPage(
343  Book const&,
344  AccountID const& uTakerID,
345  const bool bProof,
346  unsigned int iLimit,
347  Json::Value const& jvMarker,
348  Json::Value& jvResult) override;
349 
350  // Ledger proposal/close functions.
351  bool
352  processTrustedProposal(RCLCxPeerPos proposal) override;
353 
354  bool
357  std::string const& source) override;
358 
359  void
360  mapComplete(std::shared_ptr<SHAMap> const& map, bool fromAcquire) override;
361 
362  // Network state machine.
363 
364  // Used for the "jump" case.
365 private:
366  void
368  bool
369  checkLastClosedLedger(const Overlay::PeerSequence&, uint256& networkClosed);
370 
371 public:
372  bool
373  beginConsensus(uint256 const& networkClosed) override;
374  void
375  endConsensus() override;
376  void
377  setStandAlone() override;
378 
382  void
383  setStateTimer() override;
384 
385  void
386  setNeedNetworkLedger() override;
387  void
388  clearNeedNetworkLedger() override;
389  bool
390  isNeedNetworkLedger() override;
391  bool
392  isFull() override;
393 
394  void
395  setMode(OperatingMode om) override;
396 
397  bool
398  isBlocked() override;
399  bool
400  isAmendmentBlocked() override;
401  void
402  setAmendmentBlocked() override;
403  bool
404  isAmendmentWarned() override;
405  void
406  setAmendmentWarned() override;
407  void
408  clearAmendmentWarned() override;
409  bool
410  isUNLBlocked() override;
411  void
412  setUNLBlocked() override;
413  void
414  clearUNLBlocked() override;
415  void
416  consensusViewChange() override;
417 
419  getConsensusInfo() override;
421  getServerInfo(bool human, bool admin, bool counters) override;
422  void
423  clearLedgerFetch() override;
425  getLedgerFetchInfo() override;
427  acceptLedger(
428  std::optional<std::chrono::milliseconds> consensusDelay) override;
429  void
430  reportFeeChange() override;
431  void
433 
434  void
435  updateLocalTx(ReadView const& view) override;
437  getLocalTxCount() override;
438 
439  //
440  // Monitoring: publisher side.
441  //
442  void
443  pubLedger(std::shared_ptr<ReadView const> const& lpAccepted) override;
444  void
446  std::shared_ptr<ReadView const> const& lpCurrent,
447  std::shared_ptr<STTx const> const& stTxn,
448  TER terResult) override;
449  void
450  pubValidation(std::shared_ptr<STValidation> const& val) override;
451 
452  void
453  forwardValidation(Json::Value const& jvObj) override;
454  void
455  forwardManifest(Json::Value const& jvObj) override;
456  void
457  forwardProposedTransaction(Json::Value const& jvObj) override;
458  void
459  forwardProposedAccountTransaction(Json::Value const& jvObj) override;
460 
461  //--------------------------------------------------------------------------
462  //
463  // InfoSub::Source.
464  //
465  void
466  subAccount(
467  InfoSub::ref ispListener,
468  hash_set<AccountID> const& vnaAccountIDs,
469  bool rt) override;
470  void
471  unsubAccount(
472  InfoSub::ref ispListener,
473  hash_set<AccountID> const& vnaAccountIDs,
474  bool rt) override;
475 
476  // Just remove the subscription from the tracking
477  // not from the InfoSub. Needed for InfoSub destruction
478  void
480  std::uint64_t seq,
481  hash_set<AccountID> const& vnaAccountIDs,
482  bool rt) override;
483 
484  bool
485  subLedger(InfoSub::ref ispListener, Json::Value& jvResult) override;
486  bool
487  unsubLedger(std::uint64_t uListener) override;
488 
489  bool
490  subServer(InfoSub::ref ispListener, Json::Value& jvResult, bool admin)
491  override;
492  bool
493  unsubServer(std::uint64_t uListener) override;
494 
495  bool
496  subBook(InfoSub::ref ispListener, Book const&) override;
497  bool
498  unsubBook(std::uint64_t uListener, Book const&) override;
499 
500  bool
501  subManifests(InfoSub::ref ispListener) override;
502  bool
503  unsubManifests(std::uint64_t uListener) override;
504  void
505  pubManifest(Manifest const&) override;
506 
507  bool
508  subTransactions(InfoSub::ref ispListener) override;
509  bool
510  unsubTransactions(std::uint64_t uListener) override;
511 
512  bool
513  subRTTransactions(InfoSub::ref ispListener) override;
514  bool
515  unsubRTTransactions(std::uint64_t uListener) override;
516 
517  bool
518  subValidations(InfoSub::ref ispListener) override;
519  bool
520  unsubValidations(std::uint64_t uListener) override;
521 
522  bool
523  subPeerStatus(InfoSub::ref ispListener) override;
524  bool
525  unsubPeerStatus(std::uint64_t uListener) override;
526  void
527  pubPeerStatus(std::function<Json::Value(void)> const&) override;
528 
529  bool
530  subConsensus(InfoSub::ref ispListener) override;
531  bool
532  unsubConsensus(std::uint64_t uListener) override;
533 
535  findRpcSub(std::string const& strUrl) override;
537  addRpcSub(std::string const& strUrl, InfoSub::ref) override;
538  bool
539  tryRemoveRpcSub(std::string const& strUrl) override;
540 
541  void
542  stop() override
543  {
544  {
545  boost::system::error_code ec;
546  heartbeatTimer_.cancel(ec);
547  if (ec)
548  {
549  JLOG(m_journal.error())
550  << "NetworkOPs: heartbeatTimer cancel error: "
551  << ec.message();
552  }
553 
554  ec.clear();
555  clusterTimer_.cancel(ec);
556  if (ec)
557  {
558  JLOG(m_journal.error())
559  << "NetworkOPs: clusterTimer cancel error: "
560  << ec.message();
561  }
562  }
563  // Make sure that any waitHandlers pending in our timers are done.
564  using namespace std::chrono_literals;
565  waitHandlerCounter_.join("NetworkOPs", 1s, m_journal);
566  }
567 
568 private:
569  void
571  void
572  setClusterTimer();
573  void
575  void
577 
579  transJson(
580  const STTx& stTxn,
581  TER terResult,
582  bool bValidated,
583  std::shared_ptr<ReadView const> const& lpCurrent);
584 
585  void
587  std::shared_ptr<ReadView const> const& alAccepted,
588  const AcceptedLedgerTx& alTransaction);
589  void
591  std::shared_ptr<ReadView const> const& lpCurrent,
592  const AcceptedLedgerTx& alTransaction,
593  bool isAccepted);
594 
595  void
596  pubServer();
597  void
599 
601  getHostId(bool forAdmin);
602 
603 private:
607 
610 
612 
614 
616 
621 
623  boost::asio::steady_timer heartbeatTimer_;
624  boost::asio::steady_timer clusterTimer_;
625 
627 
629 
631 
634 
636 
637  enum SubTypes {
638  sLedger, // Accepted ledgers.
639  sManifests, // Received validator manifests.
640  sServer, // When server changes connectivity state.
641  sTransactions, // All accepted transactions.
642  sRTTransactions, // All proposed and accepted transactions.
643  sValidations, // Received validations.
644  sPeerStatus, // Peer status changes.
645  sConsensusPhase, // Consensus phase
646 
647  sLastEntry = sConsensusPhase // as this name implies, any new entry
648  // must be ADDED ABOVE this one
649  };
651 
653 
655 
656  // Whether we are in standalone mode.
657  bool const m_standalone;
658 
659  // The number of nodes that we need to consider ourselves connected.
661 
662  // Transaction batching.
667 
669 
670 private:
671  struct Stats
672  {
673  template <class Handler>
675  Handler const& handler,
676  beast::insight::Collector::ptr const& collector)
677  : hook(collector->make_hook(handler))
678  , disconnected_duration(collector->make_gauge(
679  "State_Accounting",
680  "Disconnected_duration"))
681  , connected_duration(collector->make_gauge(
682  "State_Accounting",
683  "Connected_duration"))
685  collector->make_gauge("State_Accounting", "Syncing_duration"))
686  , tracking_duration(collector->make_gauge(
687  "State_Accounting",
688  "Tracking_duration"))
689  , full_duration(
690  collector->make_gauge("State_Accounting", "Full_duration"))
691  , disconnected_transitions(collector->make_gauge(
692  "State_Accounting",
693  "Disconnected_transitions"))
694  , connected_transitions(collector->make_gauge(
695  "State_Accounting",
696  "Connected_transitions"))
697  , syncing_transitions(collector->make_gauge(
698  "State_Accounting",
699  "Syncing_transitions"))
700  , tracking_transitions(collector->make_gauge(
701  "State_Accounting",
702  "Tracking_transitions"))
704  collector->make_gauge("State_Accounting", "Full_transitions"))
705  {
706  }
707 
714 
720  };
721 
722  std::mutex m_statsMutex; // Mutex to lock m_stats
724 
725 private:
726  void
727  collect_metrics();
728 };
729 
730 //------------------------------------------------------------------------------
731 
733  {"disconnected", "connected", "syncing", "tracking", "full"}};
734 
736 
744 
745 //------------------------------------------------------------------------------
746 inline OperatingMode
748 {
749  return mMode;
750 }
751 
752 inline std::string
753 NetworkOPsImp::strOperatingMode(bool const admin /* = false */) const
754 {
755  return strOperatingMode(mMode, admin);
756 }
757 
758 inline void
760 {
762 }
763 
764 inline void
766 {
767  needNetworkLedger_ = true;
768 }
769 
770 inline void
772 {
773  needNetworkLedger_ = false;
774 }
775 
776 inline bool
778 {
779  return needNetworkLedger_;
780 }
781 
782 inline bool
784 {
786 }
787 
790 {
791  static std::string const hostname = boost::asio::ip::host_name();
792 
793  if (forAdmin)
794  return hostname;
795 
796  // For non-admin uses hash the node public key into a
797  // single RFC1751 word:
798  static std::string const shroudedHostId = [this]() {
799  auto const& id = app_.nodeIdentity();
800 
801  return RFC1751::getWordFromBlob(id.first.data(), id.first.size());
802  }();
803 
804  return shroudedHostId;
805 }
806 
807 void
809 {
811  setClusterTimer();
812 }
813 
814 void
816 {
817  // Only start the timer if waitHandlerCounter_ is not yet joined.
818  if (auto optionalCountedHandler = waitHandlerCounter_.wrap(
819  [this](boost::system::error_code const& e) {
820  if ((e.value() == boost::system::errc::success) &&
821  (!m_job_queue.isStopped()))
822  {
823  m_job_queue.addJob(
824  jtNETOP_TIMER, "NetOPs.heartbeat", [this](Job&) {
825  processHeartbeatTimer();
826  });
827  }
828  // Recover as best we can if an unexpected error occurs.
829  if (e.value() != boost::system::errc::success &&
830  e.value() != boost::asio::error::operation_aborted)
831  {
832  // Try again later and hope for the best.
833  JLOG(m_journal.error())
834  << "Heartbeat timer got error '" << e.message()
835  << "'. Restarting timer.";
836  setHeartbeatTimer();
837  }
838  }))
839  {
841  heartbeatTimer_.async_wait(std::move(*optionalCountedHandler));
842  }
843 }
844 
845 void
847 {
848  // Only start the timer if waitHandlerCounter_ is not yet joined.
849  if (auto optionalCountedHandler = waitHandlerCounter_.wrap(
850  [this](boost::system::error_code const& e) {
851  if ((e.value() == boost::system::errc::success) &&
852  (!m_job_queue.isStopped()))
853  {
854  m_job_queue.addJob(
855  jtNETOP_CLUSTER, "NetOPs.cluster", [this](Job&) {
856  processClusterTimer();
857  });
858  }
859  // Recover as best we can if an unexpected error occurs.
860  if (e.value() != boost::system::errc::success &&
861  e.value() != boost::asio::error::operation_aborted)
862  {
863  // Try again later and hope for the best.
864  JLOG(m_journal.error())
865  << "Cluster timer got error '" << e.message()
866  << "'. Restarting timer.";
867  setClusterTimer();
868  }
869  }))
870  {
871  using namespace std::chrono_literals;
872  clusterTimer_.expires_from_now(10s);
873  clusterTimer_.async_wait(std::move(*optionalCountedHandler));
874  }
875 }
876 
877 void
879 {
880  {
882 
883  // VFALCO NOTE This is for diagnosing a crash on exit
885  mgr.resetDeadlockDetector();
886 
887  std::size_t const numPeers = app_.overlay().size();
888 
889  // do we have sufficient peers? If not, we are disconnected.
890  if (numPeers < minPeerCount_)
891  {
893  {
895  JLOG(m_journal.warn())
896  << "Node count (" << numPeers << ") has fallen "
897  << "below required minimum (" << minPeerCount_ << ").";
898  }
899 
900  // MasterMutex lock need not be held to call setHeartbeatTimer()
901  lock.unlock();
902  // We do not call mConsensus.timerEntry until there are enough
903  // peers providing meaningful inputs to consensus
905  return;
906  }
907 
909  {
911  JLOG(m_journal.info())
912  << "Node count (" << numPeers << ") is sufficient.";
913  }
914 
915  // Check if the last validated ledger forces a change between these
916  // states.
919  else if (mMode == OperatingMode::CONNECTED)
921  }
922 
924 
925  const ConsensusPhase currPhase = mConsensus.phase();
926  if (mLastConsensusPhase != currPhase)
927  {
928  reportConsensusStateChange(currPhase);
929  mLastConsensusPhase = currPhase;
930  }
931 
933 }
934 
935 void
937 {
938  using namespace std::chrono_literals;
939  bool const update = app_.cluster().update(
940  app_.nodeIdentity().first,
941  "",
944  : 0,
945  app_.timeKeeper().now());
946 
947  if (!update)
948  {
949  JLOG(m_journal.debug()) << "Too soon to send cluster update";
950  setClusterTimer();
951  return;
952  }
953 
954  protocol::TMCluster cluster;
955  app_.cluster().for_each([&cluster](ClusterNode const& node) {
956  protocol::TMClusterNode& n = *cluster.add_clusternodes();
957  n.set_publickey(toBase58(TokenType::NodePublic, node.identity()));
958  n.set_reporttime(node.getReportTime().time_since_epoch().count());
959  n.set_nodeload(node.getLoadFee());
960  if (!node.name().empty())
961  n.set_nodename(node.name());
962  });
963 
965  for (auto& item : gossip.items)
966  {
967  protocol::TMLoadSource& node = *cluster.add_loadsources();
968  node.set_name(to_string(item.address));
969  node.set_cost(item.balance);
970  }
972  std::make_shared<Message>(cluster, protocol::mtCLUSTER),
973  peer_in_cluster()));
974  setClusterTimer();
975 }
976 
977 //------------------------------------------------------------------------------
978 
980 NetworkOPsImp::strOperatingMode(OperatingMode const mode, bool const admin)
981  const
982 {
983  if (mode == OperatingMode::FULL && admin)
984  {
985  auto const consensusMode = mConsensus.mode();
986  if (consensusMode != ConsensusMode::wrongLedger)
987  {
988  if (consensusMode == ConsensusMode::proposing)
989  return "proposing";
990 
991  if (mConsensus.validating())
992  return "validating";
993  }
994  }
995 
996  return states_[static_cast<std::size_t>(mode)];
997 }
998 
999 void
1001 {
1002  if (isNeedNetworkLedger())
1003  {
1004  // Nothing we can do if we've never been in sync
1005  return;
1006  }
1007 
1008  // this is an asynchronous interface
1009  auto const trans = sterilize(*iTrans);
1010 
1011  auto const txid = trans->getTransactionID();
1012  auto const flags = app_.getHashRouter().getFlags(txid);
1013 
1014  if ((flags & SF_BAD) != 0)
1015  {
1016  JLOG(m_journal.warn()) << "Submitted transaction cached bad";
1017  return;
1018  }
1019 
1020  try
1021  {
1022  auto const [validity, reason] = checkValidity(
1023  app_.getHashRouter(),
1024  *trans,
1026  app_.config());
1027 
1028  if (validity != Validity::Valid)
1029  {
1030  JLOG(m_journal.warn())
1031  << "Submitted transaction invalid: " << reason;
1032  return;
1033  }
1034  }
1035  catch (std::exception const&)
1036  {
1037  JLOG(m_journal.warn()) << "Exception checking transaction" << txid;
1038 
1039  return;
1040  }
1041 
1042  std::string reason;
1043 
1044  auto tx = std::make_shared<Transaction>(trans, reason, app_);
1045 
1046  m_job_queue.addJob(jtTRANSACTION, "submitTxn", [this, tx](Job&) {
1047  auto t = tx;
1048  processTransaction(t, false, false, FailHard::no);
1049  });
1050 }
1051 
1052 void
1054  std::shared_ptr<Transaction>& transaction,
1055  bool bUnlimited,
1056  bool bLocal,
1057  FailHard failType)
1058 {
1059  auto ev = m_job_queue.makeLoadEvent(jtTXN_PROC, "ProcessTXN");
1060  auto const newFlags = app_.getHashRouter().getFlags(transaction->getID());
1061 
1062  if ((newFlags & SF_BAD) != 0)
1063  {
1064  // cached bad
1065  transaction->setStatus(INVALID);
1066  transaction->setResult(temBAD_SIGNATURE);
1067  return;
1068  }
1069 
1070  // NOTE eahennis - I think this check is redundant,
1071  // but I'm not 100% sure yet.
1072  // If so, only cost is looking up HashRouter flags.
1073  auto const view = m_ledgerMaster.getCurrentLedger();
1074  auto const [validity, reason] = checkValidity(
1075  app_.getHashRouter(),
1076  *transaction->getSTransaction(),
1077  view->rules(),
1078  app_.config());
1079  assert(validity == Validity::Valid);
1080 
1081  // Not concerned with local checks at this point.
1082  if (validity == Validity::SigBad)
1083  {
1084  JLOG(m_journal.info()) << "Transaction has bad signature: " << reason;
1085  transaction->setStatus(INVALID);
1086  transaction->setResult(temBAD_SIGNATURE);
1087  app_.getHashRouter().setFlags(transaction->getID(), SF_BAD);
1088  return;
1089  }
1090 
1091  // canonicalize can change our pointer
1092  app_.getMasterTransaction().canonicalize(&transaction);
1093 
1094  if (bLocal)
1095  doTransactionSync(transaction, bUnlimited, failType);
1096  else
1097  doTransactionAsync(transaction, bUnlimited, failType);
1098 }
1099 
1100 void
1102  std::shared_ptr<Transaction> transaction,
1103  bool bUnlimited,
1104  FailHard failType)
1105 {
1106  std::lock_guard lock(mMutex);
1107 
1108  if (transaction->getApplying())
1109  return;
1110 
1111  mTransactions.push_back(
1112  TransactionStatus(transaction, bUnlimited, false, failType));
1113  transaction->setApplying();
1114 
1116  {
1117  if (m_job_queue.addJob(jtBATCH, "transactionBatch", [this](Job&) {
1118  transactionBatch();
1119  }))
1120  {
1122  }
1123  }
1124 }
1125 
1126 void
1128  std::shared_ptr<Transaction> transaction,
1129  bool bUnlimited,
1130  FailHard failType)
1131 {
1133 
1134  if (!transaction->getApplying())
1135  {
1136  mTransactions.push_back(
1137  TransactionStatus(transaction, bUnlimited, true, failType));
1138  transaction->setApplying();
1139  }
1140 
1141  do
1142  {
1144  {
1145  // A batch processing job is already running, so wait.
1146  mCond.wait(lock);
1147  }
1148  else
1149  {
1150  apply(lock);
1151 
1152  if (mTransactions.size())
1153  {
1154  // More transactions need to be applied, but by another job.
1155  if (m_job_queue.addJob(
1156  jtBATCH, "transactionBatch", [this](Job&) {
1157  transactionBatch();
1158  }))
1159  {
1161  }
1162  }
1163  }
1164  } while (transaction->getApplying());
1165 }
1166 
1167 void
1169 {
1171 
1173  return;
1174 
1175  while (mTransactions.size())
1176  {
1177  apply(lock);
1178  }
1179 }
1180 
1181 void
1183 {
1184  std::vector<TransactionStatus> submit_held;
1185  std::vector<TransactionStatus> transactions;
1186  mTransactions.swap(transactions);
1187  assert(!transactions.empty());
1188 
1191 
1192  batchLock.unlock();
1193 
1194  {
1195  std::unique_lock masterLock{app_.getMasterMutex(), std::defer_lock};
1196  bool changed = false;
1197  {
1198  std::unique_lock ledgerLock{
1199  m_ledgerMaster.peekMutex(), std::defer_lock};
1200  std::lock(masterLock, ledgerLock);
1201 
1202  app_.openLedger().modify([&](OpenView& view, beast::Journal j) {
1203  for (TransactionStatus& e : transactions)
1204  {
1205  // we check before adding to the batch
1206  ApplyFlags flags = tapNONE;
1207  if (e.admin)
1208  flags |= tapUNLIMITED;
1209 
1210  if (e.failType == FailHard::yes)
1211  flags |= tapFAIL_HARD;
1212 
1213  auto const result = app_.getTxQ().apply(
1214  app_, view, e.transaction->getSTransaction(), flags, j);
1215  e.result = result.first;
1216  e.applied = result.second;
1217  changed = changed || result.second;
1218  }
1219  return changed;
1220  });
1221  }
1222  if (changed)
1223  reportFeeChange();
1224 
1225  std::optional<LedgerIndex> validatedLedgerIndex;
1226  if (auto const l = m_ledgerMaster.getValidatedLedger())
1227  validatedLedgerIndex = l->info().seq;
1228 
1229  auto newOL = app_.openLedger().current();
1230  for (TransactionStatus& e : transactions)
1231  {
1232  e.transaction->clearSubmitResult();
1233 
1234  if (e.applied)
1235  {
1237  newOL, e.transaction->getSTransaction(), e.result);
1238  e.transaction->setApplied();
1239  }
1240 
1241  e.transaction->setResult(e.result);
1242 
1243  if (isTemMalformed(e.result))
1244  app_.getHashRouter().setFlags(e.transaction->getID(), SF_BAD);
1245 
1246 #ifdef DEBUG
1247  if (e.result != tesSUCCESS)
1248  {
1249  std::string token, human;
1250 
1251  if (transResultInfo(e.result, token, human))
1252  {
1253  JLOG(m_journal.info())
1254  << "TransactionResult: " << token << ": " << human;
1255  }
1256  }
1257 #endif
1258 
1259  bool addLocal = e.local;
1260 
1261  if (e.result == tesSUCCESS)
1262  {
1263  JLOG(m_journal.debug())
1264  << "Transaction is now included in open ledger";
1265  e.transaction->setStatus(INCLUDED);
1266 
1267  auto const& txCur = e.transaction->getSTransaction();
1268  auto const txNext = m_ledgerMaster.popAcctTransaction(txCur);
1269  if (txNext)
1270  {
1271  std::string reason;
1272  auto const trans = sterilize(*txNext);
1273  auto t = std::make_shared<Transaction>(trans, reason, app_);
1274  submit_held.emplace_back(t, false, false, FailHard::no);
1275  t->setApplying();
1276  }
1277  }
1278  else if (e.result == tefPAST_SEQ)
1279  {
1280  // duplicate or conflict
1281  JLOG(m_journal.info()) << "Transaction is obsolete";
1282  e.transaction->setStatus(OBSOLETE);
1283  }
1284  else if (e.result == terQUEUED)
1285  {
1286  JLOG(m_journal.debug())
1287  << "Transaction is likely to claim a"
1288  << " fee, but is queued until fee drops";
1289 
1290  e.transaction->setStatus(HELD);
1291  // Add to held transactions, because it could get
1292  // kicked out of the queue, and this will try to
1293  // put it back.
1294  m_ledgerMaster.addHeldTransaction(e.transaction);
1295  e.transaction->setQueued();
1296  e.transaction->setKept();
1297  }
1298  else if (isTerRetry(e.result))
1299  {
1300  if (e.failType != FailHard::yes)
1301  {
1302  // transaction should be held
1303  JLOG(m_journal.debug())
1304  << "Transaction should be held: " << e.result;
1305  e.transaction->setStatus(HELD);
1306  m_ledgerMaster.addHeldTransaction(e.transaction);
1307  e.transaction->setKept();
1308  }
1309  }
1310  else
1311  {
1312  JLOG(m_journal.debug())
1313  << "Status other than success " << e.result;
1314  e.transaction->setStatus(INVALID);
1315  }
1316 
1317  auto const enforceFailHard =
1318  e.failType == FailHard::yes && !isTesSuccess(e.result);
1319 
1320  if (addLocal && !enforceFailHard)
1321  {
1322  m_localTX->push_back(
1324  e.transaction->getSTransaction());
1325  e.transaction->setKept();
1326  }
1327 
1328  if ((e.applied ||
1329  ((mMode != OperatingMode::FULL) &&
1330  (e.failType != FailHard::yes) && e.local) ||
1331  (e.result == terQUEUED)) &&
1332  !enforceFailHard)
1333  {
1334  auto const toSkip =
1335  app_.getHashRouter().shouldRelay(e.transaction->getID());
1336 
1337  if (toSkip)
1338  {
1339  protocol::TMTransaction tx;
1340  Serializer s;
1341 
1342  e.transaction->getSTransaction()->add(s);
1343  tx.set_rawtransaction(s.data(), s.size());
1344  tx.set_status(protocol::tsCURRENT);
1345  tx.set_receivetimestamp(
1346  app_.timeKeeper().now().time_since_epoch().count());
1347  tx.set_deferred(e.result == terQUEUED);
1348  // FIXME: This should be when we received it
1349  app_.overlay().relay(e.transaction->getID(), tx, *toSkip);
1350  e.transaction->setBroadcast();
1351  }
1352  }
1353 
1354  if (validatedLedgerIndex)
1355  {
1356  auto [fee, accountSeq, availableSeq] =
1358  *newOL, e.transaction->getSTransaction());
1359  e.transaction->setCurrentLedgerState(
1360  *validatedLedgerIndex, fee, accountSeq, availableSeq);
1361  }
1362  }
1363  }
1364 
1365  batchLock.lock();
1366 
1367  for (TransactionStatus& e : transactions)
1368  e.transaction->clearApplying();
1369 
1370  if (!submit_held.empty())
1371  {
1372  if (mTransactions.empty())
1373  mTransactions.swap(submit_held);
1374  else
1375  for (auto& e : submit_held)
1376  mTransactions.push_back(std::move(e));
1377  }
1378 
1379  mCond.notify_all();
1380 
1382 }
1383 
1384 //
1385 // Owner functions
1386 //
1387 
1391  AccountID const& account)
1392 {
1393  Json::Value jvObjects(Json::objectValue);
1394  auto root = keylet::ownerDir(account);
1395  auto sleNode = lpLedger->read(keylet::page(root));
1396  if (sleNode)
1397  {
1398  std::uint64_t uNodeDir;
1399 
1400  do
1401  {
1402  for (auto const& uDirEntry : sleNode->getFieldV256(sfIndexes))
1403  {
1404  auto sleCur = lpLedger->read(keylet::child(uDirEntry));
1405  assert(sleCur);
1406 
1407  switch (sleCur->getType())
1408  {
1409  case ltOFFER:
1410  if (!jvObjects.isMember(jss::offers))
1411  jvObjects[jss::offers] =
1413 
1414  jvObjects[jss::offers].append(
1415  sleCur->getJson(JsonOptions::none));
1416  break;
1417 
1418  case ltRIPPLE_STATE:
1419  if (!jvObjects.isMember(jss::ripple_lines))
1420  {
1421  jvObjects[jss::ripple_lines] =
1423  }
1424 
1425  jvObjects[jss::ripple_lines].append(
1426  sleCur->getJson(JsonOptions::none));
1427  break;
1428 
1429  case ltACCOUNT_ROOT:
1430  case ltDIR_NODE:
1431  default:
1432  assert(false);
1433  break;
1434  }
1435  }
1436 
1437  uNodeDir = sleNode->getFieldU64(sfIndexNext);
1438 
1439  if (uNodeDir)
1440  {
1441  sleNode = lpLedger->read(keylet::page(root, uNodeDir));
1442  assert(sleNode);
1443  }
1444  } while (uNodeDir);
1445  }
1446 
1447  return jvObjects;
1448 }
1449 
1450 //
1451 // Other
1452 //
1453 
1454 inline bool
1456 {
1457  return isAmendmentBlocked() || isUNLBlocked();
1458 }
1459 
1460 inline bool
1462 {
1463  return amendmentBlocked_;
1464 }
1465 
1466 void
1468 {
1469  amendmentBlocked_ = true;
1471 }
1472 
1473 inline bool
1475 {
1477 }
1478 
1479 inline void
1481 {
1482  amendmentWarned_ = true;
1483 }
1484 
1485 inline void
1487 {
1488  amendmentWarned_ = false;
1489 }
1490 
1491 inline bool
1493 {
1494  return unlBlocked_;
1495 }
1496 
1497 void
1499 {
1500  unlBlocked_ = true;
1502 }
1503 
1504 inline void
1506 {
1507  unlBlocked_ = false;
1508 }
1509 
1510 bool
1512  const Overlay::PeerSequence& peerList,
1513  uint256& networkClosed)
1514 {
1515  // Returns true if there's an *abnormal* ledger issue, normal changing in
1516  // TRACKING mode should return false. Do we have sufficient validations for
1517  // our last closed ledger? Or do sufficient nodes agree? And do we have no
1518  // better ledger available? If so, we are either tracking or full.
1519 
1520  JLOG(m_journal.trace()) << "NetworkOPsImp::checkLastClosedLedger";
1521 
1522  auto const ourClosed = m_ledgerMaster.getClosedLedger();
1523 
1524  if (!ourClosed)
1525  return false;
1526 
1527  uint256 closedLedger = ourClosed->info().hash;
1528  uint256 prevClosedLedger = ourClosed->info().parentHash;
1529  JLOG(m_journal.trace()) << "OurClosed: " << closedLedger;
1530  JLOG(m_journal.trace()) << "PrevClosed: " << prevClosedLedger;
1531 
1532  //-------------------------------------------------------------------------
1533  // Determine preferred last closed ledger
1534 
1535  auto& validations = app_.getValidations();
1536  JLOG(m_journal.debug())
1537  << "ValidationTrie " << Json::Compact(validations.getJsonTrie());
1538 
1539  // Will rely on peer LCL if no trusted validations exist
1541  peerCounts[closedLedger] = 0;
1543  peerCounts[closedLedger]++;
1544 
1545  for (auto& peer : peerList)
1546  {
1547  uint256 peerLedger = peer->getClosedLedgerHash();
1548 
1549  if (peerLedger.isNonZero())
1550  ++peerCounts[peerLedger];
1551  }
1552 
1553  for (auto const& it : peerCounts)
1554  JLOG(m_journal.debug()) << "L: " << it.first << " n=" << it.second;
1555 
1556  uint256 preferredLCL = validations.getPreferredLCL(
1557  RCLValidatedLedger{ourClosed, validations.adaptor().journal()},
1559  peerCounts);
1560 
1561  bool switchLedgers = preferredLCL != closedLedger;
1562  if (switchLedgers)
1563  closedLedger = preferredLCL;
1564  //-------------------------------------------------------------------------
1565  if (switchLedgers && (closedLedger == prevClosedLedger))
1566  {
1567  // don't switch to our own previous ledger
1568  JLOG(m_journal.info()) << "We won't switch to our own previous ledger";
1569  networkClosed = ourClosed->info().hash;
1570  switchLedgers = false;
1571  }
1572  else
1573  networkClosed = closedLedger;
1574 
1575  if (!switchLedgers)
1576  return false;
1577 
1578  auto consensus = m_ledgerMaster.getLedgerByHash(closedLedger);
1579 
1580  if (!consensus)
1581  consensus = app_.getInboundLedgers().acquire(
1582  closedLedger, 0, InboundLedger::Reason::CONSENSUS);
1583 
1584  if (consensus &&
1585  (!m_ledgerMaster.canBeCurrent(consensus) ||
1587  *consensus, m_journal.debug(), "Not switching")))
1588  {
1589  // Don't switch to a ledger not on the validated chain
1590  // or with an invalid close time or sequence
1591  networkClosed = ourClosed->info().hash;
1592  return false;
1593  }
1594 
1595  JLOG(m_journal.warn()) << "We are not running on the consensus ledger";
1596  JLOG(m_journal.info()) << "Our LCL: " << getJson({*ourClosed, {}});
1597  JLOG(m_journal.info()) << "Net LCL " << closedLedger;
1598 
1600  {
1602  }
1603 
1604  if (consensus)
1605  {
1606  // FIXME: If this rewinds the ledger sequence, or has the same
1607  // sequence, we should update the status on any stored transactions
1608  // in the invalidated ledgers.
1609  switchLastClosedLedger(consensus);
1610  }
1611 
1612  return true;
1613 }
1614 
1615 void
1617  std::shared_ptr<Ledger const> const& newLCL)
1618 {
1619  // set the newLCL as our last closed ledger -- this is abnormal code
1620  JLOG(m_journal.error())
1621  << "JUMP last closed ledger to " << newLCL->info().hash;
1622 
1624 
1625  // Update fee computations.
1626  app_.getTxQ().processClosedLedger(app_, *newLCL, true);
1627 
1628  // Caller must own master lock
1629  {
1630  // Apply tx in old open ledger to new
1631  // open ledger. Then apply local tx.
1632 
1633  auto retries = m_localTX->getTxSet();
1634  auto const lastVal = app_.getLedgerMaster().getValidatedLedger();
1635  std::optional<Rules> rules;
1636  if (lastVal)
1637  rules.emplace(*lastVal, app_.config().features);
1638  else
1639  rules.emplace(app_.config().features);
1641  app_,
1642  *rules,
1643  newLCL,
1644  OrderedTxs({}),
1645  false,
1646  retries,
1647  tapNONE,
1648  "jump",
1649  [&](OpenView& view, beast::Journal j) {
1650  // Stuff the ledger with transactions from the queue.
1651  return app_.getTxQ().accept(app_, view);
1652  });
1653  }
1654 
1655  m_ledgerMaster.switchLCL(newLCL);
1656 
1657  protocol::TMStatusChange s;
1658  s.set_newevent(protocol::neSWITCHED_LEDGER);
1659  s.set_ledgerseq(newLCL->info().seq);
1660  s.set_networktime(app_.timeKeeper().now().time_since_epoch().count());
1661  s.set_ledgerhashprevious(
1662  newLCL->info().parentHash.begin(), newLCL->info().parentHash.size());
1663  s.set_ledgerhash(newLCL->info().hash.begin(), newLCL->info().hash.size());
1664 
1665  app_.overlay().foreach(
1666  send_always(std::make_shared<Message>(s, protocol::mtSTATUS_CHANGE)));
1667 }
1668 
1669 bool
1671 {
1672  assert(networkClosed.isNonZero());
1673 
1674  auto closingInfo = m_ledgerMaster.getCurrentLedger()->info();
1675 
1676  JLOG(m_journal.info()) << "Consensus time for #" << closingInfo.seq
1677  << " with LCL " << closingInfo.parentHash;
1678 
1679  auto prevLedger = m_ledgerMaster.getLedgerByHash(closingInfo.parentHash);
1680 
1681  if (!prevLedger)
1682  {
1683  // this shouldn't happen unless we jump ledgers
1684  if (mMode == OperatingMode::FULL)
1685  {
1686  JLOG(m_journal.warn()) << "Don't have LCL, going to tracking";
1688  }
1689 
1690  return false;
1691  }
1692 
1693  assert(prevLedger->info().hash == closingInfo.parentHash);
1694  assert(
1695  closingInfo.parentHash ==
1696  m_ledgerMaster.getClosedLedger()->info().hash);
1697 
1698  if (prevLedger->rules().enabled(featureNegativeUNL))
1699  app_.validators().setNegativeUNL(prevLedger->negativeUNL());
1700  TrustChanges const changes = app_.validators().updateTrusted(
1702  closingInfo.parentCloseTime,
1703  *this,
1704  app_.overlay(),
1705  app_.getHashRouter());
1706 
1707  if (!changes.added.empty() || !changes.removed.empty())
1708  app_.getValidations().trustChanged(changes.added, changes.removed);
1709 
1712  networkClosed,
1713  prevLedger,
1714  changes.removed,
1715  changes.added);
1716 
1717  const ConsensusPhase currPhase = mConsensus.phase();
1718  if (mLastConsensusPhase != currPhase)
1719  {
1720  reportConsensusStateChange(currPhase);
1721  mLastConsensusPhase = currPhase;
1722  }
1723 
1724  JLOG(m_journal.debug()) << "Initiating consensus engine";
1725  return true;
1726 }
1727 
1728 bool
1730 {
1731  return mConsensus.peerProposal(app_.timeKeeper().closeTime(), peerPos);
1732 }
1733 
1734 void
1736 {
1737  // We now have an additional transaction set
1738  // either created locally during the consensus process
1739  // or acquired from a peer
1740 
1741  // Inform peers we have this set
1742  protocol::TMHaveTransactionSet msg;
1743  msg.set_hash(map->getHash().as_uint256().begin(), 256 / 8);
1744  msg.set_status(protocol::tsHAVE);
1745  app_.overlay().foreach(
1746  send_always(std::make_shared<Message>(msg, protocol::mtHAVE_SET)));
1747 
1748  // We acquired it because consensus asked us to
1749  if (fromAcquire)
1751 }
1752 
1753 void
1755 {
1756  uint256 deadLedger = m_ledgerMaster.getClosedLedger()->info().parentHash;
1757 
1758  for (auto const& it : app_.overlay().getActivePeers())
1759  {
1760  if (it && (it->getClosedLedgerHash() == deadLedger))
1761  {
1762  JLOG(m_journal.trace()) << "Killing obsolete peer status";
1763  it->cycleStatus();
1764  }
1765  }
1766 
1767  uint256 networkClosed;
1768  bool ledgerChange =
1769  checkLastClosedLedger(app_.overlay().getActivePeers(), networkClosed);
1770 
1771  if (networkClosed.isZero())
1772  return;
1773 
1774  // WRITEME: Unless we are in FULL and in the process of doing a consensus,
1775  // we must count how many nodes share our LCL, how many nodes disagree with
1776  // our LCL, and how many validations our LCL has. We also want to check
1777  // timing to make sure there shouldn't be a newer LCL. We need this
1778  // information to do the next three tests.
1779 
1780  if (((mMode == OperatingMode::CONNECTED) ||
1781  (mMode == OperatingMode::SYNCING)) &&
1782  !ledgerChange)
1783  {
1784  // Count number of peers that agree with us and UNL nodes whose
1785  // validations we have for LCL. If the ledger is good enough, go to
1786  // TRACKING - TODO
1787  if (!needNetworkLedger_)
1789  }
1790 
1791  if (((mMode == OperatingMode::CONNECTED) ||
1793  !ledgerChange)
1794  {
1795  // check if the ledger is good enough to go to FULL
1796  // Note: Do not go to FULL if we don't have the previous ledger
1797  // check if the ledger is bad enough to go to CONNECTE D -- TODO
1799  if (app_.timeKeeper().now() < (current->info().parentCloseTime +
1800  2 * current->info().closeTimeResolution))
1801  {
1803  }
1804  }
1805 
1806  beginConsensus(networkClosed);
1807 }
1808 
1809 void
1811 {
1813  {
1815  }
1816 }
1817 
1818 void
1820 {
1821  // VFALCO consider std::shared_mutex
1823 
1824  if (!mStreamMaps[sManifests].empty())
1825  {
1827 
1828  jvObj[jss::type] = "manifestReceived";
1829  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, mo.masterKey);
1830  if (!mo.signingKey.empty())
1831  jvObj[jss::signing_key] =
1833  jvObj[jss::seq] = Json::UInt(mo.sequence);
1834  if (auto sig = mo.getSignature())
1835  jvObj[jss::signature] = strHex(*sig);
1836  jvObj[jss::master_signature] = strHex(mo.getMasterSignature());
1837  if (!mo.domain.empty())
1838  jvObj[jss::domain] = mo.domain;
1839  jvObj[jss::manifest] = strHex(mo.serialized);
1840 
1841  for (auto i = mStreamMaps[sManifests].begin();
1842  i != mStreamMaps[sManifests].end();)
1843  {
1844  if (auto p = i->second.lock())
1845  {
1846  p->send(jvObj, true);
1847  ++i;
1848  }
1849  else
1850  {
1851  i = mStreamMaps[sManifests].erase(i);
1852  }
1853  }
1854  }
1855 }
1856 
1858  XRPAmount fee,
1859  TxQ::Metrics&& escalationMetrics,
1860  LoadFeeTrack const& loadFeeTrack)
1861  : loadFactorServer{loadFeeTrack.getLoadFactor()}
1862  , loadBaseServer{loadFeeTrack.getLoadBase()}
1863  , baseFee{fee}
1864  , em{std::move(escalationMetrics)}
1865 {
1866 }
1867 
1868 bool
1870  NetworkOPsImp::ServerFeeSummary const& b) const
1871 {
1872  if (loadFactorServer != b.loadFactorServer ||
1873  loadBaseServer != b.loadBaseServer || baseFee != b.baseFee ||
1874  em.has_value() != b.em.has_value())
1875  return true;
1876 
1877  if (em && b.em)
1878  {
1879  return (
1880  em->minProcessingFeeLevel != b.em->minProcessingFeeLevel ||
1881  em->openLedgerFeeLevel != b.em->openLedgerFeeLevel ||
1882  em->referenceFeeLevel != b.em->referenceFeeLevel);
1883  }
1884 
1885  return false;
1886 }
1887 
1888 // Need to cap to uint64 to uint32 due to JSON limitations
1889 static std::uint32_t
1891 {
1893 
1894  return std::min(max32, v);
1895 };
1896 
1897 void
1899 {
1900  // VFALCO TODO Don't hold the lock across calls to send...make a copy of the
1901  // list into a local array while holding the lock then release
1902  // the lock and call send on everyone.
1903  //
1905 
1906  if (!mStreamMaps[sServer].empty())
1907  {
1909 
1910  ServerFeeSummary f{
1911  app_.openLedger().current()->fees().base,
1913  app_.getFeeTrack()};
1914 
1915  jvObj[jss::type] = "serverStatus";
1916  jvObj[jss::server_status] = strOperatingMode();
1917  jvObj[jss::load_base] = f.loadBaseServer;
1918  jvObj[jss::load_factor_server] = f.loadFactorServer;
1919  jvObj[jss::base_fee] = f.baseFee.jsonClipped();
1920 
1921  if (f.em)
1922  {
1923  auto const loadFactor = std::max(
1924  safe_cast<std::uint64_t>(f.loadFactorServer),
1925  mulDiv(
1926  f.em->openLedgerFeeLevel,
1927  f.loadBaseServer,
1928  f.em->referenceFeeLevel)
1929  .second);
1930 
1931  jvObj[jss::load_factor] = trunc32(loadFactor);
1932  jvObj[jss::load_factor_fee_escalation] =
1933  f.em->openLedgerFeeLevel.jsonClipped();
1934  jvObj[jss::load_factor_fee_queue] =
1935  f.em->minProcessingFeeLevel.jsonClipped();
1936  jvObj[jss::load_factor_fee_reference] =
1937  f.em->referenceFeeLevel.jsonClipped();
1938  }
1939  else
1940  jvObj[jss::load_factor] = f.loadFactorServer;
1941 
1942  mLastFeeSummary = f;
1943 
1944  for (auto i = mStreamMaps[sServer].begin();
1945  i != mStreamMaps[sServer].end();)
1946  {
1947  InfoSub::pointer p = i->second.lock();
1948 
1949  // VFALCO TODO research the possibility of using thread queues and
1950  // linearizing the deletion of subscribers with the
1951  // sending of JSON data.
1952  if (p)
1953  {
1954  p->send(jvObj, true);
1955  ++i;
1956  }
1957  else
1958  {
1959  i = mStreamMaps[sServer].erase(i);
1960  }
1961  }
1962  }
1963 }
1964 
1965 void
1967 {
1969 
1970  auto& streamMap = mStreamMaps[sConsensusPhase];
1971  if (!streamMap.empty())
1972  {
1974  jvObj[jss::type] = "consensusPhase";
1975  jvObj[jss::consensus] = to_string(phase);
1976 
1977  for (auto i = streamMap.begin(); i != streamMap.end();)
1978  {
1979  if (auto p = i->second.lock())
1980  {
1981  p->send(jvObj, true);
1982  ++i;
1983  }
1984  else
1985  {
1986  i = streamMap.erase(i);
1987  }
1988  }
1989  }
1990 }
1991 
1992 void
1994 {
1995  // VFALCO consider std::shared_mutex
1997 
1998  if (!mStreamMaps[sValidations].empty())
1999  {
2001 
2002  auto const signerPublic = val->getSignerPublic();
2003 
2004  jvObj[jss::type] = "validationReceived";
2005  jvObj[jss::validation_public_key] =
2006  toBase58(TokenType::NodePublic, signerPublic);
2007  jvObj[jss::ledger_hash] = to_string(val->getLedgerHash());
2008  jvObj[jss::signature] = strHex(val->getSignature());
2009  jvObj[jss::full] = val->isFull();
2010  jvObj[jss::flags] = val->getFlags();
2011  jvObj[jss::signing_time] = *(*val)[~sfSigningTime];
2012  jvObj[jss::data] = strHex(val->getSerializer().slice());
2013 
2014  if (auto version = (*val)[~sfServerVersion])
2015  jvObj[jss::server_version] = std::to_string(*version);
2016 
2017  if (auto cookie = (*val)[~sfCookie])
2018  jvObj[jss::cookie] = std::to_string(*cookie);
2019 
2020  if (auto hash = (*val)[~sfValidatedHash])
2021  jvObj[jss::validated_hash] = strHex(*hash);
2022 
2023  auto const masterKey =
2024  app_.validatorManifests().getMasterKey(signerPublic);
2025 
2026  if (masterKey != signerPublic)
2027  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, masterKey);
2028 
2029  if (auto const seq = (*val)[~sfLedgerSequence])
2030  jvObj[jss::ledger_index] = to_string(*seq);
2031 
2032  if (val->isFieldPresent(sfAmendments))
2033  {
2034  jvObj[jss::amendments] = Json::Value(Json::arrayValue);
2035  for (auto const& amendment : val->getFieldV256(sfAmendments))
2036  jvObj[jss::amendments].append(to_string(amendment));
2037  }
2038 
2039  if (auto const closeTime = (*val)[~sfCloseTime])
2040  jvObj[jss::close_time] = *closeTime;
2041 
2042  if (auto const loadFee = (*val)[~sfLoadFee])
2043  jvObj[jss::load_fee] = *loadFee;
2044 
2045  if (auto const baseFee = (*val)[~sfBaseFee])
2046  jvObj[jss::base_fee] = static_cast<double>(*baseFee);
2047 
2048  if (auto const reserveBase = (*val)[~sfReserveBase])
2049  jvObj[jss::reserve_base] = *reserveBase;
2050 
2051  if (auto const reserveInc = (*val)[~sfReserveIncrement])
2052  jvObj[jss::reserve_inc] = *reserveInc;
2053 
2054  for (auto i = mStreamMaps[sValidations].begin();
2055  i != mStreamMaps[sValidations].end();)
2056  {
2057  if (auto p = i->second.lock())
2058  {
2059  p->send(jvObj, true);
2060  ++i;
2061  }
2062  else
2063  {
2064  i = mStreamMaps[sValidations].erase(i);
2065  }
2066  }
2067  }
2068 }
2069 
2070 void
2072 {
2074 
2075  if (!mStreamMaps[sPeerStatus].empty())
2076  {
2077  Json::Value jvObj(func());
2078 
2079  jvObj[jss::type] = "peerStatusChange";
2080 
2081  for (auto i = mStreamMaps[sPeerStatus].begin();
2082  i != mStreamMaps[sPeerStatus].end();)
2083  {
2084  InfoSub::pointer p = i->second.lock();
2085 
2086  if (p)
2087  {
2088  p->send(jvObj, true);
2089  ++i;
2090  }
2091  else
2092  {
2093  i = mStreamMaps[sPeerStatus].erase(i);
2094  }
2095  }
2096  }
2097 }
2098 
2099 void
2101 {
2102  using namespace std::chrono_literals;
2103  if (om == OperatingMode::CONNECTED)
2104  {
2107  }
2108  else if (om == OperatingMode::SYNCING)
2109  {
2110  if (app_.getLedgerMaster().getValidatedLedgerAge() >= 1min)
2112  }
2113 
2114  if ((om > OperatingMode::CONNECTED) && isBlocked())
2116 
2117  if (mMode == om)
2118  return;
2119 
2120  mMode = om;
2121 
2122  accounting_.mode(om);
2123 
2124  JLOG(m_journal.info()) << "STATE->" << strOperatingMode();
2125  pubServer();
2126 }
2127 
2128 bool
2130  std::shared_ptr<STValidation> const& val,
2131  std::string const& source)
2132 {
2133  JLOG(m_journal.trace())
2134  << "recvValidation " << val->getLedgerHash() << " from " << source;
2135 
2136  handleNewValidation(app_, val, source);
2137 
2138  pubValidation(val);
2139 
2140  // We will always relay trusted validations; if configured, we will
2141  // also relay all untrusted validations.
2142  return app_.config().RELAY_UNTRUSTED_VALIDATIONS || val->isTrusted();
2143 }
2144 
2147 {
2148  return mConsensus.getJson(true);
2149 }
2150 
2152 NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
2153 {
2155 
2156  // System-level warnings
2157  {
2158  Json::Value warnings{Json::arrayValue};
2159  if (isAmendmentBlocked())
2160  {
2161  Json::Value& w = warnings.append(Json::objectValue);
2162  w[jss::id] = warnRPC_AMENDMENT_BLOCKED;
2163  w[jss::message] =
2164  "This server is amendment blocked, and must be updated to be "
2165  "able to stay in sync with the network.";
2166  }
2167  if (isUNLBlocked())
2168  {
2169  Json::Value& w = warnings.append(Json::objectValue);
2170  w[jss::id] = warnRPC_EXPIRED_VALIDATOR_LIST;
2171  w[jss::message] =
2172  "This server has an expired validator list. validators.txt "
2173  "may be incorrectly configured or some [validator_list_sites] "
2174  "may be unreachable.";
2175  }
2176  if (admin && isAmendmentWarned())
2177  {
2178  Json::Value& w = warnings.append(Json::objectValue);
2179  w[jss::id] = warnRPC_UNSUPPORTED_MAJORITY;
2180  w[jss::message] =
2181  "One or more unsupported amendments have reached majority. "
2182  "Upgrade to the latest version before they are activated "
2183  "to avoid being amendment blocked.";
2184  if (auto const expected =
2186  {
2187  auto& d = w[jss::details] = Json::objectValue;
2188  d[jss::expected_date] = expected->time_since_epoch().count();
2189  d[jss::expected_date_UTC] = to_string(*expected);
2190  }
2191  }
2192 
2193  if (warnings.size())
2194  info[jss::warnings] = std::move(warnings);
2195  }
2196 
2197  // hostid: unique string describing the machine
2198  if (human)
2199  info[jss::hostid] = getHostId(admin);
2200 
2201  // domain: if configured with a domain, report it:
2202  if (!app_.config().SERVER_DOMAIN.empty())
2203  info[jss::server_domain] = app_.config().SERVER_DOMAIN;
2204 
2205  if (!app_.config().reporting())
2206  if (auto const netid = app_.overlay().networkID())
2207  info[jss::network_id] = static_cast<Json::UInt>(*netid);
2208 
2209  info[jss::build_version] = BuildInfo::getVersionString();
2210 
2211  info[jss::server_state] = strOperatingMode(admin);
2212 
2213  info[jss::time] = to_string(std::chrono::floor<std::chrono::microseconds>(
2215 
2216  if (needNetworkLedger_)
2217  info[jss::network_ledger] = "waiting";
2218 
2219  info[jss::validation_quorum] =
2220  static_cast<Json::UInt>(app_.validators().quorum());
2221 
2222  if (admin)
2223  {
2224  switch (app_.config().NODE_SIZE)
2225  {
2226  case 0:
2227  info[jss::node_size] = "tiny";
2228  break;
2229  case 1:
2230  info[jss::node_size] = "small";
2231  break;
2232  case 2:
2233  info[jss::node_size] = "medium";
2234  break;
2235  case 3:
2236  info[jss::node_size] = "large";
2237  break;
2238  case 4:
2239  info[jss::node_size] = "huge";
2240  break;
2241  }
2242 
2243  auto when = app_.validators().expires();
2244 
2245  if (!human)
2246  {
2247  if (when)
2248  info[jss::validator_list_expires] =
2249  safe_cast<Json::UInt>(when->time_since_epoch().count());
2250  else
2251  info[jss::validator_list_expires] = 0;
2252  }
2253  else
2254  {
2255  auto& x = (info[jss::validator_list] = Json::objectValue);
2256 
2257  x[jss::count] = static_cast<Json::UInt>(app_.validators().count());
2258 
2259  if (when)
2260  {
2261  if (*when == TimeKeeper::time_point::max())
2262  {
2263  x[jss::expiration] = "never";
2264  x[jss::status] = "active";
2265  }
2266  else
2267  {
2268  x[jss::expiration] = to_string(*when);
2269 
2270  if (*when > app_.timeKeeper().now())
2271  x[jss::status] = "active";
2272  else
2273  x[jss::status] = "expired";
2274  }
2275  }
2276  else
2277  {
2278  x[jss::status] = "unknown";
2279  x[jss::expiration] = "unknown";
2280  }
2281  }
2282  }
2283  info[jss::io_latency_ms] =
2284  static_cast<Json::UInt>(app_.getIOLatency().count());
2285 
2286  if (admin)
2287  {
2289  {
2290  info[jss::pubkey_validator] = toBase58(
2292  }
2293  else
2294  {
2295  info[jss::pubkey_validator] = "none";
2296  }
2297  }
2298 
2299  if (counters)
2300  {
2301  info[jss::counters] = app_.getPerfLog().countersJson();
2302 
2303  Json::Value nodestore(Json::objectValue);
2304  if (app_.getShardStore())
2305  app_.getShardStore()->getCountsJson(nodestore);
2306  else
2307  app_.getNodeStore().getCountsJson(nodestore);
2308  info[jss::counters][jss::nodestore] = nodestore;
2309  info[jss::current_activities] = app_.getPerfLog().currentJson();
2310  }
2311 
2312  info[jss::pubkey_node] =
2314 
2315  info[jss::complete_ledgers] = app_.getLedgerMaster().getCompleteLedgers();
2316 
2317  if (amendmentBlocked_)
2318  info[jss::amendment_blocked] = true;
2319 
2320  auto const fp = m_ledgerMaster.getFetchPackCacheSize();
2321 
2322  if (fp != 0)
2323  info[jss::fetch_pack] = Json::UInt(fp);
2324 
2325  if (!app_.config().reporting())
2326  info[jss::peers] = Json::UInt(app_.overlay().size());
2327 
2328  Json::Value lastClose = Json::objectValue;
2329  lastClose[jss::proposers] = Json::UInt(mConsensus.prevProposers());
2330 
2331  if (human)
2332  {
2333  lastClose[jss::converge_time_s] =
2335  }
2336  else
2337  {
2338  lastClose[jss::converge_time] =
2340  }
2341 
2342  info[jss::last_close] = lastClose;
2343 
2344  // info[jss::consensus] = mConsensus.getJson();
2345 
2346  if (admin)
2347  info[jss::load] = m_job_queue.getJson();
2348 
2349  if (!app_.config().reporting())
2350  {
2351  auto const escalationMetrics =
2353 
2354  auto const loadFactorServer = app_.getFeeTrack().getLoadFactor();
2355  auto const loadBaseServer = app_.getFeeTrack().getLoadBase();
2356  /* Scale the escalated fee level to unitless "load factor".
2357  In practice, this just strips the units, but it will continue
2358  to work correctly if either base value ever changes. */
2359  auto const loadFactorFeeEscalation =
2360  mulDiv(
2361  escalationMetrics.openLedgerFeeLevel,
2362  loadBaseServer,
2363  escalationMetrics.referenceFeeLevel)
2364  .second;
2365 
2366  auto const loadFactor = std::max(
2367  safe_cast<std::uint64_t>(loadFactorServer),
2368  loadFactorFeeEscalation);
2369 
2370  if (!human)
2371  {
2372  info[jss::load_base] = loadBaseServer;
2373  info[jss::load_factor] = trunc32(loadFactor);
2374  info[jss::load_factor_server] = loadFactorServer;
2375 
2376  /* Json::Value doesn't support uint64, so clamp to max
2377  uint32 value. This is mostly theoretical, since there
2378  probably isn't enough extant XRP to drive the factor
2379  that high.
2380  */
2381  info[jss::load_factor_fee_escalation] =
2382  escalationMetrics.openLedgerFeeLevel.jsonClipped();
2383  info[jss::load_factor_fee_queue] =
2384  escalationMetrics.minProcessingFeeLevel.jsonClipped();
2385  info[jss::load_factor_fee_reference] =
2386  escalationMetrics.referenceFeeLevel.jsonClipped();
2387  }
2388  else
2389  {
2390  info[jss::load_factor] =
2391  static_cast<double>(loadFactor) / loadBaseServer;
2392 
2393  if (loadFactorServer != loadFactor)
2394  info[jss::load_factor_server] =
2395  static_cast<double>(loadFactorServer) / loadBaseServer;
2396 
2397  if (admin)
2398  {
2400  if (fee != loadBaseServer)
2401  info[jss::load_factor_local] =
2402  static_cast<double>(fee) / loadBaseServer;
2403  fee = app_.getFeeTrack().getRemoteFee();
2404  if (fee != loadBaseServer)
2405  info[jss::load_factor_net] =
2406  static_cast<double>(fee) / loadBaseServer;
2407  fee = app_.getFeeTrack().getClusterFee();
2408  if (fee != loadBaseServer)
2409  info[jss::load_factor_cluster] =
2410  static_cast<double>(fee) / loadBaseServer;
2411  }
2412  if (escalationMetrics.openLedgerFeeLevel !=
2413  escalationMetrics.referenceFeeLevel &&
2414  (admin || loadFactorFeeEscalation != loadFactor))
2415  info[jss::load_factor_fee_escalation] =
2416  escalationMetrics.openLedgerFeeLevel.decimalFromReference(
2417  escalationMetrics.referenceFeeLevel);
2418  if (escalationMetrics.minProcessingFeeLevel !=
2419  escalationMetrics.referenceFeeLevel)
2420  info[jss::load_factor_fee_queue] =
2421  escalationMetrics.minProcessingFeeLevel
2422  .decimalFromReference(
2423  escalationMetrics.referenceFeeLevel);
2424  }
2425  }
2426 
2427  bool valid = false;
2428  auto lpClosed = m_ledgerMaster.getValidatedLedger();
2429 
2430  if (lpClosed)
2431  valid = true;
2432  else if (!app_.config().reporting())
2433  lpClosed = m_ledgerMaster.getClosedLedger();
2434 
2435  if (lpClosed)
2436  {
2437  XRPAmount const baseFee = lpClosed->fees().base;
2439  l[jss::seq] = Json::UInt(lpClosed->info().seq);
2440  l[jss::hash] = to_string(lpClosed->info().hash);
2441 
2442  if (!human)
2443  {
2444  l[jss::base_fee] = baseFee.jsonClipped();
2445  l[jss::reserve_base] =
2446  lpClosed->fees().accountReserve(0).jsonClipped();
2447  l[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
2448  l[jss::close_time] = Json::Value::UInt(
2449  lpClosed->info().closeTime.time_since_epoch().count());
2450  }
2451  else
2452  {
2453  l[jss::base_fee_xrp] = baseFee.decimalXRP();
2454  l[jss::reserve_base_xrp] =
2455  lpClosed->fees().accountReserve(0).decimalXRP();
2456  l[jss::reserve_inc_xrp] = lpClosed->fees().increment.decimalXRP();
2457 
2458  auto const nowOffset = app_.timeKeeper().nowOffset();
2459  if (std::abs(nowOffset.count()) >= 60)
2460  l[jss::system_time_offset] = nowOffset.count();
2461 
2462  auto const closeOffset = app_.timeKeeper().closeOffset();
2463  if (std::abs(closeOffset.count()) >= 60)
2464  l[jss::close_time_offset] = closeOffset.count();
2465 
2466  constexpr std::chrono::seconds highAgeThreshold{1000000};
2468  {
2469  auto const age = m_ledgerMaster.getValidatedLedgerAge();
2470  l[jss::age] =
2471  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2472  }
2473  else
2474  {
2475  auto lCloseTime = lpClosed->info().closeTime;
2476  auto closeTime = app_.timeKeeper().closeTime();
2477  if (lCloseTime <= closeTime)
2478  {
2479  using namespace std::chrono_literals;
2480  auto age = closeTime - lCloseTime;
2481  l[jss::age] =
2482  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2483  }
2484  }
2485  }
2486 
2487  if (valid)
2488  info[jss::validated_ledger] = l;
2489  else
2490  info[jss::closed_ledger] = l;
2491 
2492  auto lpPublished = m_ledgerMaster.getPublishedLedger();
2493  if (!lpPublished)
2494  info[jss::published_ledger] = "none";
2495  else if (lpPublished->info().seq != lpClosed->info().seq)
2496  info[jss::published_ledger] = lpPublished->info().seq;
2497  }
2498 
2499  std::tie(info[jss::state_accounting], info[jss::server_state_duration_us]) =
2500  accounting_.json();
2501  info[jss::uptime] = UptimeClock::now().time_since_epoch().count();
2502  if (!app_.config().reporting())
2503  {
2504  info[jss::jq_trans_overflow] =
2506  info[jss::peer_disconnects] =
2508  info[jss::peer_disconnects_resources] =
2510  }
2511  else
2512  {
2513  info["reporting"] = app_.getReportingETL().getInfo();
2514  }
2515 
2516  return info;
2517 }
2518 
2519 void
2521 {
2523 }
2524 
2527 {
2528  return app_.getInboundLedgers().getInfo();
2529 }
2530 
2531 void
2533  std::shared_ptr<ReadView const> const& lpCurrent,
2534  std::shared_ptr<STTx const> const& stTxn,
2535  TER terResult)
2536 {
2537  Json::Value jvObj = transJson(*stTxn, terResult, false, lpCurrent);
2538 
2539  {
2541 
2542  auto it = mStreamMaps[sRTTransactions].begin();
2543  while (it != mStreamMaps[sRTTransactions].end())
2544  {
2545  InfoSub::pointer p = it->second.lock();
2546 
2547  if (p)
2548  {
2549  p->send(jvObj, true);
2550  ++it;
2551  }
2552  else
2553  {
2554  it = mStreamMaps[sRTTransactions].erase(it);
2555  }
2556  }
2557  }
2558  AcceptedLedgerTx alt(
2559  lpCurrent, stTxn, terResult, app_.accountIDCache(), app_.logs());
2560  JLOG(m_journal.trace()) << "pubProposed: " << alt.getJson();
2561  pubAccountTransaction(lpCurrent, alt, false);
2562 }
2563 
2564 void
2566 {
2567  // reporting does not forward validated transactions
2568  // validated transactions will be published to the proper streams when the
2569  // etl process writes a validated ledger
2570  if (jvObj[jss::validated].asBool())
2571  return;
2572  {
2574 
2575  auto it = mStreamMaps[sRTTransactions].begin();
2576  while (it != mStreamMaps[sRTTransactions].end())
2577  {
2578  InfoSub::pointer p = it->second.lock();
2579 
2580  if (p)
2581  {
2582  p->send(jvObj, true);
2583  ++it;
2584  }
2585  else
2586  {
2587  it = mStreamMaps[sRTTransactions].erase(it);
2588  }
2589  }
2590  }
2591 
2593 }
2594 
2595 void
2597 {
2599 
2600  for (auto i = mStreamMaps[sValidations].begin();
2601  i != mStreamMaps[sValidations].end();)
2602  {
2603  if (auto p = i->second.lock())
2604  {
2605  p->send(jvObj, true);
2606  ++i;
2607  }
2608  else
2609  {
2610  i = mStreamMaps[sValidations].erase(i);
2611  }
2612  }
2613 }
2614 
2615 void
2617 {
2619 
2620  for (auto i = mStreamMaps[sManifests].begin();
2621  i != mStreamMaps[sManifests].end();)
2622  {
2623  if (auto p = i->second.lock())
2624  {
2625  p->send(jvObj, true);
2626  ++i;
2627  }
2628  else
2629  {
2630  i = mStreamMaps[sManifests].erase(i);
2631  }
2632  }
2633 }
2634 
2635 static void
2637 {
2638  for (auto& jv : jvObj)
2639  {
2640  if (jv.isObject())
2641  {
2642  getAccounts(jv, accounts);
2643  }
2644  else if (jv.isString())
2645  {
2646  auto account = RPC::accountFromStringStrict(jv.asString());
2647  if (account)
2648  accounts.push_back(*account);
2649  }
2650  }
2651 }
2652 
2653 void
2655 {
2657  int iProposed = 0;
2658  // check if there are any subscribers before attempting to parse the JSON
2659  {
2661 
2662  if (mSubRTAccount.empty())
2663  return;
2664  }
2665 
2666  // parse the JSON outside of the lock
2667  std::vector<AccountID> accounts;
2668  if (jvObj.isMember(jss::transaction))
2669  {
2670  try
2671  {
2672  getAccounts(jvObj[jss::transaction], accounts);
2673  }
2674  catch (...)
2675  {
2676  JLOG(m_journal.debug())
2677  << __func__ << " : "
2678  << "error parsing json for accounts affected";
2679  return;
2680  }
2681  }
2682  {
2684 
2685  if (!mSubRTAccount.empty())
2686  {
2687  for (auto const& affectedAccount : accounts)
2688  {
2689  auto simiIt = mSubRTAccount.find(affectedAccount);
2690  if (simiIt != mSubRTAccount.end())
2691  {
2692  auto it = simiIt->second.begin();
2693 
2694  while (it != simiIt->second.end())
2695  {
2696  InfoSub::pointer p = it->second.lock();
2697 
2698  if (p)
2699  {
2700  notify.insert(p);
2701  ++it;
2702  ++iProposed;
2703  }
2704  else
2705  it = simiIt->second.erase(it);
2706  }
2707  }
2708  }
2709  }
2710  }
2711  JLOG(m_journal.trace()) << "forwardProposedAccountTransaction:"
2712  << " iProposed=" << iProposed;
2713 
2714  if (!notify.empty())
2715  {
2716  for (InfoSub::ref isrListener : notify)
2717  isrListener->send(jvObj, true);
2718  }
2719 }
2720 
2721 void
2723 {
2724  // Ledgers are published only when they acquire sufficient validations
2725  // Holes are filled across connection loss or other catastrophe
2726 
2727  std::shared_ptr<AcceptedLedger> alpAccepted =
2728  app_.getAcceptedLedgerCache().fetch(lpAccepted->info().hash);
2729  if (!alpAccepted)
2730  {
2731  alpAccepted = std::make_shared<AcceptedLedger>(lpAccepted, app_);
2732  app_.getAcceptedLedgerCache().canonicalize_replace_client(
2733  lpAccepted->info().hash, alpAccepted);
2734  }
2735 
2736  {
2737  JLOG(m_journal.debug())
2738  << "Publishing ledger = " << lpAccepted->info().seq;
2740 
2741  if (!mStreamMaps[sLedger].empty())
2742  {
2744 
2745  jvObj[jss::type] = "ledgerClosed";
2746  jvObj[jss::ledger_index] = lpAccepted->info().seq;
2747  jvObj[jss::ledger_hash] = to_string(lpAccepted->info().hash);
2748  jvObj[jss::ledger_time] = Json::Value::UInt(
2749  lpAccepted->info().closeTime.time_since_epoch().count());
2750 
2751  jvObj[jss::fee_ref] = lpAccepted->fees().units.jsonClipped();
2752  jvObj[jss::fee_base] = lpAccepted->fees().base.jsonClipped();
2753  jvObj[jss::reserve_base] =
2754  lpAccepted->fees().accountReserve(0).jsonClipped();
2755  jvObj[jss::reserve_inc] =
2756  lpAccepted->fees().increment.jsonClipped();
2757 
2758  jvObj[jss::txn_count] = Json::UInt(alpAccepted->getTxnCount());
2759 
2761  {
2762  jvObj[jss::validated_ledgers] =
2764  }
2765 
2766  auto it = mStreamMaps[sLedger].begin();
2767  while (it != mStreamMaps[sLedger].end())
2768  {
2769  InfoSub::pointer p = it->second.lock();
2770  if (p)
2771  {
2772  JLOG(m_journal.debug())
2773  << "Publishing ledger = " << lpAccepted->info().seq
2774  << " : consumer = " << p->getConsumer()
2775  << " : obj = " << jvObj;
2776  p->send(jvObj, true);
2777  ++it;
2778  }
2779  else
2780  it = mStreamMaps[sLedger].erase(it);
2781  }
2782  }
2783  }
2784 
2785  // Don't lock since pubAcceptedTransaction is locking.
2786  for (auto const& [_, accTx] : alpAccepted->getMap())
2787  {
2788  (void)_;
2789  JLOG(m_journal.trace()) << "pubAccepted: " << accTx->getJson();
2790  pubValidatedTransaction(lpAccepted, *accTx);
2791  }
2792 }
2793 
2794 void
2796 {
2797  if (app_.config().reporting())
2798  return;
2799  ServerFeeSummary f{
2800  app_.openLedger().current()->fees().base,
2802  app_.getFeeTrack()};
2803 
2804  // only schedule the job if something has changed
2805  if (f != mLastFeeSummary)
2806  {
2808  jtCLIENT, "reportFeeChange->pubServer", [this](Job&) {
2809  pubServer();
2810  });
2811  }
2812 }
2813 
2814 void
2816 {
2818  jtCLIENT,
2819  "reportConsensusStateChange->pubConsensus",
2820  [this, phase](Job&) { pubConsensus(phase); });
2821 }
2822 
2823 inline void
2825 {
2826  m_localTX->sweep(view);
2827 }
2828 inline std::size_t
2830 {
2831  return m_localTX->size();
2832 }
2833 
2834 // This routine should only be used to publish accepted or validated
2835 // transactions.
2838  const STTx& stTxn,
2839  TER terResult,
2840  bool bValidated,
2841  std::shared_ptr<ReadView const> const& lpCurrent)
2842 {
2844  std::string sToken;
2845  std::string sHuman;
2846 
2847  transResultInfo(terResult, sToken, sHuman);
2848 
2849  jvObj[jss::type] = "transaction";
2850  jvObj[jss::transaction] = stTxn.getJson(JsonOptions::none);
2851 
2852  if (bValidated)
2853  {
2854  jvObj[jss::ledger_index] = lpCurrent->info().seq;
2855  jvObj[jss::ledger_hash] = to_string(lpCurrent->info().hash);
2856  jvObj[jss::transaction][jss::date] =
2857  lpCurrent->info().closeTime.time_since_epoch().count();
2858  jvObj[jss::validated] = true;
2859 
2860  // WRITEME: Put the account next seq here
2861  }
2862  else
2863  {
2864  jvObj[jss::validated] = false;
2865  jvObj[jss::ledger_current_index] = lpCurrent->info().seq;
2866  }
2867 
2868  jvObj[jss::status] = bValidated ? "closed" : "proposed";
2869  jvObj[jss::engine_result] = sToken;
2870  jvObj[jss::engine_result_code] = terResult;
2871  jvObj[jss::engine_result_message] = sHuman;
2872 
2873  if (stTxn.getTxnType() == ttOFFER_CREATE)
2874  {
2875  auto const account = stTxn.getAccountID(sfAccount);
2876  auto const amount = stTxn.getFieldAmount(sfTakerGets);
2877 
2878  // If the offer create is not self funded then add the owner balance
2879  if (account != amount.issue().account)
2880  {
2881  auto const ownerFunds = accountFunds(
2882  *lpCurrent,
2883  account,
2884  amount,
2886  app_.journal("View"));
2887  jvObj[jss::transaction][jss::owner_funds] = ownerFunds.getText();
2888  }
2889  }
2890 
2891  return jvObj;
2892 }
2893 
2894 void
2896  std::shared_ptr<ReadView const> const& alAccepted,
2897  const AcceptedLedgerTx& alTx)
2898 {
2899  std::shared_ptr<STTx const> stTxn = alTx.getTxn();
2900  Json::Value jvObj = transJson(*stTxn, alTx.getResult(), true, alAccepted);
2901 
2902  if (auto const txMeta = alTx.getMeta())
2903  {
2904  jvObj[jss::meta] = txMeta->getJson(JsonOptions::none);
2906  jvObj[jss::meta], *alAccepted, stTxn, *txMeta);
2907  }
2908 
2909  {
2911 
2912  auto it = mStreamMaps[sTransactions].begin();
2913  while (it != mStreamMaps[sTransactions].end())
2914  {
2915  InfoSub::pointer p = it->second.lock();
2916 
2917  if (p)
2918  {
2919  p->send(jvObj, true);
2920  ++it;
2921  }
2922  else
2923  it = mStreamMaps[sTransactions].erase(it);
2924  }
2925 
2926  it = mStreamMaps[sRTTransactions].begin();
2927 
2928  while (it != mStreamMaps[sRTTransactions].end())
2929  {
2930  InfoSub::pointer p = it->second.lock();
2931 
2932  if (p)
2933  {
2934  p->send(jvObj, true);
2935  ++it;
2936  }
2937  else
2938  it = mStreamMaps[sRTTransactions].erase(it);
2939  }
2940  }
2941  app_.getOrderBookDB().processTxn(alAccepted, alTx, jvObj);
2942  pubAccountTransaction(alAccepted, alTx, true);
2943 }
2944 
2945 void
2947  std::shared_ptr<ReadView const> const& lpCurrent,
2948  const AcceptedLedgerTx& alTx,
2949  bool bAccepted)
2950 {
2952  int iProposed = 0;
2953  int iAccepted = 0;
2954 
2955  {
2957 
2958  if (!bAccepted && mSubRTAccount.empty())
2959  return;
2960 
2961  if (!mSubAccount.empty() || (!mSubRTAccount.empty()))
2962  {
2963  for (auto const& affectedAccount : alTx.getAffected())
2964  {
2965  auto simiIt = mSubRTAccount.find(affectedAccount);
2966  if (simiIt != mSubRTAccount.end())
2967  {
2968  auto it = simiIt->second.begin();
2969 
2970  while (it != simiIt->second.end())
2971  {
2972  InfoSub::pointer p = it->second.lock();
2973 
2974  if (p)
2975  {
2976  notify.insert(p);
2977  ++it;
2978  ++iProposed;
2979  }
2980  else
2981  it = simiIt->second.erase(it);
2982  }
2983  }
2984 
2985  if (bAccepted)
2986  {
2987  simiIt = mSubAccount.find(affectedAccount);
2988 
2989  if (simiIt != mSubAccount.end())
2990  {
2991  auto it = simiIt->second.begin();
2992  while (it != simiIt->second.end())
2993  {
2994  InfoSub::pointer p = it->second.lock();
2995 
2996  if (p)
2997  {
2998  notify.insert(p);
2999  ++it;
3000  ++iAccepted;
3001  }
3002  else
3003  it = simiIt->second.erase(it);
3004  }
3005  }
3006  }
3007  }
3008  }
3009  }
3010  JLOG(m_journal.trace())
3011  << "pubAccountTransaction:"
3012  << " iProposed=" << iProposed << " iAccepted=" << iAccepted;
3013 
3014  if (!notify.empty())
3015  {
3016  std::shared_ptr<STTx const> stTxn = alTx.getTxn();
3017  Json::Value jvObj =
3018  transJson(*stTxn, alTx.getResult(), bAccepted, lpCurrent);
3019 
3020  if (alTx.isApplied())
3021  {
3022  if (auto const txMeta = alTx.getMeta())
3023  {
3024  jvObj[jss::meta] = txMeta->getJson(JsonOptions::none);
3026  jvObj[jss::meta], *lpCurrent, stTxn, *txMeta);
3027  }
3028  }
3029 
3030  for (InfoSub::ref isrListener : notify)
3031  isrListener->send(jvObj, true);
3032  }
3033 }
3034 
3035 //
3036 // Monitoring
3037 //
3038 
3039 void
3041  InfoSub::ref isrListener,
3042  hash_set<AccountID> const& vnaAccountIDs,
3043  bool rt)
3044 {
3045  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3046 
3047  for (auto const& naAccountID : vnaAccountIDs)
3048  {
3049  JLOG(m_journal.trace())
3050  << "subAccount: account: " << toBase58(naAccountID);
3051 
3052  isrListener->insertSubAccountInfo(naAccountID, rt);
3053  }
3054 
3056 
3057  for (auto const& naAccountID : vnaAccountIDs)
3058  {
3059  auto simIterator = subMap.find(naAccountID);
3060  if (simIterator == subMap.end())
3061  {
3062  // Not found, note that account has a new single listner.
3063  SubMapType usisElement;
3064  usisElement[isrListener->getSeq()] = isrListener;
3065  // VFALCO NOTE This is making a needless copy of naAccountID
3066  subMap.insert(simIterator, make_pair(naAccountID, usisElement));
3067  }
3068  else
3069  {
3070  // Found, note that the account has another listener.
3071  simIterator->second[isrListener->getSeq()] = isrListener;
3072  }
3073  }
3074 }
3075 
3076 void
3078  InfoSub::ref isrListener,
3079  hash_set<AccountID> const& vnaAccountIDs,
3080  bool rt)
3081 {
3082  for (auto const& naAccountID : vnaAccountIDs)
3083  {
3084  // Remove from the InfoSub
3085  isrListener->deleteSubAccountInfo(naAccountID, rt);
3086  }
3087 
3088  // Remove from the server
3089  unsubAccountInternal(isrListener->getSeq(), vnaAccountIDs, rt);
3090 }
3091 
3092 void
3094  std::uint64_t uSeq,
3095  hash_set<AccountID> const& vnaAccountIDs,
3096  bool rt)
3097 {
3099 
3100  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3101 
3102  for (auto const& naAccountID : vnaAccountIDs)
3103  {
3104  auto simIterator = subMap.find(naAccountID);
3105 
3106  if (simIterator != subMap.end())
3107  {
3108  // Found
3109  simIterator->second.erase(uSeq);
3110 
3111  if (simIterator->second.empty())
3112  {
3113  // Don't need hash entry.
3114  subMap.erase(simIterator);
3115  }
3116  }
3117  }
3118 }
3119 
3120 bool
3121 NetworkOPsImp::subBook(InfoSub::ref isrListener, Book const& book)
3122 {
3123  if (auto listeners = app_.getOrderBookDB().makeBookListeners(book))
3124  listeners->addSubscriber(isrListener);
3125  else
3126  assert(false);
3127  return true;
3128 }
3129 
3130 bool
3132 {
3133  if (auto listeners = app_.getOrderBookDB().getBookListeners(book))
3134  listeners->removeSubscriber(uSeq);
3135 
3136  return true;
3137 }
3138 
3142 {
3143  // This code-path is exclusively used when the server is in standalone
3144  // mode via `ledger_accept`
3145  assert(m_standalone);
3146 
3147  if (!m_standalone)
3148  Throw<std::runtime_error>(
3149  "Operation only possible in STANDALONE mode.");
3150 
3151  // FIXME Could we improve on this and remove the need for a specialized
3152  // API in Consensus?
3154  mConsensus.simulate(app_.timeKeeper().closeTime(), consensusDelay);
3155  return m_ledgerMaster.getCurrentLedger()->info().seq;
3156 }
3157 
3158 // <-- bool: true=added, false=already there
3159 bool
3161 {
3162  if (auto lpClosed = m_ledgerMaster.getValidatedLedger())
3163  {
3164  jvResult[jss::ledger_index] = lpClosed->info().seq;
3165  jvResult[jss::ledger_hash] = to_string(lpClosed->info().hash);
3166  jvResult[jss::ledger_time] = Json::Value::UInt(
3167  lpClosed->info().closeTime.time_since_epoch().count());
3168  jvResult[jss::fee_ref] = lpClosed->fees().units.jsonClipped();
3169  jvResult[jss::fee_base] = lpClosed->fees().base.jsonClipped();
3170  jvResult[jss::reserve_base] =
3171  lpClosed->fees().accountReserve(0).jsonClipped();
3172  jvResult[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
3173  }
3174 
3176  {
3177  jvResult[jss::validated_ledgers] =
3179  }
3180 
3182  return mStreamMaps[sLedger]
3183  .emplace(isrListener->getSeq(), isrListener)
3184  .second;
3185 }
3186 
3187 // <-- bool: true=erased, false=was not there
3188 bool
3190 {
3192  return mStreamMaps[sLedger].erase(uSeq);
3193 }
3194 
3195 // <-- bool: true=added, false=already there
3196 bool
3198 {
3200  return mStreamMaps[sManifests]
3201  .emplace(isrListener->getSeq(), isrListener)
3202  .second;
3203 }
3204 
3205 // <-- bool: true=erased, false=was not there
3206 bool
3208 {
3210  return mStreamMaps[sManifests].erase(uSeq);
3211 }
3212 
3213 // <-- bool: true=added, false=already there
3214 bool
3216  InfoSub::ref isrListener,
3217  Json::Value& jvResult,
3218  bool admin)
3219 {
3220  uint256 uRandom;
3221 
3222  if (m_standalone)
3223  jvResult[jss::stand_alone] = m_standalone;
3224 
3225  // CHECKME: is it necessary to provide a random number here?
3226  beast::rngfill(uRandom.begin(), uRandom.size(), crypto_prng());
3227 
3228  auto const& feeTrack = app_.getFeeTrack();
3229  jvResult[jss::random] = to_string(uRandom);
3230  jvResult[jss::server_status] = strOperatingMode(admin);
3231  jvResult[jss::load_base] = feeTrack.getLoadBase();
3232  jvResult[jss::load_factor] = feeTrack.getLoadFactor();
3233  jvResult[jss::hostid] = getHostId(admin);
3234  jvResult[jss::pubkey_node] =
3236 
3238  return mStreamMaps[sServer]
3239  .emplace(isrListener->getSeq(), isrListener)
3240  .second;
3241 }
3242 
3243 // <-- bool: true=erased, false=was not there
3244 bool
3246 {
3248  return mStreamMaps[sServer].erase(uSeq);
3249 }
3250 
3251 // <-- bool: true=added, false=already there
3252 bool
3254 {
3256  return mStreamMaps[sTransactions]
3257  .emplace(isrListener->getSeq(), isrListener)
3258  .second;
3259 }
3260 
3261 // <-- bool: true=erased, false=was not there
3262 bool
3264 {
3266  return mStreamMaps[sTransactions].erase(uSeq);
3267 }
3268 
3269 // <-- bool: true=added, false=already there
3270 bool
3272 {
3275  .emplace(isrListener->getSeq(), isrListener)
3276  .second;
3277 }
3278 
3279 // <-- bool: true=erased, false=was not there
3280 bool
3282 {
3284  return mStreamMaps[sRTTransactions].erase(uSeq);
3285 }
3286 
3287 // <-- bool: true=added, false=already there
3288 bool
3290 {
3292  return mStreamMaps[sValidations]
3293  .emplace(isrListener->getSeq(), isrListener)
3294  .second;
3295 }
3296 
3297 // <-- bool: true=erased, false=was not there
3298 bool
3300 {
3302  return mStreamMaps[sValidations].erase(uSeq);
3303 }
3304 
3305 // <-- bool: true=added, false=already there
3306 bool
3308 {
3310  return mStreamMaps[sPeerStatus]
3311  .emplace(isrListener->getSeq(), isrListener)
3312  .second;
3313 }
3314 
3315 // <-- bool: true=erased, false=was not there
3316 bool
3318 {
3320  return mStreamMaps[sPeerStatus].erase(uSeq);
3321 }
3322 
3323 // <-- bool: true=added, false=already there
3324 bool
3326 {
3329  .emplace(isrListener->getSeq(), isrListener)
3330  .second;
3331 }
3332 
3333 // <-- bool: true=erased, false=was not there
3334 bool
3336 {
3338  return mStreamMaps[sConsensusPhase].erase(uSeq);
3339 }
3340 
3343 {
3345 
3346  subRpcMapType::iterator it = mRpcSubMap.find(strUrl);
3347 
3348  if (it != mRpcSubMap.end())
3349  return it->second;
3350 
3351  return InfoSub::pointer();
3352 }
3353 
3356 {
3358 
3359  mRpcSubMap.emplace(strUrl, rspEntry);
3360 
3361  return rspEntry;
3362 }
3363 
3364 bool
3366 {
3368  auto pInfo = findRpcSub(strUrl);
3369 
3370  if (!pInfo)
3371  return false;
3372 
3373  // check to see if any of the stream maps still hold a weak reference to
3374  // this entry before removing
3375  for (SubMapType const& map : mStreamMaps)
3376  {
3377  if (map.find(pInfo->getSeq()) != map.end())
3378  return false;
3379  }
3380  mRpcSubMap.erase(strUrl);
3381  return true;
3382 }
3383 
3384 #ifndef USE_NEW_BOOK_PAGE
3385 
3386 // NIKB FIXME this should be looked at. There's no reason why this shouldn't
3387 // work, but it demonstrated poor performance.
3388 //
3389 void
3392  Book const& book,
3393  AccountID const& uTakerID,
3394  bool const bProof,
3395  unsigned int iLimit,
3396  Json::Value const& jvMarker,
3397  Json::Value& jvResult)
3398 { // CAUTION: This is the old get book page logic
3399  Json::Value& jvOffers =
3400  (jvResult[jss::offers] = Json::Value(Json::arrayValue));
3401 
3403  const uint256 uBookBase = getBookBase(book);
3404  const uint256 uBookEnd = getQualityNext(uBookBase);
3405  uint256 uTipIndex = uBookBase;
3406 
3407  if (auto stream = m_journal.trace())
3408  {
3409  stream << "getBookPage:" << book;
3410  stream << "getBookPage: uBookBase=" << uBookBase;
3411  stream << "getBookPage: uBookEnd=" << uBookEnd;
3412  stream << "getBookPage: uTipIndex=" << uTipIndex;
3413  }
3414 
3415  ReadView const& view = *lpLedger;
3416 
3417  bool const bGlobalFreeze = isGlobalFrozen(view, book.out.account) ||
3418  isGlobalFrozen(view, book.in.account);
3419 
3420  bool bDone = false;
3421  bool bDirectAdvance = true;
3422 
3423  std::shared_ptr<SLE const> sleOfferDir;
3424  uint256 offerIndex;
3425  unsigned int uBookEntry;
3426  STAmount saDirRate;
3427 
3428  auto const rate = transferRate(view, book.out.account);
3429  auto viewJ = app_.journal("View");
3430 
3431  while (!bDone && iLimit-- > 0)
3432  {
3433  if (bDirectAdvance)
3434  {
3435  bDirectAdvance = false;
3436 
3437  JLOG(m_journal.trace()) << "getBookPage: bDirectAdvance";
3438 
3439  auto const ledgerIndex = view.succ(uTipIndex, uBookEnd);
3440  if (ledgerIndex)
3441  sleOfferDir = view.read(keylet::page(*ledgerIndex));
3442  else
3443  sleOfferDir.reset();
3444 
3445  if (!sleOfferDir)
3446  {
3447  JLOG(m_journal.trace()) << "getBookPage: bDone";
3448  bDone = true;
3449  }
3450  else
3451  {
3452  uTipIndex = sleOfferDir->key();
3453  saDirRate = amountFromQuality(getQuality(uTipIndex));
3454 
3455  cdirFirst(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex);
3456 
3457  JLOG(m_journal.trace())
3458  << "getBookPage: uTipIndex=" << uTipIndex;
3459  JLOG(m_journal.trace())
3460  << "getBookPage: offerIndex=" << offerIndex;
3461  }
3462  }
3463 
3464  if (!bDone)
3465  {
3466  auto sleOffer = view.read(keylet::offer(offerIndex));
3467 
3468  if (sleOffer)
3469  {
3470  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
3471  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
3472  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
3473  STAmount saOwnerFunds;
3474  bool firstOwnerOffer(true);
3475 
3476  if (book.out.account == uOfferOwnerID)
3477  {
3478  // If an offer is selling issuer's own IOUs, it is fully
3479  // funded.
3480  saOwnerFunds = saTakerGets;
3481  }
3482  else if (bGlobalFreeze)
3483  {
3484  // If either asset is globally frozen, consider all offers
3485  // that aren't ours to be totally unfunded
3486  saOwnerFunds.clear(book.out);
3487  }
3488  else
3489  {
3490  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
3491  if (umBalanceEntry != umBalance.end())
3492  {
3493  // Found in running balance table.
3494 
3495  saOwnerFunds = umBalanceEntry->second;
3496  firstOwnerOffer = false;
3497  }
3498  else
3499  {
3500  // Did not find balance in table.
3501 
3502  saOwnerFunds = accountHolds(
3503  view,
3504  uOfferOwnerID,
3505  book.out.currency,
3506  book.out.account,
3508  viewJ);
3509 
3510  if (saOwnerFunds < beast::zero)
3511  {
3512  // Treat negative funds as zero.
3513 
3514  saOwnerFunds.clear();
3515  }
3516  }
3517  }
3518 
3519  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
3520 
3521  STAmount saTakerGetsFunded;
3522  STAmount saOwnerFundsLimit = saOwnerFunds;
3523  Rate offerRate = parityRate;
3524 
3525  if (rate != parityRate
3526  // Have a tranfer fee.
3527  && uTakerID != book.out.account
3528  // Not taking offers of own IOUs.
3529  && book.out.account != uOfferOwnerID)
3530  // Offer owner not issuing ownfunds
3531  {
3532  // Need to charge a transfer fee to offer owner.
3533  offerRate = rate;
3534  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
3535  }
3536 
3537  if (saOwnerFundsLimit >= saTakerGets)
3538  {
3539  // Sufficient funds no shenanigans.
3540  saTakerGetsFunded = saTakerGets;
3541  }
3542  else
3543  {
3544  // Only provide, if not fully funded.
3545 
3546  saTakerGetsFunded = saOwnerFundsLimit;
3547 
3548  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
3549  std::min(
3550  saTakerPays,
3551  multiply(
3552  saTakerGetsFunded, saDirRate, saTakerPays.issue()))
3553  .setJson(jvOffer[jss::taker_pays_funded]);
3554  }
3555 
3556  STAmount saOwnerPays = (parityRate == offerRate)
3557  ? saTakerGetsFunded
3558  : std::min(
3559  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
3560 
3561  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
3562 
3563  // Include all offers funded and unfunded
3564  Json::Value& jvOf = jvOffers.append(jvOffer);
3565  jvOf[jss::quality] = saDirRate.getText();
3566 
3567  if (firstOwnerOffer)
3568  jvOf[jss::owner_funds] = saOwnerFunds.getText();
3569  }
3570  else
3571  {
3572  JLOG(m_journal.warn()) << "Missing offer";
3573  }
3574 
3575  if (!cdirNext(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex))
3576  {
3577  bDirectAdvance = true;
3578  }
3579  else
3580  {
3581  JLOG(m_journal.trace())
3582  << "getBookPage: offerIndex=" << offerIndex;
3583  }
3584  }
3585  }
3586 
3587  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
3588  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
3589 }
3590 
3591 #else
3592 
3593 // This is the new code that uses the book iterators
3594 // It has temporarily been disabled
3595 
3596 void
3599  Book const& book,
3600  AccountID const& uTakerID,
3601  bool const bProof,
3602  unsigned int iLimit,
3603  Json::Value const& jvMarker,
3604  Json::Value& jvResult)
3605 {
3606  auto& jvOffers = (jvResult[jss::offers] = Json::Value(Json::arrayValue));
3607 
3609 
3610  MetaView lesActive(lpLedger, tapNONE, true);
3611  OrderBookIterator obIterator(lesActive, book);
3612 
3613  auto const rate = transferRate(lesActive, book.out.account);
3614 
3615  const bool bGlobalFreeze = lesActive.isGlobalFrozen(book.out.account) ||
3616  lesActive.isGlobalFrozen(book.in.account);
3617 
3618  while (iLimit-- > 0 && obIterator.nextOffer())
3619  {
3620  SLE::pointer sleOffer = obIterator.getCurrentOffer();
3621  if (sleOffer)
3622  {
3623  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
3624  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
3625  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
3626  STAmount saDirRate = obIterator.getCurrentRate();
3627  STAmount saOwnerFunds;
3628 
3629  if (book.out.account == uOfferOwnerID)
3630  {
3631  // If offer is selling issuer's own IOUs, it is fully funded.
3632  saOwnerFunds = saTakerGets;
3633  }
3634  else if (bGlobalFreeze)
3635  {
3636  // If either asset is globally frozen, consider all offers
3637  // that aren't ours to be totally unfunded
3638  saOwnerFunds.clear(book.out);
3639  }
3640  else
3641  {
3642  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
3643 
3644  if (umBalanceEntry != umBalance.end())
3645  {
3646  // Found in running balance table.
3647 
3648  saOwnerFunds = umBalanceEntry->second;
3649  }
3650  else
3651  {
3652  // Did not find balance in table.
3653 
3654  saOwnerFunds = lesActive.accountHolds(
3655  uOfferOwnerID,
3656  book.out.currency,
3657  book.out.account,
3659 
3660  if (saOwnerFunds.isNegative())
3661  {
3662  // Treat negative funds as zero.
3663 
3664  saOwnerFunds.zero();
3665  }
3666  }
3667  }
3668 
3669  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
3670 
3671  STAmount saTakerGetsFunded;
3672  STAmount saOwnerFundsLimit = saOwnerFunds;
3673  Rate offerRate = parityRate;
3674 
3675  if (rate != parityRate
3676  // Have a tranfer fee.
3677  && uTakerID != book.out.account
3678  // Not taking offers of own IOUs.
3679  && book.out.account != uOfferOwnerID)
3680  // Offer owner not issuing ownfunds
3681  {
3682  // Need to charge a transfer fee to offer owner.
3683  offerRate = rate;
3684  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
3685  }
3686 
3687  if (saOwnerFundsLimit >= saTakerGets)
3688  {
3689  // Sufficient funds no shenanigans.
3690  saTakerGetsFunded = saTakerGets;
3691  }
3692  else
3693  {
3694  // Only provide, if not fully funded.
3695  saTakerGetsFunded = saOwnerFundsLimit;
3696 
3697  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
3698 
3699  // TOOD(tom): The result of this expression is not used - what's
3700  // going on here?
3701  std::min(
3702  saTakerPays,
3703  multiply(saTakerGetsFunded, saDirRate, saTakerPays.issue()))
3704  .setJson(jvOffer[jss::taker_pays_funded]);
3705  }
3706 
3707  STAmount saOwnerPays = (parityRate == offerRate)
3708  ? saTakerGetsFunded
3709  : std::min(
3710  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
3711 
3712  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
3713 
3714  if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID)
3715  {
3716  // Only provide funded offers and offers of the taker.
3717  Json::Value& jvOf = jvOffers.append(jvOffer);
3718  jvOf[jss::quality] = saDirRate.getText();
3719  }
3720  }
3721  }
3722 
3723  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
3724  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
3725 }
3726 
3727 #endif
3728 
3729 inline void
3731 {
3732  auto [counters, mode, start] = accounting_.getCounterData();
3733  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
3734  std::chrono::system_clock::now() - start);
3735  counters[static_cast<std::size_t>(mode)].dur += current;
3736 
3739  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
3740  .dur.count());
3742  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
3743  .dur.count());
3745  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].dur.count());
3747  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
3748  .dur.count());
3750  counters[static_cast<std::size_t>(OperatingMode::FULL)].dur.count());
3751 
3753  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
3754  .transitions);
3756  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
3757  .transitions);
3759  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].transitions);
3761  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
3762  .transitions);
3764  counters[static_cast<std::size_t>(OperatingMode::FULL)].transitions);
3765 }
3766 
3767 void
3769 {
3770  auto now = std::chrono::system_clock::now();
3771 
3772  std::lock_guard lock(mutex_);
3773  ++counters_[static_cast<std::size_t>(om)].transitions;
3774  counters_[static_cast<std::size_t>(mode_)].dur +=
3775  std::chrono::duration_cast<std::chrono::microseconds>(now - start_);
3776 
3777  mode_ = om;
3778  start_ = now;
3779 }
3780 
3783 {
3784  auto [counters, mode, start] = getCounterData();
3785  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
3786  std::chrono::system_clock::now() - start);
3787  counters[static_cast<std::size_t>(mode)].dur += current;
3788 
3790 
3791  for (std::size_t i = static_cast<std::size_t>(OperatingMode::DISCONNECTED);
3792  i <= static_cast<std::size_t>(OperatingMode::FULL);
3793  ++i)
3794  {
3795  ret[states_[i]] = Json::objectValue;
3796  auto& state = ret[states_[i]];
3797  state[jss::transitions] = counters[i].transitions;
3798  state[jss::duration_us] = std::to_string(counters[i].dur.count());
3799  }
3800 
3801  return {ret, std::to_string(current.count())};
3802 }
3803 
3804 //------------------------------------------------------------------------------
3805 
3808  Application& app,
3809  NetworkOPs::clock_type& clock,
3810  bool standalone,
3811  std::size_t minPeerCount,
3812  bool startvalid,
3813  JobQueue& job_queue,
3814  LedgerMaster& ledgerMaster,
3815  ValidatorKeys const& validatorKeys,
3816  boost::asio::io_service& io_svc,
3817  beast::Journal journal,
3818  beast::insight::Collector::ptr const& collector)
3819 {
3820  return std::make_unique<NetworkOPsImp>(
3821  app,
3822  clock,
3823  standalone,
3824  minPeerCount,
3825  startvalid,
3826  job_queue,
3827  ledgerMaster,
3828  validatorKeys,
3829  io_svc,
3830  journal,
3831  collector);
3832 }
3833 
3834 } // namespace ripple
ripple::NetworkOPsImp::forwardManifest
void forwardManifest(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2616
ripple::NetworkOPsImp::unsubValidations
bool unsubValidations(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3299
ripple::NetworkOPsImp::Stats::hook
beast::insight::Hook hook
Definition: NetworkOPs.cpp:708
ripple::STTx::getTxnType
TxType getTxnType() const
Definition: STTx.h:100
ripple::setup_FeeVote
FeeVote::Setup setup_FeeVote(Section const &section)
Build FeeVote::Setup from a config section.
Definition: FeeVoteImpl.cpp:259
ripple::NetworkOPsImp::subValidations
bool subValidations(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3289
ripple::NetworkOPsImp::processHeartbeatTimer
void processHeartbeatTimer()
Definition: NetworkOPs.cpp:878
ripple::NetworkOPs
Provides server functionality for clients.
Definition: NetworkOPs.h:86
ripple::sfIndexNext
const SF_UINT64 sfIndexNext
ripple::RCLConsensus::phase
ConsensusPhase phase() const
Definition: RCLConsensus.h:469
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:300
ripple::NetworkOPsImp::mapComplete
void mapComplete(std::shared_ptr< SHAMap > const &map, bool fromAcquire) override
Definition: NetworkOPs.cpp:1735
ripple::NetworkOPsImp::setClusterTimer
void setClusterTimer()
Definition: NetworkOPs.cpp:846
ripple::Application
Definition: Application.h:103
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:637
ripple::NetworkOPsImp::unsubConsensus
bool unsubConsensus(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3335
ripple::jtTRANSACTION
@ jtTRANSACTION
Definition: Job.h:54
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::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:1729
std::lock
T lock(T... args)
ripple::InboundLedgers::getInfo
virtual Json::Value getInfo()=0
ripple::LoadManager
Manages load sources.
Definition: LoadManager.h:45
ripple::sfReserveBase
const SF_UINT32 sfReserveBase
ripple::Application::cluster
virtual Cluster & cluster()=0
ripple::NetworkOPsImp::m_journal
beast::Journal m_journal
Definition: NetworkOPs.cpp:609
ripple::LedgerMaster::getPublishedLedger
std::shared_ptr< ReadView const > getPublishedLedger()
Definition: LedgerMaster.cpp:1642
ripple::NetworkOPsImp::sLastEntry
@ sLastEntry
Definition: NetworkOPs.cpp:647
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:2532
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:87
ripple::NetworkOPsImp::mLastFeeSummary
ServerFeeSummary mLastFeeSummary
Definition: NetworkOPs.cpp:652
ripple::ValidatorList::localPublicKey
PublicKey localPublicKey() const
Returns local validator public key.
Definition: ValidatorList.cpp:1412
ripple::InboundLedger::Reason::CONSENSUS
@ CONSENSUS
std::string
STL class.
std::shared_ptr< Transaction >
ripple::ConsensusMode::proposing
@ proposing
We are normal participant in consensus and propose our position.
ripple::NetworkOPsImp::heartbeatTimer_
boost::asio::steady_timer heartbeatTimer_
Definition: NetworkOPs.cpp:623
ripple::ManifestCache::getMasterKey
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
Definition: app/misc/impl/Manifest.cpp:296
ripple::RCLConsensus::getJson
Json::Value getJson(bool full) const
Definition: RCLConsensus.cpp:894
ripple::NetworkOPsImp::minPeerCount_
const std::size_t minPeerCount_
Definition: NetworkOPs.cpp:660
ripple::jtCLIENT
@ jtCLIENT
Definition: Job.h:51
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:808
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:516
ripple::RCLConsensus::startRound
void startRound(NetClock::time_point const &now, RCLCxLedger::ID const &prevLgrId, RCLCxLedger const &prevLgr, hash_set< NodeID > const &nowUntrusted, hash_set< NodeID > const &nowTrusted)
Adjust the set of trusted validators and kick-off the next round of consensus.
Definition: RCLConsensus.cpp:1048
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::STAmount::clear
void clear()
Definition: STAmount.h:280
ripple::sfLedgerSequence
const SF_UINT32 sfLedgerSequence
ripple::AcceptedLedgerTx::getTxn
std::shared_ptr< STTx const > const & getTxn() const
Definition: AcceptedLedgerTx.h:71
ripple::NetworkOPsImp::m_stats
Stats m_stats
Definition: NetworkOPs.cpp:723
ripple::Book::out
Issue out
Definition: Book.h:36
ripple::HashRouter::getFlags
int getFlags(uint256 const &key)
Definition: HashRouter.cpp:94
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::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:1480
ripple::NetworkOPsImp::pubManifest
void pubManifest(Manifest const &) override
Definition: NetworkOPs.cpp:1819
ripple::Manifest
Definition: Manifest.h:78
ripple::NetworkOPsImp::collect_metrics
void collect_metrics()
Definition: NetworkOPs.cpp:3730
ripple::NetworkOPsImp::subPeerStatus
bool subPeerStatus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3307
std::unordered_set
STL class.
ripple::NetworkOPsImp::mDispatchState
DispatchState mDispatchState
Definition: NetworkOPs.cpp:665
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:542
std::pair
ripple::TxQ::apply
std::pair< TER, bool > apply(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, ApplyFlags flags, beast::Journal j)
Add a new transaction to the open ledger, hold it in the queue, or reject it.
Definition: TxQ.cpp:725
ripple::Overlay::getJqTransOverflow
virtual std::uint64_t getJqTransOverflow() const =0
ripple::NetworkOPsImp::mSubRTAccount
SubInfoMapType mSubRTAccount
Definition: NetworkOPs.cpp:633
ripple::NetworkOPsImp::amendmentWarned_
std::atomic< bool > amendmentWarned_
Definition: NetworkOPs.cpp:619
ripple::NetworkOPsImp::states_
static const std::array< char const *, 5 > states_
Definition: NetworkOPs.cpp:110
ripple::LedgerMaster
Definition: LedgerMaster.h:70
ripple::ConsensusMode::wrongLedger
@ wrongLedger
We have the wrong ledger and are attempting to acquire it.
ripple::LedgerMaster::getValidLedgerIndex
LedgerIndex getValidLedgerIndex()
Definition: LedgerMaster.cpp:214
ripple::Application::getAmendmentTable
virtual AmendmentTable & getAmendmentTable()=0
ripple::NetworkOPsImp::setMode
void setMode(OperatingMode om) override
Definition: NetworkOPs.cpp:2100
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:133
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:1492
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::Validations::trustChanged
void trustChanged(hash_set< NodeID > const &added, hash_set< NodeID > const &removed)
Update trust status of validations.
Definition: Validations.h:777
ripple::NetworkOPsImp::setNeedNetworkLedger
void setNeedNetworkLedger() override
Definition: NetworkOPs.cpp:765
ripple::NetworkOPsImp::tryRemoveRpcSub
bool tryRemoveRpcSub(std::string const &strUrl) override
Definition: NetworkOPs.cpp:3365
ripple::Manifest::masterKey
PublicKey masterKey
The master key associated with this manifest.
Definition: Manifest.h:84
ripple::accountHolds
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
Definition: View.cpp:216
ripple::PublicKey::empty
bool empty() const noexcept
Definition: PublicKey.h:117
ripple::STAmount::getText
std::string getText() const override
Definition: STAmount.cpp:512
ripple::NetworkOPsImp::recvValidation
bool recvValidation(std::shared_ptr< STValidation > const &val, std::string const &source) override
Definition: NetworkOPs.cpp:2129
ripple::ValidatorList::setNegativeUNL
void setNegativeUNL(hash_set< PublicKey > const &negUnl)
set the Negative UNL with validators' master public keys
Definition: ValidatorList.cpp:1951
ripple::NetworkOPsImp::getHostId
std::string getHostId(bool forAdmin)
Definition: NetworkOPs.cpp:789
ripple::RCLConsensus::gotTxSet
void gotTxSet(NetClock::time_point const &now, RCLTxSet const &txSet)
Definition: RCLConsensus.cpp:922
ripple::NetworkOPsImp::forwardProposedTransaction
void forwardProposedTransaction(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2565
ripple::NetworkOPsImp::sValidations
@ sValidations
Definition: NetworkOPs.cpp:643
std::chrono::microseconds
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:29
ripple::Config::NODE_SIZE
std::size_t NODE_SIZE
Definition: Config.h:184
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::LedgerMaster::getValidatedRules
Rules getValidatedRules()
Definition: LedgerMaster.cpp:1627
ripple::Issue::currency
Currency currency
Definition: Issue.h:37
ripple::JobQueue::getJson
Json::Value getJson(int c=0)
Definition: JobQueue.cpp:203
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:709
ripple::NetworkOPsImp::StateAccounting::Counters
Definition: NetworkOPs.cpp:128
std::optional::emplace
T emplace(T... args)
ripple::LedgerMaster::switchLCL
void switchLCL(std::shared_ptr< Ledger const > const &lastClosed)
Definition: LedgerMaster.cpp:495
ripple::HELD
@ HELD
Definition: Transaction.h:51
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
std::recursive_mutex
STL class.
ripple::keylet::child
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Definition: Indexes.cpp:136
ripple::NetworkOPsImp::consensusViewChange
void consensusViewChange() override
Definition: NetworkOPs.cpp:1810
std::lock_guard
STL class.
ripple::NetworkOPsImp::accounting_
StateAccounting accounting_
Definition: NetworkOPs.cpp:668
ripple::ConsensusParms::ledgerGRANULARITY
std::chrono::milliseconds ledgerGRANULARITY
How often we check state or change positions.
Definition: ConsensusParms.h:95
ripple::Application::getShardStore
virtual NodeStore::DatabaseShard * getShardStore()=0
ripple::NetworkOPsImp::DispatchState::scheduled
@ scheduled
ripple::sfCloseTime
const SF_UINT32 sfCloseTime
tuple
ripple::LedgerMaster::getLedgerByHash
std::shared_ptr< Ledger const > getLedgerByHash(uint256 const &hash)
Definition: LedgerMaster.cpp:1803
ripple::RCLConsensus::timerEntry
void timerEntry(NetClock::time_point const &now)
Definition: RCLConsensus.cpp:906
ripple::Overlay::size
virtual std::size_t size() const =0
Returns the number of active peers.
ripple::NetworkOPsImp::apply
void apply(std::unique_lock< std::mutex > &batchLock)
Attempt to apply transactions and post-process based on the results.
Definition: NetworkOPs.cpp:1182
ripple::JobQueue::addJob
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
Definition: JobQueue.h:165
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:3807
ripple::NetworkOPsImp::Stats::syncing_transitions
beast::insight::Gauge syncing_transitions
Definition: NetworkOPs.cpp:717
std::function
ripple::LoadFeeTrack::getLoadBase
std::uint32_t getLoadBase() const
Definition: LoadFeeTrack.h:87
ripple::NetworkOPsImp::unlBlocked_
std::atomic< bool > unlBlocked_
Definition: NetworkOPs.cpp:620
ripple::getQualityNext
uint256 getQualityNext(uint256 const &uBase)
Definition: Indexes.cpp:97
ripple::Application::timeKeeper
virtual TimeKeeper & timeKeeper()=0
ripple::Application::getMasterMutex
virtual MutexType & getMasterMutex()=0
ripple::NetworkOPsImp::forwardProposedAccountTransaction
void forwardProposedAccountTransaction(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2654
ripple::Application::openLedger
virtual OpenLedger & openLedger()=0
ripple::NetworkOPsImp::pubLedger
void pubLedger(std::shared_ptr< ReadView const > const &lpAccepted) override
Definition: NetworkOPs.cpp:2722
ripple::Cluster::update
bool update(PublicKey const &identity, std::string name, std::uint32_t loadFee=0, NetClock::time_point reportTime=NetClock::time_point{})
Store information about the state of a cluster node.
Definition: Cluster.cpp:58
ripple::NetworkOPsImp::switchLastClosedLedger
void switchLastClosedLedger(std::shared_ptr< Ledger const > const &newLCL)
Definition: NetworkOPs.cpp:1616
ripple::tapNONE
@ tapNONE
Definition: ApplyView.h:30
ripple::NetworkOPsImp::setUNLBlocked
void setUNLBlocked() override
Definition: NetworkOPs.cpp:1498
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:1101
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::OpenLedger::accept
void accept(Application &app, Rules const &rules, std::shared_ptr< Ledger const > const &ledger, OrderedTxs const &locals, bool retriesFirst, OrderedTxs &retries, ApplyFlags flags, std::string const &suffix="", modify_type const &f={})
Accept a new ledger.
Definition: OpenLedger.cpp:71
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:88
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::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:1649
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:936
ripple::NetworkOPsImp::unsubTransactions
bool unsubTransactions(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3263
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:138
ripple::RCLConsensus::simulate
void simulate(NetClock::time_point const &now, std::optional< std::chrono::milliseconds > consensusDelay)
Definition: RCLConsensus.cpp:940
std::tie
T tie(T... args)
std::vector::push_back
T push_back(T... args)
ripple::Resource::Manager::exportConsumers
virtual Gossip exportConsumers()=0
Extract packaged consumer information for export.
ripple::LedgerMaster::peekMutex
std::recursive_mutex & peekMutex()
Definition: LedgerMaster.cpp:1595
ripple::NetworkOPsImp::ServerFeeSummary::loadFactorServer
std::uint32_t loadFactorServer
Definition: NetworkOPs.cpp:207
ripple::divide
STAmount divide(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:77
ripple::NetworkOPsImp::~NetworkOPsImp
~NetworkOPsImp() override
Definition: NetworkOPs.cpp:251
ripple::isTerRetry
bool isTerRetry(TER x)
Definition: TER.h:578
ripple::LoadFeeTrack::getRemoteFee
std::uint32_t getRemoteFee() const
Definition: LoadFeeTrack.h:66
ripple::jtBATCH
@ jtBATCH
Definition: Job.h:57
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:2636
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::m_statsMutex
std::mutex m_statsMutex
Definition: NetworkOPs.cpp:722
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:711
ripple::NetworkOPsImp::isAmendmentBlocked
bool isAmendmentBlocked() override
Definition: NetworkOPs.cpp:1461
ripple::NetworkOPsImp::addRpcSub
InfoSub::pointer addRpcSub(std::string const &strUrl, InfoSub::ref) override
Definition: NetworkOPs.cpp:3355
ripple::NetworkOPsImp::forwardValidation
void forwardValidation(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2596
ripple::NetworkOPsImp::TransactionStatus::failType
const FailHard failType
Definition: NetworkOPs.cpp:86
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:291
ripple::NetworkOPsImp::StateAccounting::json
StateCountersJson json() const
Output state counters in JSON format.
Definition: NetworkOPs.cpp:3782
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:85
ripple::NetworkOPsImp::clearAmendmentWarned
void clearAmendmentWarned() override
Definition: NetworkOPs.cpp:1486
ripple::STAmount::setJson
void setJson(Json::Value &) const
Definition: STAmount.cpp:464
ripple::UptimeClock::now
static time_point now()
Definition: UptimeClock.cpp:63
ripple::jtTXN_PROC
@ jtTXN_PROC
Definition: Job.h:74
ripple::OrderBookDB::processTxn
void processTxn(std::shared_ptr< ReadView const > const &ledger, const AcceptedLedgerTx &alTx, Json::Value const &jvObj)
Definition: OrderBookDB.cpp:245
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::getOwnerInfo
Json::Value getOwnerInfo(std::shared_ptr< ReadView const > lpLedger, AccountID const &account) override
Definition: NetworkOPs.cpp:1389
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:2795
ripple::LoadFeeTrack::getLocalFee
std::uint32_t getLocalFee() const
Definition: LoadFeeTrack.h:73
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::Application::getLoadManager
virtual LoadManager & getLoadManager()=0
ripple::InfoSub::pointer
std::shared_ptr< InfoSub > pointer
Definition: InfoSub.h:42
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::isBlocked
bool isBlocked() override
Definition: NetworkOPs.cpp:1455
ripple::InboundLedgers::acquire
virtual std::shared_ptr< Ledger const > acquire(uint256 const &hash, std::uint32_t seq, InboundLedger::Reason)=0
ripple::RCLConsensus::peerProposal
bool peerProposal(NetClock::time_point const &now, RCLCxPeerPos const &newProposal)
Definition: RCLConsensus.cpp:949
ripple::OperatingMode::TRACKING
@ TRACKING
convinced we agree with the network
ripple::NetworkOPsImp::pubValidatedTransaction
void pubValidatedTransaction(std::shared_ptr< ReadView const > const &alAccepted, const AcceptedLedgerTx &alTransaction)
Definition: NetworkOPs.cpp:2895
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:562
ripple::sfReserveIncrement
const SF_UINT32 sfReserveIncrement
ripple::JsonOptions::none
@ none
ripple::NetworkOPsImp::DispatchState
DispatchState
Synchronization states for transaction batches.
Definition: NetworkOPs.cpp:104
ripple::NetworkOPsImp::sServer
@ sServer
Definition: NetworkOPs.cpp:640
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::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:1754
ripple::ValidatorList::updateTrusted
TrustChanges updateTrusted(hash_set< NodeID > const &seenValidators, NetClock::time_point closeTime, NetworkOPs &ops, Overlay &overlay, HashRouter &hashRouter)
Update trusted nodes.
Definition: ValidatorList.cpp:1773
std::unique_lock
STL class.
ripple::sfCookie
const SF_UINT64 sfCookie
ripple::NetworkOPsImp::unsubAccount
void unsubAccount(InfoSub::ref ispListener, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
Definition: NetworkOPs.cpp:3077
ripple::Application::nodeIdentity
virtual std::pair< PublicKey, SecretKey > const & nodeIdentity()=0
ripple::LedgerMaster::canBeCurrent
bool canBeCurrent(std::shared_ptr< Ledger const > const &ledger)
Check the sequence number and parent close time of a ledger against our clock and last validated ledg...
Definition: LedgerMaster.cpp:427
ripple::NetworkOPsImp::unsubRTTransactions
bool unsubRTTransactions(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3281
ripple::Application::getTxQ
virtual TxQ & getTxQ()=0
ripple::LoadFeeTrack
Manages the current fee schedule.
Definition: LoadFeeTrack.h:43
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::NetworkOPsImp::subManifests
bool subManifests(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3197
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:83
std::array
STL class.
ripple::NetworkOPsImp::clearUNLBlocked
void clearUNLBlocked() override
Definition: NetworkOPs.cpp:1505
ripple::TxQ::getTxRequiredFeeAndSeq
FeeAndSeq getTxRequiredFeeAndSeq(OpenView const &view, std::shared_ptr< STTx const > const &tx) const
Returns minimum required fee for tx and two sequences: first vaild sequence for this account in curre...
Definition: TxQ.cpp:1738
ripple::NetworkOPsImp::ServerFeeSummary
Server fees published on server subscription.
Definition: NetworkOPs.cpp:190
ripple::NetworkOPsImp::transJson
Json::Value transJson(const STTx &stTxn, TER terResult, bool bValidated, std::shared_ptr< ReadView const > const &lpCurrent)
Definition: NetworkOPs.cpp:2837
ripple::NetworkOPsImp::m_localTX
std::unique_ptr< LocalTxs > m_localTX
Definition: NetworkOPs.cpp:611
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:214
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
ripple::LedgerMaster::isCompatible
bool isCompatible(ReadView const &, beast::Journal::Stream, char const *reason)
Definition: LedgerMaster.cpp:220
beast::Journal::info
Stream info() const
Definition: Journal.h:321
ripple::NetworkOPsImp::m_job_queue
JobQueue & m_job_queue
Definition: NetworkOPs.cpp:654
std::unordered_map::erase
T erase(T... args)
ripple::BuildInfo::getVersionString
std::string const & getVersionString()
Server version.
Definition: BuildInfo.cpp:61
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:2946
ripple::RCLConsensus::mode
ConsensusMode mode() const
Definition: RCLConsensus.h:463
ripple::AcceptedLedgerTx::getAffected
boost::container::flat_set< AccountID > const & getAffected() const
Definition: AcceptedLedgerTx.h:82
ripple::Overlay::getActivePeers
virtual PeerSequence getActivePeers() const =0
Returns a sequence representing the current list of peers.
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:712
ripple::warnRPC_UNSUPPORTED_MAJORITY
@ warnRPC_UNSUPPORTED_MAJORITY
Definition: ErrorCodes.h:151
ripple::NetworkOPsImp::subTransactions
bool subTransactions(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3253
ripple::TimeKeeper::closeTime
virtual time_point closeTime() const =0
Returns the close time, in network time.
ripple::ValStatus::current
@ current
This was a new validation and was added.
ripple::Job
Definition: Job.h:87
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:137
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:3189
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::NetworkOPsImp::isAmendmentWarned
bool isAmendmentWarned() override
Definition: NetworkOPs.cpp:1474
ripple::Application::getValidations
virtual RCLValidations & getValidations()=0
ripple::Overlay::relay
virtual std::set< Peer::id_t > relay(protocol::TMProposeSet &m, uint256 const &uid, PublicKey const &validator)=0
Relay a proposal.
std::uint32_t
std::condition_variable::wait
T wait(T... args)
ripple::NetworkOPsImp::needNetworkLedger_
std::atomic< bool > needNetworkLedger_
Definition: NetworkOPs.cpp:617
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::HashRouter::shouldRelay
std::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
Definition: HashRouter.cpp:118
ripple::LedgerMaster::addHeldTransaction
void addHeldTransaction(std::shared_ptr< Transaction > const &trans)
Definition: LedgerMaster.cpp:416
ripple::Manifest::getMasterSignature
Blob getMasterSignature() const
Returns manifest master key signature.
Definition: app/misc/impl/Manifest.cpp:230
std::atomic< OperatingMode >
ripple::Overlay::foreach
void foreach(Function f) const
Visit every active peer.
Definition: Overlay.h:198
ripple::NetworkOPsImp::ServerFeeSummary::ServerFeeSummary
ServerFeeSummary()=default
ripple::NetworkOPsImp::StateAccounting::mode_
OperatingMode mode_
Definition: NetworkOPs.cpp:136
std::map
STL class.
ripple::LoadFeeTrack::getClusterFee
std::uint32_t getClusterFee() const
Definition: LoadFeeTrack.h:80
ripple::Application::getValidationPublicKey
virtual PublicKey const & getValidationPublicKey() const =0
ripple::NetworkOPsImp::pubValidation
void pubValidation(std::shared_ptr< STValidation > const &val) override
Definition: NetworkOPs.cpp:1993
ripple::amountFromQuality
STAmount amountFromQuality(std::uint64_t rate)
Definition: STAmount.cpp:769
ripple::OrderBookDB::makeBookListeners
BookListeners::pointer makeBookListeners(Book const &)
Definition: OrderBookDB.cpp:213
ripple::NetworkOPs::FailHard
FailHard
Definition: NetworkOPs.h:91
ripple::TxQ::processClosedLedger
void processClosedLedger(Application &app, ReadView const &view, bool timeLeap)
Update fee metrics and clean up the queue in preparation for the next ledger.
Definition: TxQ.cpp:1340
ripple::NetworkOPsImp::subAccount
void subAccount(InfoSub::ref ispListener, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
Definition: NetworkOPs.cpp:3040
ripple::NetworkOPsImp::m_standalone
const bool m_standalone
Definition: NetworkOPs.cpp:657
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:1602
Json::Int
int Int
Definition: json_forwards.h:26
ripple::NetworkOPsImp::Stats
Definition: NetworkOPs.cpp:671
ripple::AcceptedLedgerTx::getResult
TER getResult() const
Definition: AcceptedLedgerTx.h:98
ripple::RCLConsensus::parms
ConsensusParms const & parms() const
Definition: RCLConsensus.h:518
ripple::STTx::getJson
Json::Value getJson(JsonOptions options) const override
Definition: STTx.cpp:207
beast::abstract_clock< std::chrono::steady_clock >
ripple::NetworkOPsImp::StateAccounting::CounterData::mode
decltype(mode_) mode
Definition: NetworkOPs.cpp:177
ripple::NetworkOPsImp::StateAccounting::CounterData
Definition: NetworkOPs.cpp:174
ripple::accountFunds
STAmount accountFunds(ReadView const &view, AccountID const &id, STAmount const &saDefault, FreezeHandling freezeHandling, beast::Journal j)
Definition: View.cpp:260
ripple::ttOFFER_CREATE
@ ttOFFER_CREATE
This transaction type creates an offer to trade one asset for another.
Definition: TxFormats.h:80
Json::Value::UInt
Json::UInt UInt
Definition: json_value.h:153
ripple::NetworkOPsImp::TransactionStatus
Transaction with input flags and results to be applied in batches.
Definition: NetworkOPs.cpp:80
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:1168
ripple::NetworkOPsImp::isNeedNetworkLedger
bool isNeedNetworkLedger() override
Definition: NetworkOPs.cpp:777
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:1869
ripple::NetworkOPsImp::TransactionStatus::TransactionStatus
TransactionStatus(std::shared_ptr< Transaction > t, bool a, bool l, FailHard f)
Definition: NetworkOPs.cpp:90
ripple::NetworkOPsImp::setStandAlone
void setStandAlone() override
Definition: NetworkOPs.cpp:759
ripple::JobQueue
A pool of threads to perform work.
Definition: JobQueue.h:55
ripple::NetworkOPsImp::mSubLock
std::recursive_mutex mSubLock
Definition: NetworkOPs.cpp:613
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:202
ripple::NetworkOPsImp::StateAccounting::start_
std::chrono::system_clock::time_point start_
Definition: NetworkOPs.cpp:139
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:230
ripple::Serializer
Definition: Serializer.h:39
ripple::Manifest::sequence
std::uint32_t sequence
The sequence number of this manifest.
Definition: Manifest.h:90
ripple::Application::getResourceManager
virtual Resource::Manager & getResourceManager()=0
ripple::LedgerMaster::getFetchPackCacheSize
std::size_t getFetchPackCacheSize() const
Definition: LedgerMaster.cpp:2313
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:645
ripple::NetworkOPsImp::mMutex
std::mutex mMutex
Definition: NetworkOPs.cpp:664
ripple::sfBaseFee
const SF_UINT64 sfBaseFee
ripple::NetworkOPsImp::Stats::tracking_transitions
beast::insight::Gauge tracking_transitions
Definition: NetworkOPs.cpp:718
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::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:716
ripple::NetworkOPsImp::clusterTimer_
boost::asio::steady_timer clusterTimer_
Definition: NetworkOPs.cpp:624
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:666
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:192
ripple::NetworkOPsImp::reportConsensusStateChange
void reportConsensusStateChange(ConsensusPhase phase)
Definition: NetworkOPs.cpp:2815
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:3245
ripple::RCLConsensus::prevRoundTime
std::chrono::milliseconds prevRoundTime() const
Get duration of the previous round.
Definition: RCLConsensus.h:456
ripple::sterilize
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Definition: STTx.cpp:526
ripple::Config::features
std::unordered_set< uint256, beast::uhash<> > features
Definition: Config.h:239
ripple::NetworkOPsImp::Stats::Stats
Stats(Handler const &handler, beast::insight::Collector::ptr const &collector)
Definition: NetworkOPs.cpp:674
ripple::NetworkOPsImp::setHeartbeatTimer
void setHeartbeatTimer()
Definition: NetworkOPs.cpp:815
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:2829
ripple::NetworkOPsImp::mStreamMaps
std::array< SubMapType, SubTypes::sLastEntry+1 > mStreamMaps
Definition: NetworkOPs.cpp:650
ripple::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:69
ripple::LoadFeeTrack::getLoadFactor
std::uint32_t getLoadFactor() const
Definition: LoadFeeTrack.h:93
ripple::NetworkOPsImp::getLedgerFetchInfo
Json::Value getLedgerFetchInfo() override
Definition: NetworkOPs.cpp:2526
ripple::tapUNLIMITED
@ tapUNLIMITED
Definition: ApplyView.h:46
ripple::NetworkOPsImp::sManifests
@ sManifests
Definition: NetworkOPs.cpp:639
ripple::NetworkOPsImp::StateAccounting::StateAccounting
StateAccounting()
Definition: NetworkOPs.cpp:144
ripple::INVALID
@ INVALID
Definition: Transaction.h:47
ripple::Validity::Valid
@ Valid
Signature and local checks are good / passed.
ripple::NetworkOPsImp::pubServer
void pubServer()
Definition: NetworkOPs.cpp:1898
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:3131
ripple::TransactionMaster::canonicalize
void canonicalize(std::shared_ptr< Transaction > *pTransaction)
Definition: TransactionMaster.cpp:143
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:3140
ripple::NetworkOPsImp::sTransactions
@ sTransactions
Definition: NetworkOPs.cpp:641
ripple::NetworkOPsImp::mSubAccount
SubInfoMapType mSubAccount
Definition: NetworkOPs.cpp:632
ripple::Config::SERVER_DOMAIN
std::string SERVER_DOMAIN
Definition: Config.h:241
ripple::AcceptedLedgerTx::isApplied
bool isApplied() const
Definition: AcceptedLedgerTx.h:109
ripple::NetworkOPsImp::clearNeedNetworkLedger
void clearNeedNetworkLedger() override
Definition: NetworkOPs.cpp:771
beast::rngfill
void rngfill(void *buffer, std::size_t bytes, Generator &g)
Definition: rngfill.h:32
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:198
Json::StaticString
Lightweight wrapper to tag static string.
Definition: json_value.h:60
ripple::NetworkOPsImp::TransactionStatus::admin
const bool admin
Definition: NetworkOPs.cpp:84
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:1511
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:980
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:3390
ripple::NetworkOPsImp::ServerFeeSummary::baseFee
XRPAmount baseFee
Definition: NetworkOPs.cpp:209
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:2071
ripple::NetworkOPsImp::mCond
std::condition_variable mCond
Definition: NetworkOPs.cpp:663
ripple::NetworkOPsImp::isFull
bool isFull() override
Definition: NetworkOPs.cpp:783
ripple::NodeStore::Database::getCountsJson
void getCountsJson(Json::Value &obj)
Definition: Database.cpp:329
ripple::LedgerMaster::getCurrentLedgerIndex
LedgerIndex getCurrentLedgerIndex()
Definition: LedgerMaster.cpp:208
ripple::NetworkOPsImp::subLedger
bool subLedger(InfoSub::ref ispListener, Json::Value &jvResult) override
Definition: NetworkOPs.cpp:3160
std::condition_variable
ripple::NetworkOPsImp::Stats::full_transitions
beast::insight::Gauge full_transitions
Definition: NetworkOPs.cpp:719
ripple::stateNames
static const std::array< char const *, 5 > stateNames
Definition: NetworkOPs.cpp:732
ripple::NetworkOPsImp::sLedger
@ sLedger
Definition: NetworkOPs.cpp:638
ripple::TimeKeeper::now
virtual time_point now() const override=0
Returns the estimate of wall time, in network time.
ripple::NetworkOPsImp::mConsensus
RCLConsensus mConsensus
Definition: NetworkOPs.cpp:626
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:644
std::chrono::milliseconds::count
T count(T... args)
ripple::NetworkOPsImp::mMode
std::atomic< OperatingMode > mMode
Definition: NetworkOPs.cpp:615
ripple::LedgerMaster::getValidatedLedger
std::shared_ptr< Ledger const > getValidatedLedger()
Definition: LedgerMaster.cpp:1612
ripple::NetworkOPsImp::unsubManifests
bool unsubManifests(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3207
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:618
ripple::NetworkOPsImp::submitTransaction
void submitTransaction(std::shared_ptr< STTx const > const &) override
Definition: NetworkOPs.cpp:1000
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::Config::RELAY_UNTRUSTED_VALIDATIONS
bool RELAY_UNTRUSTED_VALIDATIONS
Definition: Config.h:149
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:628
ripple::NetworkOPsImp::updateLocalTx
void updateLocalTx(ReadView const &view) override
Definition: NetworkOPs.cpp:2824
std::optional
mutex
ripple::NetworkOPsImp::sRTTransactions
@ sRTTransactions
Definition: NetworkOPs.cpp:642
ripple::NetworkOPs::FailHard::yes
@ yes
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:1966
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::Cluster::for_each
void for_each(std::function< void(ClusterNode const &)> func) const
Invokes the callback once for every cluster node.
Definition: Cluster.cpp:84
ripple::NetworkOPsImp::subRTTransactions
bool subRTTransactions(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3271
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:715
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:2152
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:630
ripple::NetworkOPsImp::subServer
bool subServer(InfoSub::ref ispListener, Json::Value &jvResult, bool admin) override
Definition: NetworkOPs.cpp:3215
ripple::Validations::getCurrentNodeIDs
auto getCurrentNodeIDs() -> hash_set< NodeID >
Get the set of node ids associated with current validations.
Definition: Validations.h:1001
std::numeric_limits::max
T max(T... args)
ripple::Validity::SigBad
@ SigBad
Signature is bad. Didn't do local checks.
ripple::RCLConsensus::validating
bool validating() const
Whether we are validating consensus ledgers.
Definition: RCLConsensus.h:435
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:1716
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:1127
ripple::NetworkOPsImp::StateAccounting::getCounterData
CounterData getCounterData() const
Definition: NetworkOPs.cpp:182
ripple::JobQueue::makeLoadEvent
std::unique_ptr< LoadEvent > makeLoadEvent(JobType t, std::string const &name)
Return a scoped LoadEvent.
Definition: JobQueue.cpp:166
ripple::NetworkOPsImp::Stats::full_duration
beast::insight::Gauge full_duration
Definition: NetworkOPs.cpp:713
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::OrderedTxs
CanonicalTXSet OrderedTxs
Definition: OpenLedger.h:44
ripple::NetworkOPsImp::subBook
bool subBook(InfoSub::ref ispListener, Book const &) override
Definition: NetworkOPs.cpp:3121
ripple::NetworkOPsImp::subConsensus
bool subConsensus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3325
ripple::NetworkOPsImp::getConsensusInfo
Json::Value getConsensusInfo() override
Definition: NetworkOPs.cpp:2146
ripple::NetworkOPsImp::Stats::connected_duration
beast::insight::Gauge connected_duration
Definition: NetworkOPs.cpp:710
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:622
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
Definition: NetworkOPs.cpp:74
ripple::NetworkOPsImp::StateAccounting::mode
void mode(OperatingMode om)
Record state transition.
Definition: NetworkOPs.cpp:3768
ripple::RPC::accountFromStringStrict
std::optional< AccountID > accountFromStringStrict(std::string const &account)
Get an AccountID from an account ID or public key.
Definition: RPCHelpers.cpp:39
std::unordered_map
STL class.
ripple::NetworkOPsImp::StateAccounting::states_
static const std::array< Json::StaticString const, 5 > states_
Definition: NetworkOPs.cpp:141
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:3093
ripple::sfSigningTime
const SF_UINT32 sfSigningTime
ripple::LedgerMaster::popAcctTransaction
std::shared_ptr< STTx const > popAcctTransaction(std::shared_ptr< STTx const > const &tx)
Get the next transaction held for a particular account if any.
Definition: LedgerMaster.cpp:565
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:126
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
std::condition_variable::notify_all
T notify_all(T... args)
ripple::Application::getHashRouter
virtual HashRouter & getHashRouter()=0
ripple::OpenLedger::modify
bool modify(modify_type const &f)
Modify the open ledger.
Definition: OpenLedger.cpp:57
ripple::NetworkOPsImp::StateAccounting::Counters::transitions
std::uint32_t transitions
Definition: NetworkOPs.cpp:132
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:576
ripple::NetworkOPsImp::unsubPeerStatus
bool unsubPeerStatus(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3317
ripple::NetworkOPsImp::app_
Application & app_
Definition: NetworkOPs.cpp:608
ripple::HashRouter::setFlags
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
Definition: HashRouter.cpp:102
ripple::handleNewValidation
void handleNewValidation(Application &app, std::shared_ptr< STValidation > const &val, std::string const &source)
Handle a new validation.
Definition: RCLValidations.cpp:151
ripple::isTemMalformed
bool isTemMalformed(TER x)
Definition: TER.h:566
ripple::trunc32
static std::uint32_t trunc32(std::uint64_t v)
Definition: NetworkOPs.cpp:1890
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:747
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:210
ripple::NetworkOPsImp::mRpcSubMap
subRpcMapType mRpcSubMap
Definition: NetworkOPs.cpp:635
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:3342
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:208
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::NetworkOPsImp::clearLedgerFetch
void clearLedgerFetch() override
Definition: NetworkOPs.cpp:2520
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::Application::getMasterTransaction
virtual TransactionMaster & getMasterTransaction()=0
ripple::NetworkOPsImp::beginConsensus
bool beginConsensus(uint256 const &networkClosed) override
Definition: NetworkOPs.cpp:1670
ripple::NetworkOPsImp::setAmendmentBlocked
void setAmendmentBlocked() override
Definition: NetworkOPs.cpp:1467
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:1053
beast
Definition: base_uint.h:657
string
ripple::OperatingMode::FULL
@ FULL
we have the ledger and can even validate
std::chrono::system_clock::now
T now(T... args)