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