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