rippled
NetworkOPs.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/app/consensus/RCLConsensus.h>
21 #include <ripple/app/consensus/RCLValidations.h>
22 #include <ripple/app/ledger/AcceptedLedger.h>
23 #include <ripple/app/ledger/InboundLedgers.h>
24 #include <ripple/app/ledger/LedgerMaster.h>
25 #include <ripple/app/ledger/LedgerToJson.h>
26 #include <ripple/app/ledger/LocalTxs.h>
27 #include <ripple/app/ledger/OpenLedger.h>
28 #include <ripple/app/ledger/OrderBookDB.h>
29 #include <ripple/app/ledger/TransactionMaster.h>
30 #include <ripple/app/main/LoadManager.h>
31 #include <ripple/app/misc/AmendmentTable.h>
32 #include <ripple/app/misc/HashRouter.h>
33 #include <ripple/app/misc/LoadFeeTrack.h>
34 #include <ripple/app/misc/NetworkOPs.h>
35 #include <ripple/app/misc/Transaction.h>
36 #include <ripple/app/misc/TxQ.h>
37 #include <ripple/app/misc/ValidatorKeys.h>
38 #include <ripple/app/misc/ValidatorList.h>
39 #include <ripple/app/misc/impl/AccountTxPaging.h>
40 #include <ripple/app/rdb/backend/PostgresDatabase.h>
41 #include <ripple/app/rdb/backend/SQLiteDatabase.h>
42 #include <ripple/app/reporting/ReportingETL.h>
43 #include <ripple/app/tx/apply.h>
44 #include <ripple/basics/PerfLog.h>
45 #include <ripple/basics/SubmitSync.h>
46 #include <ripple/basics/UptimeClock.h>
47 #include <ripple/basics/mulDiv.h>
48 #include <ripple/basics/safe_cast.h>
49 #include <ripple/beast/rfc2616.h>
50 #include <ripple/beast/utility/rngfill.h>
51 #include <ripple/consensus/Consensus.h>
52 #include <ripple/consensus/ConsensusParms.h>
53 #include <ripple/crypto/RFC1751.h>
54 #include <ripple/crypto/csprng.h>
55 #include <ripple/json/to_string.h>
56 #include <ripple/net/RPCErr.h>
57 #include <ripple/nodestore/DatabaseShard.h>
58 #include <ripple/overlay/Cluster.h>
59 #include <ripple/overlay/Overlay.h>
60 #include <ripple/overlay/predicates.h>
61 #include <ripple/protocol/BuildInfo.h>
62 #include <ripple/protocol/Feature.h>
63 #include <ripple/protocol/STParsedJSON.h>
64 #include <ripple/resource/Fees.h>
65 #include <ripple/resource/ResourceManager.h>
66 #include <ripple/rpc/BookChanges.h>
67 #include <ripple/rpc/DeliveredAmount.h>
68 #include <ripple/rpc/ServerHandler.h>
69 #include <ripple/rpc/impl/RPCHelpers.h>
70 #include <boost/asio/ip/host_name.hpp>
71 #include <boost/asio/steady_timer.hpp>
72 
73 #include <algorithm>
74 #include <mutex>
75 #include <string>
76 #include <tuple>
77 #include <unordered_map>
78 #include <utility>
79 
80 namespace ripple {
81 
82 class NetworkOPsImp final : public NetworkOPs
83 {
89  {
90  public:
92  bool const admin;
93  bool const local;
95  bool applied = false;
97 
100  bool a,
101  bool l,
102  FailHard f)
103  : transaction(t), admin(a), local(l), failType(f)
104  {
105  assert(local || failType == FailHard::no);
106  }
107  };
108 
112  enum class DispatchState : unsigned char {
113  none,
114  scheduled,
115  running,
116  };
117 
119 
135  {
136  struct Counters
137  {
138  explicit Counters() = default;
139 
142  };
143 
147  std::chrono::steady_clock::time_point start_ =
149  std::chrono::steady_clock::time_point const processStart_ = start_;
152 
153  public:
154  explicit StateAccounting()
155  {
157  .transitions = 1;
158  }
159 
166  void
167  mode(OperatingMode om);
168 
174  void
175  json(Json::Value& obj) const;
176 
177  struct CounterData
178  {
179  decltype(counters_) counters;
180  decltype(mode_) mode;
181  decltype(start_) start;
183  };
184 
187  {
188  std::lock_guard lock(mutex_);
189  return {counters_, mode_, start_, initialSyncUs_};
190  }
191  };
192 
195  {
196  ServerFeeSummary() = default;
197 
199  XRPAmount fee,
200  TxQ::Metrics&& escalationMetrics,
201  LoadFeeTrack const& loadFeeTrack);
202  bool
203  operator!=(ServerFeeSummary const& b) const;
204 
205  bool
206  operator==(ServerFeeSummary const& b) const
207  {
208  return !(*this != b);
209  }
210 
215  };
216 
217 public:
219  Application& app,
220  NetworkOPs::clock_type& clock,
221  bool standalone,
222  std::size_t minPeerCount,
223  bool start_valid,
224  JobQueue& job_queue,
225  LedgerMaster& ledgerMaster,
226  ValidatorKeys const& validatorKeys,
227  boost::asio::io_service& io_svc,
228  beast::Journal journal,
229  beast::insight::Collector::ptr const& collector)
230  : app_(app)
231  , m_journal(journal)
233  , mMode(start_valid ? OperatingMode::FULL : OperatingMode::DISCONNECTED)
234  , heartbeatTimer_(io_svc)
235  , clusterTimer_(io_svc)
236  , accountHistoryTxTimer_(io_svc)
237  , batchApplyTimer_(io_svc)
238  , mConsensus(
239  app,
240  make_FeeVote(
241  setup_FeeVote(app_.config().section("voting")),
242  app_.logs().journal("FeeVote")),
243  ledgerMaster,
244  *m_localTX,
245  app.getInboundTransactions(),
246  beast::get_abstract_clock<std::chrono::steady_clock>(),
247  validatorKeys,
248  app_.logs().journal("LedgerConsensus"))
250  , m_job_queue(job_queue)
251  , m_standalone(standalone)
252  , minPeerCount_(start_valid ? 0 : minPeerCount)
253  , m_stats(std::bind(&NetworkOPsImp::collect_metrics, this), collector)
254  {
255  }
256 
257  ~NetworkOPsImp() override
258  {
259  // This clear() is necessary to ensure the shared_ptrs in this map get
260  // destroyed NOW because the objects in this map invoke methods on this
261  // class when they are destroyed
262  mRpcSubMap.clear();
263  }
264 
265 public:
267  getOperatingMode() const override;
268 
270  strOperatingMode(OperatingMode const mode, bool const admin) const override;
271 
273  strOperatingMode(bool const admin = false) const override;
274 
275  //
276  // Transaction operations.
277  //
278 
279  // Must complete immediately.
280  void
282 
283  void
285  std::shared_ptr<Transaction>& transaction,
286  bool bUnlimited,
287  RPC::SubmitSync sync,
288  bool bLocal,
289  FailHard failType) override;
290 
291  bool
292  transactionBatch(bool drain) override;
293 
299  void
301 
302  //
303  // Owner functions.
304  //
305 
307  getOwnerInfo(
309  AccountID const& account) override;
310 
311  //
312  // Book functions.
313  //
314 
315  void
316  getBookPage(
318  Book const&,
319  AccountID const& uTakerID,
320  const bool bProof,
321  unsigned int iLimit,
322  Json::Value const& jvMarker,
323  Json::Value& jvResult) override;
324 
325  // Ledger proposal/close functions.
326  bool
327  processTrustedProposal(RCLCxPeerPos proposal) override;
328 
329  bool
332  std::string const& source) override;
333 
334  void
335  mapComplete(std::shared_ptr<SHAMap> const& map, bool fromAcquire) override;
336 
337  // Network state machine.
338 
339  // Used for the "jump" case.
340 private:
341  void
343  bool
344  checkLastClosedLedger(const Overlay::PeerSequence&, uint256& networkClosed);
345 
346 public:
347  bool
348  beginConsensus(uint256 const& networkClosed) override;
349  void
350  endConsensus() override;
351  void
352  setStandAlone() override;
353 
357  void
358  setStateTimer() override;
359 
360  void
361  setNeedNetworkLedger() override;
362  void
363  clearNeedNetworkLedger() override;
364  bool
365  isNeedNetworkLedger() override;
366  bool
367  isFull() override;
368 
369  void
370  setMode(OperatingMode om) override;
371 
372  bool
373  isBlocked() override;
374  bool
375  isAmendmentBlocked() override;
376  void
377  setAmendmentBlocked() override;
378  bool
379  isAmendmentWarned() override;
380  void
381  setAmendmentWarned() override;
382  void
383  clearAmendmentWarned() override;
384  bool
385  isUNLBlocked() override;
386  void
387  setUNLBlocked() override;
388  void
389  clearUNLBlocked() override;
390  void
391  consensusViewChange() override;
392 
394  getConsensusInfo() override;
396  getServerInfo(bool human, bool admin, bool counters) override;
397  void
398  clearLedgerFetch() override;
400  getLedgerFetchInfo() override;
402  acceptLedger(
403  std::optional<std::chrono::milliseconds> consensusDelay) override;
404  void
405  reportFeeChange() override;
406  void
408 
409  void
410  updateLocalTx(ReadView const& view) override;
412  getLocalTxCount() override;
413 
414  //
415  // Monitoring: publisher side.
416  //
417  void
418  pubLedger(std::shared_ptr<ReadView const> const& lpAccepted) override;
419  void
421  std::shared_ptr<ReadView const> const& ledger,
422  std::shared_ptr<STTx const> const& transaction,
423  TER result) override;
424  void
425  pubValidation(std::shared_ptr<STValidation> const& val) override;
426 
427  void
428  forwardValidation(Json::Value const& jvObj) override;
429  void
430  forwardManifest(Json::Value const& jvObj) override;
431  void
432  forwardProposedTransaction(Json::Value const& jvObj) override;
433  void
434  forwardProposedAccountTransaction(Json::Value const& jvObj) override;
435 
436  //--------------------------------------------------------------------------
437  //
438  // InfoSub::Source.
439  //
440  void
441  subAccount(
442  InfoSub::ref ispListener,
443  hash_set<AccountID> const& vnaAccountIDs,
444  bool rt) override;
445  void
446  unsubAccount(
447  InfoSub::ref ispListener,
448  hash_set<AccountID> const& vnaAccountIDs,
449  bool rt) override;
450 
451  // Just remove the subscription from the tracking
452  // not from the InfoSub. Needed for InfoSub destruction
453  void
455  std::uint64_t seq,
456  hash_set<AccountID> const& vnaAccountIDs,
457  bool rt) override;
458 
460  subAccountHistory(InfoSub::ref ispListener, AccountID const& account)
461  override;
462  void
464  InfoSub::ref ispListener,
465  AccountID const& account,
466  bool historyOnly) override;
467 
468  void
470  std::uint64_t seq,
471  AccountID const& account,
472  bool historyOnly) override;
473 
474  bool
475  subLedger(InfoSub::ref ispListener, Json::Value& jvResult) override;
476  bool
477  unsubLedger(std::uint64_t uListener) override;
478 
479  bool
480  subBookChanges(InfoSub::ref ispListener) override;
481  bool
482  unsubBookChanges(std::uint64_t uListener) override;
483 
484  bool
485  subServer(InfoSub::ref ispListener, Json::Value& jvResult, bool admin)
486  override;
487  bool
488  unsubServer(std::uint64_t uListener) override;
489 
490  bool
491  subBook(InfoSub::ref ispListener, Book const&) override;
492  bool
493  unsubBook(std::uint64_t uListener, Book const&) override;
494 
495  bool
496  subManifests(InfoSub::ref ispListener) override;
497  bool
498  unsubManifests(std::uint64_t uListener) override;
499  void
500  pubManifest(Manifest const&) override;
501 
502  bool
503  subTransactions(InfoSub::ref ispListener) override;
504  bool
505  unsubTransactions(std::uint64_t uListener) override;
506 
507  bool
508  subRTTransactions(InfoSub::ref ispListener) override;
509  bool
510  unsubRTTransactions(std::uint64_t uListener) override;
511 
512  bool
513  subValidations(InfoSub::ref ispListener) override;
514  bool
515  unsubValidations(std::uint64_t uListener) override;
516 
517  bool
518  subPeerStatus(InfoSub::ref ispListener) override;
519  bool
520  unsubPeerStatus(std::uint64_t uListener) override;
521  void
522  pubPeerStatus(std::function<Json::Value(void)> const&) override;
523 
524  bool
525  subConsensus(InfoSub::ref ispListener) override;
526  bool
527  unsubConsensus(std::uint64_t uListener) override;
528 
530  findRpcSub(std::string const& strUrl) override;
532  addRpcSub(std::string const& strUrl, InfoSub::ref) override;
533  bool
534  tryRemoveRpcSub(std::string const& strUrl) override;
535 
536  void
537  stop() override
538  {
539  {
540  boost::system::error_code ec;
541  heartbeatTimer_.cancel(ec);
542  if (ec)
543  {
544  JLOG(m_journal.error())
545  << "NetworkOPs: heartbeatTimer cancel error: "
546  << ec.message();
547  }
548 
549  ec.clear();
550  clusterTimer_.cancel(ec);
551  if (ec)
552  {
553  JLOG(m_journal.error())
554  << "NetworkOPs: clusterTimer cancel error: "
555  << ec.message();
556  }
557 
558  ec.clear();
559  accountHistoryTxTimer_.cancel(ec);
560  if (ec)
561  {
562  JLOG(m_journal.error())
563  << "NetworkOPs: accountHistoryTxTimer cancel error: "
564  << ec.message();
565  }
566 
567  ec.clear();
568  batchApplyTimer_.cancel(ec);
569  if (ec)
570  {
571  JLOG(m_journal.error())
572  << "NetworkOPs: batchApplyTimer cancel error: "
573  << ec.message();
574  }
575  }
576  // Make sure that any waitHandlers pending in our timers are done.
577  using namespace std::chrono_literals;
578  waitHandlerCounter_.join("NetworkOPs", 1s, m_journal);
579  }
580 
581  void
582  stateAccounting(Json::Value& obj) override;
583 
584 private:
585  void
586  setTimer(
587  boost::asio::steady_timer& timer,
588  std::chrono::milliseconds const& expiry_time,
589  std::function<void()> onExpire,
590  std::function<void()> onError);
591  void
593  void
594  setClusterTimer();
595  void
597  void
599 
601  transJson(
602  const STTx& transaction,
603  TER result,
604  bool validated,
605  std::shared_ptr<ReadView const> const& ledger);
606 
607  void
609  std::shared_ptr<ReadView const> const& ledger,
610  AcceptedLedgerTx const& transaction);
611 
612  void
614  std::shared_ptr<ReadView const> const& ledger,
615  AcceptedLedgerTx const& transaction);
616 
617  void
619  std::shared_ptr<ReadView const> const& ledger,
620  std::shared_ptr<STTx const> const& transaction,
621  TER result);
622 
623  void
624  pubServer();
625  void
627 
629  getHostId(bool forAdmin);
630 
631 private:
635 
636  /*
637  * With a validated ledger to separate history and future, the node
638  * streams historical txns with negative indexes starting from -1,
639  * and streams future txns starting from index 0.
640  * The SubAccountHistoryIndex struct maintains these indexes.
641  * It also has a flag stopHistorical_ for stopping streaming
642  * the historical txns.
643  */
645  {
647  // forward
649  // separate backward and forward
651  // history, backward
656 
658  : accountId_(accountId)
659  , forwardTxIndex_(0)
662  , historyTxIndex_(-1)
663  , haveHistorical_(false)
664  , stopHistorical_(false)
665  {
666  }
667  };
669  {
672  };
674  {
677  };
680 
684  void
686  std::shared_ptr<ReadView const> const& ledger,
687  SubAccountHistoryInfoWeak& subInfo);
688  void
690  void
692 
693  void
694  setBatchApplyTimer() override;
695 
698 
700 
702 
704 
709 
711  boost::asio::steady_timer heartbeatTimer_;
712  boost::asio::steady_timer clusterTimer_;
713  boost::asio::steady_timer accountHistoryTxTimer_;
715  boost::asio::steady_timer batchApplyTimer_;
716 
718 
720 
722 
725 
727 
729 
730  enum SubTypes {
731  sLedger, // Accepted ledgers.
732  sManifests, // Received validator manifests.
733  sServer, // When server changes connectivity state.
734  sTransactions, // All accepted transactions.
735  sRTTransactions, // All proposed and accepted transactions.
736  sValidations, // Received validations.
737  sPeerStatus, // Peer status changes.
738  sConsensusPhase, // Consensus phase
739  sBookChanges, // Per-ledger order book changes
740 
741  sLastEntry = sBookChanges // as this name implies, any new entry
742  // must be ADDED ABOVE this one
743  };
745 
747 
749 
750  // Whether we are in standalone mode.
751  bool const m_standalone;
752 
753  // The number of nodes that we need to consider ourselves connected.
755 
756  // Transaction batching.
761 
763 
764 private:
765  struct Stats
766  {
767  template <class Handler>
769  Handler const& handler,
770  beast::insight::Collector::ptr const& collector)
771  : hook(collector->make_hook(handler))
772  , disconnected_duration(collector->make_gauge(
773  "State_Accounting",
774  "Disconnected_duration"))
775  , connected_duration(collector->make_gauge(
776  "State_Accounting",
777  "Connected_duration"))
779  collector->make_gauge("State_Accounting", "Syncing_duration"))
780  , tracking_duration(collector->make_gauge(
781  "State_Accounting",
782  "Tracking_duration"))
783  , full_duration(
784  collector->make_gauge("State_Accounting", "Full_duration"))
785  , disconnected_transitions(collector->make_gauge(
786  "State_Accounting",
787  "Disconnected_transitions"))
788  , connected_transitions(collector->make_gauge(
789  "State_Accounting",
790  "Connected_transitions"))
791  , syncing_transitions(collector->make_gauge(
792  "State_Accounting",
793  "Syncing_transitions"))
794  , tracking_transitions(collector->make_gauge(
795  "State_Accounting",
796  "Tracking_transitions"))
798  collector->make_gauge("State_Accounting", "Full_transitions"))
799  {
800  }
801 
808 
814  };
815 
816  std::mutex m_statsMutex; // Mutex to lock m_stats
818 
819 private:
820  void
821  collect_metrics();
822 };
823 
824 //------------------------------------------------------------------------------
825 
827  {"disconnected", "connected", "syncing", "tracking", "full"}};
828 
830 
838 
839 static auto const genesisAccountId = calcAccountID(
840  generateKeyPair(KeyType::secp256k1, generateSeed("masterpassphrase"))
841  .first);
842 
843 //------------------------------------------------------------------------------
844 inline OperatingMode
846 {
847  return mMode;
848 }
849 
850 inline std::string
851 NetworkOPsImp::strOperatingMode(bool const admin /* = false */) const
852 {
853  return strOperatingMode(mMode, admin);
854 }
855 
856 inline void
858 {
860 }
861 
862 inline void
864 {
865  needNetworkLedger_ = true;
866 }
867 
868 inline void
870 {
871  needNetworkLedger_ = false;
872 }
873 
874 inline bool
876 {
877  return needNetworkLedger_;
878 }
879 
880 inline bool
882 {
884 }
885 
888 {
889  static std::string const hostname = boost::asio::ip::host_name();
890 
891  if (forAdmin)
892  return hostname;
893 
894  // For non-admin uses hash the node public key into a
895  // single RFC1751 word:
896  static std::string const shroudedHostId = [this]() {
897  auto const& id = app_.nodeIdentity();
898 
899  return RFC1751::getWordFromBlob(id.first.data(), id.first.size());
900  }();
901 
902  return shroudedHostId;
903 }
904 
905 void
907 {
909 
910  // Only do this work if a cluster is configured
911  if (app_.cluster().size() != 0)
912  setClusterTimer();
913 }
914 
915 void
917  boost::asio::steady_timer& timer,
918  const std::chrono::milliseconds& expiry_time,
919  std::function<void()> onExpire,
920  std::function<void()> onError)
921 {
922  // Only start the timer if waitHandlerCounter_ is not yet joined.
923  if (auto optionalCountedHandler = waitHandlerCounter_.wrap(
924  [this, onExpire, onError](boost::system::error_code const& e) {
925  if ((e.value() == boost::system::errc::success) &&
926  (!m_job_queue.isStopped()))
927  {
928  onExpire();
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  << "Timer got error '" << e.message()
937  << "'. Restarting timer.";
938  onError();
939  }
940  }))
941  {
942  timer.expires_from_now(expiry_time);
943  timer.async_wait(std::move(*optionalCountedHandler));
944  }
945 }
946 
947 void
949 {
950  // timerDelay is to optimize the timer interval such as for phase establish.
951  // Setting a max of ledgerGRANULARITY allows currently in-flight proposals
952  // to be accounted for at the very beginning of the phase.
953  std::chrono::milliseconds timerDelay;
954  auto td = mConsensus.getTimerDelay();
955  if (td)
956  {
957  timerDelay = std::min(*td, mConsensus.parms().ledgerGRANULARITY);
959  }
960  else
961  {
962  timerDelay = mConsensus.parms().ledgerGRANULARITY;
963  }
964 
965  setTimer(
967  timerDelay,
968  [this]() {
969  m_job_queue.addJob(jtNETOP_TIMER, "NetOPs.heartbeat", [this]() {
971  });
972  },
973  [this]() { setHeartbeatTimer(); });
974 }
975 
976 void
978 {
979  using namespace std::chrono_literals;
980 
981  setTimer(
983  10s,
984  [this]() {
985  m_job_queue.addJob(jtNETOP_CLUSTER, "NetOPs.cluster", [this]() {
987  });
988  },
989  [this]() { setClusterTimer(); });
990 }
991 
992 void
994 {
995  JLOG(m_journal.debug()) << "Scheduling AccountHistory job for account "
996  << toBase58(subInfo.index_->accountId_);
997  using namespace std::chrono_literals;
998  setTimer(
1000  4s,
1001  [this, subInfo]() { addAccountHistoryJob(subInfo); },
1002  [this, subInfo]() { setAccountHistoryJobTimer(subInfo); });
1003 }
1004 
1005 void
1007 {
1008  using namespace std::chrono_literals;
1009  // 100ms lag between batch intervals provides significant throughput gains
1010  // with little increased latency. Tuning this figure further will
1011  // require further testing. In general, increasing this figure will
1012  // also increase theoretical throughput, but with diminishing returns.
1013  auto constexpr batchInterval = 100ms;
1014 
1015  setTimer(
1017  batchInterval,
1018  [this]() {
1019  {
1020  std::lock_guard lock(mMutex);
1021  // Only do the job if there's work to do and it's not currently
1022  // being done.
1023  if (mTransactions.size() &&
1025  {
1026  if (m_job_queue.addJob(
1027  jtBATCH, "transactionBatch", [this]() {
1028  transactionBatch(false);
1029  }))
1030  {
1032  }
1033  return;
1034  }
1035  }
1037  },
1038  [this]() { setBatchApplyTimer(); });
1039 }
1040 
1041 void
1043 {
1044  {
1046 
1047  // VFALCO NOTE This is for diagnosing a crash on exit
1049  mgr.resetDeadlockDetector();
1050 
1051  std::size_t const numPeers = app_.overlay().size();
1052 
1053  // do we have sufficient peers? If not, we are disconnected.
1054  if (numPeers < minPeerCount_)
1055  {
1057  {
1059  JLOG(m_journal.warn())
1060  << "Node count (" << numPeers << ") has fallen "
1061  << "below required minimum (" << minPeerCount_ << ").";
1062  }
1063 
1064  // MasterMutex lock need not be held to call setHeartbeatTimer()
1065  lock.unlock();
1066  // We do not call mConsensus.timerEntry until there are enough
1067  // peers providing meaningful inputs to consensus
1069  return;
1070  }
1071 
1073  {
1075  JLOG(m_journal.info())
1076  << "Node count (" << numPeers << ") is sufficient.";
1077  }
1078 
1079  // Check if the last validated ledger forces a change between these
1080  // states.
1083  else if (mMode == OperatingMode::CONNECTED)
1085  }
1086 
1088 
1089  const ConsensusPhase currPhase = mConsensus.phase();
1090  if (mLastConsensusPhase != currPhase)
1091  {
1092  reportConsensusStateChange(currPhase);
1093  mLastConsensusPhase = currPhase;
1094  }
1095 
1097 }
1098 
1099 void
1101 {
1102  if (app_.cluster().size() == 0)
1103  return;
1104 
1105  using namespace std::chrono_literals;
1106 
1107  bool const update = app_.cluster().update(
1108  app_.nodeIdentity().first,
1109  "",
1112  : 0,
1113  app_.timeKeeper().now());
1114 
1115  if (!update)
1116  {
1117  JLOG(m_journal.debug()) << "Too soon to send cluster update";
1118  setClusterTimer();
1119  return;
1120  }
1121 
1122  protocol::TMCluster cluster;
1123  app_.cluster().for_each([&cluster](ClusterNode const& node) {
1124  protocol::TMClusterNode& n = *cluster.add_clusternodes();
1125  n.set_publickey(toBase58(TokenType::NodePublic, node.identity()));
1126  n.set_reporttime(node.getReportTime().time_since_epoch().count());
1127  n.set_nodeload(node.getLoadFee());
1128  if (!node.name().empty())
1129  n.set_nodename(node.name());
1130  });
1131 
1133  for (auto& item : gossip.items)
1134  {
1135  protocol::TMLoadSource& node = *cluster.add_loadsources();
1136  node.set_name(to_string(item.address));
1137  node.set_cost(item.balance);
1138  }
1140  std::make_shared<Message>(cluster, protocol::mtCLUSTER),
1141  peer_in_cluster()));
1142  setClusterTimer();
1143 }
1144 
1145 //------------------------------------------------------------------------------
1146 
1148 NetworkOPsImp::strOperatingMode(OperatingMode const mode, bool const admin)
1149  const
1150 {
1151  if (mode == OperatingMode::FULL && admin)
1152  {
1153  auto const consensusMode = mConsensus.mode();
1154  if (consensusMode != ConsensusMode::wrongLedger)
1155  {
1156  if (consensusMode == ConsensusMode::proposing)
1157  return "proposing";
1158 
1159  if (mConsensus.validating())
1160  return "validating";
1161  }
1162  }
1163 
1164  return states_[static_cast<std::size_t>(mode)];
1165 }
1166 
1167 void
1169 {
1170  if (isNeedNetworkLedger())
1171  {
1172  // Nothing we can do if we've never been in sync
1173  return;
1174  }
1175 
1176  // this is an asynchronous interface
1177  auto const trans = sterilize(*iTrans);
1178 
1179  auto const txid = trans->getTransactionID();
1180  auto const flags = app_.getHashRouter().getFlags(txid);
1181 
1182  if ((flags & SF_BAD) != 0)
1183  {
1184  JLOG(m_journal.warn()) << "Submitted transaction cached bad";
1185  return;
1186  }
1187 
1188  try
1189  {
1190  auto const [validity, reason] = checkValidity(
1191  app_.getHashRouter(),
1192  *trans,
1194  app_.config());
1195 
1196  if (validity != Validity::Valid)
1197  {
1198  JLOG(m_journal.warn())
1199  << "Submitted transaction invalid: " << reason;
1200  return;
1201  }
1202  }
1203  catch (std::exception const& ex)
1204  {
1205  JLOG(m_journal.warn())
1206  << "Exception checking transaction " << txid << ": " << ex.what();
1207 
1208  return;
1209  }
1210 
1211  std::string reason;
1212 
1213  auto tx = std::make_shared<Transaction>(trans, reason, app_);
1214 
1215  m_job_queue.addJob(jtTRANSACTION, "submitTxn", [this, tx]() {
1216  auto t = tx;
1218  t, false, RPC::SubmitSync::async, false, FailHard::no);
1219  });
1220 }
1221 
1222 void
1224  std::shared_ptr<Transaction>& transaction,
1225  bool bUnlimited,
1226  RPC::SubmitSync sync,
1227  bool bLocal,
1228  FailHard failType)
1229 {
1230  auto ev = m_job_queue.makeLoadEvent(jtTXN_PROC, "ProcessTXN");
1231  auto const newFlags = app_.getHashRouter().getFlags(transaction->getID());
1232 
1233  if ((newFlags & SF_BAD) != 0)
1234  {
1235  // cached bad
1236  JLOG(m_journal.warn()) << transaction->getID() << ": cached bad!\n";
1237  transaction->setStatus(INVALID);
1238  transaction->setResult(temBAD_SIGNATURE);
1239  return;
1240  }
1241 
1242  // NOTE eahennis - I think this check is redundant,
1243  // but I'm not 100% sure yet.
1244  // If so, only cost is looking up HashRouter flags.
1245  auto const view = m_ledgerMaster.getCurrentLedger();
1246  auto const [validity, reason] = checkValidity(
1247  app_.getHashRouter(),
1248  *transaction->getSTransaction(),
1249  view->rules(),
1250  app_.config());
1251  assert(validity == Validity::Valid);
1252 
1253  // Not concerned with local checks at this point.
1254  if (validity == Validity::SigBad)
1255  {
1256  JLOG(m_journal.trace()) << "Transaction has bad signature: " << reason;
1257  transaction->setStatus(INVALID);
1258  transaction->setResult(temBAD_SIGNATURE);
1259  app_.getHashRouter().setFlags(transaction->getID(), SF_BAD);
1260  return;
1261  }
1262 
1263  // canonicalize can change our pointer
1264  app_.getMasterTransaction().canonicalize(&transaction);
1265 
1266  std::unique_lock lock(mMutex);
1267  if (!transaction->getApplying())
1268  {
1269  transaction->setApplying();
1270  mTransactions.push_back(
1271  TransactionStatus(transaction, bUnlimited, bLocal, failType));
1272  }
1273  switch (sync)
1274  {
1275  using enum RPC::SubmitSync;
1276  case sync:
1277  do
1278  {
1279  // If a batch is being processed, then wait. Otherwise,
1280  // process a batch.
1282  mCond.wait(lock);
1283  else
1284  apply(lock);
1285  } while (transaction->getApplying());
1286  break;
1287 
1288  case async:
1289  // It's conceivable for the submitted transaction to be
1290  // processed and its result to be modified before being returned
1291  // to the client. Make a copy of the transaction and set its
1292  // status to guarantee that the client gets the terSUBMITTED
1293  // result in all cases.
1294  transaction = std::make_shared<Transaction>(*transaction);
1295  transaction->setResult(terSUBMITTED);
1296  break;
1297 
1298  case wait:
1299  mCond.wait(
1300  lock, [&transaction] { return !transaction->getApplying(); });
1301  break;
1302 
1303  default:
1304  assert(false);
1305  }
1306 }
1307 
1308 bool
1310 {
1311  {
1314  return false;
1315 
1316  do
1317  apply(lock);
1318  while (drain && mTransactions.size());
1319  }
1321  return true;
1322 }
1323 
1324 void
1326 {
1327  assert(!mTransactions.empty());
1329  std::vector<TransactionStatus> submit_held;
1330  std::vector<TransactionStatus> transactions;
1331  mTransactions.swap(transactions);
1333 
1334  batchLock.unlock();
1335 
1336  {
1337  std::unique_lock masterLock{app_.getMasterMutex(), std::defer_lock};
1338  bool changed = false;
1339  {
1340  std::unique_lock ledgerLock{
1341  m_ledgerMaster.peekMutex(), std::defer_lock};
1342  std::lock(masterLock, ledgerLock);
1343 
1344  app_.openLedger().modify([&](OpenView& view, beast::Journal j) {
1345  for (TransactionStatus& e : transactions)
1346  {
1347  // we check before adding to the batch
1348  ApplyFlags flags = tapNONE;
1349  if (e.admin)
1350  flags |= tapUNLIMITED;
1351 
1352  if (e.failType == FailHard::yes)
1353  flags |= tapFAIL_HARD;
1354 
1355  auto const result = app_.getTxQ().apply(
1356  app_, view, e.transaction->getSTransaction(), flags, j);
1357  e.result = result.first;
1358  e.applied = result.second;
1359  changed = changed || result.second;
1360  }
1361  return changed;
1362  });
1363  }
1364  if (changed)
1365  reportFeeChange();
1366 
1367  std::optional<LedgerIndex> validatedLedgerIndex;
1368  if (auto const l = m_ledgerMaster.getValidatedLedger())
1369  validatedLedgerIndex = l->info().seq;
1370 
1371  auto newOL = app_.openLedger().current();
1372  for (TransactionStatus& e : transactions)
1373  {
1374  e.transaction->clearSubmitResult();
1375 
1376  if (e.applied)
1377  {
1379  newOL, e.transaction->getSTransaction(), e.result);
1380  e.transaction->setApplied();
1381  }
1382 
1383  e.transaction->setResult(e.result);
1384 
1385  if (isTemMalformed(e.result))
1386  app_.getHashRouter().setFlags(e.transaction->getID(), SF_BAD);
1387 
1388 #ifdef DEBUG
1389  if (e.result != tesSUCCESS)
1390  {
1391  std::string token, human;
1392 
1393  if (transResultInfo(e.result, token, human))
1394  {
1395  JLOG(m_journal.info())
1396  << "TransactionResult: " << token << ": " << human;
1397  }
1398  }
1399 #endif
1400 
1401  bool addLocal = e.local;
1402 
1403  if (e.result == tesSUCCESS)
1404  {
1405  JLOG(m_journal.debug())
1406  << "Transaction is now included in open ledger";
1407  e.transaction->setStatus(INCLUDED);
1408 
1409  auto const& txCur = e.transaction->getSTransaction();
1410  auto const txNext = m_ledgerMaster.popAcctTransaction(txCur);
1411  if (txNext)
1412  {
1413  std::string reason;
1414  auto const trans = sterilize(*txNext);
1415  auto t = std::make_shared<Transaction>(trans, reason, app_);
1416  submit_held.emplace_back(t, false, false, FailHard::no);
1417  t->setApplying();
1418  }
1419  }
1420  else if (e.result == tefPAST_SEQ)
1421  {
1422  // duplicate or conflict
1423  JLOG(m_journal.info()) << "Transaction is obsolete";
1424  e.transaction->setStatus(OBSOLETE);
1425  }
1426  else if (e.result == terQUEUED)
1427  {
1428  JLOG(m_journal.debug())
1429  << "Transaction is likely to claim a"
1430  << " fee, but is queued until fee drops";
1431 
1432  e.transaction->setStatus(HELD);
1433  // Add to held transactions, because it could get
1434  // kicked out of the queue, and this will try to
1435  // put it back.
1436  m_ledgerMaster.addHeldTransaction(e.transaction);
1437  e.transaction->setQueued();
1438  e.transaction->setKept();
1439  }
1440  else if (isTerRetry(e.result))
1441  {
1442  if (e.failType != FailHard::yes)
1443  {
1444  // transaction should be held
1445  JLOG(m_journal.debug())
1446  << "Transaction should be held: " << e.result;
1447  e.transaction->setStatus(HELD);
1448  m_ledgerMaster.addHeldTransaction(e.transaction);
1449  e.transaction->setKept();
1450  }
1451  }
1452  else
1453  {
1454  JLOG(m_journal.debug())
1455  << "Status other than success " << e.result;
1456  e.transaction->setStatus(INVALID);
1457  }
1458 
1459  auto const enforceFailHard =
1460  e.failType == FailHard::yes && !isTesSuccess(e.result);
1461 
1462  if (addLocal && !enforceFailHard)
1463  {
1464  m_localTX->push_back(
1466  e.transaction->getSTransaction());
1467  e.transaction->setKept();
1468  }
1469 
1470  if ((e.applied ||
1471  ((mMode != OperatingMode::FULL) &&
1472  (e.failType != FailHard::yes) && e.local) ||
1473  (e.result == terQUEUED)) &&
1474  !enforceFailHard)
1475  {
1476  auto const toSkip =
1477  app_.getHashRouter().shouldRelay(e.transaction->getID());
1478 
1479  if (toSkip)
1480  {
1481  protocol::TMTransaction tx;
1482  Serializer s;
1483 
1484  e.transaction->getSTransaction()->add(s);
1485  tx.set_rawtransaction(s.data(), s.size());
1486  tx.set_status(protocol::tsCURRENT);
1487  tx.set_receivetimestamp(
1488  app_.timeKeeper().now().time_since_epoch().count());
1489  tx.set_deferred(e.result == terQUEUED);
1490  // FIXME: This should be when we received it
1491  app_.overlay().relay(e.transaction->getID(), tx, *toSkip);
1492  e.transaction->setBroadcast();
1493  }
1494  }
1495 
1496  if (validatedLedgerIndex)
1497  {
1498  auto [fee, accountSeq, availableSeq] =
1500  *newOL, e.transaction->getSTransaction());
1501  e.transaction->setCurrentLedgerState(
1502  *validatedLedgerIndex, fee, accountSeq, availableSeq);
1503  }
1504  }
1505  }
1506 
1507  batchLock.lock();
1508 
1509  for (TransactionStatus& e : transactions)
1510  e.transaction->clearApplying();
1511 
1512  if (!submit_held.empty())
1513  {
1514  if (mTransactions.empty())
1515  mTransactions.swap(submit_held);
1516  else
1517  for (auto& e : submit_held)
1518  mTransactions.push_back(std::move(e));
1519  }
1520 
1521  mCond.notify_all();
1522 
1524 }
1525 
1526 //
1527 // Owner functions
1528 //
1529 
1533  AccountID const& account)
1534 {
1535  Json::Value jvObjects(Json::objectValue);
1536  auto root = keylet::ownerDir(account);
1537  auto sleNode = lpLedger->read(keylet::page(root));
1538  if (sleNode)
1539  {
1540  std::uint64_t uNodeDir;
1541 
1542  do
1543  {
1544  for (auto const& uDirEntry : sleNode->getFieldV256(sfIndexes))
1545  {
1546  auto sleCur = lpLedger->read(keylet::child(uDirEntry));
1547  assert(sleCur);
1548 
1549  switch (sleCur->getType())
1550  {
1551  case ltOFFER:
1552  if (!jvObjects.isMember(jss::offers))
1553  jvObjects[jss::offers] =
1555 
1556  jvObjects[jss::offers].append(
1557  sleCur->getJson(JsonOptions::none));
1558  break;
1559 
1560  case ltRIPPLE_STATE:
1561  if (!jvObjects.isMember(jss::ripple_lines))
1562  {
1563  jvObjects[jss::ripple_lines] =
1565  }
1566 
1567  jvObjects[jss::ripple_lines].append(
1568  sleCur->getJson(JsonOptions::none));
1569  break;
1570 
1571  case ltACCOUNT_ROOT:
1572  case ltDIR_NODE:
1573  default:
1574  assert(false);
1575  break;
1576  }
1577  }
1578 
1579  uNodeDir = sleNode->getFieldU64(sfIndexNext);
1580 
1581  if (uNodeDir)
1582  {
1583  sleNode = lpLedger->read(keylet::page(root, uNodeDir));
1584  assert(sleNode);
1585  }
1586  } while (uNodeDir);
1587  }
1588 
1589  return jvObjects;
1590 }
1591 
1592 //
1593 // Other
1594 //
1595 
1596 inline bool
1598 {
1599  return isAmendmentBlocked() || isUNLBlocked();
1600 }
1601 
1602 inline bool
1604 {
1605  return amendmentBlocked_;
1606 }
1607 
1608 void
1610 {
1611  amendmentBlocked_ = true;
1613 }
1614 
1615 inline bool
1617 {
1619 }
1620 
1621 inline void
1623 {
1624  amendmentWarned_ = true;
1625 }
1626 
1627 inline void
1629 {
1630  amendmentWarned_ = false;
1631 }
1632 
1633 inline bool
1635 {
1636  return unlBlocked_;
1637 }
1638 
1639 void
1641 {
1642  unlBlocked_ = true;
1644 }
1645 
1646 inline void
1648 {
1649  unlBlocked_ = false;
1650 }
1651 
1652 bool
1654  const Overlay::PeerSequence& peerList,
1655  uint256& networkClosed)
1656 {
1657  // Returns true if there's an *abnormal* ledger issue, normal changing in
1658  // TRACKING mode should return false. Do we have sufficient validations for
1659  // our last closed ledger? Or do sufficient nodes agree? And do we have no
1660  // better ledger available? If so, we are either tracking or full.
1661 
1662  JLOG(m_journal.trace()) << "NetworkOPsImp::checkLastClosedLedger";
1663 
1664  auto const ourClosed = m_ledgerMaster.getClosedLedger();
1665 
1666  if (!ourClosed)
1667  return false;
1668 
1669  uint256 closedLedger = ourClosed->info().hash;
1670  uint256 prevClosedLedger = ourClosed->info().parentHash;
1671  JLOG(m_journal.trace()) << "OurClosed: " << closedLedger;
1672  JLOG(m_journal.trace()) << "PrevClosed: " << prevClosedLedger;
1673 
1674  //-------------------------------------------------------------------------
1675  // Determine preferred last closed ledger
1676 
1677  auto& validations = app_.getValidations();
1678  JLOG(m_journal.debug())
1679  << "ValidationTrie " << Json::Compact(validations.getJsonTrie());
1680 
1681  // Will rely on peer LCL if no trusted validations exist
1683  peerCounts[closedLedger] = 0;
1685  peerCounts[closedLedger]++;
1686 
1687  for (auto& peer : peerList)
1688  {
1689  uint256 peerLedger = peer->getClosedLedgerHash();
1690 
1691  if (peerLedger.isNonZero())
1692  ++peerCounts[peerLedger];
1693  }
1694 
1695  for (auto const& it : peerCounts)
1696  JLOG(m_journal.debug()) << "L: " << it.first << " n=" << it.second;
1697 
1698  uint256 preferredLCL = validations.getPreferredLCL(
1699  RCLValidatedLedger{ourClosed, validations.adaptor().journal()},
1701  peerCounts);
1702 
1703  bool switchLedgers = preferredLCL != closedLedger;
1704  if (switchLedgers)
1705  closedLedger = preferredLCL;
1706  //-------------------------------------------------------------------------
1707  if (switchLedgers && (closedLedger == prevClosedLedger))
1708  {
1709  // don't switch to our own previous ledger
1710  JLOG(m_journal.info()) << "We won't switch to our own previous ledger";
1711  networkClosed = ourClosed->info().hash;
1712  switchLedgers = false;
1713  }
1714  else
1715  {
1716  networkClosed = closedLedger;
1717  }
1718 
1719  if (!switchLedgers)
1720  return false;
1721 
1722  auto consensus = m_ledgerMaster.getLedgerByHash(closedLedger);
1723 
1724  if (!consensus)
1725  consensus = app_.getInboundLedgers().acquire(
1726  closedLedger, 0, InboundLedger::Reason::CONSENSUS);
1727 
1728  if (consensus &&
1729  (!m_ledgerMaster.canBeCurrent(consensus) ||
1731  *consensus, m_journal.debug(), "Not switching")))
1732  {
1733  // Don't switch to a ledger not on the validated chain
1734  // or with an invalid close time or sequence
1735  networkClosed = ourClosed->info().hash;
1736  return false;
1737  }
1738 
1739  JLOG(m_journal.warn()) << "We are not running on the consensus ledger";
1740  JLOG(m_journal.info()) << "Our LCL: " << getJson({*ourClosed, {}});
1741  JLOG(m_journal.info()) << "Net LCL " << closedLedger;
1742 
1744  {
1746  }
1747 
1748  if (consensus)
1749  {
1750  // FIXME: If this rewinds the ledger sequence, or has the same
1751  // sequence, we should update the status on any stored transactions
1752  // in the invalidated ledgers.
1753  switchLastClosedLedger(consensus);
1754  }
1755 
1756  return true;
1757 }
1758 
1759 void
1761  std::shared_ptr<Ledger const> const& newLCL)
1762 {
1763  // set the newLCL as our last closed ledger -- this is abnormal code
1764  JLOG(m_journal.error())
1765  << "JUMP last closed ledger to " << newLCL->info().hash;
1766 
1768 
1769  // Update fee computations.
1770  app_.getTxQ().processClosedLedger(app_, *newLCL, true);
1771 
1772  // Caller must own master lock
1773  {
1774  // Apply tx in old open ledger to new
1775  // open ledger. Then apply local tx.
1776 
1777  auto retries = m_localTX->getTxSet();
1778  auto const lastVal = app_.getLedgerMaster().getValidatedLedger();
1779  std::optional<Rules> rules;
1780  if (lastVal)
1781  rules = makeRulesGivenLedger(*lastVal, app_.config().features);
1782  else
1783  rules.emplace(app_.config().features);
1785  app_,
1786  *rules,
1787  newLCL,
1788  OrderedTxs({}),
1789  false,
1790  retries,
1791  tapNONE,
1792  "jump",
1793  [&](OpenView& view, beast::Journal j) {
1794  // Stuff the ledger with transactions from the queue.
1795  return app_.getTxQ().accept(app_, view);
1796  });
1797  }
1798 
1799  m_ledgerMaster.switchLCL(newLCL);
1800 
1801  protocol::TMStatusChange s;
1802  s.set_newevent(protocol::neSWITCHED_LEDGER);
1803  s.set_ledgerseq(newLCL->info().seq);
1804  s.set_networktime(app_.timeKeeper().now().time_since_epoch().count());
1805  s.set_ledgerhashprevious(
1806  newLCL->info().parentHash.begin(), newLCL->info().parentHash.size());
1807  s.set_ledgerhash(newLCL->info().hash.begin(), newLCL->info().hash.size());
1808 
1809  app_.overlay().foreach(
1810  send_always(std::make_shared<Message>(s, protocol::mtSTATUS_CHANGE)));
1811 }
1812 
1813 bool
1815 {
1816  assert(networkClosed.isNonZero());
1817 
1818  auto closingInfo = m_ledgerMaster.getCurrentLedger()->info();
1819 
1820  JLOG(m_journal.info()) << "Consensus time for #" << closingInfo.seq
1821  << " with LCL " << closingInfo.parentHash;
1822 
1823  auto prevLedger = m_ledgerMaster.getLedgerByHash(closingInfo.parentHash);
1824 
1825  if (!prevLedger)
1826  {
1827  // this shouldn't happen unless we jump ledgers
1828  if (mMode == OperatingMode::FULL)
1829  {
1830  JLOG(m_journal.warn()) << "Don't have LCL, going to tracking";
1832  }
1833 
1834  return false;
1835  }
1836 
1837  assert(prevLedger->info().hash == closingInfo.parentHash);
1838  assert(
1839  closingInfo.parentHash ==
1840  m_ledgerMaster.getClosedLedger()->info().hash);
1841 
1842  if (prevLedger->rules().enabled(featureNegativeUNL))
1843  app_.validators().setNegativeUNL(prevLedger->negativeUNL());
1844  TrustChanges const changes = app_.validators().updateTrusted(
1846  closingInfo.parentCloseTime,
1847  *this,
1848  app_.overlay(),
1849  app_.getHashRouter());
1850 
1851  if (!changes.added.empty() || !changes.removed.empty())
1852  app_.getValidations().trustChanged(changes.added, changes.removed);
1853 
1856  networkClosed,
1857  prevLedger,
1858  changes.removed,
1859  changes.added);
1860 
1861  const ConsensusPhase currPhase = mConsensus.phase();
1862  if (mLastConsensusPhase != currPhase)
1863  {
1864  reportConsensusStateChange(currPhase);
1865  mLastConsensusPhase = currPhase;
1866  }
1867 
1868  JLOG(m_journal.debug()) << "Initiating consensus engine";
1869  return true;
1870 }
1871 
1872 bool
1874 {
1875  return mConsensus.peerProposal(app_.timeKeeper().closeTime(), peerPos);
1876 }
1877 
1878 void
1880 {
1881  // We now have an additional transaction set
1882  // either created locally during the consensus process
1883  // or acquired from a peer
1884 
1885  // Inform peers we have this set
1886  protocol::TMHaveTransactionSet msg;
1887  msg.set_hash(map->getHash().as_uint256().begin(), 256 / 8);
1888  msg.set_status(protocol::tsHAVE);
1889  app_.overlay().foreach(
1890  send_always(std::make_shared<Message>(msg, protocol::mtHAVE_SET)));
1891 
1892  // We acquired it because consensus asked us to
1893  if (fromAcquire)
1895 }
1896 
1897 void
1899 {
1900  uint256 deadLedger = m_ledgerMaster.getClosedLedger()->info().parentHash;
1901 
1902  for (auto const& it : app_.overlay().getActivePeers())
1903  {
1904  if (it && (it->getClosedLedgerHash() == deadLedger))
1905  {
1906  JLOG(m_journal.trace()) << "Killing obsolete peer status";
1907  it->cycleStatus();
1908  }
1909  }
1910 
1911  uint256 networkClosed;
1912  bool ledgerChange =
1913  checkLastClosedLedger(app_.overlay().getActivePeers(), networkClosed);
1914 
1915  if (networkClosed.isZero())
1916  return;
1917 
1918  // WRITEME: Unless we are in FULL and in the process of doing a consensus,
1919  // we must count how many nodes share our LCL, how many nodes disagree with
1920  // our LCL, and how many validations our LCL has. We also want to check
1921  // timing to make sure there shouldn't be a newer LCL. We need this
1922  // information to do the next three tests.
1923 
1924  if (((mMode == OperatingMode::CONNECTED) ||
1925  (mMode == OperatingMode::SYNCING)) &&
1926  !ledgerChange)
1927  {
1928  // Count number of peers that agree with us and UNL nodes whose
1929  // validations we have for LCL. If the ledger is good enough, go to
1930  // TRACKING - TODO
1931  if (!needNetworkLedger_)
1933  }
1934 
1935  if (((mMode == OperatingMode::CONNECTED) ||
1937  !ledgerChange)
1938  {
1939  // check if the ledger is good enough to go to FULL
1940  // Note: Do not go to FULL if we don't have the previous ledger
1941  // check if the ledger is bad enough to go to CONNECTE D -- TODO
1943  if (app_.timeKeeper().now() < (current->info().parentCloseTime +
1944  2 * current->info().closeTimeResolution))
1945  {
1947  }
1948  }
1949 
1950  beginConsensus(networkClosed);
1951 }
1952 
1953 void
1955 {
1957  {
1959  }
1960 }
1961 
1962 void
1964 {
1965  // VFALCO consider std::shared_mutex
1967 
1968  if (!mStreamMaps[sManifests].empty())
1969  {
1971 
1972  jvObj[jss::type] = "manifestReceived";
1973  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, mo.masterKey);
1974  if (!mo.signingKey.empty())
1975  jvObj[jss::signing_key] =
1977  jvObj[jss::seq] = Json::UInt(mo.sequence);
1978  if (auto sig = mo.getSignature())
1979  jvObj[jss::signature] = strHex(*sig);
1980  jvObj[jss::master_signature] = strHex(mo.getMasterSignature());
1981  if (!mo.domain.empty())
1982  jvObj[jss::domain] = mo.domain;
1983  jvObj[jss::manifest] = strHex(mo.serialized);
1984 
1985  for (auto i = mStreamMaps[sManifests].begin();
1986  i != mStreamMaps[sManifests].end();)
1987  {
1988  if (auto p = i->second.lock())
1989  {
1990  p->send(jvObj, true);
1991  ++i;
1992  }
1993  else
1994  {
1995  i = mStreamMaps[sManifests].erase(i);
1996  }
1997  }
1998  }
1999 }
2000 
2002  XRPAmount fee,
2003  TxQ::Metrics&& escalationMetrics,
2004  LoadFeeTrack const& loadFeeTrack)
2005  : loadFactorServer{loadFeeTrack.getLoadFactor()}
2006  , loadBaseServer{loadFeeTrack.getLoadBase()}
2007  , baseFee{fee}
2008  , em{std::move(escalationMetrics)}
2009 {
2010 }
2011 
2012 bool
2014  NetworkOPsImp::ServerFeeSummary const& b) const
2015 {
2016  if (loadFactorServer != b.loadFactorServer ||
2017  loadBaseServer != b.loadBaseServer || baseFee != b.baseFee ||
2018  em.has_value() != b.em.has_value())
2019  return true;
2020 
2021  if (em && b.em)
2022  {
2023  return (
2024  em->minProcessingFeeLevel != b.em->minProcessingFeeLevel ||
2025  em->openLedgerFeeLevel != b.em->openLedgerFeeLevel ||
2026  em->referenceFeeLevel != b.em->referenceFeeLevel);
2027  }
2028 
2029  return false;
2030 }
2031 
2032 // Need to cap to uint64 to uint32 due to JSON limitations
2033 static std::uint32_t
2035 {
2037 
2038  return std::min(max32, v);
2039 };
2040 
2041 void
2043 {
2044  // VFALCO TODO Don't hold the lock across calls to send...make a copy of the
2045  // list into a local array while holding the lock then release
2046  // the lock and call send on everyone.
2047  //
2049 
2050  if (!mStreamMaps[sServer].empty())
2051  {
2053 
2054  ServerFeeSummary f{
2055  app_.openLedger().current()->fees().base,
2057  app_.getFeeTrack()};
2058 
2059  jvObj[jss::type] = "serverStatus";
2060  jvObj[jss::server_status] = strOperatingMode();
2061  jvObj[jss::load_base] = f.loadBaseServer;
2062  jvObj[jss::load_factor_server] = f.loadFactorServer;
2063  jvObj[jss::base_fee] = f.baseFee.jsonClipped();
2064 
2065  if (f.em)
2066  {
2067  auto const loadFactor = std::max(
2068  safe_cast<std::uint64_t>(f.loadFactorServer),
2069  mulDiv(
2070  f.em->openLedgerFeeLevel,
2071  f.loadBaseServer,
2072  f.em->referenceFeeLevel)
2073  .value_or(ripple::muldiv_max));
2074 
2075  jvObj[jss::load_factor] = trunc32(loadFactor);
2076  jvObj[jss::load_factor_fee_escalation] =
2077  f.em->openLedgerFeeLevel.jsonClipped();
2078  jvObj[jss::load_factor_fee_queue] =
2079  f.em->minProcessingFeeLevel.jsonClipped();
2080  jvObj[jss::load_factor_fee_reference] =
2081  f.em->referenceFeeLevel.jsonClipped();
2082  }
2083  else
2084  jvObj[jss::load_factor] = f.loadFactorServer;
2085 
2086  mLastFeeSummary = f;
2087 
2088  for (auto i = mStreamMaps[sServer].begin();
2089  i != mStreamMaps[sServer].end();)
2090  {
2091  InfoSub::pointer p = i->second.lock();
2092 
2093  // VFALCO TODO research the possibility of using thread queues and
2094  // linearizing the deletion of subscribers with the
2095  // sending of JSON data.
2096  if (p)
2097  {
2098  p->send(jvObj, true);
2099  ++i;
2100  }
2101  else
2102  {
2103  i = mStreamMaps[sServer].erase(i);
2104  }
2105  }
2106  }
2107 }
2108 
2109 void
2111 {
2113 
2114  auto& streamMap = mStreamMaps[sConsensusPhase];
2115  if (!streamMap.empty())
2116  {
2118  jvObj[jss::type] = "consensusPhase";
2119  jvObj[jss::consensus] = to_string(phase);
2120 
2121  for (auto i = streamMap.begin(); i != streamMap.end();)
2122  {
2123  if (auto p = i->second.lock())
2124  {
2125  p->send(jvObj, true);
2126  ++i;
2127  }
2128  else
2129  {
2130  i = streamMap.erase(i);
2131  }
2132  }
2133  }
2134 }
2135 
2136 void
2138 {
2139  // VFALCO consider std::shared_mutex
2141 
2142  if (!mStreamMaps[sValidations].empty())
2143  {
2145 
2146  auto const signerPublic = val->getSignerPublic();
2147 
2148  jvObj[jss::type] = "validationReceived";
2149  jvObj[jss::validation_public_key] =
2150  toBase58(TokenType::NodePublic, signerPublic);
2151  jvObj[jss::ledger_hash] = to_string(val->getLedgerHash());
2152  jvObj[jss::signature] = strHex(val->getSignature());
2153  jvObj[jss::full] = val->isFull();
2154  jvObj[jss::flags] = val->getFlags();
2155  jvObj[jss::signing_time] = *(*val)[~sfSigningTime];
2156  jvObj[jss::data] = strHex(val->getSerializer().slice());
2157 
2158  if (auto version = (*val)[~sfServerVersion])
2159  jvObj[jss::server_version] = std::to_string(*version);
2160 
2161  if (auto cookie = (*val)[~sfCookie])
2162  jvObj[jss::cookie] = std::to_string(*cookie);
2163 
2164  if (auto hash = (*val)[~sfValidatedHash])
2165  jvObj[jss::validated_hash] = strHex(*hash);
2166 
2167  auto const masterKey =
2168  app_.validatorManifests().getMasterKey(signerPublic);
2169 
2170  if (masterKey != signerPublic)
2171  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, masterKey);
2172 
2173  if (auto const seq = (*val)[~sfLedgerSequence])
2174  jvObj[jss::ledger_index] = to_string(*seq);
2175 
2176  if (val->isFieldPresent(sfAmendments))
2177  {
2178  jvObj[jss::amendments] = Json::Value(Json::arrayValue);
2179  for (auto const& amendment : val->getFieldV256(sfAmendments))
2180  jvObj[jss::amendments].append(to_string(amendment));
2181  }
2182 
2183  if (auto const closeTime = (*val)[~sfCloseTime])
2184  jvObj[jss::close_time] = *closeTime;
2185 
2186  if (auto const loadFee = (*val)[~sfLoadFee])
2187  jvObj[jss::load_fee] = *loadFee;
2188 
2189  if (auto const baseFee = val->at(~sfBaseFee))
2190  jvObj[jss::base_fee] = static_cast<double>(*baseFee);
2191 
2192  if (auto const reserveBase = val->at(~sfReserveBase))
2193  jvObj[jss::reserve_base] = *reserveBase;
2194 
2195  if (auto const reserveInc = val->at(~sfReserveIncrement))
2196  jvObj[jss::reserve_inc] = *reserveInc;
2197 
2198  // (The ~ operator converts the Proxy to a std::optional, which
2199  // simplifies later operations)
2200  if (auto const baseFeeXRP = ~val->at(~sfBaseFeeDrops);
2201  baseFeeXRP && baseFeeXRP->native())
2202  jvObj[jss::base_fee] = baseFeeXRP->xrp().jsonClipped();
2203 
2204  if (auto const reserveBaseXRP = ~val->at(~sfReserveBaseDrops);
2205  reserveBaseXRP && reserveBaseXRP->native())
2206  jvObj[jss::reserve_base] = reserveBaseXRP->xrp().jsonClipped();
2207 
2208  if (auto const reserveIncXRP = ~val->at(~sfReserveIncrementDrops);
2209  reserveIncXRP && reserveIncXRP->native())
2210  jvObj[jss::reserve_inc] = reserveIncXRP->xrp().jsonClipped();
2211 
2212  for (auto i = mStreamMaps[sValidations].begin();
2213  i != mStreamMaps[sValidations].end();)
2214  {
2215  if (auto p = i->second.lock())
2216  {
2217  p->send(jvObj, true);
2218  ++i;
2219  }
2220  else
2221  {
2222  i = mStreamMaps[sValidations].erase(i);
2223  }
2224  }
2225  }
2226 }
2227 
2228 void
2230 {
2232 
2233  if (!mStreamMaps[sPeerStatus].empty())
2234  {
2235  Json::Value jvObj(func());
2236 
2237  jvObj[jss::type] = "peerStatusChange";
2238 
2239  for (auto i = mStreamMaps[sPeerStatus].begin();
2240  i != mStreamMaps[sPeerStatus].end();)
2241  {
2242  InfoSub::pointer p = i->second.lock();
2243 
2244  if (p)
2245  {
2246  p->send(jvObj, true);
2247  ++i;
2248  }
2249  else
2250  {
2251  i = mStreamMaps[sPeerStatus].erase(i);
2252  }
2253  }
2254  }
2255 }
2256 
2257 void
2259 {
2260  using namespace std::chrono_literals;
2261  if (om == OperatingMode::CONNECTED)
2262  {
2265  }
2266  else if (om == OperatingMode::SYNCING)
2267  {
2268  if (app_.getLedgerMaster().getValidatedLedgerAge() >= 1min)
2270  }
2271 
2272  if ((om > OperatingMode::CONNECTED) && isBlocked())
2274 
2275  if (mMode == om)
2276  return;
2277 
2278  mMode = om;
2279 
2280  accounting_.mode(om);
2281 
2282  JLOG(m_journal.info()) << "STATE->" << strOperatingMode();
2283  pubServer();
2284 }
2285 
2286 bool
2288  std::shared_ptr<STValidation> const& val,
2289  std::string const& source)
2290 {
2291  JLOG(m_journal.trace())
2292  << "recvValidation " << val->getLedgerHash() << " from " << source;
2293 
2294  handleNewValidation(app_, val, source);
2295 
2296  pubValidation(val);
2297 
2298  // We will always relay trusted validations; if configured, we will
2299  // also relay all untrusted validations.
2300  return app_.config().RELAY_UNTRUSTED_VALIDATIONS == 1 || val->isTrusted();
2301 }
2302 
2305 {
2306  return mConsensus.getJson(true);
2307 }
2308 
2310 NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
2311 {
2313 
2314  // System-level warnings
2315  {
2316  Json::Value warnings{Json::arrayValue};
2317  if (isAmendmentBlocked())
2318  {
2319  Json::Value& w = warnings.append(Json::objectValue);
2320  w[jss::id] = warnRPC_AMENDMENT_BLOCKED;
2321  w[jss::message] =
2322  "This server is amendment blocked, and must be updated to be "
2323  "able to stay in sync with the network.";
2324  }
2325  if (isUNLBlocked())
2326  {
2327  Json::Value& w = warnings.append(Json::objectValue);
2328  w[jss::id] = warnRPC_EXPIRED_VALIDATOR_LIST;
2329  w[jss::message] =
2330  "This server has an expired validator list. validators.txt "
2331  "may be incorrectly configured or some [validator_list_sites] "
2332  "may be unreachable.";
2333  }
2334  if (admin && isAmendmentWarned())
2335  {
2336  Json::Value& w = warnings.append(Json::objectValue);
2337  w[jss::id] = warnRPC_UNSUPPORTED_MAJORITY;
2338  w[jss::message] =
2339  "One or more unsupported amendments have reached majority. "
2340  "Upgrade to the latest version before they are activated "
2341  "to avoid being amendment blocked.";
2342  if (auto const expected =
2344  {
2345  auto& d = w[jss::details] = Json::objectValue;
2346  d[jss::expected_date] = expected->time_since_epoch().count();
2347  d[jss::expected_date_UTC] = to_string(*expected);
2348  }
2349  }
2350 
2351  if (warnings.size())
2352  info[jss::warnings] = std::move(warnings);
2353  }
2354 
2355  // hostid: unique string describing the machine
2356  if (human)
2357  info[jss::hostid] = getHostId(admin);
2358 
2359  // domain: if configured with a domain, report it:
2360  if (!app_.config().SERVER_DOMAIN.empty())
2361  info[jss::server_domain] = app_.config().SERVER_DOMAIN;
2362 
2363  info[jss::build_version] = BuildInfo::getVersionString();
2364 
2365  info[jss::server_state] = strOperatingMode(admin);
2366 
2367  info[jss::time] = to_string(std::chrono::floor<std::chrono::microseconds>(
2369 
2370  if (needNetworkLedger_)
2371  info[jss::network_ledger] = "waiting";
2372 
2373  info[jss::validation_quorum] =
2374  static_cast<Json::UInt>(app_.validators().quorum());
2375 
2376  if (admin)
2377  {
2378  switch (app_.config().NODE_SIZE)
2379  {
2380  case 0:
2381  info[jss::node_size] = "tiny";
2382  break;
2383  case 1:
2384  info[jss::node_size] = "small";
2385  break;
2386  case 2:
2387  info[jss::node_size] = "medium";
2388  break;
2389  case 3:
2390  info[jss::node_size] = "large";
2391  break;
2392  case 4:
2393  info[jss::node_size] = "huge";
2394  break;
2395  }
2396 
2397  auto when = app_.validators().expires();
2398 
2399  if (!human)
2400  {
2401  if (when)
2402  info[jss::validator_list_expires] =
2403  safe_cast<Json::UInt>(when->time_since_epoch().count());
2404  else
2405  info[jss::validator_list_expires] = 0;
2406  }
2407  else
2408  {
2409  auto& x = (info[jss::validator_list] = Json::objectValue);
2410 
2411  x[jss::count] = static_cast<Json::UInt>(app_.validators().count());
2412 
2413  if (when)
2414  {
2415  if (*when == TimeKeeper::time_point::max())
2416  {
2417  x[jss::expiration] = "never";
2418  x[jss::status] = "active";
2419  }
2420  else
2421  {
2422  x[jss::expiration] = to_string(*when);
2423 
2424  if (*when > app_.timeKeeper().now())
2425  x[jss::status] = "active";
2426  else
2427  x[jss::status] = "expired";
2428  }
2429  }
2430  else
2431  {
2432  x[jss::status] = "unknown";
2433  x[jss::expiration] = "unknown";
2434  }
2435  }
2436  }
2437  info[jss::io_latency_ms] =
2438  static_cast<Json::UInt>(app_.getIOLatency().count());
2439 
2440  if (admin)
2441  {
2443  {
2444  info[jss::pubkey_validator] = toBase58(
2446  }
2447  else
2448  {
2449  info[jss::pubkey_validator] = "none";
2450  }
2451  }
2452 
2453  if (counters)
2454  {
2455  info[jss::counters] = app_.getPerfLog().countersJson();
2456 
2457  Json::Value nodestore(Json::objectValue);
2458  if (app_.getShardStore())
2459  app_.getShardStore()->getCountsJson(nodestore);
2460  else
2461  app_.getNodeStore().getCountsJson(nodestore);
2462  info[jss::counters][jss::nodestore] = nodestore;
2463  info[jss::current_activities] = app_.getPerfLog().currentJson();
2464  }
2465 
2466  info[jss::pubkey_node] =
2468 
2469  info[jss::complete_ledgers] = app_.getLedgerMaster().getCompleteLedgers();
2470 
2471  if (amendmentBlocked_)
2472  info[jss::amendment_blocked] = true;
2473 
2474  auto const fp = m_ledgerMaster.getFetchPackCacheSize();
2475 
2476  if (fp != 0)
2477  info[jss::fetch_pack] = Json::UInt(fp);
2478 
2479  if (!app_.config().reporting())
2480  info[jss::peers] = Json::UInt(app_.overlay().size());
2481 
2482  Json::Value lastClose = Json::objectValue;
2483  lastClose[jss::proposers] = Json::UInt(mConsensus.prevProposers());
2484 
2485  if (human)
2486  {
2487  lastClose[jss::converge_time_s] =
2489  }
2490  else
2491  {
2492  lastClose[jss::converge_time] =
2494  }
2495 
2496  info[jss::last_close] = lastClose;
2497 
2498  // info[jss::consensus] = mConsensus.getJson();
2499 
2500  if (admin)
2501  info[jss::load] = m_job_queue.getJson();
2502 
2503  if (!app_.config().reporting())
2504  {
2505  if (auto const netid = app_.overlay().networkID())
2506  info[jss::network_id] = static_cast<Json::UInt>(*netid);
2507 
2508  auto const escalationMetrics =
2510 
2511  auto const loadFactorServer = app_.getFeeTrack().getLoadFactor();
2512  auto const loadBaseServer = app_.getFeeTrack().getLoadBase();
2513  /* Scale the escalated fee level to unitless "load factor".
2514  In practice, this just strips the units, but it will continue
2515  to work correctly if either base value ever changes. */
2516  auto const loadFactorFeeEscalation =
2517  mulDiv(
2518  escalationMetrics.openLedgerFeeLevel,
2519  loadBaseServer,
2520  escalationMetrics.referenceFeeLevel)
2521  .value_or(ripple::muldiv_max);
2522 
2523  auto const loadFactor = std::max(
2524  safe_cast<std::uint64_t>(loadFactorServer),
2525  loadFactorFeeEscalation);
2526 
2527  if (!human)
2528  {
2529  info[jss::load_base] = loadBaseServer;
2530  info[jss::load_factor] = trunc32(loadFactor);
2531  info[jss::load_factor_server] = loadFactorServer;
2532 
2533  /* Json::Value doesn't support uint64, so clamp to max
2534  uint32 value. This is mostly theoretical, since there
2535  probably isn't enough extant XRP to drive the factor
2536  that high.
2537  */
2538  info[jss::load_factor_fee_escalation] =
2539  escalationMetrics.openLedgerFeeLevel.jsonClipped();
2540  info[jss::load_factor_fee_queue] =
2541  escalationMetrics.minProcessingFeeLevel.jsonClipped();
2542  info[jss::load_factor_fee_reference] =
2543  escalationMetrics.referenceFeeLevel.jsonClipped();
2544  }
2545  else
2546  {
2547  info[jss::load_factor] =
2548  static_cast<double>(loadFactor) / loadBaseServer;
2549 
2550  if (loadFactorServer != loadFactor)
2551  info[jss::load_factor_server] =
2552  static_cast<double>(loadFactorServer) / loadBaseServer;
2553 
2554  if (admin)
2555  {
2557  if (fee != loadBaseServer)
2558  info[jss::load_factor_local] =
2559  static_cast<double>(fee) / loadBaseServer;
2560  fee = app_.getFeeTrack().getRemoteFee();
2561  if (fee != loadBaseServer)
2562  info[jss::load_factor_net] =
2563  static_cast<double>(fee) / loadBaseServer;
2564  fee = app_.getFeeTrack().getClusterFee();
2565  if (fee != loadBaseServer)
2566  info[jss::load_factor_cluster] =
2567  static_cast<double>(fee) / loadBaseServer;
2568  }
2569  if (escalationMetrics.openLedgerFeeLevel !=
2570  escalationMetrics.referenceFeeLevel &&
2571  (admin || loadFactorFeeEscalation != loadFactor))
2572  info[jss::load_factor_fee_escalation] =
2573  escalationMetrics.openLedgerFeeLevel.decimalFromReference(
2574  escalationMetrics.referenceFeeLevel);
2575  if (escalationMetrics.minProcessingFeeLevel !=
2576  escalationMetrics.referenceFeeLevel)
2577  info[jss::load_factor_fee_queue] =
2578  escalationMetrics.minProcessingFeeLevel
2579  .decimalFromReference(
2580  escalationMetrics.referenceFeeLevel);
2581  }
2582  }
2583 
2584  bool valid = false;
2585  auto lpClosed = m_ledgerMaster.getValidatedLedger();
2586 
2587  if (lpClosed)
2588  valid = true;
2589  else if (!app_.config().reporting())
2590  lpClosed = m_ledgerMaster.getClosedLedger();
2591 
2592  if (lpClosed)
2593  {
2594  XRPAmount const baseFee = lpClosed->fees().base;
2596  l[jss::seq] = Json::UInt(lpClosed->info().seq);
2597  l[jss::hash] = to_string(lpClosed->info().hash);
2598 
2599  if (!human)
2600  {
2601  l[jss::base_fee] = baseFee.jsonClipped();
2602  l[jss::reserve_base] =
2603  lpClosed->fees().accountReserve(0).jsonClipped();
2604  l[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
2605  l[jss::close_time] = Json::Value::UInt(
2606  lpClosed->info().closeTime.time_since_epoch().count());
2607  }
2608  else
2609  {
2610  l[jss::base_fee_xrp] = baseFee.decimalXRP();
2611  l[jss::reserve_base_xrp] =
2612  lpClosed->fees().accountReserve(0).decimalXRP();
2613  l[jss::reserve_inc_xrp] = lpClosed->fees().increment.decimalXRP();
2614 
2615  auto const nowOffset = app_.timeKeeper().nowOffset();
2616  if (std::abs(nowOffset.count()) >= 60)
2617  l[jss::system_time_offset] = nowOffset.count();
2618 
2619  auto const closeOffset = app_.timeKeeper().closeOffset();
2620  if (std::abs(closeOffset.count()) >= 60)
2621  l[jss::close_time_offset] = closeOffset.count();
2622 
2623 #if RIPPLED_REPORTING
2624  std::int64_t const dbAge =
2626  l[jss::age] = Json::UInt(dbAge);
2627 #else
2628  constexpr std::chrono::seconds highAgeThreshold{1000000};
2630  {
2631  auto const age = m_ledgerMaster.getValidatedLedgerAge();
2632  l[jss::age] =
2633  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2634  }
2635  else
2636  {
2637  auto lCloseTime = lpClosed->info().closeTime;
2638  auto closeTime = app_.timeKeeper().closeTime();
2639  if (lCloseTime <= closeTime)
2640  {
2641  using namespace std::chrono_literals;
2642  auto age = closeTime - lCloseTime;
2643  l[jss::age] =
2644  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2645  }
2646  }
2647 #endif
2648  }
2649 
2650  if (valid)
2651  info[jss::validated_ledger] = l;
2652  else
2653  info[jss::closed_ledger] = l;
2654 
2655  auto lpPublished = m_ledgerMaster.getPublishedLedger();
2656  if (!lpPublished)
2657  info[jss::published_ledger] = "none";
2658  else if (lpPublished->info().seq != lpClosed->info().seq)
2659  info[jss::published_ledger] = lpPublished->info().seq;
2660  }
2661 
2662  accounting_.json(info);
2663  info[jss::uptime] = UptimeClock::now().time_since_epoch().count();
2664  if (!app_.config().reporting())
2665  {
2666  info[jss::jq_trans_overflow] =
2668  info[jss::peer_disconnects] =
2670  info[jss::peer_disconnects_resources] =
2672  }
2673  else
2674  {
2675  info["reporting"] = app_.getReportingETL().getInfo();
2676  }
2677 
2678  // This array must be sorted in increasing order.
2679  static constexpr std::array<std::string_view, 7> protocols{
2680  "http", "https", "peer", "ws", "ws2", "wss", "wss2"};
2681  static_assert(std::is_sorted(std::begin(protocols), std::end(protocols)));
2682  {
2684  for (auto const& port : app_.getServerHandler().setup().ports)
2685  {
2686  // Don't publish admin ports for non-admin users
2687  if (!admin &&
2688  !(port.admin_nets_v4.empty() && port.admin_nets_v6.empty() &&
2689  port.admin_user.empty() && port.admin_password.empty()))
2690  continue;
2693  std::begin(port.protocol),
2694  std::end(port.protocol),
2695  std::begin(protocols),
2696  std::end(protocols),
2697  std::back_inserter(proto));
2698  if (!proto.empty())
2699  {
2700  auto& jv = ports.append(Json::Value(Json::objectValue));
2701  jv[jss::port] = std::to_string(port.port);
2702  jv[jss::protocol] = Json::Value{Json::arrayValue};
2703  for (auto const& p : proto)
2704  jv[jss::protocol].append(p);
2705  }
2706  }
2707 
2708  if (app_.config().exists("port_grpc"))
2709  {
2710  auto const& grpcSection = app_.config().section("port_grpc");
2711  auto const optPort = grpcSection.get("port");
2712  if (optPort && grpcSection.get("ip"))
2713  {
2714  auto& jv = ports.append(Json::Value(Json::objectValue));
2715  jv[jss::port] = *optPort;
2716  jv[jss::protocol] = Json::Value{Json::arrayValue};
2717  jv[jss::protocol].append("grpc");
2718  }
2719  }
2720  info[jss::ports] = std::move(ports);
2721  }
2722 
2723  return info;
2724 }
2725 
2726 void
2728 {
2730 }
2731 
2734 {
2735  return app_.getInboundLedgers().getInfo();
2736 }
2737 
2738 void
2740  std::shared_ptr<ReadView const> const& ledger,
2741  std::shared_ptr<STTx const> const& transaction,
2742  TER result)
2743 {
2744  Json::Value jvObj = transJson(*transaction, result, false, ledger);
2745 
2746  {
2748 
2749  auto it = mStreamMaps[sRTTransactions].begin();
2750  while (it != mStreamMaps[sRTTransactions].end())
2751  {
2752  InfoSub::pointer p = it->second.lock();
2753 
2754  if (p)
2755  {
2756  p->send(jvObj, true);
2757  ++it;
2758  }
2759  else
2760  {
2761  it = mStreamMaps[sRTTransactions].erase(it);
2762  }
2763  }
2764  }
2765 
2766  pubProposedAccountTransaction(ledger, transaction, result);
2767 }
2768 
2769 void
2771 {
2772  // reporting does not forward validated transactions
2773  // validated transactions will be published to the proper streams when the
2774  // etl process writes a validated ledger
2775  if (jvObj[jss::validated].asBool())
2776  return;
2777  {
2779 
2780  auto it = mStreamMaps[sRTTransactions].begin();
2781  while (it != mStreamMaps[sRTTransactions].end())
2782  {
2783  InfoSub::pointer p = it->second.lock();
2784 
2785  if (p)
2786  {
2787  p->send(jvObj, true);
2788  ++it;
2789  }
2790  else
2791  {
2792  it = mStreamMaps[sRTTransactions].erase(it);
2793  }
2794  }
2795  }
2796 
2798 }
2799 
2800 void
2802 {
2804 
2805  for (auto i = mStreamMaps[sValidations].begin();
2806  i != mStreamMaps[sValidations].end();)
2807  {
2808  if (auto p = i->second.lock())
2809  {
2810  p->send(jvObj, true);
2811  ++i;
2812  }
2813  else
2814  {
2815  i = mStreamMaps[sValidations].erase(i);
2816  }
2817  }
2818 }
2819 
2820 void
2822 {
2824 
2825  for (auto i = mStreamMaps[sManifests].begin();
2826  i != mStreamMaps[sManifests].end();)
2827  {
2828  if (auto p = i->second.lock())
2829  {
2830  p->send(jvObj, true);
2831  ++i;
2832  }
2833  else
2834  {
2835  i = mStreamMaps[sManifests].erase(i);
2836  }
2837  }
2838 }
2839 
2840 static void
2842 {
2843  for (auto& jv : jvObj)
2844  {
2845  if (jv.isObject())
2846  {
2847  getAccounts(jv, accounts);
2848  }
2849  else if (jv.isString())
2850  {
2851  auto account = RPC::accountFromStringStrict(jv.asString());
2852  if (account)
2853  accounts.push_back(*account);
2854  }
2855  }
2856 }
2857 
2858 void
2860 {
2862  int iProposed = 0;
2863  // check if there are any subscribers before attempting to parse the JSON
2864  {
2866 
2867  if (mSubRTAccount.empty())
2868  return;
2869  }
2870 
2871  // parse the JSON outside of the lock
2872  std::vector<AccountID> accounts;
2873  if (jvObj.isMember(jss::transaction))
2874  {
2875  try
2876  {
2877  getAccounts(jvObj[jss::transaction], accounts);
2878  }
2879  catch (...)
2880  {
2881  JLOG(m_journal.debug())
2882  << __func__ << " : "
2883  << "error parsing json for accounts affected";
2884  return;
2885  }
2886  }
2887  {
2889 
2890  if (!mSubRTAccount.empty())
2891  {
2892  for (auto const& affectedAccount : accounts)
2893  {
2894  auto simiIt = mSubRTAccount.find(affectedAccount);
2895  if (simiIt != mSubRTAccount.end())
2896  {
2897  auto it = simiIt->second.begin();
2898 
2899  while (it != simiIt->second.end())
2900  {
2901  InfoSub::pointer p = it->second.lock();
2902 
2903  if (p)
2904  {
2905  notify.insert(p);
2906  ++it;
2907  ++iProposed;
2908  }
2909  else
2910  it = simiIt->second.erase(it);
2911  }
2912  }
2913  }
2914  }
2915  }
2916  JLOG(m_journal.trace()) << "forwardProposedAccountTransaction:"
2917  << " iProposed=" << iProposed;
2918 
2919  if (!notify.empty())
2920  {
2921  for (InfoSub::ref isrListener : notify)
2922  isrListener->send(jvObj, true);
2923  }
2924 }
2925 
2926 void
2928 {
2929  // Ledgers are published only when they acquire sufficient validations
2930  // Holes are filled across connection loss or other catastrophe
2931 
2932  std::shared_ptr<AcceptedLedger> alpAccepted =
2933  app_.getAcceptedLedgerCache().fetch(lpAccepted->info().hash);
2934  if (!alpAccepted)
2935  {
2936  alpAccepted = std::make_shared<AcceptedLedger>(lpAccepted, app_);
2937  app_.getAcceptedLedgerCache().canonicalize_replace_client(
2938  lpAccepted->info().hash, alpAccepted);
2939  }
2940 
2941  assert(alpAccepted->getLedger().get() == lpAccepted.get());
2942 
2943  {
2944  JLOG(m_journal.debug())
2945  << "Publishing ledger " << lpAccepted->info().seq << " "
2946  << lpAccepted->info().hash;
2947 
2949 
2950  if (!mStreamMaps[sLedger].empty())
2951  {
2953 
2954  jvObj[jss::type] = "ledgerClosed";
2955  jvObj[jss::ledger_index] = lpAccepted->info().seq;
2956  jvObj[jss::ledger_hash] = to_string(lpAccepted->info().hash);
2957  jvObj[jss::ledger_time] = Json::Value::UInt(
2958  lpAccepted->info().closeTime.time_since_epoch().count());
2959 
2960  if (!lpAccepted->rules().enabled(featureXRPFees))
2961  jvObj[jss::fee_ref] = Config::FEE_UNITS_DEPRECATED;
2962  jvObj[jss::fee_base] = lpAccepted->fees().base.jsonClipped();
2963  jvObj[jss::reserve_base] =
2964  lpAccepted->fees().accountReserve(0).jsonClipped();
2965  jvObj[jss::reserve_inc] =
2966  lpAccepted->fees().increment.jsonClipped();
2967 
2968  jvObj[jss::txn_count] = Json::UInt(alpAccepted->size());
2969 
2971  {
2972  jvObj[jss::validated_ledgers] =
2974  }
2975 
2976  auto it = mStreamMaps[sLedger].begin();
2977  while (it != mStreamMaps[sLedger].end())
2978  {
2979  InfoSub::pointer p = it->second.lock();
2980  if (p)
2981  {
2982  p->send(jvObj, true);
2983  ++it;
2984  }
2985  else
2986  it = mStreamMaps[sLedger].erase(it);
2987  }
2988  }
2989 
2990  if (!mStreamMaps[sBookChanges].empty())
2991  {
2992  Json::Value jvObj = ripple::RPC::computeBookChanges(lpAccepted);
2993 
2994  auto it = mStreamMaps[sBookChanges].begin();
2995  while (it != mStreamMaps[sBookChanges].end())
2996  {
2997  InfoSub::pointer p = it->second.lock();
2998  if (p)
2999  {
3000  p->send(jvObj, true);
3001  ++it;
3002  }
3003  else
3004  it = mStreamMaps[sBookChanges].erase(it);
3005  }
3006  }
3007 
3008  {
3009  static bool firstTime = true;
3010  if (firstTime)
3011  {
3012  // First validated ledger, start delayed SubAccountHistory
3013  firstTime = false;
3014  for (auto& outer : mSubAccountHistory)
3015  {
3016  for (auto& inner : outer.second)
3017  {
3018  auto& subInfo = inner.second;
3019  if (subInfo.index_->separationLedgerSeq_ == 0)
3020  {
3022  alpAccepted->getLedger(), subInfo);
3023  }
3024  }
3025  }
3026  }
3027  }
3028  }
3029 
3030  // Don't lock since pubAcceptedTransaction is locking.
3031  for (auto const& accTx : *alpAccepted)
3032  {
3033  JLOG(m_journal.trace()) << "pubAccepted: " << accTx->getJson();
3034  pubValidatedTransaction(lpAccepted, *accTx);
3035  }
3036 }
3037 
3038 void
3040 {
3041  if (app_.config().reporting())
3042  return;
3043  ServerFeeSummary f{
3044  app_.openLedger().current()->fees().base,
3046  app_.getFeeTrack()};
3047 
3048  // only schedule the job if something has changed
3049  if (f != mLastFeeSummary)
3050  {
3052  jtCLIENT_FEE_CHANGE, "reportFeeChange->pubServer", [this]() {
3053  pubServer();
3054  });
3055  }
3056 }
3057 
3058 void
3060 {
3063  "reportConsensusStateChange->pubConsensus",
3064  [this, phase]() { pubConsensus(phase); });
3065 }
3066 
3067 inline void
3069 {
3070  m_localTX->sweep(view);
3071 }
3072 inline std::size_t
3074 {
3075  return m_localTX->size();
3076 }
3077 
3078 // This routine should only be used to publish accepted or validated
3079 // transactions.
3082  const STTx& transaction,
3083  TER result,
3084  bool validated,
3085  std::shared_ptr<ReadView const> const& ledger)
3086 {
3088  std::string sToken;
3089  std::string sHuman;
3090 
3091  transResultInfo(result, sToken, sHuman);
3092 
3093  jvObj[jss::type] = "transaction";
3094  jvObj[jss::transaction] = transaction.getJson(JsonOptions::none);
3095 
3096  if (validated)
3097  {
3098  jvObj[jss::ledger_index] = ledger->info().seq;
3099  jvObj[jss::ledger_hash] = to_string(ledger->info().hash);
3100  jvObj[jss::transaction][jss::date] =
3101  ledger->info().closeTime.time_since_epoch().count();
3102  jvObj[jss::validated] = true;
3103 
3104  // WRITEME: Put the account next seq here
3105  }
3106  else
3107  {
3108  jvObj[jss::validated] = false;
3109  jvObj[jss::ledger_current_index] = ledger->info().seq;
3110  }
3111 
3112  jvObj[jss::status] = validated ? "closed" : "proposed";
3113  jvObj[jss::engine_result] = sToken;
3114  jvObj[jss::engine_result_code] = result;
3115  jvObj[jss::engine_result_message] = sHuman;
3116 
3117  if (transaction.getTxnType() == ttOFFER_CREATE)
3118  {
3119  auto const account = transaction.getAccountID(sfAccount);
3120  auto const amount = transaction.getFieldAmount(sfTakerGets);
3121 
3122  // If the offer create is not self funded then add the owner balance
3123  if (account != amount.issue().account)
3124  {
3125  auto const ownerFunds = accountFunds(
3126  *ledger,
3127  account,
3128  amount,
3130  app_.journal("View"));
3131  jvObj[jss::transaction][jss::owner_funds] = ownerFunds.getText();
3132  }
3133  }
3134 
3135  return jvObj;
3136 }
3137 
3138 void
3140  std::shared_ptr<ReadView const> const& ledger,
3141  const AcceptedLedgerTx& transaction)
3142 {
3143  auto const& stTxn = transaction.getTxn();
3144 
3145  Json::Value jvObj =
3146  transJson(*stTxn, transaction.getResult(), true, ledger);
3147 
3148  {
3149  auto const& meta = transaction.getMeta();
3150  jvObj[jss::meta] = meta.getJson(JsonOptions::none);
3151  RPC::insertDeliveredAmount(jvObj[jss::meta], *ledger, stTxn, meta);
3152  }
3153 
3154  {
3156 
3157  auto it = mStreamMaps[sTransactions].begin();
3158  while (it != mStreamMaps[sTransactions].end())
3159  {
3160  InfoSub::pointer p = it->second.lock();
3161 
3162  if (p)
3163  {
3164  p->send(jvObj, true);
3165  ++it;
3166  }
3167  else
3168  it = mStreamMaps[sTransactions].erase(it);
3169  }
3170 
3171  it = mStreamMaps[sRTTransactions].begin();
3172 
3173  while (it != mStreamMaps[sRTTransactions].end())
3174  {
3175  InfoSub::pointer p = it->second.lock();
3176 
3177  if (p)
3178  {
3179  p->send(jvObj, true);
3180  ++it;
3181  }
3182  else
3183  it = mStreamMaps[sRTTransactions].erase(it);
3184  }
3185  }
3186 
3187  if (transaction.getResult() == tesSUCCESS)
3188  app_.getOrderBookDB().processTxn(ledger, transaction, jvObj);
3189 
3190  pubAccountTransaction(ledger, transaction);
3191 }
3192 
3193 void
3195  std::shared_ptr<ReadView const> const& ledger,
3196  AcceptedLedgerTx const& transaction)
3197 {
3199  int iProposed = 0;
3200  int iAccepted = 0;
3201 
3202  std::vector<SubAccountHistoryInfo> accountHistoryNotify;
3203  auto const currLedgerSeq = ledger->seq();
3204  {
3206 
3207  if (!mSubAccount.empty() || !mSubRTAccount.empty() ||
3209  {
3210  for (auto const& affectedAccount : transaction.getAffected())
3211  {
3212  if (auto simiIt = mSubRTAccount.find(affectedAccount);
3213  simiIt != mSubRTAccount.end())
3214  {
3215  auto it = simiIt->second.begin();
3216 
3217  while (it != simiIt->second.end())
3218  {
3219  InfoSub::pointer p = it->second.lock();
3220 
3221  if (p)
3222  {
3223  notify.insert(p);
3224  ++it;
3225  ++iProposed;
3226  }
3227  else
3228  it = simiIt->second.erase(it);
3229  }
3230  }
3231 
3232  if (auto simiIt = mSubAccount.find(affectedAccount);
3233  simiIt != mSubAccount.end())
3234  {
3235  auto it = simiIt->second.begin();
3236  while (it != simiIt->second.end())
3237  {
3238  InfoSub::pointer p = it->second.lock();
3239 
3240  if (p)
3241  {
3242  notify.insert(p);
3243  ++it;
3244  ++iAccepted;
3245  }
3246  else
3247  it = simiIt->second.erase(it);
3248  }
3249  }
3250 
3251  if (auto histoIt = mSubAccountHistory.find(affectedAccount);
3252  histoIt != mSubAccountHistory.end())
3253  {
3254  auto& subs = histoIt->second;
3255  auto it = subs.begin();
3256  while (it != subs.end())
3257  {
3258  SubAccountHistoryInfoWeak const& info = it->second;
3259  if (currLedgerSeq <= info.index_->separationLedgerSeq_)
3260  {
3261  ++it;
3262  continue;
3263  }
3264 
3265  if (auto isSptr = info.sinkWptr_.lock(); isSptr)
3266  {
3267  accountHistoryNotify.emplace_back(
3268  SubAccountHistoryInfo{isSptr, info.index_});
3269  ++it;
3270  }
3271  else
3272  {
3273  it = subs.erase(it);
3274  }
3275  }
3276  if (subs.empty())
3277  mSubAccountHistory.erase(histoIt);
3278  }
3279  }
3280  }
3281  }
3282 
3283  JLOG(m_journal.trace())
3284  << "pubAccountTransaction: "
3285  << "proposed=" << iProposed << ", accepted=" << iAccepted;
3286 
3287  if (!notify.empty() || !accountHistoryNotify.empty())
3288  {
3289  auto const& stTxn = transaction.getTxn();
3290 
3291  Json::Value jvObj =
3292  transJson(*stTxn, transaction.getResult(), true, ledger);
3293 
3294  {
3295  auto const& meta = transaction.getMeta();
3296 
3297  jvObj[jss::meta] = meta.getJson(JsonOptions::none);
3298  RPC::insertDeliveredAmount(jvObj[jss::meta], *ledger, stTxn, meta);
3299  }
3300 
3301  for (InfoSub::ref isrListener : notify)
3302  isrListener->send(jvObj, true);
3303 
3304  assert(!jvObj.isMember(jss::account_history_tx_stream));
3305  for (auto& info : accountHistoryNotify)
3306  {
3307  auto& index = info.index_;
3308  if (index->forwardTxIndex_ == 0 && !index->haveHistorical_)
3309  jvObj[jss::account_history_tx_first] = true;
3310  jvObj[jss::account_history_tx_index] = index->forwardTxIndex_++;
3311  info.sink_->send(jvObj, true);
3312  }
3313  }
3314 }
3315 
3316 void
3318  std::shared_ptr<ReadView const> const& ledger,
3319  std::shared_ptr<STTx const> const& tx,
3320  TER result)
3321 {
3323  int iProposed = 0;
3324 
3325  std::vector<SubAccountHistoryInfo> accountHistoryNotify;
3326 
3327  {
3329 
3330  if (mSubRTAccount.empty())
3331  return;
3332 
3333  if (!mSubAccount.empty() || !mSubRTAccount.empty() ||
3335  {
3336  for (auto const& affectedAccount : tx->getMentionedAccounts())
3337  {
3338  if (auto simiIt = mSubRTAccount.find(affectedAccount);
3339  simiIt != mSubRTAccount.end())
3340  {
3341  auto it = simiIt->second.begin();
3342 
3343  while (it != simiIt->second.end())
3344  {
3345  InfoSub::pointer p = it->second.lock();
3346 
3347  if (p)
3348  {
3349  notify.insert(p);
3350  ++it;
3351  ++iProposed;
3352  }
3353  else
3354  it = simiIt->second.erase(it);
3355  }
3356  }
3357  }
3358  }
3359  }
3360 
3361  JLOG(m_journal.trace()) << "pubProposedAccountTransaction: " << iProposed;
3362 
3363  if (!notify.empty() || !accountHistoryNotify.empty())
3364  {
3365  Json::Value jvObj = transJson(*tx, result, false, ledger);
3366 
3367  for (InfoSub::ref isrListener : notify)
3368  isrListener->send(jvObj, true);
3369 
3370  assert(!jvObj.isMember(jss::account_history_tx_stream));
3371  for (auto& info : accountHistoryNotify)
3372  {
3373  auto& index = info.index_;
3374  if (index->forwardTxIndex_ == 0 && !index->haveHistorical_)
3375  jvObj[jss::account_history_tx_first] = true;
3376  jvObj[jss::account_history_tx_index] = index->forwardTxIndex_++;
3377  info.sink_->send(jvObj, true);
3378  }
3379  }
3380 }
3381 
3382 //
3383 // Monitoring
3384 //
3385 
3386 void
3388  InfoSub::ref isrListener,
3389  hash_set<AccountID> const& vnaAccountIDs,
3390  bool rt)
3391 {
3392  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3393 
3394  for (auto const& naAccountID : vnaAccountIDs)
3395  {
3396  JLOG(m_journal.trace())
3397  << "subAccount: account: " << toBase58(naAccountID);
3398 
3399  isrListener->insertSubAccountInfo(naAccountID, rt);
3400  }
3401 
3403 
3404  for (auto const& naAccountID : vnaAccountIDs)
3405  {
3406  auto simIterator = subMap.find(naAccountID);
3407  if (simIterator == subMap.end())
3408  {
3409  // Not found, note that account has a new single listner.
3410  SubMapType usisElement;
3411  usisElement[isrListener->getSeq()] = isrListener;
3412  // VFALCO NOTE This is making a needless copy of naAccountID
3413  subMap.insert(simIterator, make_pair(naAccountID, usisElement));
3414  }
3415  else
3416  {
3417  // Found, note that the account has another listener.
3418  simIterator->second[isrListener->getSeq()] = isrListener;
3419  }
3420  }
3421 }
3422 
3423 void
3425  InfoSub::ref isrListener,
3426  hash_set<AccountID> const& vnaAccountIDs,
3427  bool rt)
3428 {
3429  for (auto const& naAccountID : vnaAccountIDs)
3430  {
3431  // Remove from the InfoSub
3432  isrListener->deleteSubAccountInfo(naAccountID, rt);
3433  }
3434 
3435  // Remove from the server
3436  unsubAccountInternal(isrListener->getSeq(), vnaAccountIDs, rt);
3437 }
3438 
3439 void
3441  std::uint64_t uSeq,
3442  hash_set<AccountID> const& vnaAccountIDs,
3443  bool rt)
3444 {
3446 
3447  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3448 
3449  for (auto const& naAccountID : vnaAccountIDs)
3450  {
3451  auto simIterator = subMap.find(naAccountID);
3452 
3453  if (simIterator != subMap.end())
3454  {
3455  // Found
3456  simIterator->second.erase(uSeq);
3457 
3458  if (simIterator->second.empty())
3459  {
3460  // Don't need hash entry.
3461  subMap.erase(simIterator);
3462  }
3463  }
3464  }
3465 }
3466 
3467 void
3469 {
3470  enum DatabaseType { Postgres, Sqlite, None };
3471  static const auto databaseType = [&]() -> DatabaseType {
3472 #ifdef RIPPLED_REPORTING
3473  if (app_.config().reporting())
3474  {
3475  // Use a dynamic_cast to return DatabaseType::None
3476  // on failure.
3477  if (dynamic_cast<PostgresDatabase*>(&app_.getRelationalDatabase()))
3478  {
3479  return DatabaseType::Postgres;
3480  }
3481  return DatabaseType::None;
3482  }
3483  else
3484  {
3485  // Use a dynamic_cast to return DatabaseType::None
3486  // on failure.
3487  if (dynamic_cast<SQLiteDatabase*>(&app_.getRelationalDatabase()))
3488  {
3489  return DatabaseType::Sqlite;
3490  }
3491  return DatabaseType::None;
3492  }
3493 #else
3494  // Use a dynamic_cast to return DatabaseType::None
3495  // on failure.
3496  if (dynamic_cast<SQLiteDatabase*>(&app_.getRelationalDatabase()))
3497  {
3498  return DatabaseType::Sqlite;
3499  }
3500  return DatabaseType::None;
3501 #endif
3502  }();
3503 
3504  if (databaseType == DatabaseType::None)
3505  {
3506  JLOG(m_journal.error())
3507  << "AccountHistory job for account "
3508  << toBase58(subInfo.index_->accountId_) << " no database";
3509  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3510  {
3511  sptr->send(rpcError(rpcINTERNAL), true);
3512  unsubAccountHistory(sptr, subInfo.index_->accountId_, false);
3513  }
3514  return;
3515  }
3516 
3519  "AccountHistoryTxStream",
3520  [this, dbType = databaseType, subInfo]() {
3521  auto const& accountId = subInfo.index_->accountId_;
3522  auto& lastLedgerSeq = subInfo.index_->historyLastLedgerSeq_;
3523  auto& txHistoryIndex = subInfo.index_->historyTxIndex_;
3524 
3525  JLOG(m_journal.trace())
3526  << "AccountHistory job for account " << toBase58(accountId)
3527  << " started. lastLedgerSeq=" << lastLedgerSeq;
3528 
3529  auto isFirstTx = [&](std::shared_ptr<Transaction> const& tx,
3530  std::shared_ptr<TxMeta> const& meta) -> bool {
3531  /*
3532  * genesis account: first tx is the one with seq 1
3533  * other account: first tx is the one created the account
3534  */
3535  if (accountId == genesisAccountId)
3536  {
3537  auto stx = tx->getSTransaction();
3538  if (stx->getAccountID(sfAccount) == accountId &&
3539  stx->getSeqProxy().value() == 1)
3540  return true;
3541  }
3542 
3543  for (auto& node : meta->getNodes())
3544  {
3545  if (node.getFieldU16(sfLedgerEntryType) != ltACCOUNT_ROOT)
3546  continue;
3547 
3548  if (node.isFieldPresent(sfNewFields))
3549  {
3550  if (auto inner = dynamic_cast<const STObject*>(
3551  node.peekAtPField(sfNewFields));
3552  inner)
3553  {
3554  if (inner->isFieldPresent(sfAccount) &&
3555  inner->getAccountID(sfAccount) == accountId)
3556  {
3557  return true;
3558  }
3559  }
3560  }
3561  }
3562 
3563  return false;
3564  };
3565 
3566  auto send = [&](Json::Value const& jvObj,
3567  bool unsubscribe) -> bool {
3568  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3569  {
3570  sptr->send(jvObj, true);
3571  if (unsubscribe)
3572  unsubAccountHistory(sptr, accountId, false);
3573  return true;
3574  }
3575 
3576  return false;
3577  };
3578 
3579  auto getMoreTxns =
3580  [&](std::uint32_t minLedger,
3581  std::uint32_t maxLedger,
3586  switch (dbType)
3587  {
3588  case Postgres: {
3589  auto db = static_cast<PostgresDatabase*>(
3592  args.account = accountId;
3593  LedgerRange range{minLedger, maxLedger};
3594  args.ledger = range;
3595  args.marker = marker;
3596  auto [txResult, status] = db->getAccountTx(args);
3597  if (status != rpcSUCCESS)
3598  {
3599  JLOG(m_journal.debug())
3600  << "AccountHistory job for account "
3601  << toBase58(accountId)
3602  << " getAccountTx failed";
3603  return {};
3604  }
3605 
3606  if (auto txns =
3607  std::get_if<RelationalDatabase::AccountTxs>(
3608  &txResult.transactions);
3609  txns)
3610  {
3611  return std::make_pair(*txns, txResult.marker);
3612  }
3613  else
3614  {
3615  JLOG(m_journal.debug())
3616  << "AccountHistory job for account "
3617  << toBase58(accountId)
3618  << " getAccountTx wrong data";
3619  return {};
3620  }
3621  }
3622  case Sqlite: {
3623  auto db = static_cast<SQLiteDatabase*>(
3626  accountId, minLedger, maxLedger, marker, 0, true};
3627  return db->newestAccountTxPage(options);
3628  }
3629  default: {
3630  assert(false);
3631  return {};
3632  }
3633  }
3634  };
3635 
3636  /*
3637  * search backward until the genesis ledger or asked to stop
3638  */
3639  while (lastLedgerSeq >= 2 && !subInfo.index_->stopHistorical_)
3640  {
3641  int feeChargeCount = 0;
3642  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3643  {
3644  sptr->getConsumer().charge(Resource::feeMediumBurdenRPC);
3645  ++feeChargeCount;
3646  }
3647  else
3648  {
3649  JLOG(m_journal.trace())
3650  << "AccountHistory job for account "
3651  << toBase58(accountId) << " no InfoSub. Fee charged "
3652  << feeChargeCount << " times.";
3653  return;
3654  }
3655 
3656  // try to search in 1024 ledgers till reaching genesis ledgers
3657  auto startLedgerSeq =
3658  (lastLedgerSeq > 1024 + 2 ? lastLedgerSeq - 1024 : 2);
3659  JLOG(m_journal.trace())
3660  << "AccountHistory job for account " << toBase58(accountId)
3661  << ", working on ledger range [" << startLedgerSeq << ","
3662  << lastLedgerSeq << "]";
3663 
3664  auto haveRange = [&]() -> bool {
3665  std::uint32_t validatedMin = UINT_MAX;
3666  std::uint32_t validatedMax = 0;
3667  auto haveSomeValidatedLedgers =
3669  validatedMin, validatedMax);
3670 
3671  return haveSomeValidatedLedgers &&
3672  validatedMin <= startLedgerSeq &&
3673  lastLedgerSeq <= validatedMax;
3674  }();
3675 
3676  if (!haveRange)
3677  {
3678  JLOG(m_journal.debug())
3679  << "AccountHistory reschedule job for account "
3680  << toBase58(accountId) << ", incomplete ledger range ["
3681  << startLedgerSeq << "," << lastLedgerSeq << "]";
3682  setAccountHistoryJobTimer(subInfo);
3683  return;
3684  }
3685 
3687  while (!subInfo.index_->stopHistorical_)
3688  {
3689  auto dbResult =
3690  getMoreTxns(startLedgerSeq, lastLedgerSeq, marker);
3691  if (!dbResult)
3692  {
3693  JLOG(m_journal.debug())
3694  << "AccountHistory job for account "
3695  << toBase58(accountId) << " getMoreTxns failed.";
3696  send(rpcError(rpcINTERNAL), true);
3697  return;
3698  }
3699 
3700  auto const& txns = dbResult->first;
3701  marker = dbResult->second;
3702  for (auto const& [tx, meta] : txns)
3703  {
3704  if (!tx || !meta)
3705  {
3706  JLOG(m_journal.debug())
3707  << "AccountHistory job for account "
3708  << toBase58(accountId) << " empty tx or meta.";
3709  send(rpcError(rpcINTERNAL), true);
3710  return;
3711  }
3712  auto curTxLedger =
3714  tx->getLedger());
3715  if (!curTxLedger)
3716  {
3717  JLOG(m_journal.debug())
3718  << "AccountHistory job for account "
3719  << toBase58(accountId) << " no ledger.";
3720  send(rpcError(rpcINTERNAL), true);
3721  return;
3722  }
3724  tx->getSTransaction();
3725  if (!stTxn)
3726  {
3727  JLOG(m_journal.debug())
3728  << "AccountHistory job for account "
3729  << toBase58(accountId)
3730  << " getSTransaction failed.";
3731  send(rpcError(rpcINTERNAL), true);
3732  return;
3733  }
3734  Json::Value jvTx = transJson(
3735  *stTxn, meta->getResultTER(), true, curTxLedger);
3736  jvTx[jss::meta] = meta->getJson(JsonOptions::none);
3737  jvTx[jss::account_history_tx_index] = txHistoryIndex--;
3739  jvTx[jss::meta], *curTxLedger, stTxn, *meta);
3740  if (isFirstTx(tx, meta))
3741  {
3742  jvTx[jss::account_history_tx_first] = true;
3743  send(jvTx, false);
3744 
3745  JLOG(m_journal.trace())
3746  << "AccountHistory job for account "
3747  << toBase58(accountId)
3748  << " done, found last tx.";
3749  return;
3750  }
3751  else
3752  {
3753  send(jvTx, false);
3754  }
3755  }
3756 
3757  if (marker)
3758  {
3759  JLOG(m_journal.trace())
3760  << "AccountHistory job for account "
3761  << toBase58(accountId)
3762  << " paging, marker=" << marker->ledgerSeq << ":"
3763  << marker->txnSeq;
3764  }
3765  else
3766  {
3767  break;
3768  }
3769  }
3770 
3771  if (!subInfo.index_->stopHistorical_)
3772  {
3773  lastLedgerSeq = startLedgerSeq - 1;
3774  if (lastLedgerSeq <= 1)
3775  {
3776  JLOG(m_journal.trace())
3777  << "AccountHistory job for account "
3778  << toBase58(accountId)
3779  << " done, reached genesis ledger.";
3780  return;
3781  }
3782  }
3783  }
3784  });
3785 }
3786 
3787 void
3789  std::shared_ptr<ReadView const> const& ledger,
3790  SubAccountHistoryInfoWeak& subInfo)
3791 {
3792  subInfo.index_->separationLedgerSeq_ = ledger->seq();
3793  auto const& accountId = subInfo.index_->accountId_;
3794  auto const accountKeylet = keylet::account(accountId);
3795  if (!ledger->exists(accountKeylet))
3796  {
3797  JLOG(m_journal.debug())
3798  << "subAccountHistoryStart, no account " << toBase58(accountId)
3799  << ", no need to add AccountHistory job.";
3800  return;
3801  }
3802  if (accountId == genesisAccountId)
3803  {
3804  if (auto const sleAcct = ledger->read(accountKeylet); sleAcct)
3805  {
3806  if (sleAcct->getFieldU32(sfSequence) == 1)
3807  {
3808  JLOG(m_journal.debug())
3809  << "subAccountHistoryStart, genesis account "
3810  << toBase58(accountId)
3811  << " does not have tx, no need to add AccountHistory job.";
3812  return;
3813  }
3814  }
3815  else
3816  {
3817  assert(false);
3818  return;
3819  }
3820  }
3821  subInfo.index_->historyLastLedgerSeq_ = ledger->seq();
3822  subInfo.index_->haveHistorical_ = true;
3823 
3824  JLOG(m_journal.debug())
3825  << "subAccountHistoryStart, add AccountHistory job: accountId="
3826  << toBase58(accountId) << ", currentLedgerSeq=" << ledger->seq();
3827 
3828  addAccountHistoryJob(subInfo);
3829 }
3830 
3833  InfoSub::ref isrListener,
3834  AccountID const& accountId)
3835 {
3836  if (!isrListener->insertSubAccountHistory(accountId))
3837  {
3838  JLOG(m_journal.debug())
3839  << "subAccountHistory, already subscribed to account "
3840  << toBase58(accountId);
3841  return rpcINVALID_PARAMS;
3842  }
3843 
3846  isrListener, std::make_shared<SubAccountHistoryIndex>(accountId)};
3847  auto simIterator = mSubAccountHistory.find(accountId);
3848  if (simIterator == mSubAccountHistory.end())
3849  {
3851  inner.emplace(isrListener->getSeq(), ahi);
3853  simIterator, std::make_pair(accountId, inner));
3854  }
3855  else
3856  {
3857  simIterator->second.emplace(isrListener->getSeq(), ahi);
3858  }
3859 
3860  auto const ledger = app_.getLedgerMaster().getValidatedLedger();
3861  if (ledger)
3862  {
3863  subAccountHistoryStart(ledger, ahi);
3864  }
3865  else
3866  {
3867  // The node does not have validated ledgers, so wait for
3868  // one before start streaming.
3869  // In this case, the subscription is also considered successful.
3870  JLOG(m_journal.debug())
3871  << "subAccountHistory, no validated ledger yet, delay start";
3872  }
3873 
3874  return rpcSUCCESS;
3875 }
3876 
3877 void
3879  InfoSub::ref isrListener,
3880  AccountID const& account,
3881  bool historyOnly)
3882 {
3883  if (!historyOnly)
3884  isrListener->deleteSubAccountHistory(account);
3885  unsubAccountHistoryInternal(isrListener->getSeq(), account, historyOnly);
3886 }
3887 
3888 void
3890  std::uint64_t seq,
3891  const AccountID& account,
3892  bool historyOnly)
3893 {
3895  auto simIterator = mSubAccountHistory.find(account);
3896  if (simIterator != mSubAccountHistory.end())
3897  {
3898  auto& subInfoMap = simIterator->second;
3899  auto subInfoIter = subInfoMap.find(seq);
3900  if (subInfoIter != subInfoMap.end())
3901  {
3902  subInfoIter->second.index_->stopHistorical_ = true;
3903  }
3904 
3905  if (!historyOnly)
3906  {
3907  simIterator->second.erase(seq);
3908  if (simIterator->second.empty())
3909  {
3910  mSubAccountHistory.erase(simIterator);
3911  }
3912  }
3913  JLOG(m_journal.debug())
3914  << "unsubAccountHistory, account " << toBase58(account)
3915  << ", historyOnly = " << (historyOnly ? "true" : "false");
3916  }
3917 }
3918 
3919 bool
3920 NetworkOPsImp::subBook(InfoSub::ref isrListener, Book const& book)
3921 {
3922  if (auto listeners = app_.getOrderBookDB().makeBookListeners(book))
3923  listeners->addSubscriber(isrListener);
3924  else
3925  assert(false);
3926  return true;
3927 }
3928 
3929 bool
3931 {
3932  if (auto listeners = app_.getOrderBookDB().getBookListeners(book))
3933  listeners->removeSubscriber(uSeq);
3934 
3935  return true;
3936 }
3937 
3941 {
3942  // This code-path is exclusively used when the server is in standalone
3943  // mode via `ledger_accept`
3944  assert(m_standalone);
3945 
3946  if (!m_standalone)
3947  Throw<std::runtime_error>(
3948  "Operation only possible in STANDALONE mode.");
3949 
3950  // FIXME Could we improve on this and remove the need for a specialized
3951  // API in Consensus?
3953  mConsensus.simulate(app_.timeKeeper().closeTime(), consensusDelay);
3954  return m_ledgerMaster.getCurrentLedger()->info().seq;
3955 }
3956 
3957 // <-- bool: true=added, false=already there
3958 bool
3960 {
3961  if (auto lpClosed = m_ledgerMaster.getValidatedLedger())
3962  {
3963  jvResult[jss::ledger_index] = lpClosed->info().seq;
3964  jvResult[jss::ledger_hash] = to_string(lpClosed->info().hash);
3965  jvResult[jss::ledger_time] = Json::Value::UInt(
3966  lpClosed->info().closeTime.time_since_epoch().count());
3967  if (!lpClosed->rules().enabled(featureXRPFees))
3968  jvResult[jss::fee_ref] = Config::FEE_UNITS_DEPRECATED;
3969  jvResult[jss::fee_base] = lpClosed->fees().base.jsonClipped();
3970  jvResult[jss::reserve_base] =
3971  lpClosed->fees().accountReserve(0).jsonClipped();
3972  jvResult[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
3973  }
3974 
3976  {
3977  jvResult[jss::validated_ledgers] =
3979  }
3980 
3982  return mStreamMaps[sLedger]
3983  .emplace(isrListener->getSeq(), isrListener)
3984  .second;
3985 }
3986 
3987 // <-- bool: true=added, false=already there
3988 bool
3990 {
3992  return mStreamMaps[sBookChanges]
3993  .emplace(isrListener->getSeq(), isrListener)
3994  .second;
3995 }
3996 
3997 // <-- bool: true=erased, false=was not there
3998 bool
4000 {
4002  return mStreamMaps[sLedger].erase(uSeq);
4003 }
4004 
4005 // <-- bool: true=erased, false=was not there
4006 bool
4008 {
4010  return mStreamMaps[sBookChanges].erase(uSeq);
4011 }
4012 
4013 // <-- bool: true=added, false=already there
4014 bool
4016 {
4018  return mStreamMaps[sManifests]
4019  .emplace(isrListener->getSeq(), isrListener)
4020  .second;
4021 }
4022 
4023 // <-- bool: true=erased, false=was not there
4024 bool
4026 {
4028  return mStreamMaps[sManifests].erase(uSeq);
4029 }
4030 
4031 // <-- bool: true=added, false=already there
4032 bool
4034  InfoSub::ref isrListener,
4035  Json::Value& jvResult,
4036  bool admin)
4037 {
4038  uint256 uRandom;
4039 
4040  if (m_standalone)
4041  jvResult[jss::stand_alone] = m_standalone;
4042 
4043  // CHECKME: is it necessary to provide a random number here?
4044  beast::rngfill(uRandom.begin(), uRandom.size(), crypto_prng());
4045 
4046  auto const& feeTrack = app_.getFeeTrack();
4047  jvResult[jss::random] = to_string(uRandom);
4048  jvResult[jss::server_status] = strOperatingMode(admin);
4049  jvResult[jss::load_base] = feeTrack.getLoadBase();
4050  jvResult[jss::load_factor] = feeTrack.getLoadFactor();
4051  jvResult[jss::hostid] = getHostId(admin);
4052  jvResult[jss::pubkey_node] =
4054 
4056  return mStreamMaps[sServer]
4057  .emplace(isrListener->getSeq(), isrListener)
4058  .second;
4059 }
4060 
4061 // <-- bool: true=erased, false=was not there
4062 bool
4064 {
4066  return mStreamMaps[sServer].erase(uSeq);
4067 }
4068 
4069 // <-- bool: true=added, false=already there
4070 bool
4072 {
4074  return mStreamMaps[sTransactions]
4075  .emplace(isrListener->getSeq(), isrListener)
4076  .second;
4077 }
4078 
4079 // <-- bool: true=erased, false=was not there
4080 bool
4082 {
4084  return mStreamMaps[sTransactions].erase(uSeq);
4085 }
4086 
4087 // <-- bool: true=added, false=already there
4088 bool
4090 {
4093  .emplace(isrListener->getSeq(), isrListener)
4094  .second;
4095 }
4096 
4097 // <-- bool: true=erased, false=was not there
4098 bool
4100 {
4102  return mStreamMaps[sRTTransactions].erase(uSeq);
4103 }
4104 
4105 // <-- bool: true=added, false=already there
4106 bool
4108 {
4110  return mStreamMaps[sValidations]
4111  .emplace(isrListener->getSeq(), isrListener)
4112  .second;
4113 }
4114 
4115 void
4117 {
4118  accounting_.json(obj);
4119 }
4120 
4121 // <-- bool: true=erased, false=was not there
4122 bool
4124 {
4126  return mStreamMaps[sValidations].erase(uSeq);
4127 }
4128 
4129 // <-- bool: true=added, false=already there
4130 bool
4132 {
4134  return mStreamMaps[sPeerStatus]
4135  .emplace(isrListener->getSeq(), isrListener)
4136  .second;
4137 }
4138 
4139 // <-- bool: true=erased, false=was not there
4140 bool
4142 {
4144  return mStreamMaps[sPeerStatus].erase(uSeq);
4145 }
4146 
4147 // <-- bool: true=added, false=already there
4148 bool
4150 {
4153  .emplace(isrListener->getSeq(), isrListener)
4154  .second;
4155 }
4156 
4157 // <-- bool: true=erased, false=was not there
4158 bool
4160 {
4162  return mStreamMaps[sConsensusPhase].erase(uSeq);
4163 }
4164 
4167 {
4169 
4170  subRpcMapType::iterator it = mRpcSubMap.find(strUrl);
4171 
4172  if (it != mRpcSubMap.end())
4173  return it->second;
4174 
4175  return InfoSub::pointer();
4176 }
4177 
4180 {
4182 
4183  mRpcSubMap.emplace(strUrl, rspEntry);
4184 
4185  return rspEntry;
4186 }
4187 
4188 bool
4190 {
4192  auto pInfo = findRpcSub(strUrl);
4193 
4194  if (!pInfo)
4195  return false;
4196 
4197  // check to see if any of the stream maps still hold a weak reference to
4198  // this entry before removing
4199  for (SubMapType const& map : mStreamMaps)
4200  {
4201  if (map.find(pInfo->getSeq()) != map.end())
4202  return false;
4203  }
4204  mRpcSubMap.erase(strUrl);
4205  return true;
4206 }
4207 
4208 #ifndef USE_NEW_BOOK_PAGE
4209 
4210 // NIKB FIXME this should be looked at. There's no reason why this shouldn't
4211 // work, but it demonstrated poor performance.
4212 //
4213 void
4216  Book const& book,
4217  AccountID const& uTakerID,
4218  bool const bProof,
4219  unsigned int iLimit,
4220  Json::Value const& jvMarker,
4221  Json::Value& jvResult)
4222 { // CAUTION: This is the old get book page logic
4223  Json::Value& jvOffers =
4224  (jvResult[jss::offers] = Json::Value(Json::arrayValue));
4225 
4227  const uint256 uBookBase = getBookBase(book);
4228  const uint256 uBookEnd = getQualityNext(uBookBase);
4229  uint256 uTipIndex = uBookBase;
4230 
4231  if (auto stream = m_journal.trace())
4232  {
4233  stream << "getBookPage:" << book;
4234  stream << "getBookPage: uBookBase=" << uBookBase;
4235  stream << "getBookPage: uBookEnd=" << uBookEnd;
4236  stream << "getBookPage: uTipIndex=" << uTipIndex;
4237  }
4238 
4239  ReadView const& view = *lpLedger;
4240 
4241  bool const bGlobalFreeze = isGlobalFrozen(view, book.out.account) ||
4242  isGlobalFrozen(view, book.in.account);
4243 
4244  bool bDone = false;
4245  bool bDirectAdvance = true;
4246 
4247  std::shared_ptr<SLE const> sleOfferDir;
4248  uint256 offerIndex;
4249  unsigned int uBookEntry;
4250  STAmount saDirRate;
4251 
4252  auto const rate = transferRate(view, book.out.account);
4253  auto viewJ = app_.journal("View");
4254 
4255  while (!bDone && iLimit-- > 0)
4256  {
4257  if (bDirectAdvance)
4258  {
4259  bDirectAdvance = false;
4260 
4261  JLOG(m_journal.trace()) << "getBookPage: bDirectAdvance";
4262 
4263  auto const ledgerIndex = view.succ(uTipIndex, uBookEnd);
4264  if (ledgerIndex)
4265  sleOfferDir = view.read(keylet::page(*ledgerIndex));
4266  else
4267  sleOfferDir.reset();
4268 
4269  if (!sleOfferDir)
4270  {
4271  JLOG(m_journal.trace()) << "getBookPage: bDone";
4272  bDone = true;
4273  }
4274  else
4275  {
4276  uTipIndex = sleOfferDir->key();
4277  saDirRate = amountFromQuality(getQuality(uTipIndex));
4278 
4279  cdirFirst(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex);
4280 
4281  JLOG(m_journal.trace())
4282  << "getBookPage: uTipIndex=" << uTipIndex;
4283  JLOG(m_journal.trace())
4284  << "getBookPage: offerIndex=" << offerIndex;
4285  }
4286  }
4287 
4288  if (!bDone)
4289  {
4290  auto sleOffer = view.read(keylet::offer(offerIndex));
4291 
4292  if (sleOffer)
4293  {
4294  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
4295  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
4296  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
4297  STAmount saOwnerFunds;
4298  bool firstOwnerOffer(true);
4299 
4300  if (book.out.account == uOfferOwnerID)
4301  {
4302  // If an offer is selling issuer's own IOUs, it is fully
4303  // funded.
4304  saOwnerFunds = saTakerGets;
4305  }
4306  else if (bGlobalFreeze)
4307  {
4308  // If either asset is globally frozen, consider all offers
4309  // that aren't ours to be totally unfunded
4310  saOwnerFunds.clear(book.out);
4311  }
4312  else
4313  {
4314  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
4315  if (umBalanceEntry != umBalance.end())
4316  {
4317  // Found in running balance table.
4318 
4319  saOwnerFunds = umBalanceEntry->second;
4320  firstOwnerOffer = false;
4321  }
4322  else
4323  {
4324  // Did not find balance in table.
4325 
4326  saOwnerFunds = accountHolds(
4327  view,
4328  uOfferOwnerID,
4329  book.out.currency,
4330  book.out.account,
4332  viewJ);
4333 
4334  if (saOwnerFunds < beast::zero)
4335  {
4336  // Treat negative funds as zero.
4337 
4338  saOwnerFunds.clear();
4339  }
4340  }
4341  }
4342 
4343  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
4344 
4345  STAmount saTakerGetsFunded;
4346  STAmount saOwnerFundsLimit = saOwnerFunds;
4347  Rate offerRate = parityRate;
4348 
4349  if (rate != parityRate
4350  // Have a tranfer fee.
4351  && uTakerID != book.out.account
4352  // Not taking offers of own IOUs.
4353  && book.out.account != uOfferOwnerID)
4354  // Offer owner not issuing ownfunds
4355  {
4356  // Need to charge a transfer fee to offer owner.
4357  offerRate = rate;
4358  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
4359  }
4360 
4361  if (saOwnerFundsLimit >= saTakerGets)
4362  {
4363  // Sufficient funds no shenanigans.
4364  saTakerGetsFunded = saTakerGets;
4365  }
4366  else
4367  {
4368  // Only provide, if not fully funded.
4369 
4370  saTakerGetsFunded = saOwnerFundsLimit;
4371 
4372  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
4373  std::min(
4374  saTakerPays,
4375  multiply(
4376  saTakerGetsFunded, saDirRate, saTakerPays.issue()))
4377  .setJson(jvOffer[jss::taker_pays_funded]);
4378  }
4379 
4380  STAmount saOwnerPays = (parityRate == offerRate)
4381  ? saTakerGetsFunded
4382  : std::min(
4383  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
4384 
4385  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
4386 
4387  // Include all offers funded and unfunded
4388  Json::Value& jvOf = jvOffers.append(jvOffer);
4389  jvOf[jss::quality] = saDirRate.getText();
4390 
4391  if (firstOwnerOffer)
4392  jvOf[jss::owner_funds] = saOwnerFunds.getText();
4393  }
4394  else
4395  {
4396  JLOG(m_journal.warn()) << "Missing offer";
4397  }
4398 
4399  if (!cdirNext(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex))
4400  {
4401  bDirectAdvance = true;
4402  }
4403  else
4404  {
4405  JLOG(m_journal.trace())
4406  << "getBookPage: offerIndex=" << offerIndex;
4407  }
4408  }
4409  }
4410 
4411  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
4412  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
4413 }
4414 
4415 #else
4416 
4417 // This is the new code that uses the book iterators
4418 // It has temporarily been disabled
4419 
4420 void
4423  Book const& book,
4424  AccountID const& uTakerID,
4425  bool const bProof,
4426  unsigned int iLimit,
4427  Json::Value const& jvMarker,
4428  Json::Value& jvResult)
4429 {
4430  auto& jvOffers = (jvResult[jss::offers] = Json::Value(Json::arrayValue));
4431 
4433 
4434  MetaView lesActive(lpLedger, tapNONE, true);
4435  OrderBookIterator obIterator(lesActive, book);
4436 
4437  auto const rate = transferRate(lesActive, book.out.account);
4438 
4439  const bool bGlobalFreeze = lesActive.isGlobalFrozen(book.out.account) ||
4440  lesActive.isGlobalFrozen(book.in.account);
4441 
4442  while (iLimit-- > 0 && obIterator.nextOffer())
4443  {
4444  SLE::pointer sleOffer = obIterator.getCurrentOffer();
4445  if (sleOffer)
4446  {
4447  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
4448  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
4449  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
4450  STAmount saDirRate = obIterator.getCurrentRate();
4451  STAmount saOwnerFunds;
4452 
4453  if (book.out.account == uOfferOwnerID)
4454  {
4455  // If offer is selling issuer's own IOUs, it is fully funded.
4456  saOwnerFunds = saTakerGets;
4457  }
4458  else if (bGlobalFreeze)
4459  {
4460  // If either asset is globally frozen, consider all offers
4461  // that aren't ours to be totally unfunded
4462  saOwnerFunds.clear(book.out);
4463  }
4464  else
4465  {
4466  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
4467 
4468  if (umBalanceEntry != umBalance.end())
4469  {
4470  // Found in running balance table.
4471 
4472  saOwnerFunds = umBalanceEntry->second;
4473  }
4474  else
4475  {
4476  // Did not find balance in table.
4477 
4478  saOwnerFunds = lesActive.accountHolds(
4479  uOfferOwnerID,
4480  book.out.currency,
4481  book.out.account,
4483 
4484  if (saOwnerFunds.isNegative())
4485  {
4486  // Treat negative funds as zero.
4487 
4488  saOwnerFunds.zero();
4489  }
4490  }
4491  }
4492 
4493  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
4494 
4495  STAmount saTakerGetsFunded;
4496  STAmount saOwnerFundsLimit = saOwnerFunds;
4497  Rate offerRate = parityRate;
4498 
4499  if (rate != parityRate
4500  // Have a tranfer fee.
4501  && uTakerID != book.out.account
4502  // Not taking offers of own IOUs.
4503  && book.out.account != uOfferOwnerID)
4504  // Offer owner not issuing ownfunds
4505  {
4506  // Need to charge a transfer fee to offer owner.
4507  offerRate = rate;
4508  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
4509  }
4510 
4511  if (saOwnerFundsLimit >= saTakerGets)
4512  {
4513  // Sufficient funds no shenanigans.
4514  saTakerGetsFunded = saTakerGets;
4515  }
4516  else
4517  {
4518  // Only provide, if not fully funded.
4519  saTakerGetsFunded = saOwnerFundsLimit;
4520 
4521  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
4522 
4523  // TOOD(tom): The result of this expression is not used - what's
4524  // going on here?
4525  std::min(
4526  saTakerPays,
4527  multiply(saTakerGetsFunded, saDirRate, saTakerPays.issue()))
4528  .setJson(jvOffer[jss::taker_pays_funded]);
4529  }
4530 
4531  STAmount saOwnerPays = (parityRate == offerRate)
4532  ? saTakerGetsFunded
4533  : std::min(
4534  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
4535 
4536  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
4537 
4538  if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID)
4539  {
4540  // Only provide funded offers and offers of the taker.
4541  Json::Value& jvOf = jvOffers.append(jvOffer);
4542  jvOf[jss::quality] = saDirRate.getText();
4543  }
4544  }
4545  }
4546 
4547  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
4548  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
4549 }
4550 
4551 #endif
4552 
4553 inline void
4555 {
4556  auto [counters, mode, start, initialSync] = accounting_.getCounterData();
4557  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
4558  std::chrono::steady_clock::now() - start);
4559  counters[static_cast<std::size_t>(mode)].dur += current;
4560 
4563  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
4564  .dur.count());
4566  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
4567  .dur.count());
4569  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].dur.count());
4571  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
4572  .dur.count());
4574  counters[static_cast<std::size_t>(OperatingMode::FULL)].dur.count());
4575 
4577  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
4578  .transitions);
4580  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
4581  .transitions);
4583  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].transitions);
4585  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
4586  .transitions);
4588  counters[static_cast<std::size_t>(OperatingMode::FULL)].transitions);
4589 }
4590 
4591 void
4593 {
4594  auto now = std::chrono::steady_clock::now();
4595 
4596  std::lock_guard lock(mutex_);
4597  ++counters_[static_cast<std::size_t>(om)].transitions;
4598  if (om == OperatingMode::FULL &&
4599  counters_[static_cast<std::size_t>(om)].transitions == 1)
4600  {
4601  initialSyncUs_ = std::chrono::duration_cast<std::chrono::microseconds>(
4602  now - processStart_)
4603  .count();
4604  }
4605  counters_[static_cast<std::size_t>(mode_)].dur +=
4606  std::chrono::duration_cast<std::chrono::microseconds>(now - start_);
4607 
4608  mode_ = om;
4609  start_ = now;
4610 }
4611 
4612 void
4614 {
4615  auto [counters, mode, start, initialSync] = getCounterData();
4616  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
4617  std::chrono::steady_clock::now() - start);
4618  counters[static_cast<std::size_t>(mode)].dur += current;
4619 
4620  obj[jss::state_accounting] = Json::objectValue;
4621  for (std::size_t i = static_cast<std::size_t>(OperatingMode::DISCONNECTED);
4622  i <= static_cast<std::size_t>(OperatingMode::FULL);
4623  ++i)
4624  {
4625  obj[jss::state_accounting][states_[i]] = Json::objectValue;
4626  auto& state = obj[jss::state_accounting][states_[i]];
4627  state[jss::transitions] = std::to_string(counters[i].transitions);
4628  state[jss::duration_us] = std::to_string(counters[i].dur.count());
4629  }
4630  obj[jss::server_state_duration_us] = std::to_string(current.count());
4631  if (initialSync)
4632  obj[jss::initial_sync_duration_us] = std::to_string(initialSync);
4633 }
4634 
4635 //------------------------------------------------------------------------------
4636 
4639  Application& app,
4640  NetworkOPs::clock_type& clock,
4641  bool standalone,
4642  std::size_t minPeerCount,
4643  bool startvalid,
4644  JobQueue& job_queue,
4645  LedgerMaster& ledgerMaster,
4646  ValidatorKeys const& validatorKeys,
4647  boost::asio::io_service& io_svc,
4648  beast::Journal journal,
4649  beast::insight::Collector::ptr const& collector)
4650 {
4651  return std::make_unique<NetworkOPsImp>(
4652  app,
4653  clock,
4654  standalone,
4655  minPeerCount,
4656  startvalid,
4657  job_queue,
4658  ledgerMaster,
4659  validatorKeys,
4660  io_svc,
4661  journal,
4662  collector);
4663 }
4664 
4665 } // namespace ripple
ripple::SQLiteDatabase
Definition: SQLiteDatabase.h:27
ripple::NetworkOPsImp::forwardManifest
void forwardManifest(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2821
ripple::NetworkOPsImp::unsubValidations
bool unsubValidations(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4123
ripple::NetworkOPsImp::Stats::hook
beast::insight::Hook hook
Definition: NetworkOPs.cpp:802
ripple::STTx::getTxnType
TxType getTxnType() const
Definition: STTx.h:179
ripple::NetworkOPsImp::subValidations
bool subValidations(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4107
ripple::NetworkOPsImp::processHeartbeatTimer
void processHeartbeatTimer()
Definition: NetworkOPs.cpp:1042
ripple::NetworkOPs
Provides server functionality for clients.
Definition: NetworkOPs.h:90
ripple::sfIndexNext
const SF_UINT64 sfIndexNext
ripple::NetworkOPsImp::SubAccountHistoryIndex::historyLastLedgerSeq_
std::uint32_t historyLastLedgerSeq_
Definition: NetworkOPs.cpp:652
ripple::LedgerMaster::getValidatedRange
bool getValidatedRange(std::uint32_t &minVal, std::uint32_t &maxVal)
Definition: LedgerMaster.cpp:635
ripple::RCLConsensus::phase
ConsensusPhase phase() const
Definition: RCLConsensus.h:596
ripple::keylet::ownerDir
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Definition: Indexes.cpp:304
ripple::NetworkOPsImp::mapComplete
void mapComplete(std::shared_ptr< SHAMap > const &map, bool fromAcquire) override
Definition: NetworkOPs.cpp:1879
ripple::NetworkOPsImp::setClusterTimer
void setClusterTimer()
Definition: NetworkOPs.cpp:977
ripple::Application
Definition: Application.h:116
ripple::transferRate
Rate transferRate(ReadView const &view, AccountID const &issuer)
Definition: View.cpp:488
ripple::TimeKeeper::nowOffset
virtual std::chrono::duration< std::int32_t > nowOffset() const =0
ripple::cdirNext
bool cdirNext(ReadView const &view, uint256 const &root, std::shared_ptr< SLE const > &page, unsigned int &index, uint256 &entry)
Returns the next entry in the directory, advancing the index.
Definition: View.cpp:145
ripple::ClusterNode
Definition: ClusterNode.h:30
ripple::NetworkOPsImp::SubTypes
SubTypes
Definition: NetworkOPs.cpp:730
ripple::NetworkOPsImp::unsubConsensus
bool unsubConsensus(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4159
ripple::jtTRANSACTION
@ jtTRANSACTION
Definition: Job.h:63
ripple::Manifest::domain
std::string domain
The domain, if one was specified in the manifest; empty otherwise.
Definition: Manifest.h:95
ripple::RPC::SubmitSync::async
@ async
ripple::Application::getOrderBookDB
virtual OrderBookDB & getOrderBookDB()=0
ripple::RCLConsensus::setTimerDelay
void setTimerDelay(std::optional< std::chrono::milliseconds > td=std::nullopt)
Definition: RCLConsensus.h:657
ripple::NetworkOPsImp::SubAccountHistoryIndex::haveHistorical_
bool haveHistorical_
Definition: NetworkOPs.cpp:654
ripple::RCLCxPeerPos
A peer's signed, proposed position for use in RCLConsensus.
Definition: RCLCxPeerPos.h:44
ripple::HashPrefix::ledgerMaster
@ ledgerMaster
ledger master data for signing
ripple::NetworkOPsImp::processTrustedProposal
bool processTrustedProposal(RCLCxPeerPos proposal) override
Definition: NetworkOPs.cpp:1873
std::lock
T lock(T... args)
ripple::NetworkOPsImp::setAccountHistoryJobTimer
void setAccountHistoryJobTimer(SubAccountHistoryInfoWeak subInfo)
Definition: NetworkOPs.cpp:993
ripple::NetworkOPsImp::pubAccountTransaction
void pubAccountTransaction(std::shared_ptr< ReadView const > const &ledger, AcceptedLedgerTx const &transaction)
Definition: NetworkOPs.cpp:3194
ripple::sfBaseFeeDrops
const SF_AMOUNT sfBaseFeeDrops
ripple::InboundLedgers::getInfo
virtual Json::Value getInfo()=0
ripple::NetworkOPsImp::stateAccounting
void stateAccounting(Json::Value &obj) override
Definition: NetworkOPs.cpp:4116
ripple::RPC::SubmitSync
SubmitSync
Possible values for defining synchronous behavior of the transaction submission API.
Definition: SubmitSync.h:36
ripple::LoadManager
Manages load sources.
Definition: LoadManager.h:45
ripple::sfReserveBase
const SF_UINT32 sfReserveBase
ripple::Application::cluster
virtual Cluster & cluster()=0
ripple::NetworkOPsImp::m_journal
beast::Journal m_journal
Definition: NetworkOPs.cpp:697
ripple::LedgerMaster::getPublishedLedger
std::shared_ptr< ReadView const > getPublishedLedger()
Definition: LedgerMaster.cpp:1699
ripple::mulDiv
std::optional< Dest > mulDiv(Source1 value, Dest mul, Source2 div)
Definition: FeeUnits.h:468
ripple::featureXRPFees
const uint256 featureXRPFees
ripple::NetworkOPsImp::sLastEntry
@ sLastEntry
Definition: NetworkOPs.cpp:741
ripple::Application::getAcceptedLedgerCache
virtual TaggedCache< uint256, AcceptedLedger > & getAcceptedLedgerCache()=0
ripple::OpenLedger::current
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
Definition: OpenLedger.cpp:50
ripple::NetworkOPsImp::TransactionStatus::applied
bool applied
Definition: NetworkOPs.cpp:95
ripple::NetworkOPsImp::mLastFeeSummary
ServerFeeSummary mLastFeeSummary
Definition: NetworkOPs.cpp:746
ripple::ValidatorList::localPublicKey
PublicKey localPublicKey() const
Returns local validator public key.
Definition: ValidatorList.cpp:1413
ripple::NetworkOPsImp::StateAccounting::processStart_
const std::chrono::steady_clock::time_point processStart_
Definition: NetworkOPs.cpp:149
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:711
ripple::ManifestCache::getMasterKey
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
Definition: app/misc/impl/Manifest.cpp:303
ripple::RCLConsensus::getJson
Json::Value getJson(bool full) const
Definition: RCLConsensus.cpp:924
ripple::NetworkOPsImp::minPeerCount_
const std::size_t minPeerCount_
Definition: NetworkOPs.cpp:754
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
ripple::rpcError
Json::Value rpcError(int iError)
Definition: RPCErr.cpp:29
ripple::fhZERO_IF_FROZEN
@ fhZERO_IF_FROZEN
Definition: View.h:79
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:906
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:537
ripple::RCLConsensus::startRound
void startRound(NetClock::time_point const &now, RCLCxLedger::ID const &prevLgrId, RCLCxLedger const &prevLgr, hash_set< NodeID > const &nowUntrusted, hash_set< NodeID > const &nowTrusted)
Adjust the set of trusted validators and kick-off the next round of consensus.
Definition: RCLConsensus.cpp:1084
ripple::NetworkOPsImp::StateAccounting::json
void json(Json::Value &obj) const
Output state counters in JSON format.
Definition: NetworkOPs.cpp:4613
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::STAmount::clear
void clear()
Definition: STAmount.h:409
ripple::sfLedgerSequence
const SF_UINT32 sfLedgerSequence
ripple::AcceptedLedgerTx::getTxn
std::shared_ptr< STTx const > const & getTxn() const
Definition: AcceptedLedgerTx.h:52
ripple::NetworkOPsImp::m_stats
Stats m_stats
Definition: NetworkOPs.cpp:817
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:347
ripple::Book::out
Issue out
Definition: Book.h:37
ripple::HashRouter::getFlags
int getFlags(uint256 const &key)
Definition: HashRouter.cpp:94
ripple::Resource::feeMediumBurdenRPC
const Charge feeMediumBurdenRPC
ripple::isTesSuccess
bool isTesSuccess(TER x)
Definition: TER.h:609
ripple::TrustChanges
Changes in trusted nodes after updating validator list.
Definition: ValidatorList.h:107
ripple::Resource::Gossip
Data format for exchanging consumption information across peers.
Definition: Gossip.h:29
ripple::NetworkOPsImp::setAmendmentWarned
void setAmendmentWarned() override
Definition: NetworkOPs.cpp:1622
ripple::NetworkOPsImp::pubManifest
void pubManifest(Manifest const &) override
Definition: NetworkOPs.cpp:1963
ripple::RelationalDatabase::AccountTxArgs
Definition: RelationalDatabase.h:96
ripple::Manifest
Definition: Manifest.h:80
ripple::NetworkOPsImp::collect_metrics
void collect_metrics()
Definition: NetworkOPs.cpp:4554
ripple::NetworkOPsImp::subPeerStatus
bool subPeerStatus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4131
std::unordered_set
STL class.
ripple::NetworkOPsImp::mDispatchState
DispatchState mDispatchState
Definition: NetworkOPs.cpp:759
ripple::NetworkOPsImp::DispatchState::none
@ none
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
ripple::NetworkOPs::FailHard::no
@ no
ripple::NetworkOPsImp::setBatchApplyTimer
void setBatchApplyTimer() override
Definition: NetworkOPs.cpp:1006
ripple::NetworkOPsImp::stop
void stop() override
Definition: NetworkOPs.cpp:537
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:714
ripple::Overlay::getJqTransOverflow
virtual std::uint64_t getJqTransOverflow() const =0
ripple::NetworkOPsImp::mSubRTAccount
SubInfoMapType mSubRTAccount
Definition: NetworkOPs.cpp:724
ripple::NetworkOPsImp::amendmentWarned_
std::atomic< bool > amendmentWarned_
Definition: NetworkOPs.cpp:707
ripple::NetworkOPsImp::states_
static const std::array< char const *, 5 > states_
Definition: NetworkOPs.cpp:118
ripple::sfSequence
const SF_UINT32 sfSequence
ripple::LedgerMaster
Definition: LedgerMaster.h:70
ripple::ConsensusMode::wrongLedger
@ wrongLedger
We have the wrong ledger and are attempting to acquire it.
ripple::LedgerMaster::getValidLedgerIndex
LedgerIndex getValidLedgerIndex()
Definition: LedgerMaster.cpp:213
ripple::Application::getAmendmentTable
virtual AmendmentTable & getAmendmentTable()=0
ripple::NetworkOPsImp::setMode
void setMode(OperatingMode om) override
Definition: NetworkOPs.cpp:2258
ripple::ClusterNode::name
std::string const & name() const
Definition: ClusterNode.h:45
ripple::OpenView
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:55
Json::UInt
unsigned int UInt
Definition: json_forwards.h:27
Json::Compact
Decorator for streaming out compact json.
Definition: json_writer.h:316
ripple::getBookBase
uint256 getBookBase(Book const &book)
Definition: Indexes.cpp:83
ripple::NetworkOPsImp::StateAccounting::Counters::dur
std::chrono::microseconds dur
Definition: NetworkOPs.cpp:141
ripple::Manifest::signingKey
PublicKey signingKey
The ephemeral key associated with this manifest.
Definition: Manifest.h:89
ripple::NetworkOPsImp::pubProposedAccountTransaction
void pubProposedAccountTransaction(std::shared_ptr< ReadView const > const &ledger, std::shared_ptr< STTx const > const &transaction, TER result)
Definition: NetworkOPs.cpp:3317
std::vector
STL class.
ripple::NetworkOPsImp::isUNLBlocked
bool isUNLBlocked() override
Definition: NetworkOPs.cpp:1634
std::unordered_map::find
T find(T... args)
ripple::ReportingETL::getInfo
Json::Value getInfo()
Definition: ReportingETL.h:310
ripple::Manifest::serialized
std::string serialized
The manifest in serialized form.
Definition: Manifest.h:83
ripple::Validations::trustChanged
void trustChanged(hash_set< NodeID > const &added, hash_set< NodeID > const &removed)
Update trust status of validations.
Definition: Validations.h:792
ripple::NetworkOPsImp::setNeedNetworkLedger
void setNeedNetworkLedger() override
Definition: NetworkOPs.cpp:863
ripple::NetworkOPsImp::tryRemoveRpcSub
bool tryRemoveRpcSub(std::string const &strUrl) override
Definition: NetworkOPs.cpp:4189
ripple::Manifest::masterKey
PublicKey masterKey
The master key associated with this manifest.
Definition: Manifest.h:86
ripple::accountHolds
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const &currency, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
Definition: View.cpp:226
ripple::PublicKey::empty
bool empty() const noexcept
Definition: PublicKey.h:117
ripple::STAmount::getText
std::string getText() const override
Definition: STAmount.cpp:558
ripple::NetworkOPsImp::recvValidation
bool recvValidation(std::shared_ptr< STValidation > const &val, std::string const &source) override
Definition: NetworkOPs.cpp:2287
ripple::jtNETOP_CLUSTER
@ jtNETOP_CLUSTER
Definition: Job.h:76
std::back_inserter
T back_inserter(T... args)
ripple::ValidatorList::setNegativeUNL
void setNegativeUNL(hash_set< PublicKey > const &negUnl)
set the Negative UNL with validators' master public keys
Definition: ValidatorList.cpp:1950
ripple::NetworkOPsImp::getHostId
std::string getHostId(bool forAdmin)
Definition: NetworkOPs.cpp:887
ripple::RCLConsensus::gotTxSet
void gotTxSet(NetClock::time_point const &now, RCLTxSet const &txSet)
Definition: RCLConsensus.cpp:952
ripple::NetworkOPsImp::forwardProposedTransaction
void forwardProposedTransaction(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2770
ripple::NetworkOPsImp::batchApplyTimer_
boost::asio::steady_timer batchApplyTimer_
This timer is for applying transaction batches.
Definition: NetworkOPs.cpp:715
ripple::NetworkOPsImp::sValidations
@ sValidations
Definition: NetworkOPs.cpp:736
std::chrono::microseconds
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:29
ripple::Config::NODE_SIZE
std::size_t NODE_SIZE
Definition: Config.h:218
ripple::crypto_prng
csprng_engine & crypto_prng()
The default cryptographically secure PRNG.
Definition: csprng.cpp:99
ripple::keylet::offer
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
Definition: Indexes.cpp:223
ripple::LedgerMaster::getValidatedRules
Rules getValidatedRules()
Definition: LedgerMaster.cpp:1684
ripple::Issue::currency
Currency currency
Definition: Issue.h:38
ripple::JobQueue::getJson
Json::Value getJson(int c=0)
Definition: JobQueue.cpp:196
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:104
ripple::NetworkOPsImp::Stats::disconnected_duration
beast::insight::Gauge disconnected_duration
Definition: NetworkOPs.cpp:803
ripple::NetworkOPsImp::StateAccounting::Counters
Definition: NetworkOPs.cpp:136
ripple::muldiv_max
constexpr auto muldiv_max
Definition: mulDiv.h:29
std::optional::emplace
T emplace(T... args)
ripple::LedgerMaster::switchLCL
void switchLCL(std::shared_ptr< Ledger const > const &lastClosed)
Definition: LedgerMaster.cpp:506
ripple::HELD
@ HELD
Definition: Transaction.h:51
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
std::recursive_mutex
STL class.
ripple::keylet::child
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Definition: Indexes.cpp:140
std::shared_ptr::get
T get(T... args)
ripple::NetworkOPsImp::consensusViewChange
void consensusViewChange() override
Definition: NetworkOPs.cpp:1954
std::lock_guard
STL class.
ripple::RPC::computeBookChanges
Json::Value computeBookChanges(std::shared_ptr< L const > const &lpAccepted)
Definition: BookChanges.h:38
ripple::NetworkOPsImp::accounting_
StateAccounting accounting_
Definition: NetworkOPs.cpp:762
ripple::ConsensusParms::ledgerGRANULARITY
std::chrono::milliseconds ledgerGRANULARITY
How often we check state or change positions.
Definition: ConsensusParms.h:103
ripple::NetworkOPsImp::unsubAccountHistoryInternal
void unsubAccountHistoryInternal(std::uint64_t seq, AccountID const &account, bool historyOnly) override
Definition: NetworkOPs.cpp:3889
ripple::Application::getShardStore
virtual NodeStore::DatabaseShard * getShardStore()=0
ripple::NetworkOPsImp::DispatchState::scheduled
@ scheduled
ripple::sfCloseTime
const SF_UINT32 sfCloseTime
tuple
ripple::NetworkOPsImp::SubAccountHistoryInfo::index_
std::shared_ptr< SubAccountHistoryIndex > index_
Definition: NetworkOPs.cpp:671
ripple::LedgerMaster::getLedgerByHash
std::shared_ptr< Ledger const > getLedgerByHash(uint256 const &hash)
Definition: LedgerMaster.cpp:1859
ripple::RCLConsensus::timerEntry
void timerEntry(NetClock::time_point const &now)
Definition: RCLConsensus.cpp:936
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:1325
ripple::JobQueue::addJob
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
Definition: JobQueue.h:166
ripple::jtCLIENT_CONSENSUS
@ jtCLIENT_CONSENSUS
Definition: Job.h:48
ripple::make_NetworkOPs
std::unique_ptr< NetworkOPs > make_NetworkOPs(Application &app, NetworkOPs::clock_type &clock, bool standalone, std::size_t minPeerCount, bool startvalid, JobQueue &job_queue, LedgerMaster &ledgerMaster, ValidatorKeys const &validatorKeys, boost::asio::io_service &io_svc, beast::Journal journal, beast::insight::Collector::ptr const &collector)
Definition: NetworkOPs.cpp:4638
ripple::NetworkOPsImp::Stats::syncing_transitions
beast::insight::Gauge syncing_transitions
Definition: NetworkOPs.cpp:811
std::function
ripple::LoadFeeTrack::getLoadBase
std::uint32_t getLoadBase() const
Definition: LoadFeeTrack.h:89
ripple::NetworkOPsImp::unlBlocked_
std::atomic< bool > unlBlocked_
Definition: NetworkOPs.cpp:708
ripple::NetworkOPsImp::SubAccountHistoryIndex::SubAccountHistoryIndex
SubAccountHistoryIndex(AccountID const &accountId)
Definition: NetworkOPs.cpp:657
ripple::getQualityNext
uint256 getQualityNext(uint256 const &uBase)
Definition: Indexes.cpp:101
ripple::Application::timeKeeper
virtual TimeKeeper & timeKeeper()=0
ripple::Application::getMasterMutex
virtual MutexType & getMasterMutex()=0
ripple::NetworkOPsImp::forwardProposedAccountTransaction
void forwardProposedAccountTransaction(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2859
ripple::Application::openLedger
virtual OpenLedger & openLedger()=0
ripple::NetworkOPsImp::pubLedger
void pubLedger(std::shared_ptr< ReadView const > const &lpAccepted) override
Definition: NetworkOPs.cpp:2927
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::RelationalDatabase::AccountTxArgs::account
AccountID account
Definition: RelationalDatabase.h:98
ripple::NetworkOPsImp::switchLastClosedLedger
void switchLastClosedLedger(std::shared_ptr< Ledger const > const &newLCL)
Definition: NetworkOPs.cpp:1760
ripple::tapNONE
@ tapNONE
Definition: ApplyView.h:30
ripple::NetworkOPsImp::setUNLBlocked
void setUNLBlocked() override
Definition: NetworkOPs.cpp:1640
ripple::NetworkOPsImp::SubAccountHistoryInfo
Definition: NetworkOPs.cpp:668
ripple::TxQ::Metrics
Structure returned by TxQ::getMetrics, expressed in reference fee level units.
Definition: TxQ.h:161
ripple::RCLValidatedLedger
Wraps a ledger instance for use in generic Validations LedgerTrie.
Definition: RCLValidations.h:153
ripple::OpenLedger::accept
void accept(Application &app, Rules const &rules, std::shared_ptr< Ledger const > const &ledger, OrderedTxs const &locals, bool retriesFirst, OrderedTxs &retries, ApplyFlags flags, std::string const &suffix="", modify_type const &f={})
Accept a new ledger.
Definition: OpenLedger.cpp:71
ripple::parityRate
const Rate parityRate(QUALITY_ONE)
A transfer rate signifying a 1:1 exchange.
Definition: Rate.h:101
std::shared_ptr::reset
T reset(T... args)
ripple::NetworkOPsImp::TransactionStatus::result
TER result
Definition: NetworkOPs.cpp:96
algorithm
ripple::generateKeyPair
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
Definition: SecretKey.cpp:351
ripple::error_code_i
error_code_i
Definition: ErrorCodes.h:40
ripple::ValidatorKeys
Validator keys and manifest as set in configuration file.
Definition: ValidatorKeys.h:36
std::unordered_map::clear
T clear(T... args)
std::is_sorted
T is_sorted(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:519
ripple::LedgerMaster::getCompleteLedgers
std::string getCompleteLedgers()
Definition: LedgerMaster.cpp:1706
ripple::ltDIR_NODE
@ ltDIR_NODE
A ledger object which contains a list of object identifiers.
Definition: LedgerFormats.h:66
ripple::send_always
Sends a message to all peers.
Definition: predicates.h:31
ripple::OperatingMode::SYNCING
@ SYNCING
fallen slightly behind
ripple::NetworkOPsImp::processClusterTimer
void processClusterTimer()
Definition: NetworkOPs.cpp:1100
ripple::NetworkOPsImp::unsubTransactions
bool unsubTransactions(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4081
std::unique_lock::unlock
T unlock(T... args)
ripple::Serializer::data
void const * data() const noexcept
Definition: Serializer.h:76
ripple::terQUEUED
@ terQUEUED
Definition: TER.h:208
ripple::sfIndexes
const SF_VECTOR256 sfIndexes
ripple::NetworkOPsImp::StateAccounting::mutex_
std::mutex mutex_
Definition: NetworkOPs.cpp:146
ripple::RCLConsensus::simulate
void simulate(NetClock::time_point const &now, std::optional< std::chrono::milliseconds > consensusDelay)
Definition: RCLConsensus.cpp:970
std::vector::push_back
T push_back(T... args)
ripple::Resource::Manager::exportConsumers
virtual Gossip exportConsumers()=0
Extract packaged consumer information for export.
ripple::LedgerMaster::peekMutex
std::recursive_mutex & peekMutex()
Definition: LedgerMaster.cpp:1652
ripple::NetworkOPsImp::ServerFeeSummary::loadFactorServer
std::uint32_t loadFactorServer
Definition: NetworkOPs.cpp:211
ripple::divide
STAmount divide(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:86
ripple::NetworkOPsImp::~NetworkOPsImp
~NetworkOPsImp() override
Definition: NetworkOPs.cpp:257
ripple::isTerRetry
bool isTerRetry(TER x)
Definition: TER.h:603
ripple::LoadFeeTrack::getRemoteFee
std::uint32_t getRemoteFee() const
Definition: LoadFeeTrack.h:68
ripple::jtBATCH
@ jtBATCH
Definition: Job.h:66
ripple::sfValidatedHash
const SF_UINT256 sfValidatedHash
ripple::RCLConsensus::getTimerDelay
std::optional< std::chrono::milliseconds > getTimerDelay() const
Definition: RCLConsensus.h:651
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:82
ripple::sfTakerPays
const SF_AMOUNT sfTakerPays
ripple::INCLUDED
@ INCLUDED
Definition: Transaction.h:48
ripple::getAccounts
static void getAccounts(Json::Value const &jvObj, std::vector< AccountID > &accounts)
Definition: NetworkOPs.cpp:2841
ripple::RCLConsensus
Manages the generic consensus algorithm for use by the RCL.
Definition: RCLConsensus.h:54
ripple::warnRPC_AMENDMENT_BLOCKED
@ warnRPC_AMENDMENT_BLOCKED
Definition: ErrorCodes.h:157
ripple::NetworkOPsImp::SubAccountHistoryIndex
Definition: NetworkOPs.cpp:644
ripple::NetworkOPsImp::m_statsMutex
std::mutex m_statsMutex
Definition: NetworkOPs.cpp:816
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:171
ripple::NetworkOPsImp::Stats::syncing_duration
beast::insight::Gauge syncing_duration
Definition: NetworkOPs.cpp:805
ripple::NetworkOPsImp::isAmendmentBlocked
bool isAmendmentBlocked() override
Definition: NetworkOPs.cpp:1603
ripple::NetworkOPsImp::addRpcSub
InfoSub::pointer addRpcSub(std::string const &strUrl, InfoSub::ref) override
Definition: NetworkOPs.cpp:4179
ripple::rpcSUCCESS
@ rpcSUCCESS
Definition: ErrorCodes.h:44
ripple::NetworkOPsImp::forwardValidation
void forwardValidation(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2801
ripple::NetworkOPsImp::TransactionStatus::failType
const FailHard failType
Definition: NetworkOPs.cpp:94
ripple::ltOFFER
@ ltOFFER
A ledger object which describes an offer on the DEX.
Definition: LedgerFormats.h:92
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
ripple::Config::reporting
bool reporting() const
Definition: Config.h:338
ripple::Application::getReportingETL
virtual ReportingETL & getReportingETL()=0
ripple::OperatingMode::DISCONNECTED
@ DISCONNECTED
not ready to process requests
ripple::NetworkOPsImp::TransactionStatus::local
const bool local
Definition: NetworkOPs.cpp:93
ripple::NetworkOPsImp::clearAmendmentWarned
void clearAmendmentWarned() override
Definition: NetworkOPs.cpp:1628
ripple::STAmount::setJson
void setJson(Json::Value &) const
Definition: STAmount.cpp:517
ripple::UptimeClock::now
static time_point now()
Definition: UptimeClock.cpp:63
ripple::NetworkOPsImp::subAccountHistoryStart
void subAccountHistoryStart(std::shared_ptr< ReadView const > const &ledger, SubAccountHistoryInfoWeak &subInfo)
Definition: NetworkOPs.cpp:3788
ripple::jtTXN_PROC
@ jtTXN_PROC
Definition: Job.h:83
ripple::OrderBookDB::processTxn
void processTxn(std::shared_ptr< ReadView const > const &ledger, const AcceptedLedgerTx &alTx, Json::Value const &jvObj)
Definition: OrderBookDB.cpp:250
ripple::Application::getIOLatency
virtual std::chrono::milliseconds getIOLatency()=0
ripple::NetworkOPsImp::SubAccountHistoryInfo::sink_
InfoSub::pointer sink_
Definition: NetworkOPs.cpp:670
ripple::NetworkOPsImp::getOwnerInfo
Json::Value getOwnerInfo(std::shared_ptr< ReadView const > lpLedger, AccountID const &account) override
Definition: NetworkOPs.cpp:1531
ripple::sfServerVersion
const SF_UINT64 sfServerVersion
ripple::checkValidity
std::pair< Validity, std::string > checkValidity(HashRouter &router, STTx const &tx, Rules const &rules, Config const &config)
Checks transaction signature and local checks.
Definition: apply.cpp:37
ripple::NetworkOPsImp::reportFeeChange
void reportFeeChange() override
Definition: NetworkOPs.cpp:3039
ripple::LoadFeeTrack::getLocalFee
std::uint32_t getLocalFee() const
Definition: LoadFeeTrack.h:75
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:532
ripple::OperatingMode::CONNECTED
@ CONNECTED
convinced we are talking to the network
ripple::jtNETOP_TIMER
@ jtNETOP_TIMER
Definition: Job.h:77
ripple::OBSOLETE
@ OBSOLETE
Definition: Transaction.h:53
ripple::NetworkOPsImp::StateAccounting::Counters::transitions
std::uint64_t transitions
Definition: NetworkOPs.cpp:140
ripple::Application::getLoadManager
virtual LoadManager & getLoadManager()=0
ripple::InfoSub::pointer
std::shared_ptr< InfoSub > pointer
Definition: InfoSub.h:54
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::XRPAmount::decimalXRP
constexpr double decimalXRP() const
Definition: XRPAmount.h:253
ripple::sfLoadFee
const SF_UINT32 sfLoadFee
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::NetworkOPsImp::addAccountHistoryJob
void addAccountHistoryJob(SubAccountHistoryInfoWeak subInfo)
Definition: NetworkOPs.cpp:3468
ripple::NetworkOPsImp::isBlocked
bool isBlocked() override
Definition: NetworkOPs.cpp:1597
ripple::InboundLedgers::acquire
virtual std::shared_ptr< Ledger const > acquire(uint256 const &hash, std::uint32_t seq, InboundLedger::Reason)=0
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:134
ripple::RCLConsensus::peerProposal
bool peerProposal(NetClock::time_point const &now, RCLCxPeerPos const &newProposal)
Definition: RCLConsensus.cpp:979
ripple::OperatingMode::TRACKING
@ TRACKING
convinced we agree with the network
ripple::NetworkOPsImp::SubAccountHistoryIndex::separationLedgerSeq_
std::uint32_t separationLedgerSeq_
Definition: NetworkOPs.cpp:650
ripple::STObject::getAccountID
AccountID getAccountID(SField const &field) const
Definition: STObject.cpp:589
ripple::sfNewFields
const SField sfNewFields
ripple::NetworkOPsImp::SubAccountHistoryInfoWeak::sinkWptr_
InfoSub::wptr sinkWptr_
Definition: NetworkOPs.cpp:675
ripple::sfReserveIncrement
const SF_UINT32 sfReserveIncrement
ripple::NetworkOPsImp::setTimer
void setTimer(boost::asio::steady_timer &timer, std::chrono::milliseconds const &expiry_time, std::function< void()> onExpire, std::function< void()> onError)
Definition: NetworkOPs.cpp:916
ripple::JsonOptions::none
@ none
ripple::NetworkOPsImp::DispatchState
DispatchState
Synchronization states for transaction batches.
Definition: NetworkOPs.cpp:112
ripple::NetworkOPsImp::sServer
@ sServer
Definition: NetworkOPs.cpp:733
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::NetworkOPsImp::StateAccounting::start_
std::chrono::steady_clock::time_point start_
Definition: NetworkOPs.cpp:147
ripple::TERSubset< CanCvtToTER >
ripple::TrustChanges::removed
hash_set< NodeID > removed
Definition: ValidatorList.h:112
ripple::RCLTxSet
Represents a set of transactions in RCLConsensus.
Definition: RCLCxTx.h:65
ripple::keylet::page
Keylet page(uint256 const &key, std::uint64_t index) noexcept
A page in a directory.
Definition: Indexes.cpp:310
ripple::NetworkOPsImp::endConsensus
void endConsensus() override
Definition: NetworkOPs.cpp:1898
ripple::RelationalDatabase::AccountTxArgs::marker
std::optional< AccountTxMarker > marker
Definition: RelationalDatabase.h:103
ripple::ValidatorList::updateTrusted
TrustChanges updateTrusted(hash_set< NodeID > const &seenValidators, NetClock::time_point closeTime, NetworkOPs &ops, Overlay &overlay, HashRouter &hashRouter)
Update trusted nodes.
Definition: ValidatorList.cpp:1772
std::unique_lock
STL class.
ripple::sfCookie
const SF_UINT64 sfCookie
ripple::calcAccountID
AccountID calcAccountID(PublicKey const &pk)
Definition: AccountID.cpp:158
ripple::NetworkOPsImp::unsubAccount
void unsubAccount(InfoSub::ref ispListener, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
Definition: NetworkOPs.cpp:3424
ripple::Application::getRelationalDatabase
virtual RelationalDatabase & getRelationalDatabase()=0
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:438
ripple::NetworkOPsImp::unsubRTTransactions
bool unsubRTTransactions(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4099
ripple::Application::getTxQ
virtual TxQ & getTxQ()=0
ripple::LoadFeeTrack
Manages the current fee schedule.
Definition: LoadFeeTrack.h:44
ripple::Manifest::getSignature
std::optional< Blob > getSignature() const
Returns manifest signature.
Definition: app/misc/impl/Manifest.cpp:224
ripple::NetworkOPsImp::pubValidatedTransaction
void pubValidatedTransaction(std::shared_ptr< ReadView const > const &ledger, AcceptedLedgerTx const &transaction)
Definition: NetworkOPs.cpp:3139
std::to_string
T to_string(T... args)
ripple::Application::getJobQueue
virtual JobQueue & getJobQueue()=0
ripple::NetworkOPsImp::subManifests
bool subManifests(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4015
ripple::AcceptedLedgerTx
A transaction that is in a closed ledger.
Definition: AcceptedLedgerTx.h:43
ripple::AmendmentTable::firstUnsupportedExpected
virtual std::optional< NetClock::time_point > firstUnsupportedExpected() const =0
ripple::Resource::Gossip::items
std::vector< Item > items
Definition: Gossip.h:42
ripple::NetworkOPsImp::TransactionStatus::transaction
const std::shared_ptr< Transaction > transaction
Definition: NetworkOPs.cpp:91
std::array
STL class.
ripple::NetworkOPsImp::clearUNLBlocked
void clearUNLBlocked() override
Definition: NetworkOPs.cpp:1647
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:1770
ripple::NetworkOPsImp::ServerFeeSummary
Server fees published on server subscription.
Definition: NetworkOPs.cpp:194
ripple::NetworkOPsImp::m_localTX
std::unique_ptr< LocalTxs > m_localTX
Definition: NetworkOPs.cpp:699
ripple::NetworkOPsImp::NetworkOPsImp
NetworkOPsImp(Application &app, NetworkOPs::clock_type &clock, bool standalone, std::size_t minPeerCount, bool start_valid, JobQueue &job_queue, LedgerMaster &ledgerMaster, ValidatorKeys const &validatorKeys, boost::asio::io_service &io_svc, beast::Journal journal, beast::insight::Collector::ptr const &collector)
Definition: NetworkOPs.cpp:218
ripple::NetworkOPsImp::DispatchState::running
@ running
ripple::NetworkOPsImp::StateAccounting::CounterData::start
decltype(start_) start
Definition: NetworkOPs.cpp:181
ripple::ConsensusPhase
ConsensusPhase
Phases of consensus for a single ledger round.
Definition: ConsensusTypes.h:102
ripple::STAmount
Definition: STAmount.h:45
ripple::NetworkOPsImp::StateAccounting::Counters::Counters
Counters()=default
ripple::warnRPC_EXPIRED_VALIDATOR_LIST
@ warnRPC_EXPIRED_VALIDATOR_LIST
Definition: ErrorCodes.h:158
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:219
beast::Journal::info
Stream info() const
Definition: Journal.h:321
ripple::NetworkOPsImp::m_job_queue
JobQueue & m_job_queue
Definition: NetworkOPs.cpp:748
std::unordered_map::erase
T erase(T... args)
ripple::BuildInfo::getVersionString
std::string const & getVersionString()
Server version.
Definition: BuildInfo.cpp:65
ripple::sfTakerGets
const SF_AMOUNT sfTakerGets
ripple::NetworkOPsImp::subBookChanges
bool subBookChanges(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:3989
ripple::STTx
Definition: STTx.h:45
ripple::setup_FeeVote
FeeSetup setup_FeeVote(Section const &section)
Definition: Config.cpp:1026
ripple::LedgerMaster::getLedgerBySeq
std::shared_ptr< Ledger const > getLedgerBySeq(std::uint32_t index)
Definition: LedgerMaster.cpp:1823
ripple::RCLConsensus::mode
ConsensusMode mode() const
Definition: RCLConsensus.h:590
ripple::AcceptedLedgerTx::getAffected
boost::container::flat_set< AccountID > const & getAffected() const
Definition: AcceptedLedgerTx.h:63
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:179
ripple::NetworkOPsImp::Stats::tracking_duration
beast::insight::Gauge tracking_duration
Definition: NetworkOPs.cpp:806
ripple::warnRPC_UNSUPPORTED_MAJORITY
@ warnRPC_UNSUPPORTED_MAJORITY
Definition: ErrorCodes.h:156
ripple::NetworkOPsImp::subTransactions
bool subTransactions(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4071
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::ClosureCounter
The role of a ClosureCounter is to assist in shutdown by letting callers wait for the completion of c...
Definition: ClosureCounter.h:54
ripple::NetworkOPsImp::StateAccounting::counters_
std::array< Counters, 5 > counters_
Definition: NetworkOPs.cpp:145
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:3999
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::NetworkOPsImp::isAmendmentWarned
bool isAmendmentWarned() override
Definition: NetworkOPs.cpp:1616
ripple::Application::getValidations
virtual RCLValidations & getValidations()=0
ripple::Overlay::relay
virtual std::set< Peer::id_t > relay(protocol::TMProposeSet &m, uint256 const &uid, PublicKey const &validator)=0
Relay a proposal.
std::uint64_t
std::condition_variable::wait
T wait(T... args)
ripple::NetworkOPsImp::needNetworkLedger_
std::atomic< bool > needNetworkLedger_
Definition: NetworkOPs.cpp:705
ripple::temBAD_SIGNATURE
@ temBAD_SIGNATURE
Definition: TER.h:103
ripple::ReadView::succ
virtual std::optional< key_type > succ(key_type const &key, std::optional< key_type > const &last=std::nullopt) const =0
Return the key of the next state item.
ripple::HashRouter::shouldRelay
std::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
Definition: HashRouter.cpp:118
ripple::LedgerMaster::addHeldTransaction
void addHeldTransaction(std::shared_ptr< Transaction > const &trans)
Definition: LedgerMaster.cpp:427
ripple::Manifest::getMasterSignature
Blob getMasterSignature() const
Returns manifest master key signature.
Definition: app/misc/impl/Manifest.cpp:235
std::atomic< bool >
ripple::Overlay::foreach
void foreach(Function f) const
Visit every active peer.
Definition: Overlay.h:198
ripple::NetworkOPsImp::ServerFeeSummary::ServerFeeSummary
ServerFeeSummary()=default
ripple::NetworkOPsImp::StateAccounting::mode_
OperatingMode mode_
Definition: NetworkOPs.cpp:144
std::map
STL class.
ripple::LoadFeeTrack::getClusterFee
std::uint32_t getClusterFee() const
Definition: LoadFeeTrack.h:82
ripple::range
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition: RangeSet.h:54
ripple::Application::getValidationPublicKey
virtual PublicKey const & getValidationPublicKey() const =0
ripple::NetworkOPsImp::pubValidation
void pubValidation(std::shared_ptr< STValidation > const &val) override
Definition: NetworkOPs.cpp:2137
ripple::amountFromQuality
STAmount amountFromQuality(std::uint64_t rate)
Definition: STAmount.cpp:839
ripple::OrderBookDB::makeBookListeners
BookListeners::pointer makeBookListeners(Book const &)
Definition: OrderBookDB.cpp:218
ripple::NetworkOPs::FailHard
FailHard
Definition: NetworkOPs.h:95
ripple::TxQ::processClosedLedger
void processClosedLedger(Application &app, ReadView const &view, bool timeLeap)
Update fee metrics and clean up the queue in preparation for the next ledger.
Definition: TxQ.cpp:1347
ripple::sfReserveIncrementDrops
const SF_AMOUNT sfReserveIncrementDrops
ripple::NetworkOPsImp::subAccount
void subAccount(InfoSub::ref ispListener, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
Definition: NetworkOPs.cpp:3387
ripple::NetworkOPsImp::m_standalone
const bool m_standalone
Definition: NetworkOPs.cpp:751
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:1659
Json::Int
int Int
Definition: json_forwards.h:26
ripple::NetworkOPsImp::Stats
Definition: NetworkOPs.cpp:765
ripple::AcceptedLedgerTx::getResult
TER getResult() const
Definition: AcceptedLedgerTx.h:79
ripple::RCLConsensus::parms
ConsensusParms const & parms() const
Definition: RCLConsensus.h:645
ripple::Cluster::size
std::size_t size() const
The number of nodes in the cluster list.
Definition: Cluster.cpp:50
ripple::NetworkOPsImp::StateAccounting::CounterData::initialSyncUs
decltype(initialSyncUs_) initialSyncUs
Definition: NetworkOPs.cpp:182
ripple::STTx::getJson
Json::Value getJson(JsonOptions options) const override
Definition: STTx.cpp:229
beast::abstract_clock< std::chrono::steady_clock >
ripple::sfReserveBaseDrops
const SF_AMOUNT sfReserveBaseDrops
ripple::NetworkOPsImp::StateAccounting::CounterData::mode
decltype(mode_) mode
Definition: NetworkOPs.cpp:180
ripple::Config::FEE_UNITS_DEPRECATED
static constexpr std::uint32_t FEE_UNITS_DEPRECATED
Definition: Config.h:165
ripple::NetworkOPsImp::StateAccounting::CounterData
Definition: NetworkOPs.cpp:177
ripple::accountFunds
STAmount accountFunds(ReadView const &view, AccountID const &id, STAmount const &saDefault, FreezeHandling freezeHandling, beast::Journal j)
Definition: View.cpp:282
ripple::ttOFFER_CREATE
@ ttOFFER_CREATE
This transaction type creates an offer to trade one asset for another.
Definition: TxFormats.h:80
Json::Value::UInt
Json::UInt UInt
Definition: json_value.h:153
ripple::NetworkOPsImp::SubAccountHistoryIndex::historyTxIndex_
std::int32_t historyTxIndex_
Definition: NetworkOPs.cpp:653
ripple::NetworkOPsImp::TransactionStatus
Transaction with input flags and results to be applied in batches.
Definition: NetworkOPs.cpp:88
ripple::jtCLIENT_ACCT_HIST
@ jtCLIENT_ACCT_HIST
Definition: Job.h:49
ripple::Application::validators
virtual ValidatorList & validators()=0
beast::insight::Gauge
A metric for measuring an integral value.
Definition: Gauge.h:39
ripple::NetworkOPsImp::isNeedNetworkLedger
bool isNeedNetworkLedger() override
Definition: NetworkOPs.cpp:875
ripple::LoadManager::resetDeadlockDetector
void resetDeadlockDetector()
Reset the deadlock detection timer.
Definition: LoadManager.cpp:63
ripple::NetworkOPsImp::ServerFeeSummary::operator!=
bool operator!=(ServerFeeSummary const &b) const
Definition: NetworkOPs.cpp:2013
ripple::jtCLIENT_FEE_CHANGE
@ jtCLIENT_FEE_CHANGE
Definition: Job.h:47
ripple::NetworkOPsImp::TransactionStatus::TransactionStatus
TransactionStatus(std::shared_ptr< Transaction > t, bool a, bool l, FailHard f)
Definition: NetworkOPs.cpp:98
ripple::KeyType::secp256k1
@ secp256k1
ripple::NetworkOPsImp::setStandAlone
void setStandAlone() override
Definition: NetworkOPs.cpp:857
ripple::JobQueue
A pool of threads to perform work.
Definition: JobQueue.h:55
ripple::NetworkOPsImp::mSubLock
std::recursive_mutex mSubLock
Definition: NetworkOPs.cpp:701
ripple::ValidatorList::expires
std::optional< TimeKeeper::time_point > expires() const
Return the time when the validator list will expire.
Definition: ValidatorList.cpp:1501
ripple::NetworkOPsImp::ServerFeeSummary::operator==
bool operator==(ServerFeeSummary const &b) const
Definition: NetworkOPs.cpp:206
std::weak_ptr< InfoSub >
ripple::rpcINTERNAL
@ rpcINTERNAL
Definition: ErrorCodes.h:130
ripple::multiply
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:47
std::min
T min(T... args)
ripple::OrderBookDB::getBookListeners
BookListeners::pointer getBookListeners(Book const &)
Definition: OrderBookDB.cpp:235
ripple::NetworkOPsImp::SubAccountHistoryIndex::forwardTxIndex_
std::uint32_t forwardTxIndex_
Definition: NetworkOPs.cpp:648
ripple::Serializer
Definition: Serializer.h:40
ripple::Manifest::sequence
std::uint32_t sequence
The sequence number of this manifest.
Definition: Manifest.h:92
ripple::Application::getResourceManager
virtual Resource::Manager & getResourceManager()=0
ripple::LedgerMaster::getFetchPackCacheSize
std::size_t getFetchPackCacheSize() const
Definition: LedgerMaster.cpp:2365
ripple::getJson
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
Definition: LedgerToJson.cpp:291
ripple::NetworkOPsImp::sConsensusPhase
@ sConsensusPhase
Definition: NetworkOPs.cpp:738
ripple::NetworkOPsImp::mMutex
std::mutex mMutex
Definition: NetworkOPs.cpp:758
ripple::sfBaseFee
const SF_UINT64 sfBaseFee
ripple::NetworkOPsImp::Stats::tracking_transitions
beast::insight::Gauge tracking_transitions
Definition: NetworkOPs.cpp:812
ripple::LedgerMaster::haveValidated
bool haveValidated()
Whether we have ever fully validated a ledger.
Definition: LedgerMaster.h:286
ripple::LedgerMaster::getValidatedLedgerAge
std::chrono::seconds getValidatedLedgerAge()
Definition: LedgerMaster.cpp:274
ripple::generateSeed
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition: Seed.cpp:69
ripple::LedgerMaster::getClosedLedger
std::shared_ptr< Ledger const > getClosedLedger()
Definition: LedgerMaster.h:98
ripple::NetworkOPsImp::Stats::connected_transitions
beast::insight::Gauge connected_transitions
Definition: NetworkOPs.cpp:810
ripple::NetworkOPsImp::clusterTimer_
boost::asio::steady_timer clusterTimer_
Definition: NetworkOPs.cpp:712
ripple::STObject
Definition: STObject.h:52
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:760
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:54
ripple::NetworkOPsImp::reportConsensusStateChange
void reportConsensusStateChange(ConsensusPhase phase)
Definition: NetworkOPs.cpp:3059
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:206
ripple::NetworkOPsImp::unsubServer
bool unsubServer(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4063
ripple::RCLConsensus::prevRoundTime
std::chrono::milliseconds prevRoundTime() const
Get duration of the previous round.
Definition: RCLConsensus.h:583
ripple::NetworkOPsImp::processTransaction
void processTransaction(std::shared_ptr< Transaction > &transaction, bool bUnlimited, RPC::SubmitSync sync, bool bLocal, FailHard failType) override
Process a transaction.
Definition: NetworkOPs.cpp:1223
ripple::sterilize
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Definition: STTx.cpp:550
ripple::Config::features
std::unordered_set< uint256, beast::uhash<> > features
Definition: Config.h:283
ripple::NetworkOPsImp::Stats::Stats
Stats(Handler const &handler, beast::insight::Collector::ptr const &collector)
Definition: NetworkOPs.cpp:768
ripple::NetworkOPsImp::setHeartbeatTimer
void setHeartbeatTimer()
Definition: NetworkOPs.cpp:948
ripple::NetworkOPsImp::unsubBookChanges
bool unsubBookChanges(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4007
ripple::Application::getNodeStore
virtual NodeStore::Database & getNodeStore()=0
ripple::Application::journal
virtual beast::Journal journal(std::string const &name)=0
ripple::Application::validatorManifests
virtual ManifestCache & validatorManifests()=0
ripple::Application::getServerHandler
virtual ServerHandler & getServerHandler()=0
ripple::NetworkOPsImp::getLocalTxCount
std::size_t getLocalTxCount() override
Definition: NetworkOPs.cpp:3073
ripple::NetworkOPsImp::StateAccounting::initialSyncUs_
std::uint64_t initialSyncUs_
Definition: NetworkOPs.cpp:150
ripple::NetworkOPsImp::mStreamMaps
std::array< SubMapType, SubTypes::sLastEntry+1 > mStreamMaps
Definition: NetworkOPs.cpp:744
ripple::Serializer::size
std::size_t size() const noexcept
Definition: Serializer.h:70
ripple::LoadFeeTrack::getLoadFactor
std::uint32_t getLoadFactor() const
Definition: LoadFeeTrack.h:95
ripple::NetworkOPsImp::getLedgerFetchInfo
Json::Value getLedgerFetchInfo() override
Definition: NetworkOPs.cpp:2733
ripple::tapUNLIMITED
@ tapUNLIMITED
Definition: ApplyView.h:41
ripple::NetworkOPsImp::sManifests
@ sManifests
Definition: NetworkOPs.cpp:732
ripple::sfLedgerEntryType
const SF_UINT16 sfLedgerEntryType
ripple::NetworkOPsImp::StateAccounting::StateAccounting
StateAccounting()
Definition: NetworkOPs.cpp:154
ripple::NetworkOPsImp::SubAccountHistoryInfoWeak
Definition: NetworkOPs.cpp:673
ripple::INVALID
@ INVALID
Definition: Transaction.h:47
ripple::Validity::Valid
@ Valid
Signature and local checks are good / passed.
ripple::NetworkOPsImp::pubServer
void pubServer()
Definition: NetworkOPs.cpp:2042
ripple::base_uint::begin
iterator begin()
Definition: base_uint.h:133
ripple::tefPAST_SEQ
@ tefPAST_SEQ
Definition: TER.h:159
ripple::NetworkOPsImp::unsubBook
bool unsubBook(std::uint64_t uListener, Book const &) override
Definition: NetworkOPs.cpp:3930
ripple::TransactionMaster::canonicalize
void canonicalize(std::shared_ptr< Transaction > *pTransaction)
Definition: TransactionMaster.cpp:143
ripple::terSUBMITTED
@ terSUBMITTED
Definition: TER.h:211
ripple::NetworkOPsImp::acceptLedger
std::uint32_t acceptLedger(std::optional< std::chrono::milliseconds > consensusDelay) override
Accepts the current transaction tree, return the new ledger's sequence.
Definition: NetworkOPs.cpp:3939
ripple::NetworkOPsImp::sTransactions
@ sTransactions
Definition: NetworkOPs.cpp:734
ripple::NetworkOPsImp::mSubAccount
SubInfoMapType mSubAccount
Definition: NetworkOPs.cpp:723
ripple::Config::SERVER_DOMAIN
std::string SERVER_DOMAIN
Definition: Config.h:285
ripple::AcceptedLedgerTx::getMeta
TxMeta const & getMeta() const
Definition: AcceptedLedgerTx.h:57
ripple::NetworkOPsImp::clearNeedNetworkLedger
void clearNeedNetworkLedger() override
Definition: NetworkOPs.cpp:869
ripple::NetworkOPsImp::sBookChanges
@ sBookChanges
Definition: NetworkOPs.cpp:739
std::begin
T begin(T... args)
beast::rngfill
void rngfill(void *buffer, std::size_t bytes, Generator &g)
Definition: rngfill.h:33
Json::StaticString
Lightweight wrapper to tag static string.
Definition: json_value.h:60
ripple::NetworkOPsImp::TransactionStatus::admin
const bool admin
Definition: NetworkOPs.cpp:92
std
STL namespace.
ripple::featureNegativeUNL
const uint256 featureNegativeUNL
ripple::ltACCOUNT_ROOT
@ ltACCOUNT_ROOT
A ledger object which describes an account.
Definition: LedgerFormats.h:59
ripple::NetworkOPsImp::checkLastClosedLedger
bool checkLastClosedLedger(const Overlay::PeerSequence &, uint256 &networkClosed)
Definition: NetworkOPs.cpp:1653
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:1148
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:4214
ripple::NetworkOPsImp::ServerFeeSummary::baseFee
XRPAmount baseFee
Definition: NetworkOPs.cpp:213
ripple::RPC::insertDeliveredAmount
void insertDeliveredAmount(Json::Value &meta, ReadView const &, std::shared_ptr< STTx const > const &serializedTx, TxMeta const &)
Add a delivered_amount field to the meta input/output parameter.
Definition: DeliveredAmount.cpp:143
ripple::NetworkOPsImp::pubPeerStatus
void pubPeerStatus(std::function< Json::Value(void)> const &) override
Definition: NetworkOPs.cpp:2229
ripple::NetworkOPsImp::mCond
std::condition_variable mCond
Definition: NetworkOPs.cpp:757
ripple::NetworkOPsImp::isFull
bool isFull() override
Definition: NetworkOPs.cpp:881
ripple::PostgresDatabase
Definition: PostgresDatabase.h:27
ripple::NodeStore::Database::getCountsJson
void getCountsJson(Json::Value &obj)
Definition: Database.cpp:377
ripple::LedgerMaster::getCurrentLedgerIndex
LedgerIndex getCurrentLedgerIndex()
Definition: LedgerMaster.cpp:207
ripple::NetworkOPsImp::subLedger
bool subLedger(InfoSub::ref ispListener, Json::Value &jvResult) override
Definition: NetworkOPs.cpp:3959
std::condition_variable
ripple::NetworkOPsImp::Stats::full_transitions
beast::insight::Gauge full_transitions
Definition: NetworkOPs.cpp:813
ripple::Config::RELAY_UNTRUSTED_VALIDATIONS
int RELAY_UNTRUSTED_VALIDATIONS
Definition: Config.h:174
ripple::stateNames
static const std::array< char const *, 5 > stateNames
Definition: NetworkOPs.cpp:826
ripple::NetworkOPsImp::sLedger
@ sLedger
Definition: NetworkOPs.cpp:731
ripple::TimeKeeper::now
virtual time_point now() const override=0
Returns the estimate of wall time, in network time.
ripple::NetworkOPsImp::subAccountHistory
error_code_i subAccountHistory(InfoSub::ref ispListener, AccountID const &account) override
subscribe an account's new transactions and retrieve the account's historical transactions
Definition: NetworkOPs.cpp:3832
ripple::NetworkOPsImp::mConsensus
RCLConsensus mConsensus
Definition: NetworkOPs.cpp:717
ripple::RCLConsensus::prevProposers
std::size_t prevProposers() const
Get the number of proposing peers that participated in the previous round.
Definition: RCLConsensus.h:570
ripple::Application::overlay
virtual Overlay & overlay()=0
ripple::NetworkOPsImp::sPeerStatus
@ sPeerStatus
Definition: NetworkOPs.cpp:737
std::chrono::milliseconds::count
T count(T... args)
ripple::NetworkOPsImp::mMode
std::atomic< OperatingMode > mMode
Definition: NetworkOPs.cpp:703
ripple::LedgerMaster::getValidatedLedger
std::shared_ptr< Ledger const > getValidatedLedger()
Definition: LedgerMaster.cpp:1669
ripple::NetworkOPsImp::unsubManifests
bool unsubManifests(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4025
ripple::Section::get
std::optional< T > get(std::string const &name) const
Definition: BasicConfig.h:138
ripple::tapFAIL_HARD
@ tapFAIL_HARD
Definition: ApplyView.h:34
ripple::TrustChanges::added
hash_set< NodeID > added
Definition: ValidatorList.h:111
ripple::makeRulesGivenLedger
Rules makeRulesGivenLedger(DigestAwareReadView const &ledger, Rules const &current)
Definition: ReadView.cpp:69
ripple::NetworkOPsImp::amendmentBlocked_
std::atomic< bool > amendmentBlocked_
Definition: NetworkOPs.cpp:706
ripple::NetworkOPsImp::submitTransaction
void submitTransaction(std::shared_ptr< STTx const > const &) override
Definition: NetworkOPs.cpp:1168
std::string::empty
T empty(T... args)
ripple::OperatingMode
OperatingMode
Specifies the mode under which the server believes it's operating.
Definition: NetworkOPs.h:66
ripple::fhIGNORE_FREEZE
@ fhIGNORE_FREEZE
Definition: View.h:79
ripple::Overlay::networkID
virtual std::optional< std::uint32_t > networkID() const =0
Returns the ID of the network this server is configured for, if any.
ripple::InboundLedgers::clearFailures
virtual void clearFailures()=0
ripple::TokenType::NodePublic
@ NodePublic
ripple::NetworkOPsImp::transJson
Json::Value transJson(const STTx &transaction, TER result, bool validated, std::shared_ptr< ReadView const > const &ledger)
Definition: NetworkOPs.cpp:3081
ripple::ClosureCounter::join
void join(char const *name, std::chrono::milliseconds wait, beast::Journal j)
Returns once all counted in-flight closures are destroyed.
Definition: ClosureCounter.h:166
ripple::NetworkOPsImp::mLastConsensusPhase
ConsensusPhase mLastConsensusPhase
Definition: NetworkOPs.cpp:719
ripple::NetworkOPsImp::updateLocalTx
void updateLocalTx(ReadView const &view) override
Definition: NetworkOPs.cpp:3068
std::optional
mutex
ripple::NetworkOPsImp::sRTTransactions
@ sRTTransactions
Definition: NetworkOPs.cpp:735
ripple::NetworkOPs::FailHard::yes
@ yes
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::NetworkOPsImp::pubConsensus
void pubConsensus(ConsensusPhase phase)
Definition: NetworkOPs.cpp:2110
std::size_t
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
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:4089
ripple::Book
Specifies an order book.
Definition: Book.h:33
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:809
ripple::genesisAccountId
static const auto genesisAccountId
Definition: NetworkOPs.cpp:839
std::make_pair
T make_pair(T... args)
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::NetworkOPsImp::pubProposedTransaction
void pubProposedTransaction(std::shared_ptr< ReadView const > const &ledger, std::shared_ptr< STTx const > const &transaction, TER result) override
Definition: NetworkOPs.cpp:2739
ripple::ltRIPPLE_STATE
@ ltRIPPLE_STATE
A ledger object which describes a bidirectional trust line.
Definition: LedgerFormats.h:74
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
std::end
T end(T... args)
ripple::NetworkOPsImp::getServerInfo
Json::Value getServerInfo(bool human, bool admin, bool counters) override
Definition: NetworkOPs.cpp:2310
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:721
ripple::NetworkOPsImp::subServer
bool subServer(InfoSub::ref ispListener, Json::Value &jvResult, bool admin) override
Definition: NetworkOPs.cpp:4033
ripple::Validations::getCurrentNodeIDs
auto getCurrentNodeIDs() -> hash_set< NodeID >
Get the set of node ids associated with current validations.
Definition: Validations.h:1016
ripple::NetworkOPsImp::SubAccountHistoryInfoWeak::index_
std::shared_ptr< SubAccountHistoryIndex > index_
Definition: NetworkOPs.cpp:676
ripple::RelationalDatabase::AccountTxArgs::ledger
std::optional< LedgerSpecifier > ledger
Definition: RelationalDatabase.h:99
ripple::LedgerRange
Definition: RelationalDatabase.h:42
std::numeric_limits::max
T max(T... args)
ripple::NetworkOPsImp::accountHistoryTxTimer_
boost::asio::steady_timer accountHistoryTxTimer_
Definition: NetworkOPs.cpp:713
ripple::Validity::SigBad
@ SigBad
Signature is bad. Didn't do local checks.
ripple::RCLConsensus::validating
bool validating() const
Whether we are validating consensus ledgers.
Definition: RCLConsensus.h:562
ripple::make_LocalTxs
std::unique_ptr< LocalTxs > make_LocalTxs()
Definition: LocalTxs.cpp:197
ripple::TxQ::getMetrics
Metrics getMetrics(OpenView const &view) const
Returns fee metrics in reference fee level units.
Definition: TxQ.cpp:1748
ripple::ServerHandler::setup
void setup(Setup const &setup, beast::Journal journal)
Definition: ServerHandler.cpp:131
ripple::NetworkOPsImp::StateAccounting::getCounterData
CounterData getCounterData() const
Definition: NetworkOPs.cpp:186
ripple::JobQueue::makeLoadEvent
std::unique_ptr< LoadEvent > makeLoadEvent(JobType t, std::string const &name)
Return a scoped LoadEvent.
Definition: JobQueue.cpp:165
std::set_intersection
T set_intersection(T... args)
ripple::NetworkOPsImp::Stats::full_duration
beast::insight::Gauge full_duration
Definition: NetworkOPs.cpp:807
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:3920
ripple::NetworkOPsImp::subConsensus
bool subConsensus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4149
ripple::NetworkOPsImp::getConsensusInfo
Json::Value getConsensusInfo() override
Definition: NetworkOPs.cpp:2304
ripple::NetworkOPsImp::Stats::connected_duration
beast::insight::Gauge connected_duration
Definition: NetworkOPs.cpp:804
ripple::ValidatorList::count
std::size_t count() const
Return the number of configured validator list sites.
Definition: ValidatorList.cpp:1460
ripple::NetworkOPsImp::waitHandlerCounter_
ClosureCounter< void, boost::system::error_code const & > waitHandlerCounter_
Definition: NetworkOPs.cpp:710
std::unique_ptr
STL class.
ripple::cdirFirst
bool cdirFirst(ReadView const &view, uint256 const &root, std::shared_ptr< SLE const > &page, unsigned int &index, uint256 &entry)
Returns the first entry in the directory, advancing the index.
Definition: View.cpp:134
ripple::NetworkOPsImp::SubAccountHistoryIndex::stopHistorical_
std::atomic< bool > stopHistorical_
Definition: NetworkOPs.cpp:655
ripple::NetworkOPsImp
Definition: NetworkOPs.cpp:82
ripple::NetworkOPsImp::mSubAccountHistory
SubAccountHistoryMapType mSubAccountHistory
Definition: NetworkOPs.cpp:728
ripple::NetworkOPsImp::StateAccounting::mode
void mode(OperatingMode om)
Record state transition.
Definition: NetworkOPs.cpp:4592
ripple::RPC::accountFromStringStrict
std::optional< AccountID > accountFromStringStrict(std::string const &account)
Get an AccountID from an account ID or public key.
Definition: RPCHelpers.cpp:43
unordered_map
ripple::NetworkOPsImp::StateAccounting::states_
static const std::array< Json::StaticString const, 5 > states_
Definition: NetworkOPs.cpp:151
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:3440
ripple::sfSigningTime
const SF_UINT32 sfSigningTime
ripple::LedgerMaster::popAcctTransaction
std::shared_ptr< STTx const > popAcctTransaction(std::shared_ptr< STTx const > const &tx)
Get the next transaction held for a particular account if any.
Definition: LedgerMaster.cpp:579
ripple::NetworkOPsImp::unsubAccountHistory
void unsubAccountHistory(InfoSub::ref ispListener, AccountID const &account, bool historyOnly) override
unsubscribe an account's transactions
Definition: NetworkOPs.cpp:3878
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:226
ripple::NetworkOPsImp::StateAccounting
State accounting records two attributes for each possible server state: 1) Amount of time spent in ea...
Definition: NetworkOPs.cpp:134
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:109
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::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:603
ripple::NetworkOPsImp::unsubPeerStatus
bool unsubPeerStatus(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4141
ripple::NetworkOPsImp::app_
Application & app_
Definition: NetworkOPs.cpp:696
ripple::NetworkOPsImp::transactionBatch
bool transactionBatch(bool drain) override
Apply transactions in batches.
Definition: NetworkOPs.cpp:1309
ripple::HashRouter::setFlags
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
Definition: HashRouter.cpp:102
ripple::handleNewValidation
void handleNewValidation(Application &app, std::shared_ptr< STValidation > const &val, std::string const &source)
Handle a new validation.
Definition: RCLValidations.cpp:152
ripple::NetworkOPsImp::SubAccountHistoryIndex::accountId_
const AccountID accountId_
Definition: NetworkOPs.cpp:646
ripple::isTemMalformed
bool isTemMalformed(TER x)
Definition: TER.h:591
ripple::trunc32
static std::uint32_t trunc32(std::uint64_t v)
Definition: NetworkOPs.cpp:2034
ripple::make_FeeVote
std::unique_ptr< FeeVote > make_FeeVote(FeeSetup const &setup, beast::Journal journal)
Create an instance of the FeeVote logic.
Definition: FeeVoteImpl.cpp:339
ripple::XRPAmount::jsonClipped
Json::Value jsonClipped() const
Definition: XRPAmount.h:209
ripple::Book::in
Issue in
Definition: Book.h:36
ripple::RelationalDatabase::AccountTxPageOptions
Definition: RelationalDatabase.h:74
ripple::NetworkOPsImp::getOperatingMode
OperatingMode getOperatingMode() const override
Definition: NetworkOPs.cpp:845
ripple::Issue::account
AccountID account
Definition: Issue.h:39
std::exception::what
T what(T... args)
ripple::ClusterNode::identity
PublicKey const & identity() const
Definition: ClusterNode.h:63
ripple::NetworkOPsImp::ServerFeeSummary::em
std::optional< TxQ::Metrics > em
Definition: NetworkOPs.cpp:214
ripple::NetworkOPsImp::mRpcSubMap
subRpcMapType mRpcSubMap
Definition: NetworkOPs.cpp:726
ripple::ValidatorList::quorum
std::size_t quorum() const
Get quorum value for current trusted key set.
Definition: ValidatorList.h:492
ripple::BasicConfig::exists
bool exists(std::string const &name) const
Returns true if a section with the given name exists.
Definition: BasicConfig.cpp:121
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::sfAmendments
const SF_VECTOR256 sfAmendments
ripple::TimeKeeper::closeOffset
virtual std::chrono::duration< std::int32_t > closeOffset() const =0
ripple::NetworkOPsImp::findRpcSub
InfoSub::pointer findRpcSub(std::string const &strUrl) override
Definition: NetworkOPs.cpp:4166
beast::insight::Gauge::set
void set(value_type value) const
Set the value on the gauge.
Definition: Gauge.h:68
ripple::NetworkOPsImp::ServerFeeSummary::loadBaseServer
std::uint32_t loadBaseServer
Definition: NetworkOPs.cpp:212
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::BasicConfig::section
Section & section(std::string const &name)
Returns the section with the given name.
Definition: BasicConfig.cpp:127
ripple::NetworkOPsImp::clearLedgerFetch
void clearLedgerFetch() override
Definition: NetworkOPs.cpp:2727
ripple::ClusterNode::getLoadFee
std::uint32_t getLoadFee() const
Definition: ClusterNode.h:51
ripple::ClosureCounter::wrap
std::optional< Substitute< Closure > > wrap(Closure &&closure)
Wrap the passed closure with a reference counter.
Definition: ClosureCounter.h:192
ripple::test::jtx::rate
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
Definition: rate.cpp:30
ripple::Application::getMasterTransaction
virtual TransactionMaster & getMasterTransaction()=0
ripple::root
Number root(Number f, unsigned d)
Definition: Number.cpp:624
ripple::NetworkOPsImp::beginConsensus
bool beginConsensus(uint256 const &networkClosed) override
Definition: NetworkOPs.cpp:1814
ripple::NetworkOPsImp::setAmendmentBlocked
void setAmendmentBlocked() override
Definition: NetworkOPs.cpp:1609
beast
Definition: base_uint.h:641
string
ripple::OperatingMode::FULL
@ FULL
we have the ledger and can even validate
std::chrono::steady_clock::now
T now(T... args)