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  if (auto version = (*val)[~sfServerVersion])
2013  jvObj[jss::server_version] = std::to_string(*version);
2014 
2015  if (auto cookie = (*val)[~sfCookie])
2016  jvObj[jss::cookie] = std::to_string(*cookie);
2017 
2018  if (auto hash = (*val)[~sfValidatedHash])
2019  jvObj[jss::validated_hash] = strHex(*hash);
2020 
2021  auto const masterKey =
2022  app_.validatorManifests().getMasterKey(signerPublic);
2023 
2024  if (masterKey != signerPublic)
2025  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, masterKey);
2026 
2027  if (auto const seq = (*val)[~sfLedgerSequence])
2028  jvObj[jss::ledger_index] = to_string(*seq);
2029 
2030  if (val->isFieldPresent(sfAmendments))
2031  {
2032  jvObj[jss::amendments] = Json::Value(Json::arrayValue);
2033  for (auto const& amendment : val->getFieldV256(sfAmendments))
2034  jvObj[jss::amendments].append(to_string(amendment));
2035  }
2036 
2037  if (auto const closeTime = (*val)[~sfCloseTime])
2038  jvObj[jss::close_time] = *closeTime;
2039 
2040  if (auto const loadFee = (*val)[~sfLoadFee])
2041  jvObj[jss::load_fee] = *loadFee;
2042 
2043  if (auto const baseFee = (*val)[~sfBaseFee])
2044  jvObj[jss::base_fee] = static_cast<double>(*baseFee);
2045 
2046  if (auto const reserveBase = (*val)[~sfReserveBase])
2047  jvObj[jss::reserve_base] = *reserveBase;
2048 
2049  if (auto const reserveInc = (*val)[~sfReserveIncrement])
2050  jvObj[jss::reserve_inc] = *reserveInc;
2051 
2052  for (auto i = mStreamMaps[sValidations].begin();
2053  i != mStreamMaps[sValidations].end();)
2054  {
2055  if (auto p = i->second.lock())
2056  {
2057  p->send(jvObj, true);
2058  ++i;
2059  }
2060  else
2061  {
2062  i = mStreamMaps[sValidations].erase(i);
2063  }
2064  }
2065  }
2066 }
2067 
2068 void
2070 {
2072 
2073  if (!mStreamMaps[sPeerStatus].empty())
2074  {
2075  Json::Value jvObj(func());
2076 
2077  jvObj[jss::type] = "peerStatusChange";
2078 
2079  for (auto i = mStreamMaps[sPeerStatus].begin();
2080  i != mStreamMaps[sPeerStatus].end();)
2081  {
2082  InfoSub::pointer p = i->second.lock();
2083 
2084  if (p)
2085  {
2086  p->send(jvObj, true);
2087  ++i;
2088  }
2089  else
2090  {
2091  i = mStreamMaps[sPeerStatus].erase(i);
2092  }
2093  }
2094  }
2095 }
2096 
2097 void
2099 {
2100  using namespace std::chrono_literals;
2101  if (om == OperatingMode::CONNECTED)
2102  {
2105  }
2106  else if (om == OperatingMode::SYNCING)
2107  {
2108  if (app_.getLedgerMaster().getValidatedLedgerAge() >= 1min)
2110  }
2111 
2112  if ((om > OperatingMode::CONNECTED) && isBlocked())
2114 
2115  if (mMode == om)
2116  return;
2117 
2118  mMode = om;
2119 
2120  accounting_.mode(om);
2121 
2122  JLOG(m_journal.info()) << "STATE->" << strOperatingMode();
2123  pubServer();
2124 }
2125 
2126 bool
2128  std::shared_ptr<STValidation> const& val,
2129  std::string const& source)
2130 {
2131  JLOG(m_journal.trace())
2132  << "recvValidation " << val->getLedgerHash() << " from " << source;
2133 
2134  handleNewValidation(app_, val, source);
2135 
2136  pubValidation(val);
2137 
2138  // We will always relay trusted validations; if configured, we will
2139  // also relay all untrusted validations.
2140  return app_.config().RELAY_UNTRUSTED_VALIDATIONS || val->isTrusted();
2141 }
2142 
2145 {
2146  return mConsensus.getJson(true);
2147 }
2148 
2150 NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
2151 {
2153 
2154  // System-level warnings
2155  {
2156  Json::Value warnings{Json::arrayValue};
2157  if (isAmendmentBlocked())
2158  {
2159  Json::Value& w = warnings.append(Json::objectValue);
2160  w[jss::id] = warnRPC_AMENDMENT_BLOCKED;
2161  w[jss::message] =
2162  "This server is amendment blocked, and must be updated to be "
2163  "able to stay in sync with the network.";
2164  }
2165  if (isUNLBlocked())
2166  {
2167  Json::Value& w = warnings.append(Json::objectValue);
2168  w[jss::id] = warnRPC_EXPIRED_VALIDATOR_LIST;
2169  w[jss::message] =
2170  "This server has an expired validator list. validators.txt "
2171  "may be incorrectly configured or some [validator_list_sites] "
2172  "may be unreachable.";
2173  }
2174  if (admin && isAmendmentWarned())
2175  {
2176  Json::Value& w = warnings.append(Json::objectValue);
2177  w[jss::id] = warnRPC_UNSUPPORTED_MAJORITY;
2178  w[jss::message] =
2179  "One or more unsupported amendments have reached majority. "
2180  "Upgrade to the latest version before they are activated "
2181  "to avoid being amendment blocked.";
2182  if (auto const expected =
2184  {
2185  auto& d = w[jss::details] = Json::objectValue;
2186  d[jss::expected_date] = expected->time_since_epoch().count();
2187  d[jss::expected_date_UTC] = to_string(*expected);
2188  }
2189  }
2190 
2191  if (warnings.size())
2192  info[jss::warnings] = std::move(warnings);
2193  }
2194 
2195  // hostid: unique string describing the machine
2196  if (human)
2197  info[jss::hostid] = getHostId(admin);
2198 
2199  // domain: if configured with a domain, report it:
2200  if (!app_.config().SERVER_DOMAIN.empty())
2201  info[jss::server_domain] = app_.config().SERVER_DOMAIN;
2202 
2203  if (!app_.config().reporting())
2204  if (auto const netid = app_.overlay().networkID())
2205  info[jss::network_id] = static_cast<Json::UInt>(*netid);
2206 
2207  info[jss::build_version] = BuildInfo::getVersionString();
2208 
2209  info[jss::server_state] = strOperatingMode(admin);
2210 
2211  info[jss::time] = to_string(std::chrono::floor<std::chrono::microseconds>(
2213 
2214  if (needNetworkLedger_)
2215  info[jss::network_ledger] = "waiting";
2216 
2217  info[jss::validation_quorum] =
2218  static_cast<Json::UInt>(app_.validators().quorum());
2219 
2220  if (admin)
2221  {
2222  switch (app_.config().NODE_SIZE)
2223  {
2224  case 0:
2225  info[jss::node_size] = "tiny";
2226  break;
2227  case 1:
2228  info[jss::node_size] = "small";
2229  break;
2230  case 2:
2231  info[jss::node_size] = "medium";
2232  break;
2233  case 3:
2234  info[jss::node_size] = "large";
2235  break;
2236  case 4:
2237  info[jss::node_size] = "huge";
2238  break;
2239  }
2240 
2241  auto when = app_.validators().expires();
2242 
2243  if (!human)
2244  {
2245  if (when)
2246  info[jss::validator_list_expires] =
2247  safe_cast<Json::UInt>(when->time_since_epoch().count());
2248  else
2249  info[jss::validator_list_expires] = 0;
2250  }
2251  else
2252  {
2253  auto& x = (info[jss::validator_list] = Json::objectValue);
2254 
2255  x[jss::count] = static_cast<Json::UInt>(app_.validators().count());
2256 
2257  if (when)
2258  {
2259  if (*when == TimeKeeper::time_point::max())
2260  {
2261  x[jss::expiration] = "never";
2262  x[jss::status] = "active";
2263  }
2264  else
2265  {
2266  x[jss::expiration] = to_string(*when);
2267 
2268  if (*when > app_.timeKeeper().now())
2269  x[jss::status] = "active";
2270  else
2271  x[jss::status] = "expired";
2272  }
2273  }
2274  else
2275  {
2276  x[jss::status] = "unknown";
2277  x[jss::expiration] = "unknown";
2278  }
2279  }
2280  }
2281  info[jss::io_latency_ms] =
2282  static_cast<Json::UInt>(app_.getIOLatency().count());
2283 
2284  if (admin)
2285  {
2287  {
2288  info[jss::pubkey_validator] = toBase58(
2290  }
2291  else
2292  {
2293  info[jss::pubkey_validator] = "none";
2294  }
2295  }
2296 
2297  if (counters)
2298  {
2299  info[jss::counters] = app_.getPerfLog().countersJson();
2300 
2301  Json::Value nodestore(Json::objectValue);
2302  if (app_.getShardStore())
2303  app_.getShardStore()->getCountsJson(nodestore);
2304  else
2305  app_.getNodeStore().getCountsJson(nodestore);
2306  info[jss::counters][jss::nodestore] = nodestore;
2307  info[jss::current_activities] = app_.getPerfLog().currentJson();
2308  }
2309 
2310  info[jss::pubkey_node] =
2312 
2313  info[jss::complete_ledgers] = app_.getLedgerMaster().getCompleteLedgers();
2314 
2315  if (amendmentBlocked_)
2316  info[jss::amendment_blocked] = true;
2317 
2318  auto const fp = m_ledgerMaster.getFetchPackCacheSize();
2319 
2320  if (fp != 0)
2321  info[jss::fetch_pack] = Json::UInt(fp);
2322 
2323  if (!app_.config().reporting())
2324  info[jss::peers] = Json::UInt(app_.overlay().size());
2325 
2326  Json::Value lastClose = Json::objectValue;
2327  lastClose[jss::proposers] = Json::UInt(mConsensus.prevProposers());
2328 
2329  if (human)
2330  {
2331  lastClose[jss::converge_time_s] =
2333  }
2334  else
2335  {
2336  lastClose[jss::converge_time] =
2338  }
2339 
2340  info[jss::last_close] = lastClose;
2341 
2342  // info[jss::consensus] = mConsensus.getJson();
2343 
2344  if (admin)
2345  info[jss::load] = m_job_queue.getJson();
2346 
2347  if (!app_.config().reporting())
2348  {
2349  auto const escalationMetrics =
2351 
2352  auto const loadFactorServer = app_.getFeeTrack().getLoadFactor();
2353  auto const loadBaseServer = app_.getFeeTrack().getLoadBase();
2354  /* Scale the escalated fee level to unitless "load factor".
2355  In practice, this just strips the units, but it will continue
2356  to work correctly if either base value ever changes. */
2357  auto const loadFactorFeeEscalation =
2358  mulDiv(
2359  escalationMetrics.openLedgerFeeLevel,
2360  loadBaseServer,
2361  escalationMetrics.referenceFeeLevel)
2362  .second;
2363 
2364  auto const loadFactor = std::max(
2365  safe_cast<std::uint64_t>(loadFactorServer),
2366  loadFactorFeeEscalation);
2367 
2368  if (!human)
2369  {
2370  info[jss::load_base] = loadBaseServer;
2371  info[jss::load_factor] = trunc32(loadFactor);
2372  info[jss::load_factor_server] = loadFactorServer;
2373 
2374  /* Json::Value doesn't support uint64, so clamp to max
2375  uint32 value. This is mostly theoretical, since there
2376  probably isn't enough extant XRP to drive the factor
2377  that high.
2378  */
2379  info[jss::load_factor_fee_escalation] =
2380  escalationMetrics.openLedgerFeeLevel.jsonClipped();
2381  info[jss::load_factor_fee_queue] =
2382  escalationMetrics.minProcessingFeeLevel.jsonClipped();
2383  info[jss::load_factor_fee_reference] =
2384  escalationMetrics.referenceFeeLevel.jsonClipped();
2385  }
2386  else
2387  {
2388  info[jss::load_factor] =
2389  static_cast<double>(loadFactor) / loadBaseServer;
2390 
2391  if (loadFactorServer != loadFactor)
2392  info[jss::load_factor_server] =
2393  static_cast<double>(loadFactorServer) / loadBaseServer;
2394 
2395  if (admin)
2396  {
2398  if (fee != loadBaseServer)
2399  info[jss::load_factor_local] =
2400  static_cast<double>(fee) / loadBaseServer;
2401  fee = app_.getFeeTrack().getRemoteFee();
2402  if (fee != loadBaseServer)
2403  info[jss::load_factor_net] =
2404  static_cast<double>(fee) / loadBaseServer;
2405  fee = app_.getFeeTrack().getClusterFee();
2406  if (fee != loadBaseServer)
2407  info[jss::load_factor_cluster] =
2408  static_cast<double>(fee) / loadBaseServer;
2409  }
2410  if (escalationMetrics.openLedgerFeeLevel !=
2411  escalationMetrics.referenceFeeLevel &&
2412  (admin || loadFactorFeeEscalation != loadFactor))
2413  info[jss::load_factor_fee_escalation] =
2414  escalationMetrics.openLedgerFeeLevel.decimalFromReference(
2415  escalationMetrics.referenceFeeLevel);
2416  if (escalationMetrics.minProcessingFeeLevel !=
2417  escalationMetrics.referenceFeeLevel)
2418  info[jss::load_factor_fee_queue] =
2419  escalationMetrics.minProcessingFeeLevel
2420  .decimalFromReference(
2421  escalationMetrics.referenceFeeLevel);
2422  }
2423  }
2424 
2425  bool valid = false;
2426  auto lpClosed = m_ledgerMaster.getValidatedLedger();
2427 
2428  if (lpClosed)
2429  valid = true;
2430  else if (!app_.config().reporting())
2431  lpClosed = m_ledgerMaster.getClosedLedger();
2432 
2433  if (lpClosed)
2434  {
2435  XRPAmount const baseFee = lpClosed->fees().base;
2437  l[jss::seq] = Json::UInt(lpClosed->info().seq);
2438  l[jss::hash] = to_string(lpClosed->info().hash);
2439 
2440  if (!human)
2441  {
2442  l[jss::base_fee] = baseFee.jsonClipped();
2443  l[jss::reserve_base] =
2444  lpClosed->fees().accountReserve(0).jsonClipped();
2445  l[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
2446  l[jss::close_time] = Json::Value::UInt(
2447  lpClosed->info().closeTime.time_since_epoch().count());
2448  }
2449  else
2450  {
2451  l[jss::base_fee_xrp] = baseFee.decimalXRP();
2452  l[jss::reserve_base_xrp] =
2453  lpClosed->fees().accountReserve(0).decimalXRP();
2454  l[jss::reserve_inc_xrp] = lpClosed->fees().increment.decimalXRP();
2455 
2456  auto const nowOffset = app_.timeKeeper().nowOffset();
2457  if (std::abs(nowOffset.count()) >= 60)
2458  l[jss::system_time_offset] = nowOffset.count();
2459 
2460  auto const closeOffset = app_.timeKeeper().closeOffset();
2461  if (std::abs(closeOffset.count()) >= 60)
2462  l[jss::close_time_offset] = closeOffset.count();
2463 
2464  constexpr std::chrono::seconds highAgeThreshold{1000000};
2466  {
2467  auto const age = m_ledgerMaster.getValidatedLedgerAge();
2468  l[jss::age] =
2469  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2470  }
2471  else
2472  {
2473  auto lCloseTime = lpClosed->info().closeTime;
2474  auto closeTime = app_.timeKeeper().closeTime();
2475  if (lCloseTime <= closeTime)
2476  {
2477  using namespace std::chrono_literals;
2478  auto age = closeTime - lCloseTime;
2479  l[jss::age] =
2480  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2481  }
2482  }
2483  }
2484 
2485  if (valid)
2486  info[jss::validated_ledger] = l;
2487  else
2488  info[jss::closed_ledger] = l;
2489 
2490  auto lpPublished = m_ledgerMaster.getPublishedLedger();
2491  if (!lpPublished)
2492  info[jss::published_ledger] = "none";
2493  else if (lpPublished->info().seq != lpClosed->info().seq)
2494  info[jss::published_ledger] = lpPublished->info().seq;
2495  }
2496 
2497  std::tie(info[jss::state_accounting], info[jss::server_state_duration_us]) =
2498  accounting_.json();
2499  info[jss::uptime] = UptimeClock::now().time_since_epoch().count();
2500  if (!app_.config().reporting())
2501  {
2502  info[jss::jq_trans_overflow] =
2504  info[jss::peer_disconnects] =
2506  info[jss::peer_disconnects_resources] =
2508  }
2509  else
2510  {
2511  info["reporting"] = app_.getReportingETL().getInfo();
2512  }
2513 
2514  return info;
2515 }
2516 
2517 void
2519 {
2521 }
2522 
2525 {
2526  return app_.getInboundLedgers().getInfo();
2527 }
2528 
2529 void
2531  std::shared_ptr<ReadView const> const& lpCurrent,
2532  std::shared_ptr<STTx const> const& stTxn,
2533  TER terResult)
2534 {
2535  Json::Value jvObj = transJson(*stTxn, terResult, false, lpCurrent);
2536 
2537  {
2539 
2540  auto it = mStreamMaps[sRTTransactions].begin();
2541  while (it != mStreamMaps[sRTTransactions].end())
2542  {
2543  InfoSub::pointer p = it->second.lock();
2544 
2545  if (p)
2546  {
2547  p->send(jvObj, true);
2548  ++it;
2549  }
2550  else
2551  {
2552  it = mStreamMaps[sRTTransactions].erase(it);
2553  }
2554  }
2555  }
2556  AcceptedLedgerTx alt(
2557  lpCurrent, stTxn, terResult, app_.accountIDCache(), app_.logs());
2558  JLOG(m_journal.trace()) << "pubProposed: " << alt.getJson();
2559  pubAccountTransaction(lpCurrent, alt, false);
2560 }
2561 
2562 void
2564 {
2565  // reporting does not forward validated transactions
2566  // validated transactions will be published to the proper streams when the
2567  // etl process writes a validated ledger
2568  if (jvObj[jss::validated].asBool())
2569  return;
2570  {
2572 
2573  auto it = mStreamMaps[sRTTransactions].begin();
2574  while (it != mStreamMaps[sRTTransactions].end())
2575  {
2576  InfoSub::pointer p = it->second.lock();
2577 
2578  if (p)
2579  {
2580  p->send(jvObj, true);
2581  ++it;
2582  }
2583  else
2584  {
2585  it = mStreamMaps[sRTTransactions].erase(it);
2586  }
2587  }
2588  }
2589 
2591 }
2592 
2593 static void
2595 {
2596  for (auto& jv : jvObj)
2597  {
2598  if (jv.isObject())
2599  {
2600  getAccounts(jv, accounts);
2601  }
2602  else if (jv.isString())
2603  {
2604  auto account = RPC::accountFromStringStrict(jv.asString());
2605  if (account)
2606  accounts.push_back(*account);
2607  }
2608  }
2609 }
2610 
2611 void
2613 {
2615  int iProposed = 0;
2616  // check if there are any subscribers before attempting to parse the JSON
2617  {
2619 
2620  if (mSubRTAccount.empty())
2621  return;
2622  }
2623 
2624  // parse the JSON outside of the lock
2625  std::vector<AccountID> accounts;
2626  if (jvObj.isMember(jss::transaction))
2627  {
2628  try
2629  {
2630  getAccounts(jvObj[jss::transaction], accounts);
2631  }
2632  catch (...)
2633  {
2634  JLOG(m_journal.debug())
2635  << __func__ << " : "
2636  << "error parsing json for accounts affected";
2637  return;
2638  }
2639  }
2640  {
2642 
2643  if (!mSubRTAccount.empty())
2644  {
2645  for (auto const& affectedAccount : accounts)
2646  {
2647  auto simiIt = mSubRTAccount.find(affectedAccount);
2648  if (simiIt != mSubRTAccount.end())
2649  {
2650  auto it = simiIt->second.begin();
2651 
2652  while (it != simiIt->second.end())
2653  {
2654  InfoSub::pointer p = it->second.lock();
2655 
2656  if (p)
2657  {
2658  notify.insert(p);
2659  ++it;
2660  ++iProposed;
2661  }
2662  else
2663  it = simiIt->second.erase(it);
2664  }
2665  }
2666  }
2667  }
2668  }
2669  JLOG(m_journal.trace()) << "forwardProposedAccountTransaction:"
2670  << " iProposed=" << iProposed;
2671 
2672  if (!notify.empty())
2673  {
2674  for (InfoSub::ref isrListener : notify)
2675  isrListener->send(jvObj, true);
2676  }
2677 }
2678 
2679 void
2681 {
2682  // Ledgers are published only when they acquire sufficient validations
2683  // Holes are filled across connection loss or other catastrophe
2684 
2685  std::shared_ptr<AcceptedLedger> alpAccepted =
2686  app_.getAcceptedLedgerCache().fetch(lpAccepted->info().hash);
2687  if (!alpAccepted)
2688  {
2689  alpAccepted = std::make_shared<AcceptedLedger>(lpAccepted, app_);
2690  app_.getAcceptedLedgerCache().canonicalize_replace_client(
2691  lpAccepted->info().hash, alpAccepted);
2692  }
2693 
2694  {
2695  JLOG(m_journal.debug())
2696  << "Publishing ledger = " << lpAccepted->info().seq;
2698 
2699  if (!mStreamMaps[sLedger].empty())
2700  {
2702 
2703  jvObj[jss::type] = "ledgerClosed";
2704  jvObj[jss::ledger_index] = lpAccepted->info().seq;
2705  jvObj[jss::ledger_hash] = to_string(lpAccepted->info().hash);
2706  jvObj[jss::ledger_time] = Json::Value::UInt(
2707  lpAccepted->info().closeTime.time_since_epoch().count());
2708 
2709  jvObj[jss::fee_ref] = lpAccepted->fees().units.jsonClipped();
2710  jvObj[jss::fee_base] = lpAccepted->fees().base.jsonClipped();
2711  jvObj[jss::reserve_base] =
2712  lpAccepted->fees().accountReserve(0).jsonClipped();
2713  jvObj[jss::reserve_inc] =
2714  lpAccepted->fees().increment.jsonClipped();
2715 
2716  jvObj[jss::txn_count] = Json::UInt(alpAccepted->getTxnCount());
2717 
2719  {
2720  jvObj[jss::validated_ledgers] =
2722  }
2723 
2724  auto it = mStreamMaps[sLedger].begin();
2725  while (it != mStreamMaps[sLedger].end())
2726  {
2727  InfoSub::pointer p = it->second.lock();
2728  if (p)
2729  {
2730  JLOG(m_journal.debug())
2731  << "Publishing ledger = " << lpAccepted->info().seq
2732  << " : consumer = " << p->getConsumer()
2733  << " : obj = " << jvObj;
2734  p->send(jvObj, true);
2735  ++it;
2736  }
2737  else
2738  it = mStreamMaps[sLedger].erase(it);
2739  }
2740  }
2741  }
2742 
2743  // Don't lock since pubAcceptedTransaction is locking.
2744  for (auto const& [_, accTx] : alpAccepted->getMap())
2745  {
2746  (void)_;
2747  JLOG(m_journal.trace()) << "pubAccepted: " << accTx->getJson();
2748  pubValidatedTransaction(lpAccepted, *accTx);
2749  }
2750 }
2751 
2752 void
2754 {
2755  if (app_.config().reporting())
2756  return;
2757  ServerFeeSummary f{
2758  app_.openLedger().current()->fees().base,
2760  app_.getFeeTrack()};
2761 
2762  // only schedule the job if something has changed
2763  if (f != mLastFeeSummary)
2764  {
2766  jtCLIENT, "reportFeeChange->pubServer", [this](Job&) {
2767  pubServer();
2768  });
2769  }
2770 }
2771 
2772 void
2774 {
2776  jtCLIENT,
2777  "reportConsensusStateChange->pubConsensus",
2778  [this, phase](Job&) { pubConsensus(phase); });
2779 }
2780 
2781 inline void
2783 {
2784  m_localTX->sweep(view);
2785 }
2786 inline std::size_t
2788 {
2789  return m_localTX->size();
2790 }
2791 
2792 // This routine should only be used to publish accepted or validated
2793 // transactions.
2796  const STTx& stTxn,
2797  TER terResult,
2798  bool bValidated,
2799  std::shared_ptr<ReadView const> const& lpCurrent)
2800 {
2802  std::string sToken;
2803  std::string sHuman;
2804 
2805  transResultInfo(terResult, sToken, sHuman);
2806 
2807  jvObj[jss::type] = "transaction";
2808  jvObj[jss::transaction] = stTxn.getJson(JsonOptions::none);
2809 
2810  if (bValidated)
2811  {
2812  jvObj[jss::ledger_index] = lpCurrent->info().seq;
2813  jvObj[jss::ledger_hash] = to_string(lpCurrent->info().hash);
2814  jvObj[jss::transaction][jss::date] =
2815  lpCurrent->info().closeTime.time_since_epoch().count();
2816  jvObj[jss::validated] = true;
2817 
2818  // WRITEME: Put the account next seq here
2819  }
2820  else
2821  {
2822  jvObj[jss::validated] = false;
2823  jvObj[jss::ledger_current_index] = lpCurrent->info().seq;
2824  }
2825 
2826  jvObj[jss::status] = bValidated ? "closed" : "proposed";
2827  jvObj[jss::engine_result] = sToken;
2828  jvObj[jss::engine_result_code] = terResult;
2829  jvObj[jss::engine_result_message] = sHuman;
2830 
2831  if (stTxn.getTxnType() == ttOFFER_CREATE)
2832  {
2833  auto const account = stTxn.getAccountID(sfAccount);
2834  auto const amount = stTxn.getFieldAmount(sfTakerGets);
2835 
2836  // If the offer create is not self funded then add the owner balance
2837  if (account != amount.issue().account)
2838  {
2839  auto const ownerFunds = accountFunds(
2840  *lpCurrent,
2841  account,
2842  amount,
2844  app_.journal("View"));
2845  jvObj[jss::transaction][jss::owner_funds] = ownerFunds.getText();
2846  }
2847  }
2848 
2849  return jvObj;
2850 }
2851 
2852 void
2854  std::shared_ptr<ReadView const> const& alAccepted,
2855  const AcceptedLedgerTx& alTx)
2856 {
2857  std::shared_ptr<STTx const> stTxn = alTx.getTxn();
2858  Json::Value jvObj = transJson(*stTxn, alTx.getResult(), true, alAccepted);
2859 
2860  if (auto const txMeta = alTx.getMeta())
2861  {
2862  jvObj[jss::meta] = txMeta->getJson(JsonOptions::none);
2864  jvObj[jss::meta], *alAccepted, stTxn, *txMeta);
2865  }
2866 
2867  {
2869 
2870  auto it = mStreamMaps[sTransactions].begin();
2871  while (it != mStreamMaps[sTransactions].end())
2872  {
2873  InfoSub::pointer p = it->second.lock();
2874 
2875  if (p)
2876  {
2877  p->send(jvObj, true);
2878  ++it;
2879  }
2880  else
2881  it = mStreamMaps[sTransactions].erase(it);
2882  }
2883 
2884  it = mStreamMaps[sRTTransactions].begin();
2885 
2886  while (it != mStreamMaps[sRTTransactions].end())
2887  {
2888  InfoSub::pointer p = it->second.lock();
2889 
2890  if (p)
2891  {
2892  p->send(jvObj, true);
2893  ++it;
2894  }
2895  else
2896  it = mStreamMaps[sRTTransactions].erase(it);
2897  }
2898  }
2899  app_.getOrderBookDB().processTxn(alAccepted, alTx, jvObj);
2900  pubAccountTransaction(alAccepted, alTx, true);
2901 }
2902 
2903 void
2905  std::shared_ptr<ReadView const> const& lpCurrent,
2906  const AcceptedLedgerTx& alTx,
2907  bool bAccepted)
2908 {
2910  int iProposed = 0;
2911  int iAccepted = 0;
2912 
2913  {
2915 
2916  if (!bAccepted && mSubRTAccount.empty())
2917  return;
2918 
2919  if (!mSubAccount.empty() || (!mSubRTAccount.empty()))
2920  {
2921  for (auto const& affectedAccount : alTx.getAffected())
2922  {
2923  auto simiIt = mSubRTAccount.find(affectedAccount);
2924  if (simiIt != mSubRTAccount.end())
2925  {
2926  auto it = simiIt->second.begin();
2927 
2928  while (it != simiIt->second.end())
2929  {
2930  InfoSub::pointer p = it->second.lock();
2931 
2932  if (p)
2933  {
2934  notify.insert(p);
2935  ++it;
2936  ++iProposed;
2937  }
2938  else
2939  it = simiIt->second.erase(it);
2940  }
2941  }
2942 
2943  if (bAccepted)
2944  {
2945  simiIt = mSubAccount.find(affectedAccount);
2946 
2947  if (simiIt != mSubAccount.end())
2948  {
2949  auto it = simiIt->second.begin();
2950  while (it != simiIt->second.end())
2951  {
2952  InfoSub::pointer p = it->second.lock();
2953 
2954  if (p)
2955  {
2956  notify.insert(p);
2957  ++it;
2958  ++iAccepted;
2959  }
2960  else
2961  it = simiIt->second.erase(it);
2962  }
2963  }
2964  }
2965  }
2966  }
2967  }
2968  JLOG(m_journal.trace())
2969  << "pubAccountTransaction:"
2970  << " iProposed=" << iProposed << " iAccepted=" << iAccepted;
2971 
2972  if (!notify.empty())
2973  {
2974  std::shared_ptr<STTx const> stTxn = alTx.getTxn();
2975  Json::Value jvObj =
2976  transJson(*stTxn, alTx.getResult(), bAccepted, lpCurrent);
2977 
2978  if (alTx.isApplied())
2979  {
2980  if (auto const txMeta = alTx.getMeta())
2981  {
2982  jvObj[jss::meta] = txMeta->getJson(JsonOptions::none);
2984  jvObj[jss::meta], *lpCurrent, stTxn, *txMeta);
2985  }
2986  }
2987 
2988  for (InfoSub::ref isrListener : notify)
2989  isrListener->send(jvObj, true);
2990  }
2991 }
2992 
2993 //
2994 // Monitoring
2995 //
2996 
2997 void
2999  InfoSub::ref isrListener,
3000  hash_set<AccountID> const& vnaAccountIDs,
3001  bool rt)
3002 {
3003  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3004 
3005  for (auto const& naAccountID : vnaAccountIDs)
3006  {
3007  JLOG(m_journal.trace())
3008  << "subAccount: account: " << toBase58(naAccountID);
3009 
3010  isrListener->insertSubAccountInfo(naAccountID, rt);
3011  }
3012 
3014 
3015  for (auto const& naAccountID : vnaAccountIDs)
3016  {
3017  auto simIterator = subMap.find(naAccountID);
3018  if (simIterator == subMap.end())
3019  {
3020  // Not found, note that account has a new single listner.
3021  SubMapType usisElement;
3022  usisElement[isrListener->getSeq()] = isrListener;
3023  // VFALCO NOTE This is making a needless copy of naAccountID
3024  subMap.insert(simIterator, make_pair(naAccountID, usisElement));
3025  }
3026  else
3027  {
3028  // Found, note that the account has another listener.
3029  simIterator->second[isrListener->getSeq()] = isrListener;
3030  }
3031  }
3032 }
3033 
3034 void
3036  InfoSub::ref isrListener,
3037  hash_set<AccountID> const& vnaAccountIDs,
3038  bool rt)
3039 {
3040  for (auto const& naAccountID : vnaAccountIDs)
3041  {
3042  // Remove from the InfoSub
3043  isrListener->deleteSubAccountInfo(naAccountID, rt);
3044  }
3045 
3046  // Remove from the server
3047  unsubAccountInternal(isrListener->getSeq(), vnaAccountIDs, rt);
3048 }
3049 
3050 void
3052  std::uint64_t uSeq,
3053  hash_set<AccountID> const& vnaAccountIDs,
3054  bool rt)
3055 {
3057 
3058  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3059 
3060  for (auto const& naAccountID : vnaAccountIDs)
3061  {
3062  auto simIterator = subMap.find(naAccountID);
3063 
3064  if (simIterator != subMap.end())
3065  {
3066  // Found
3067  simIterator->second.erase(uSeq);
3068 
3069  if (simIterator->second.empty())
3070  {
3071  // Don't need hash entry.
3072  subMap.erase(simIterator);
3073  }
3074  }
3075  }
3076 }
3077 
3078 bool
3079 NetworkOPsImp::subBook(InfoSub::ref isrListener, Book const& book)
3080 {
3081  if (auto listeners = app_.getOrderBookDB().makeBookListeners(book))
3082  listeners->addSubscriber(isrListener);
3083  else
3084  assert(false);
3085  return true;
3086 }
3087 
3088 bool
3090 {
3091  if (auto listeners = app_.getOrderBookDB().getBookListeners(book))
3092  listeners->removeSubscriber(uSeq);
3093 
3094  return true;
3095 }
3096 
3100 {
3101  // This code-path is exclusively used when the server is in standalone
3102  // mode via `ledger_accept`
3103  assert(m_standalone);
3104 
3105  if (!m_standalone)
3106  Throw<std::runtime_error>(
3107  "Operation only possible in STANDALONE mode.");
3108 
3109  // FIXME Could we improve on this and remove the need for a specialized
3110  // API in Consensus?
3112  mConsensus.simulate(app_.timeKeeper().closeTime(), consensusDelay);
3113  return m_ledgerMaster.getCurrentLedger()->info().seq;
3114 }
3115 
3116 // <-- bool: true=added, false=already there
3117 bool
3119 {
3120  if (auto lpClosed = m_ledgerMaster.getValidatedLedger())
3121  {
3122  jvResult[jss::ledger_index] = lpClosed->info().seq;
3123  jvResult[jss::ledger_hash] = to_string(lpClosed->info().hash);
3124  jvResult[jss::ledger_time] = Json::Value::UInt(
3125  lpClosed->info().closeTime.time_since_epoch().count());
3126  jvResult[jss::fee_ref] = lpClosed->fees().units.jsonClipped();
3127  jvResult[jss::fee_base] = lpClosed->fees().base.jsonClipped();
3128  jvResult[jss::reserve_base] =
3129  lpClosed->fees().accountReserve(0).jsonClipped();
3130  jvResult[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
3131  }
3132 
3134  {
3135  jvResult[jss::validated_ledgers] =
3137  }
3138 
3140  return mStreamMaps[sLedger]
3141  .emplace(isrListener->getSeq(), isrListener)
3142  .second;
3143 }
3144 
3145 // <-- bool: true=erased, false=was not there
3146 bool
3148 {
3150  return mStreamMaps[sLedger].erase(uSeq);
3151 }
3152 
3153 // <-- bool: true=added, false=already there
3154 bool
3156 {
3158  return mStreamMaps[sManifests]
3159  .emplace(isrListener->getSeq(), isrListener)
3160  .second;
3161 }
3162 
3163 // <-- bool: true=erased, false=was not there
3164 bool
3166 {
3168  return mStreamMaps[sManifests].erase(uSeq);
3169 }
3170 
3171 // <-- bool: true=added, false=already there
3172 bool
3174  InfoSub::ref isrListener,
3175  Json::Value& jvResult,
3176  bool admin)
3177 {
3178  uint256 uRandom;
3179 
3180  if (m_standalone)
3181  jvResult[jss::stand_alone] = m_standalone;
3182 
3183  // CHECKME: is it necessary to provide a random number here?
3184  beast::rngfill(uRandom.begin(), uRandom.size(), crypto_prng());
3185 
3186  auto const& feeTrack = app_.getFeeTrack();
3187  jvResult[jss::random] = to_string(uRandom);
3188  jvResult[jss::server_status] = strOperatingMode(admin);
3189  jvResult[jss::load_base] = feeTrack.getLoadBase();
3190  jvResult[jss::load_factor] = feeTrack.getLoadFactor();
3191  jvResult[jss::hostid] = getHostId(admin);
3192  jvResult[jss::pubkey_node] =
3194 
3196  return mStreamMaps[sServer]
3197  .emplace(isrListener->getSeq(), isrListener)
3198  .second;
3199 }
3200 
3201 // <-- bool: true=erased, false=was not there
3202 bool
3204 {
3206  return mStreamMaps[sServer].erase(uSeq);
3207 }
3208 
3209 // <-- bool: true=added, false=already there
3210 bool
3212 {
3214  return mStreamMaps[sTransactions]
3215  .emplace(isrListener->getSeq(), isrListener)
3216  .second;
3217 }
3218 
3219 // <-- bool: true=erased, false=was not there
3220 bool
3222 {
3224  return mStreamMaps[sTransactions].erase(uSeq);
3225 }
3226 
3227 // <-- bool: true=added, false=already there
3228 bool
3230 {
3233  .emplace(isrListener->getSeq(), isrListener)
3234  .second;
3235 }
3236 
3237 // <-- bool: true=erased, false=was not there
3238 bool
3240 {
3242  return mStreamMaps[sRTTransactions].erase(uSeq);
3243 }
3244 
3245 // <-- bool: true=added, false=already there
3246 bool
3248 {
3250  return mStreamMaps[sValidations]
3251  .emplace(isrListener->getSeq(), isrListener)
3252  .second;
3253 }
3254 
3255 // <-- bool: true=erased, false=was not there
3256 bool
3258 {
3260  return mStreamMaps[sValidations].erase(uSeq);
3261 }
3262 
3263 // <-- bool: true=added, false=already there
3264 bool
3266 {
3268  return mStreamMaps[sPeerStatus]
3269  .emplace(isrListener->getSeq(), isrListener)
3270  .second;
3271 }
3272 
3273 // <-- bool: true=erased, false=was not there
3274 bool
3276 {
3278  return mStreamMaps[sPeerStatus].erase(uSeq);
3279 }
3280 
3281 // <-- bool: true=added, false=already there
3282 bool
3284 {
3287  .emplace(isrListener->getSeq(), isrListener)
3288  .second;
3289 }
3290 
3291 // <-- bool: true=erased, false=was not there
3292 bool
3294 {
3296  return mStreamMaps[sConsensusPhase].erase(uSeq);
3297 }
3298 
3301 {
3303 
3304  subRpcMapType::iterator it = mRpcSubMap.find(strUrl);
3305 
3306  if (it != mRpcSubMap.end())
3307  return it->second;
3308 
3309  return InfoSub::pointer();
3310 }
3311 
3314 {
3316 
3317  mRpcSubMap.emplace(strUrl, rspEntry);
3318 
3319  return rspEntry;
3320 }
3321 
3322 bool
3324 {
3326  auto pInfo = findRpcSub(strUrl);
3327 
3328  if (!pInfo)
3329  return false;
3330 
3331  // check to see if any of the stream maps still hold a weak reference to
3332  // this entry before removing
3333  for (SubMapType const& map : mStreamMaps)
3334  {
3335  if (map.find(pInfo->getSeq()) != map.end())
3336  return false;
3337  }
3338  mRpcSubMap.erase(strUrl);
3339  return true;
3340 }
3341 
3342 #ifndef USE_NEW_BOOK_PAGE
3343 
3344 // NIKB FIXME this should be looked at. There's no reason why this shouldn't
3345 // work, but it demonstrated poor performance.
3346 //
3347 void
3350  Book const& book,
3351  AccountID const& uTakerID,
3352  bool const bProof,
3353  unsigned int iLimit,
3354  Json::Value const& jvMarker,
3355  Json::Value& jvResult)
3356 { // CAUTION: This is the old get book page logic
3357  Json::Value& jvOffers =
3358  (jvResult[jss::offers] = Json::Value(Json::arrayValue));
3359 
3361  const uint256 uBookBase = getBookBase(book);
3362  const uint256 uBookEnd = getQualityNext(uBookBase);
3363  uint256 uTipIndex = uBookBase;
3364 
3365  if (auto stream = m_journal.trace())
3366  {
3367  stream << "getBookPage:" << book;
3368  stream << "getBookPage: uBookBase=" << uBookBase;
3369  stream << "getBookPage: uBookEnd=" << uBookEnd;
3370  stream << "getBookPage: uTipIndex=" << uTipIndex;
3371  }
3372 
3373  ReadView const& view = *lpLedger;
3374 
3375  bool const bGlobalFreeze = isGlobalFrozen(view, book.out.account) ||
3376  isGlobalFrozen(view, book.in.account);
3377 
3378  bool bDone = false;
3379  bool bDirectAdvance = true;
3380 
3381  std::shared_ptr<SLE const> sleOfferDir;
3382  uint256 offerIndex;
3383  unsigned int uBookEntry;
3384  STAmount saDirRate;
3385 
3386  auto const rate = transferRate(view, book.out.account);
3387  auto viewJ = app_.journal("View");
3388 
3389  while (!bDone && iLimit-- > 0)
3390  {
3391  if (bDirectAdvance)
3392  {
3393  bDirectAdvance = false;
3394 
3395  JLOG(m_journal.trace()) << "getBookPage: bDirectAdvance";
3396 
3397  auto const ledgerIndex = view.succ(uTipIndex, uBookEnd);
3398  if (ledgerIndex)
3399  sleOfferDir = view.read(keylet::page(*ledgerIndex));
3400  else
3401  sleOfferDir.reset();
3402 
3403  if (!sleOfferDir)
3404  {
3405  JLOG(m_journal.trace()) << "getBookPage: bDone";
3406  bDone = true;
3407  }
3408  else
3409  {
3410  uTipIndex = sleOfferDir->key();
3411  saDirRate = amountFromQuality(getQuality(uTipIndex));
3412 
3413  cdirFirst(
3414  view,
3415  uTipIndex,
3416  sleOfferDir,
3417  uBookEntry,
3418  offerIndex,
3419  viewJ);
3420 
3421  JLOG(m_journal.trace())
3422  << "getBookPage: uTipIndex=" << uTipIndex;
3423  JLOG(m_journal.trace())
3424  << "getBookPage: offerIndex=" << offerIndex;
3425  }
3426  }
3427 
3428  if (!bDone)
3429  {
3430  auto sleOffer = view.read(keylet::offer(offerIndex));
3431 
3432  if (sleOffer)
3433  {
3434  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
3435  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
3436  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
3437  STAmount saOwnerFunds;
3438  bool firstOwnerOffer(true);
3439 
3440  if (book.out.account == uOfferOwnerID)
3441  {
3442  // If an offer is selling issuer's own IOUs, it is fully
3443  // funded.
3444  saOwnerFunds = saTakerGets;
3445  }
3446  else if (bGlobalFreeze)
3447  {
3448  // If either asset is globally frozen, consider all offers
3449  // that aren't ours to be totally unfunded
3450  saOwnerFunds.clear(book.out);
3451  }
3452  else
3453  {
3454  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
3455  if (umBalanceEntry != umBalance.end())
3456  {
3457  // Found in running balance table.
3458 
3459  saOwnerFunds = umBalanceEntry->second;
3460  firstOwnerOffer = false;
3461  }
3462  else
3463  {
3464  // Did not find balance in table.
3465 
3466  saOwnerFunds = accountHolds(
3467  view,
3468  uOfferOwnerID,
3469  book.out.currency,
3470  book.out.account,
3472  viewJ);
3473 
3474  if (saOwnerFunds < beast::zero)
3475  {
3476  // Treat negative funds as zero.
3477 
3478  saOwnerFunds.clear();
3479  }
3480  }
3481  }
3482 
3483  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
3484 
3485  STAmount saTakerGetsFunded;
3486  STAmount saOwnerFundsLimit = saOwnerFunds;
3487  Rate offerRate = parityRate;
3488 
3489  if (rate != parityRate
3490  // Have a tranfer fee.
3491  && uTakerID != book.out.account
3492  // Not taking offers of own IOUs.
3493  && book.out.account != uOfferOwnerID)
3494  // Offer owner not issuing ownfunds
3495  {
3496  // Need to charge a transfer fee to offer owner.
3497  offerRate = rate;
3498  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
3499  }
3500 
3501  if (saOwnerFundsLimit >= saTakerGets)
3502  {
3503  // Sufficient funds no shenanigans.
3504  saTakerGetsFunded = saTakerGets;
3505  }
3506  else
3507  {
3508  // Only provide, if not fully funded.
3509 
3510  saTakerGetsFunded = saOwnerFundsLimit;
3511 
3512  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
3513  std::min(
3514  saTakerPays,
3515  multiply(
3516  saTakerGetsFunded, saDirRate, saTakerPays.issue()))
3517  .setJson(jvOffer[jss::taker_pays_funded]);
3518  }
3519 
3520  STAmount saOwnerPays = (parityRate == offerRate)
3521  ? saTakerGetsFunded
3522  : std::min(
3523  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
3524 
3525  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
3526 
3527  // Include all offers funded and unfunded
3528  Json::Value& jvOf = jvOffers.append(jvOffer);
3529  jvOf[jss::quality] = saDirRate.getText();
3530 
3531  if (firstOwnerOffer)
3532  jvOf[jss::owner_funds] = saOwnerFunds.getText();
3533  }
3534  else
3535  {
3536  JLOG(m_journal.warn()) << "Missing offer";
3537  }
3538 
3539  if (!cdirNext(
3540  view,
3541  uTipIndex,
3542  sleOfferDir,
3543  uBookEntry,
3544  offerIndex,
3545  viewJ))
3546  {
3547  bDirectAdvance = true;
3548  }
3549  else
3550  {
3551  JLOG(m_journal.trace())
3552  << "getBookPage: offerIndex=" << offerIndex;
3553  }
3554  }
3555  }
3556 
3557  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
3558  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
3559 }
3560 
3561 #else
3562 
3563 // This is the new code that uses the book iterators
3564 // It has temporarily been disabled
3565 
3566 void
3569  Book const& book,
3570  AccountID const& uTakerID,
3571  bool const bProof,
3572  unsigned int iLimit,
3573  Json::Value const& jvMarker,
3574  Json::Value& jvResult)
3575 {
3576  auto& jvOffers = (jvResult[jss::offers] = Json::Value(Json::arrayValue));
3577 
3579 
3580  MetaView lesActive(lpLedger, tapNONE, true);
3581  OrderBookIterator obIterator(lesActive, book);
3582 
3583  auto const rate = transferRate(lesActive, book.out.account);
3584 
3585  const bool bGlobalFreeze = lesActive.isGlobalFrozen(book.out.account) ||
3586  lesActive.isGlobalFrozen(book.in.account);
3587 
3588  while (iLimit-- > 0 && obIterator.nextOffer())
3589  {
3590  SLE::pointer sleOffer = obIterator.getCurrentOffer();
3591  if (sleOffer)
3592  {
3593  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
3594  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
3595  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
3596  STAmount saDirRate = obIterator.getCurrentRate();
3597  STAmount saOwnerFunds;
3598 
3599  if (book.out.account == uOfferOwnerID)
3600  {
3601  // If offer is selling issuer's own IOUs, it is fully funded.
3602  saOwnerFunds = saTakerGets;
3603  }
3604  else if (bGlobalFreeze)
3605  {
3606  // If either asset is globally frozen, consider all offers
3607  // that aren't ours to be totally unfunded
3608  saOwnerFunds.clear(book.out);
3609  }
3610  else
3611  {
3612  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
3613 
3614  if (umBalanceEntry != umBalance.end())
3615  {
3616  // Found in running balance table.
3617 
3618  saOwnerFunds = umBalanceEntry->second;
3619  }
3620  else
3621  {
3622  // Did not find balance in table.
3623 
3624  saOwnerFunds = lesActive.accountHolds(
3625  uOfferOwnerID,
3626  book.out.currency,
3627  book.out.account,
3629 
3630  if (saOwnerFunds.isNegative())
3631  {
3632  // Treat negative funds as zero.
3633 
3634  saOwnerFunds.zero();
3635  }
3636  }
3637  }
3638 
3639  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
3640 
3641  STAmount saTakerGetsFunded;
3642  STAmount saOwnerFundsLimit = saOwnerFunds;
3643  Rate offerRate = parityRate;
3644 
3645  if (rate != parityRate
3646  // Have a tranfer fee.
3647  && uTakerID != book.out.account
3648  // Not taking offers of own IOUs.
3649  && book.out.account != uOfferOwnerID)
3650  // Offer owner not issuing ownfunds
3651  {
3652  // Need to charge a transfer fee to offer owner.
3653  offerRate = rate;
3654  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
3655  }
3656 
3657  if (saOwnerFundsLimit >= saTakerGets)
3658  {
3659  // Sufficient funds no shenanigans.
3660  saTakerGetsFunded = saTakerGets;
3661  }
3662  else
3663  {
3664  // Only provide, if not fully funded.
3665  saTakerGetsFunded = saOwnerFundsLimit;
3666 
3667  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
3668 
3669  // TOOD(tom): The result of this expression is not used - what's
3670  // going on here?
3671  std::min(
3672  saTakerPays,
3673  multiply(saTakerGetsFunded, saDirRate, saTakerPays.issue()))
3674  .setJson(jvOffer[jss::taker_pays_funded]);
3675  }
3676 
3677  STAmount saOwnerPays = (parityRate == offerRate)
3678  ? saTakerGetsFunded
3679  : std::min(
3680  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
3681 
3682  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
3683 
3684  if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID)
3685  {
3686  // Only provide funded offers and offers of the taker.
3687  Json::Value& jvOf = jvOffers.append(jvOffer);
3688  jvOf[jss::quality] = saDirRate.getText();
3689  }
3690  }
3691  }
3692 
3693  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
3694  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
3695 }
3696 
3697 #endif
3698 
3699 inline void
3701 {
3702  auto [counters, mode, start] = accounting_.getCounterData();
3703  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
3704  std::chrono::system_clock::now() - start);
3705  counters[static_cast<std::size_t>(mode)].dur += current;
3706 
3709  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
3710  .dur.count());
3712  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
3713  .dur.count());
3715  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].dur.count());
3717  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
3718  .dur.count());
3720  counters[static_cast<std::size_t>(OperatingMode::FULL)].dur.count());
3721 
3723  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
3724  .transitions);
3726  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
3727  .transitions);
3729  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].transitions);
3731  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
3732  .transitions);
3734  counters[static_cast<std::size_t>(OperatingMode::FULL)].transitions);
3735 }
3736 
3737 void
3739 {
3740  auto now = std::chrono::system_clock::now();
3741 
3742  std::lock_guard lock(mutex_);
3743  ++counters_[static_cast<std::size_t>(om)].transitions;
3744  counters_[static_cast<std::size_t>(mode_)].dur +=
3745  std::chrono::duration_cast<std::chrono::microseconds>(now - start_);
3746 
3747  mode_ = om;
3748  start_ = now;
3749 }
3750 
3753 {
3754  auto [counters, mode, start] = getCounterData();
3755  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
3756  std::chrono::system_clock::now() - start);
3757  counters[static_cast<std::size_t>(mode)].dur += current;
3758 
3760 
3761  for (std::size_t i = static_cast<std::size_t>(OperatingMode::DISCONNECTED);
3762  i <= static_cast<std::size_t>(OperatingMode::FULL);
3763  ++i)
3764  {
3765  ret[states_[i]] = Json::objectValue;
3766  auto& state = ret[states_[i]];
3767  state[jss::transitions] = counters[i].transitions;
3768  state[jss::duration_us] = std::to_string(counters[i].dur.count());
3769  }
3770 
3771  return {ret, std::to_string(current.count())};
3772 }
3773 
3774 //------------------------------------------------------------------------------
3775 
3778  Application& app,
3779  NetworkOPs::clock_type& clock,
3780  bool standalone,
3781  std::size_t minPeerCount,
3782  bool startvalid,
3783  JobQueue& job_queue,
3784  LedgerMaster& ledgerMaster,
3785  ValidatorKeys const& validatorKeys,
3786  boost::asio::io_service& io_svc,
3787  beast::Journal journal,
3788  beast::insight::Collector::ptr const& collector)
3789 {
3790  return std::make_unique<NetworkOPsImp>(
3791  app,
3792  clock,
3793  standalone,
3794  minPeerCount,
3795  startvalid,
3796  job_queue,
3797  ledgerMaster,
3798  validatorKeys,
3799  io_svc,
3800  journal,
3801  collector);
3802 }
3803 
3804 } // namespace ripple
ripple::NetworkOPsImp::unsubValidations
bool unsubValidations(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:3257
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:3247
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:3293
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:2530
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:3700
ripple::NetworkOPsImp::subPeerStatus
bool subPeerStatus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3265
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:2098
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:3323
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:2127
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:2563
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:3777
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:2612
ripple::Application::openLedger
virtual OpenLedger & openLedger()=0
ripple::NetworkOPsImp::pubLedger
void pubLedger(std::shared_ptr< ReadView const > const &lpAccepted) override
Definition: NetworkOPs.cpp:2680
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::sfValidatedHash
const SF_HASH256 sfValidatedHash
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:3221
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:2594
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:3313
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:3752
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::sfServerVersion
const SF_UINT64 sfServerVersion
ripple::checkValidity
std::pair< Validity, std::string > checkValidity(HashRouter &router, STTx const &tx, Rules const &rules, Config const &config)
Checks transaction signature and local checks.
Definition: apply.cpp:37
ripple::NetworkOPsImp::reportFeeChange
void reportFeeChange() override
Definition: NetworkOPs.cpp:2753
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:2853
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::sfCookie
const SF_UINT64 sfCookie
ripple::NetworkOPsImp::unsubAccount
void unsubAccount(InfoSub::ref ispListener, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
Definition: NetworkOPs.cpp:3035
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:3239
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:3155
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:2795
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:2904
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:3211
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:3147
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:2998
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:2773
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:3203
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:2787
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:2524
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:3089
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:3098
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:192
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:3348
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:2069
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:3118
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:3165
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:2782
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:3229
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:2150
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:3173
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:3079
ripple::NetworkOPsImp::subConsensus
bool subConsensus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3283
ripple::NetworkOPsImp::getConsensusInfo
Json::Value getConsensusInfo() override
Definition: NetworkOPs.cpp:2144
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:3738
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:3051
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:3275
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:3300
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:2518
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)