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