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  bool last);
612 
613  void
615  std::shared_ptr<ReadView const> const& ledger,
616  AcceptedLedgerTx const& transaction,
617  bool last);
618 
619  void
621  std::shared_ptr<ReadView const> const& ledger,
622  std::shared_ptr<STTx const> const& transaction,
623  TER result);
624 
625  void
626  pubServer();
627  void
629 
631  getHostId(bool forAdmin);
632 
633 private:
637 
638  /*
639  * With a validated ledger to separate history and future, the node
640  * streams historical txns with negative indexes starting from -1,
641  * and streams future txns starting from index 0.
642  * The SubAccountHistoryIndex struct maintains these indexes.
643  * It also has a flag stopHistorical_ for stopping streaming
644  * the historical txns.
645  */
647  {
649  // forward
651  // separate backward and forward
653  // history, backward
658 
660  : accountId_(accountId)
661  , forwardTxIndex_(0)
664  , historyTxIndex_(-1)
665  , haveHistorical_(false)
666  , stopHistorical_(false)
667  {
668  }
669  };
671  {
674  };
676  {
679  };
682 
686  void
688  std::shared_ptr<ReadView const> const& ledger,
689  SubAccountHistoryInfoWeak& subInfo);
690  void
692  void
694 
695  void
696  setBatchApplyTimer() override;
697 
700 
702 
704 
706 
711 
713  boost::asio::steady_timer heartbeatTimer_;
714  boost::asio::steady_timer clusterTimer_;
715  boost::asio::steady_timer accountHistoryTxTimer_;
717  boost::asio::steady_timer batchApplyTimer_;
718 
720 
722 
724 
727 
729 
731 
732  enum SubTypes {
733  sLedger, // Accepted ledgers.
734  sManifests, // Received validator manifests.
735  sServer, // When server changes connectivity state.
736  sTransactions, // All accepted transactions.
737  sRTTransactions, // All proposed and accepted transactions.
738  sValidations, // Received validations.
739  sPeerStatus, // Peer status changes.
740  sConsensusPhase, // Consensus phase
741  sBookChanges, // Per-ledger order book changes
742  sLastEntry // Any new entry must be ADDED ABOVE this one
743  };
744 
746 
748 
750 
751  // Whether we are in standalone mode.
752  bool const m_standalone;
753 
754  // The number of nodes that we need to consider ourselves connected.
756 
757  // Transaction batching.
762 
764 
765 private:
766  struct Stats
767  {
768  template <class Handler>
770  Handler const& handler,
771  beast::insight::Collector::ptr const& collector)
772  : hook(collector->make_hook(handler))
773  , disconnected_duration(collector->make_gauge(
774  "State_Accounting",
775  "Disconnected_duration"))
776  , connected_duration(collector->make_gauge(
777  "State_Accounting",
778  "Connected_duration"))
780  collector->make_gauge("State_Accounting", "Syncing_duration"))
781  , tracking_duration(collector->make_gauge(
782  "State_Accounting",
783  "Tracking_duration"))
784  , full_duration(
785  collector->make_gauge("State_Accounting", "Full_duration"))
786  , disconnected_transitions(collector->make_gauge(
787  "State_Accounting",
788  "Disconnected_transitions"))
789  , connected_transitions(collector->make_gauge(
790  "State_Accounting",
791  "Connected_transitions"))
792  , syncing_transitions(collector->make_gauge(
793  "State_Accounting",
794  "Syncing_transitions"))
795  , tracking_transitions(collector->make_gauge(
796  "State_Accounting",
797  "Tracking_transitions"))
799  collector->make_gauge("State_Accounting", "Full_transitions"))
800  {
801  }
802 
809 
815  };
816 
817  std::mutex m_statsMutex; // Mutex to lock m_stats
819 
820 private:
821  void
822  collect_metrics();
823 };
824 
825 //------------------------------------------------------------------------------
826 
828  {"disconnected", "connected", "syncing", "tracking", "full"}};
829 
831 
839 
840 static auto const genesisAccountId = calcAccountID(
841  generateKeyPair(KeyType::secp256k1, generateSeed("masterpassphrase"))
842  .first);
843 
844 //------------------------------------------------------------------------------
845 inline OperatingMode
847 {
848  return mMode;
849 }
850 
851 inline std::string
852 NetworkOPsImp::strOperatingMode(bool const admin /* = false */) const
853 {
854  return strOperatingMode(mMode, admin);
855 }
856 
857 inline void
859 {
861 }
862 
863 inline void
865 {
866  needNetworkLedger_ = true;
867 }
868 
869 inline void
871 {
872  needNetworkLedger_ = false;
873 }
874 
875 inline bool
877 {
878  return needNetworkLedger_;
879 }
880 
881 inline bool
883 {
885 }
886 
889 {
890  static std::string const hostname = boost::asio::ip::host_name();
891 
892  if (forAdmin)
893  return hostname;
894 
895  // For non-admin uses hash the node public key into a
896  // single RFC1751 word:
897  static std::string const shroudedHostId = [this]() {
898  auto const& id = app_.nodeIdentity();
899 
900  return RFC1751::getWordFromBlob(id.first.data(), id.first.size());
901  }();
902 
903  return shroudedHostId;
904 }
905 
906 void
908 {
910 
911  // Only do this work if a cluster is configured
912  if (app_.cluster().size() != 0)
913  setClusterTimer();
914 }
915 
916 void
918  boost::asio::steady_timer& timer,
919  const std::chrono::milliseconds& expiry_time,
920  std::function<void()> onExpire,
921  std::function<void()> onError)
922 {
923  // Only start the timer if waitHandlerCounter_ is not yet joined.
924  if (auto optionalCountedHandler = waitHandlerCounter_.wrap(
925  [this, onExpire, onError](boost::system::error_code const& e) {
926  if ((e.value() == boost::system::errc::success) &&
927  (!m_job_queue.isStopped()))
928  {
929  onExpire();
930  }
931  // Recover as best we can if an unexpected error occurs.
932  if (e.value() != boost::system::errc::success &&
933  e.value() != boost::asio::error::operation_aborted)
934  {
935  // Try again later and hope for the best.
936  JLOG(m_journal.error())
937  << "Timer got error '" << e.message()
938  << "'. Restarting timer.";
939  onError();
940  }
941  }))
942  {
943  timer.expires_from_now(expiry_time);
944  timer.async_wait(std::move(*optionalCountedHandler));
945  }
946 }
947 
948 void
950 {
951  // timerDelay is to optimize the timer interval such as for phase establish.
952  // Setting a max of ledgerGRANULARITY allows currently in-flight proposals
953  // to be accounted for at the very beginning of the phase.
954  std::chrono::milliseconds timerDelay;
955  auto td = mConsensus.getTimerDelay();
956  if (td)
957  {
958  timerDelay = std::min(*td, mConsensus.parms().ledgerGRANULARITY);
960  }
961  else
962  {
963  timerDelay = mConsensus.parms().ledgerGRANULARITY;
964  }
965 
966  setTimer(
968  timerDelay,
969  [this]() {
970  m_job_queue.addJob(jtNETOP_TIMER, "NetOPs.heartbeat", [this]() {
972  });
973  },
974  [this]() { setHeartbeatTimer(); });
975 }
976 
977 void
979 {
980  using namespace std::chrono_literals;
981 
982  setTimer(
984  10s,
985  [this]() {
986  m_job_queue.addJob(jtNETOP_CLUSTER, "NetOPs.cluster", [this]() {
988  });
989  },
990  [this]() { setClusterTimer(); });
991 }
992 
993 void
995 {
996  JLOG(m_journal.debug()) << "Scheduling AccountHistory job for account "
997  << toBase58(subInfo.index_->accountId_);
998  using namespace std::chrono_literals;
999  setTimer(
1001  4s,
1002  [this, subInfo]() { addAccountHistoryJob(subInfo); },
1003  [this, subInfo]() { setAccountHistoryJobTimer(subInfo); });
1004 }
1005 
1006 void
1008 {
1009  using namespace std::chrono_literals;
1010  // 100ms lag between batch intervals provides significant throughput gains
1011  // with little increased latency. Tuning this figure further will
1012  // require further testing. In general, increasing this figure will
1013  // also increase theoretical throughput, but with diminishing returns.
1014  auto constexpr batchInterval = 100ms;
1015 
1016  setTimer(
1018  batchInterval,
1019  [this]() {
1020  {
1021  std::lock_guard lock(mMutex);
1022  // Only do the job if there's work to do and it's not currently
1023  // being done.
1024  if (mTransactions.size() &&
1026  {
1027  if (m_job_queue.addJob(
1028  jtBATCH, "transactionBatch", [this]() {
1029  transactionBatch(false);
1030  }))
1031  {
1033  }
1034  return;
1035  }
1036  }
1038  },
1039  [this]() { setBatchApplyTimer(); });
1040 }
1041 
1042 void
1044 {
1045  {
1047 
1048  // VFALCO NOTE This is for diagnosing a crash on exit
1050  mgr.resetDeadlockDetector();
1051 
1052  std::size_t const numPeers = app_.overlay().size();
1053 
1054  // do we have sufficient peers? If not, we are disconnected.
1055  if (numPeers < minPeerCount_)
1056  {
1058  {
1060  JLOG(m_journal.warn())
1061  << "Node count (" << numPeers << ") has fallen "
1062  << "below required minimum (" << minPeerCount_ << ").";
1063  }
1064 
1065  // MasterMutex lock need not be held to call setHeartbeatTimer()
1066  lock.unlock();
1067  // We do not call mConsensus.timerEntry until there are enough
1068  // peers providing meaningful inputs to consensus
1070  return;
1071  }
1072 
1074  {
1076  JLOG(m_journal.info())
1077  << "Node count (" << numPeers << ") is sufficient.";
1078  }
1079 
1080  // Check if the last validated ledger forces a change between these
1081  // states.
1084  else if (mMode == OperatingMode::CONNECTED)
1086  }
1087 
1089 
1090  const ConsensusPhase currPhase = mConsensus.phase();
1091  if (mLastConsensusPhase != currPhase)
1092  {
1093  reportConsensusStateChange(currPhase);
1094  mLastConsensusPhase = currPhase;
1095  }
1096 
1098 }
1099 
1100 void
1102 {
1103  if (app_.cluster().size() == 0)
1104  return;
1105 
1106  using namespace std::chrono_literals;
1107 
1108  bool const update = app_.cluster().update(
1109  app_.nodeIdentity().first,
1110  "",
1113  : 0,
1114  app_.timeKeeper().now());
1115 
1116  if (!update)
1117  {
1118  JLOG(m_journal.debug()) << "Too soon to send cluster update";
1119  setClusterTimer();
1120  return;
1121  }
1122 
1123  protocol::TMCluster cluster;
1124  app_.cluster().for_each([&cluster](ClusterNode const& node) {
1125  protocol::TMClusterNode& n = *cluster.add_clusternodes();
1126  n.set_publickey(toBase58(TokenType::NodePublic, node.identity()));
1127  n.set_reporttime(node.getReportTime().time_since_epoch().count());
1128  n.set_nodeload(node.getLoadFee());
1129  if (!node.name().empty())
1130  n.set_nodename(node.name());
1131  });
1132 
1134  for (auto& item : gossip.items)
1135  {
1136  protocol::TMLoadSource& node = *cluster.add_loadsources();
1137  node.set_name(to_string(item.address));
1138  node.set_cost(item.balance);
1139  }
1141  std::make_shared<Message>(cluster, protocol::mtCLUSTER),
1142  peer_in_cluster()));
1143  setClusterTimer();
1144 }
1145 
1146 //------------------------------------------------------------------------------
1147 
1149 NetworkOPsImp::strOperatingMode(OperatingMode const mode, bool const admin)
1150  const
1151 {
1152  if (mode == OperatingMode::FULL && admin)
1153  {
1154  auto const consensusMode = mConsensus.mode();
1155  if (consensusMode != ConsensusMode::wrongLedger)
1156  {
1157  if (consensusMode == ConsensusMode::proposing)
1158  return "proposing";
1159 
1160  if (mConsensus.validating())
1161  return "validating";
1162  }
1163  }
1164 
1165  return states_[static_cast<std::size_t>(mode)];
1166 }
1167 
1168 void
1170 {
1171  if (isNeedNetworkLedger())
1172  {
1173  // Nothing we can do if we've never been in sync
1174  return;
1175  }
1176 
1177  // this is an asynchronous interface
1178  auto const trans = sterilize(*iTrans);
1179 
1180  auto const txid = trans->getTransactionID();
1181  auto const flags = app_.getHashRouter().getFlags(txid);
1182 
1183  if ((flags & SF_BAD) != 0)
1184  {
1185  JLOG(m_journal.warn()) << "Submitted transaction cached bad";
1186  return;
1187  }
1188 
1189  try
1190  {
1191  auto const [validity, reason] = checkValidity(
1192  app_.getHashRouter(),
1193  *trans,
1195  app_.config());
1196 
1197  if (validity != Validity::Valid)
1198  {
1199  JLOG(m_journal.warn())
1200  << "Submitted transaction invalid: " << reason;
1201  return;
1202  }
1203  }
1204  catch (std::exception const& ex)
1205  {
1206  JLOG(m_journal.warn())
1207  << "Exception checking transaction " << txid << ": " << ex.what();
1208 
1209  return;
1210  }
1211 
1212  std::string reason;
1213 
1214  auto tx = std::make_shared<Transaction>(trans, reason, app_);
1215 
1216  m_job_queue.addJob(jtTRANSACTION, "submitTxn", [this, tx]() {
1217  auto t = tx;
1219  t, false, RPC::SubmitSync::async, false, FailHard::no);
1220  });
1221 }
1222 
1223 void
1225  std::shared_ptr<Transaction>& transaction,
1226  bool bUnlimited,
1227  RPC::SubmitSync sync,
1228  bool bLocal,
1229  FailHard failType)
1230 {
1231  auto ev = m_job_queue.makeLoadEvent(jtTXN_PROC, "ProcessTXN");
1232  auto const newFlags = app_.getHashRouter().getFlags(transaction->getID());
1233 
1234  if ((newFlags & SF_BAD) != 0)
1235  {
1236  // cached bad
1237  JLOG(m_journal.warn()) << transaction->getID() << ": cached bad!\n";
1238  transaction->setStatus(INVALID);
1239  transaction->setResult(temBAD_SIGNATURE);
1240  return;
1241  }
1242 
1243  // NOTE eahennis - I think this check is redundant,
1244  // but I'm not 100% sure yet.
1245  // If so, only cost is looking up HashRouter flags.
1246  auto const view = m_ledgerMaster.getCurrentLedger();
1247  auto const [validity, reason] = checkValidity(
1248  app_.getHashRouter(),
1249  *transaction->getSTransaction(),
1250  view->rules(),
1251  app_.config());
1252  assert(validity == Validity::Valid);
1253 
1254  // Not concerned with local checks at this point.
1255  if (validity == Validity::SigBad)
1256  {
1257  JLOG(m_journal.trace()) << "Transaction has bad signature: " << reason;
1258  transaction->setStatus(INVALID);
1259  transaction->setResult(temBAD_SIGNATURE);
1260  app_.getHashRouter().setFlags(transaction->getID(), SF_BAD);
1261  return;
1262  }
1263 
1264  // canonicalize can change our pointer
1265  app_.getMasterTransaction().canonicalize(&transaction);
1266 
1267  std::unique_lock lock(mMutex);
1268  if (!transaction->getApplying())
1269  {
1270  transaction->setApplying();
1271  mTransactions.push_back(
1272  TransactionStatus(transaction, bUnlimited, bLocal, failType));
1273  }
1274  switch (sync)
1275  {
1276  using enum RPC::SubmitSync;
1277  case sync:
1278  do
1279  {
1280  // If a batch is being processed, then wait. Otherwise,
1281  // process a batch.
1283  mCond.wait(lock);
1284  else
1285  apply(lock);
1286  } while (transaction->getApplying());
1287  break;
1288 
1289  case async:
1290  // It's conceivable for the submitted transaction to be
1291  // processed and its result to be modified before being returned
1292  // to the client. Make a copy of the transaction and set its
1293  // status to guarantee that the client gets the terSUBMITTED
1294  // result in all cases.
1295  transaction = std::make_shared<Transaction>(*transaction);
1296  transaction->setResult(terSUBMITTED);
1297  break;
1298 
1299  case wait:
1300  mCond.wait(
1301  lock, [&transaction] { return !transaction->getApplying(); });
1302  break;
1303 
1304  default:
1305  assert(false);
1306  }
1307 }
1308 
1309 bool
1311 {
1312  {
1315  return false;
1316 
1317  do
1318  apply(lock);
1319  while (drain && mTransactions.size());
1320  }
1322  return true;
1323 }
1324 
1325 void
1327 {
1328  assert(!mTransactions.empty());
1330  std::vector<TransactionStatus> submit_held;
1331  std::vector<TransactionStatus> transactions;
1332  mTransactions.swap(transactions);
1334 
1335  batchLock.unlock();
1336 
1337  {
1338  std::unique_lock masterLock{app_.getMasterMutex(), std::defer_lock};
1339  bool changed = false;
1340  {
1341  std::unique_lock ledgerLock{
1342  m_ledgerMaster.peekMutex(), std::defer_lock};
1343  std::lock(masterLock, ledgerLock);
1344 
1345  app_.openLedger().modify([&](OpenView& view, beast::Journal j) {
1346  for (TransactionStatus& e : transactions)
1347  {
1348  // we check before adding to the batch
1349  ApplyFlags flags = tapNONE;
1350  if (e.admin)
1351  flags |= tapUNLIMITED;
1352 
1353  if (e.failType == FailHard::yes)
1354  flags |= tapFAIL_HARD;
1355 
1356  auto const result = app_.getTxQ().apply(
1357  app_, view, e.transaction->getSTransaction(), flags, j);
1358  e.result = result.first;
1359  e.applied = result.second;
1360  changed = changed || result.second;
1361  }
1362  return changed;
1363  });
1364  }
1365  if (changed)
1366  reportFeeChange();
1367 
1368  std::optional<LedgerIndex> validatedLedgerIndex;
1369  if (auto const l = m_ledgerMaster.getValidatedLedger())
1370  validatedLedgerIndex = l->info().seq;
1371 
1372  auto newOL = app_.openLedger().current();
1373  for (TransactionStatus& e : transactions)
1374  {
1375  e.transaction->clearSubmitResult();
1376 
1377  if (e.applied)
1378  {
1380  newOL, e.transaction->getSTransaction(), e.result);
1381  e.transaction->setApplied();
1382  }
1383 
1384  e.transaction->setResult(e.result);
1385 
1386  if (isTemMalformed(e.result))
1387  app_.getHashRouter().setFlags(e.transaction->getID(), SF_BAD);
1388 
1389 #ifdef DEBUG
1390  if (e.result != tesSUCCESS)
1391  {
1392  std::string token, human;
1393 
1394  if (transResultInfo(e.result, token, human))
1395  {
1396  JLOG(m_journal.info())
1397  << "TransactionResult: " << token << ": " << human;
1398  }
1399  }
1400 #endif
1401 
1402  bool addLocal = e.local;
1403 
1404  if (e.result == tesSUCCESS)
1405  {
1406  JLOG(m_journal.debug())
1407  << "Transaction is now included in open ledger";
1408  e.transaction->setStatus(INCLUDED);
1409 
1410  auto const& txCur = e.transaction->getSTransaction();
1411  auto const txNext = m_ledgerMaster.popAcctTransaction(txCur);
1412  if (txNext)
1413  {
1414  std::string reason;
1415  auto const trans = sterilize(*txNext);
1416  auto t = std::make_shared<Transaction>(trans, reason, app_);
1417  submit_held.emplace_back(t, false, false, FailHard::no);
1418  t->setApplying();
1419  }
1420  }
1421  else if (e.result == tefPAST_SEQ)
1422  {
1423  // duplicate or conflict
1424  JLOG(m_journal.info()) << "Transaction is obsolete";
1425  e.transaction->setStatus(OBSOLETE);
1426  }
1427  else if (e.result == terQUEUED)
1428  {
1429  JLOG(m_journal.debug())
1430  << "Transaction is likely to claim a"
1431  << " fee, but is queued until fee drops";
1432 
1433  e.transaction->setStatus(HELD);
1434  // Add to held transactions, because it could get
1435  // kicked out of the queue, and this will try to
1436  // put it back.
1437  m_ledgerMaster.addHeldTransaction(e.transaction);
1438  e.transaction->setQueued();
1439  e.transaction->setKept();
1440  }
1441  else if (isTerRetry(e.result))
1442  {
1443  if (e.failType != FailHard::yes)
1444  {
1445  // transaction should be held
1446  JLOG(m_journal.debug())
1447  << "Transaction should be held: " << e.result;
1448  e.transaction->setStatus(HELD);
1449  m_ledgerMaster.addHeldTransaction(e.transaction);
1450  e.transaction->setKept();
1451  }
1452  }
1453  else
1454  {
1455  JLOG(m_journal.debug())
1456  << "Status other than success " << e.result;
1457  e.transaction->setStatus(INVALID);
1458  }
1459 
1460  auto const enforceFailHard =
1461  e.failType == FailHard::yes && !isTesSuccess(e.result);
1462 
1463  if (addLocal && !enforceFailHard)
1464  {
1465  m_localTX->push_back(
1467  e.transaction->getSTransaction());
1468  e.transaction->setKept();
1469  }
1470 
1471  if ((e.applied ||
1472  ((mMode != OperatingMode::FULL) &&
1473  (e.failType != FailHard::yes) && e.local) ||
1474  (e.result == terQUEUED)) &&
1475  !enforceFailHard)
1476  {
1477  auto const toSkip =
1478  app_.getHashRouter().shouldRelay(e.transaction->getID());
1479 
1480  if (toSkip)
1481  {
1482  protocol::TMTransaction tx;
1483  Serializer s;
1484 
1485  e.transaction->getSTransaction()->add(s);
1486  tx.set_rawtransaction(s.data(), s.size());
1487  tx.set_status(protocol::tsCURRENT);
1488  tx.set_receivetimestamp(
1489  app_.timeKeeper().now().time_since_epoch().count());
1490  tx.set_deferred(e.result == terQUEUED);
1491  // FIXME: This should be when we received it
1492  app_.overlay().relay(e.transaction->getID(), tx, *toSkip);
1493  e.transaction->setBroadcast();
1494  }
1495  }
1496 
1497  if (validatedLedgerIndex)
1498  {
1499  auto [fee, accountSeq, availableSeq] =
1501  *newOL, e.transaction->getSTransaction());
1502  e.transaction->setCurrentLedgerState(
1503  *validatedLedgerIndex, fee, accountSeq, availableSeq);
1504  }
1505  }
1506  }
1507 
1508  batchLock.lock();
1509 
1510  for (TransactionStatus& e : transactions)
1511  e.transaction->clearApplying();
1512 
1513  if (!submit_held.empty())
1514  {
1515  if (mTransactions.empty())
1516  mTransactions.swap(submit_held);
1517  else
1518  for (auto& e : submit_held)
1519  mTransactions.push_back(std::move(e));
1520  }
1521 
1522  mCond.notify_all();
1523 
1525 }
1526 
1527 //
1528 // Owner functions
1529 //
1530 
1534  AccountID const& account)
1535 {
1536  Json::Value jvObjects(Json::objectValue);
1537  auto root = keylet::ownerDir(account);
1538  auto sleNode = lpLedger->read(keylet::page(root));
1539  if (sleNode)
1540  {
1541  std::uint64_t uNodeDir;
1542 
1543  do
1544  {
1545  for (auto const& uDirEntry : sleNode->getFieldV256(sfIndexes))
1546  {
1547  auto sleCur = lpLedger->read(keylet::child(uDirEntry));
1548  assert(sleCur);
1549 
1550  switch (sleCur->getType())
1551  {
1552  case ltOFFER:
1553  if (!jvObjects.isMember(jss::offers))
1554  jvObjects[jss::offers] =
1556 
1557  jvObjects[jss::offers].append(
1558  sleCur->getJson(JsonOptions::none));
1559  break;
1560 
1561  case ltRIPPLE_STATE:
1562  if (!jvObjects.isMember(jss::ripple_lines))
1563  {
1564  jvObjects[jss::ripple_lines] =
1566  }
1567 
1568  jvObjects[jss::ripple_lines].append(
1569  sleCur->getJson(JsonOptions::none));
1570  break;
1571 
1572  case ltACCOUNT_ROOT:
1573  case ltDIR_NODE:
1574  default:
1575  assert(false);
1576  break;
1577  }
1578  }
1579 
1580  uNodeDir = sleNode->getFieldU64(sfIndexNext);
1581 
1582  if (uNodeDir)
1583  {
1584  sleNode = lpLedger->read(keylet::page(root, uNodeDir));
1585  assert(sleNode);
1586  }
1587  } while (uNodeDir);
1588  }
1589 
1590  return jvObjects;
1591 }
1592 
1593 //
1594 // Other
1595 //
1596 
1597 inline bool
1599 {
1600  return isAmendmentBlocked() || isUNLBlocked();
1601 }
1602 
1603 inline bool
1605 {
1606  return amendmentBlocked_;
1607 }
1608 
1609 void
1611 {
1612  amendmentBlocked_ = true;
1614 }
1615 
1616 inline bool
1618 {
1620 }
1621 
1622 inline void
1624 {
1625  amendmentWarned_ = true;
1626 }
1627 
1628 inline void
1630 {
1631  amendmentWarned_ = false;
1632 }
1633 
1634 inline bool
1636 {
1637  return unlBlocked_;
1638 }
1639 
1640 void
1642 {
1643  unlBlocked_ = true;
1645 }
1646 
1647 inline void
1649 {
1650  unlBlocked_ = false;
1651 }
1652 
1653 bool
1655  const Overlay::PeerSequence& peerList,
1656  uint256& networkClosed)
1657 {
1658  // Returns true if there's an *abnormal* ledger issue, normal changing in
1659  // TRACKING mode should return false. Do we have sufficient validations for
1660  // our last closed ledger? Or do sufficient nodes agree? And do we have no
1661  // better ledger available? If so, we are either tracking or full.
1662 
1663  JLOG(m_journal.trace()) << "NetworkOPsImp::checkLastClosedLedger";
1664 
1665  auto const ourClosed = m_ledgerMaster.getClosedLedger();
1666 
1667  if (!ourClosed)
1668  return false;
1669 
1670  uint256 closedLedger = ourClosed->info().hash;
1671  uint256 prevClosedLedger = ourClosed->info().parentHash;
1672  JLOG(m_journal.trace()) << "OurClosed: " << closedLedger;
1673  JLOG(m_journal.trace()) << "PrevClosed: " << prevClosedLedger;
1674 
1675  //-------------------------------------------------------------------------
1676  // Determine preferred last closed ledger
1677 
1678  auto& validations = app_.getValidations();
1679  JLOG(m_journal.debug())
1680  << "ValidationTrie " << Json::Compact(validations.getJsonTrie());
1681 
1682  // Will rely on peer LCL if no trusted validations exist
1684  peerCounts[closedLedger] = 0;
1686  peerCounts[closedLedger]++;
1687 
1688  for (auto& peer : peerList)
1689  {
1690  uint256 peerLedger = peer->getClosedLedgerHash();
1691 
1692  if (peerLedger.isNonZero())
1693  ++peerCounts[peerLedger];
1694  }
1695 
1696  for (auto const& it : peerCounts)
1697  JLOG(m_journal.debug()) << "L: " << it.first << " n=" << it.second;
1698 
1699  uint256 preferredLCL = validations.getPreferredLCL(
1700  RCLValidatedLedger{ourClosed, validations.adaptor().journal()},
1702  peerCounts);
1703 
1704  bool switchLedgers = preferredLCL != closedLedger;
1705  if (switchLedgers)
1706  closedLedger = preferredLCL;
1707  //-------------------------------------------------------------------------
1708  if (switchLedgers && (closedLedger == prevClosedLedger))
1709  {
1710  // don't switch to our own previous ledger
1711  JLOG(m_journal.info()) << "We won't switch to our own previous ledger";
1712  networkClosed = ourClosed->info().hash;
1713  switchLedgers = false;
1714  }
1715  else
1716  {
1717  networkClosed = closedLedger;
1718  }
1719 
1720  if (!switchLedgers)
1721  return false;
1722 
1723  auto consensus = m_ledgerMaster.getLedgerByHash(closedLedger);
1724 
1725  if (!consensus)
1726  consensus = app_.getInboundLedgers().acquire(
1727  closedLedger, 0, InboundLedger::Reason::CONSENSUS);
1728 
1729  if (consensus &&
1730  (!m_ledgerMaster.canBeCurrent(consensus) ||
1732  *consensus, m_journal.debug(), "Not switching")))
1733  {
1734  // Don't switch to a ledger not on the validated chain
1735  // or with an invalid close time or sequence
1736  networkClosed = ourClosed->info().hash;
1737  return false;
1738  }
1739 
1740  JLOG(m_journal.warn()) << "We are not running on the consensus ledger";
1741  JLOG(m_journal.info()) << "Our LCL: " << getJson({*ourClosed, {}});
1742  JLOG(m_journal.info()) << "Net LCL " << closedLedger;
1743 
1745  {
1747  }
1748 
1749  if (consensus)
1750  {
1751  // FIXME: If this rewinds the ledger sequence, or has the same
1752  // sequence, we should update the status on any stored transactions
1753  // in the invalidated ledgers.
1754  switchLastClosedLedger(consensus);
1755  }
1756 
1757  return true;
1758 }
1759 
1760 void
1762  std::shared_ptr<Ledger const> const& newLCL)
1763 {
1764  // set the newLCL as our last closed ledger -- this is abnormal code
1765  JLOG(m_journal.error())
1766  << "JUMP last closed ledger to " << newLCL->info().hash;
1767 
1769 
1770  // Update fee computations.
1771  app_.getTxQ().processClosedLedger(app_, *newLCL, true);
1772 
1773  // Caller must own master lock
1774  {
1775  // Apply tx in old open ledger to new
1776  // open ledger. Then apply local tx.
1777 
1778  auto retries = m_localTX->getTxSet();
1779  auto const lastVal = app_.getLedgerMaster().getValidatedLedger();
1780  std::optional<Rules> rules;
1781  if (lastVal)
1782  rules = makeRulesGivenLedger(*lastVal, app_.config().features);
1783  else
1784  rules.emplace(app_.config().features);
1786  app_,
1787  *rules,
1788  newLCL,
1789  OrderedTxs({}),
1790  false,
1791  retries,
1792  tapNONE,
1793  "jump",
1794  [&](OpenView& view, beast::Journal j) {
1795  // Stuff the ledger with transactions from the queue.
1796  return app_.getTxQ().accept(app_, view);
1797  });
1798  }
1799 
1800  m_ledgerMaster.switchLCL(newLCL);
1801 
1802  protocol::TMStatusChange s;
1803  s.set_newevent(protocol::neSWITCHED_LEDGER);
1804  s.set_ledgerseq(newLCL->info().seq);
1805  s.set_networktime(app_.timeKeeper().now().time_since_epoch().count());
1806  s.set_ledgerhashprevious(
1807  newLCL->info().parentHash.begin(), newLCL->info().parentHash.size());
1808  s.set_ledgerhash(newLCL->info().hash.begin(), newLCL->info().hash.size());
1809 
1810  app_.overlay().foreach(
1811  send_always(std::make_shared<Message>(s, protocol::mtSTATUS_CHANGE)));
1812 }
1813 
1814 bool
1816 {
1817  assert(networkClosed.isNonZero());
1818 
1819  auto closingInfo = m_ledgerMaster.getCurrentLedger()->info();
1820 
1821  JLOG(m_journal.info()) << "Consensus time for #" << closingInfo.seq
1822  << " with LCL " << closingInfo.parentHash;
1823 
1824  auto prevLedger = m_ledgerMaster.getLedgerByHash(closingInfo.parentHash);
1825 
1826  if (!prevLedger)
1827  {
1828  // this shouldn't happen unless we jump ledgers
1829  if (mMode == OperatingMode::FULL)
1830  {
1831  JLOG(m_journal.warn()) << "Don't have LCL, going to tracking";
1833  }
1834 
1835  return false;
1836  }
1837 
1838  assert(prevLedger->info().hash == closingInfo.parentHash);
1839  assert(
1840  closingInfo.parentHash ==
1841  m_ledgerMaster.getClosedLedger()->info().hash);
1842 
1843  if (prevLedger->rules().enabled(featureNegativeUNL))
1844  app_.validators().setNegativeUNL(prevLedger->negativeUNL());
1845  TrustChanges const changes = app_.validators().updateTrusted(
1847  closingInfo.parentCloseTime,
1848  *this,
1849  app_.overlay(),
1850  app_.getHashRouter());
1851 
1852  if (!changes.added.empty() || !changes.removed.empty())
1853  {
1854  app_.getValidations().trustChanged(changes.added, changes.removed);
1855  // Update the AmendmentTable so it tracks the current validators.
1858  }
1859 
1862  networkClosed,
1863  prevLedger,
1864  changes.removed,
1865  changes.added);
1866 
1867  const ConsensusPhase currPhase = mConsensus.phase();
1868  if (mLastConsensusPhase != currPhase)
1869  {
1870  reportConsensusStateChange(currPhase);
1871  mLastConsensusPhase = currPhase;
1872  }
1873 
1874  JLOG(m_journal.debug()) << "Initiating consensus engine";
1875  return true;
1876 }
1877 
1878 bool
1880 {
1881  return mConsensus.peerProposal(app_.timeKeeper().closeTime(), peerPos);
1882 }
1883 
1884 void
1886 {
1887  // We now have an additional transaction set
1888  // either created locally during the consensus process
1889  // or acquired from a peer
1890 
1891  // Inform peers we have this set
1892  protocol::TMHaveTransactionSet msg;
1893  msg.set_hash(map->getHash().as_uint256().begin(), 256 / 8);
1894  msg.set_status(protocol::tsHAVE);
1895  app_.overlay().foreach(
1896  send_always(std::make_shared<Message>(msg, protocol::mtHAVE_SET)));
1897 
1898  // We acquired it because consensus asked us to
1899  if (fromAcquire)
1901 }
1902 
1903 void
1905 {
1906  uint256 deadLedger = m_ledgerMaster.getClosedLedger()->info().parentHash;
1907 
1908  for (auto const& it : app_.overlay().getActivePeers())
1909  {
1910  if (it && (it->getClosedLedgerHash() == deadLedger))
1911  {
1912  JLOG(m_journal.trace()) << "Killing obsolete peer status";
1913  it->cycleStatus();
1914  }
1915  }
1916 
1917  uint256 networkClosed;
1918  bool ledgerChange =
1919  checkLastClosedLedger(app_.overlay().getActivePeers(), networkClosed);
1920 
1921  if (networkClosed.isZero())
1922  return;
1923 
1924  // WRITEME: Unless we are in FULL and in the process of doing a consensus,
1925  // we must count how many nodes share our LCL, how many nodes disagree with
1926  // our LCL, and how many validations our LCL has. We also want to check
1927  // timing to make sure there shouldn't be a newer LCL. We need this
1928  // information to do the next three tests.
1929 
1930  if (((mMode == OperatingMode::CONNECTED) ||
1931  (mMode == OperatingMode::SYNCING)) &&
1932  !ledgerChange)
1933  {
1934  // Count number of peers that agree with us and UNL nodes whose
1935  // validations we have for LCL. If the ledger is good enough, go to
1936  // TRACKING - TODO
1937  if (!needNetworkLedger_)
1939  }
1940 
1941  if (((mMode == OperatingMode::CONNECTED) ||
1943  !ledgerChange)
1944  {
1945  // check if the ledger is good enough to go to FULL
1946  // Note: Do not go to FULL if we don't have the previous ledger
1947  // check if the ledger is bad enough to go to CONNECTE D -- TODO
1949  if (app_.timeKeeper().now() < (current->info().parentCloseTime +
1950  2 * current->info().closeTimeResolution))
1951  {
1953  }
1954  }
1955 
1956  beginConsensus(networkClosed);
1957 }
1958 
1959 void
1961 {
1963  {
1965  }
1966 }
1967 
1968 void
1970 {
1971  // VFALCO consider std::shared_mutex
1973 
1974  if (!mStreamMaps[sManifests].empty())
1975  {
1977 
1978  jvObj[jss::type] = "manifestReceived";
1979  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, mo.masterKey);
1980  if (!mo.signingKey.empty())
1981  jvObj[jss::signing_key] =
1983  jvObj[jss::seq] = Json::UInt(mo.sequence);
1984  if (auto sig = mo.getSignature())
1985  jvObj[jss::signature] = strHex(*sig);
1986  jvObj[jss::master_signature] = strHex(mo.getMasterSignature());
1987  if (!mo.domain.empty())
1988  jvObj[jss::domain] = mo.domain;
1989  jvObj[jss::manifest] = strHex(mo.serialized);
1990 
1991  for (auto i = mStreamMaps[sManifests].begin();
1992  i != mStreamMaps[sManifests].end();)
1993  {
1994  if (auto p = i->second.lock())
1995  {
1996  p->send(jvObj, true);
1997  ++i;
1998  }
1999  else
2000  {
2001  i = mStreamMaps[sManifests].erase(i);
2002  }
2003  }
2004  }
2005 }
2006 
2008  XRPAmount fee,
2009  TxQ::Metrics&& escalationMetrics,
2010  LoadFeeTrack const& loadFeeTrack)
2011  : loadFactorServer{loadFeeTrack.getLoadFactor()}
2012  , loadBaseServer{loadFeeTrack.getLoadBase()}
2013  , baseFee{fee}
2014  , em{std::move(escalationMetrics)}
2015 {
2016 }
2017 
2018 bool
2020  NetworkOPsImp::ServerFeeSummary const& b) const
2021 {
2022  if (loadFactorServer != b.loadFactorServer ||
2023  loadBaseServer != b.loadBaseServer || baseFee != b.baseFee ||
2024  em.has_value() != b.em.has_value())
2025  return true;
2026 
2027  if (em && b.em)
2028  {
2029  return (
2030  em->minProcessingFeeLevel != b.em->minProcessingFeeLevel ||
2031  em->openLedgerFeeLevel != b.em->openLedgerFeeLevel ||
2032  em->referenceFeeLevel != b.em->referenceFeeLevel);
2033  }
2034 
2035  return false;
2036 }
2037 
2038 // Need to cap to uint64 to uint32 due to JSON limitations
2039 static std::uint32_t
2041 {
2043 
2044  return std::min(max32, v);
2045 };
2046 
2047 void
2049 {
2050  // VFALCO TODO Don't hold the lock across calls to send...make a copy of the
2051  // list into a local array while holding the lock then release
2052  // the lock and call send on everyone.
2053  //
2055 
2056  if (!mStreamMaps[sServer].empty())
2057  {
2059 
2060  ServerFeeSummary f{
2061  app_.openLedger().current()->fees().base,
2063  app_.getFeeTrack()};
2064 
2065  jvObj[jss::type] = "serverStatus";
2066  jvObj[jss::server_status] = strOperatingMode();
2067  jvObj[jss::load_base] = f.loadBaseServer;
2068  jvObj[jss::load_factor_server] = f.loadFactorServer;
2069  jvObj[jss::base_fee] = f.baseFee.jsonClipped();
2070 
2071  if (f.em)
2072  {
2073  auto const loadFactor = std::max(
2074  safe_cast<std::uint64_t>(f.loadFactorServer),
2075  mulDiv(
2076  f.em->openLedgerFeeLevel,
2077  f.loadBaseServer,
2078  f.em->referenceFeeLevel)
2079  .value_or(ripple::muldiv_max));
2080 
2081  jvObj[jss::load_factor] = trunc32(loadFactor);
2082  jvObj[jss::load_factor_fee_escalation] =
2083  f.em->openLedgerFeeLevel.jsonClipped();
2084  jvObj[jss::load_factor_fee_queue] =
2085  f.em->minProcessingFeeLevel.jsonClipped();
2086  jvObj[jss::load_factor_fee_reference] =
2087  f.em->referenceFeeLevel.jsonClipped();
2088  }
2089  else
2090  jvObj[jss::load_factor] = f.loadFactorServer;
2091 
2092  mLastFeeSummary = f;
2093 
2094  for (auto i = mStreamMaps[sServer].begin();
2095  i != mStreamMaps[sServer].end();)
2096  {
2097  InfoSub::pointer p = i->second.lock();
2098 
2099  // VFALCO TODO research the possibility of using thread queues and
2100  // linearizing the deletion of subscribers with the
2101  // sending of JSON data.
2102  if (p)
2103  {
2104  p->send(jvObj, true);
2105  ++i;
2106  }
2107  else
2108  {
2109  i = mStreamMaps[sServer].erase(i);
2110  }
2111  }
2112  }
2113 }
2114 
2115 void
2117 {
2119 
2120  auto& streamMap = mStreamMaps[sConsensusPhase];
2121  if (!streamMap.empty())
2122  {
2124  jvObj[jss::type] = "consensusPhase";
2125  jvObj[jss::consensus] = to_string(phase);
2126 
2127  for (auto i = streamMap.begin(); i != streamMap.end();)
2128  {
2129  if (auto p = i->second.lock())
2130  {
2131  p->send(jvObj, true);
2132  ++i;
2133  }
2134  else
2135  {
2136  i = streamMap.erase(i);
2137  }
2138  }
2139  }
2140 }
2141 
2142 void
2144 {
2145  // VFALCO consider std::shared_mutex
2147 
2148  if (!mStreamMaps[sValidations].empty())
2149  {
2151 
2152  auto const signerPublic = val->getSignerPublic();
2153 
2154  jvObj[jss::type] = "validationReceived";
2155  jvObj[jss::validation_public_key] =
2156  toBase58(TokenType::NodePublic, signerPublic);
2157  jvObj[jss::ledger_hash] = to_string(val->getLedgerHash());
2158  jvObj[jss::signature] = strHex(val->getSignature());
2159  jvObj[jss::full] = val->isFull();
2160  jvObj[jss::flags] = val->getFlags();
2161  jvObj[jss::signing_time] = *(*val)[~sfSigningTime];
2162  jvObj[jss::data] = strHex(val->getSerializer().slice());
2163 
2164  if (auto version = (*val)[~sfServerVersion])
2165  jvObj[jss::server_version] = std::to_string(*version);
2166 
2167  if (auto cookie = (*val)[~sfCookie])
2168  jvObj[jss::cookie] = std::to_string(*cookie);
2169 
2170  if (auto hash = (*val)[~sfValidatedHash])
2171  jvObj[jss::validated_hash] = strHex(*hash);
2172 
2173  auto const masterKey =
2174  app_.validatorManifests().getMasterKey(signerPublic);
2175 
2176  if (masterKey != signerPublic)
2177  jvObj[jss::master_key] = toBase58(TokenType::NodePublic, masterKey);
2178 
2179  if (auto const seq = (*val)[~sfLedgerSequence])
2180  jvObj[jss::ledger_index] = to_string(*seq);
2181 
2182  if (val->isFieldPresent(sfAmendments))
2183  {
2184  jvObj[jss::amendments] = Json::Value(Json::arrayValue);
2185  for (auto const& amendment : val->getFieldV256(sfAmendments))
2186  jvObj[jss::amendments].append(to_string(amendment));
2187  }
2188 
2189  if (auto const closeTime = (*val)[~sfCloseTime])
2190  jvObj[jss::close_time] = *closeTime;
2191 
2192  if (auto const loadFee = (*val)[~sfLoadFee])
2193  jvObj[jss::load_fee] = *loadFee;
2194 
2195  if (auto const baseFee = val->at(~sfBaseFee))
2196  jvObj[jss::base_fee] = static_cast<double>(*baseFee);
2197 
2198  if (auto const reserveBase = val->at(~sfReserveBase))
2199  jvObj[jss::reserve_base] = *reserveBase;
2200 
2201  if (auto const reserveInc = val->at(~sfReserveIncrement))
2202  jvObj[jss::reserve_inc] = *reserveInc;
2203 
2204  // (The ~ operator converts the Proxy to a std::optional, which
2205  // simplifies later operations)
2206  if (auto const baseFeeXRP = ~val->at(~sfBaseFeeDrops);
2207  baseFeeXRP && baseFeeXRP->native())
2208  jvObj[jss::base_fee] = baseFeeXRP->xrp().jsonClipped();
2209 
2210  if (auto const reserveBaseXRP = ~val->at(~sfReserveBaseDrops);
2211  reserveBaseXRP && reserveBaseXRP->native())
2212  jvObj[jss::reserve_base] = reserveBaseXRP->xrp().jsonClipped();
2213 
2214  if (auto const reserveIncXRP = ~val->at(~sfReserveIncrementDrops);
2215  reserveIncXRP && reserveIncXRP->native())
2216  jvObj[jss::reserve_inc] = reserveIncXRP->xrp().jsonClipped();
2217 
2218  for (auto i = mStreamMaps[sValidations].begin();
2219  i != mStreamMaps[sValidations].end();)
2220  {
2221  if (auto p = i->second.lock())
2222  {
2223  p->send(jvObj, true);
2224  ++i;
2225  }
2226  else
2227  {
2228  i = mStreamMaps[sValidations].erase(i);
2229  }
2230  }
2231  }
2232 }
2233 
2234 void
2236 {
2238 
2239  if (!mStreamMaps[sPeerStatus].empty())
2240  {
2241  Json::Value jvObj(func());
2242 
2243  jvObj[jss::type] = "peerStatusChange";
2244 
2245  for (auto i = mStreamMaps[sPeerStatus].begin();
2246  i != mStreamMaps[sPeerStatus].end();)
2247  {
2248  InfoSub::pointer p = i->second.lock();
2249 
2250  if (p)
2251  {
2252  p->send(jvObj, true);
2253  ++i;
2254  }
2255  else
2256  {
2257  i = mStreamMaps[sPeerStatus].erase(i);
2258  }
2259  }
2260  }
2261 }
2262 
2263 void
2265 {
2266  using namespace std::chrono_literals;
2267  if (om == OperatingMode::CONNECTED)
2268  {
2271  }
2272  else if (om == OperatingMode::SYNCING)
2273  {
2274  if (app_.getLedgerMaster().getValidatedLedgerAge() >= 1min)
2276  }
2277 
2278  if ((om > OperatingMode::CONNECTED) && isBlocked())
2280 
2281  if (mMode == om)
2282  return;
2283 
2284  mMode = om;
2285 
2286  accounting_.mode(om);
2287 
2288  JLOG(m_journal.info()) << "STATE->" << strOperatingMode();
2289  pubServer();
2290 }
2291 
2292 bool
2294  std::shared_ptr<STValidation> const& val,
2295  std::string const& source)
2296 {
2297  JLOG(m_journal.trace())
2298  << "recvValidation " << val->getLedgerHash() << " from " << source;
2299 
2300  handleNewValidation(app_, val, source);
2301 
2302  pubValidation(val);
2303 
2304  // We will always relay trusted validations; if configured, we will
2305  // also relay all untrusted validations.
2306  return app_.config().RELAY_UNTRUSTED_VALIDATIONS == 1 || val->isTrusted();
2307 }
2308 
2311 {
2312  return mConsensus.getJson(true);
2313 }
2314 
2316 NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
2317 {
2319 
2320  // System-level warnings
2321  {
2322  Json::Value warnings{Json::arrayValue};
2323  if (isAmendmentBlocked())
2324  {
2325  Json::Value& w = warnings.append(Json::objectValue);
2326  w[jss::id] = warnRPC_AMENDMENT_BLOCKED;
2327  w[jss::message] =
2328  "This server is amendment blocked, and must be updated to be "
2329  "able to stay in sync with the network.";
2330  }
2331  if (isUNLBlocked())
2332  {
2333  Json::Value& w = warnings.append(Json::objectValue);
2334  w[jss::id] = warnRPC_EXPIRED_VALIDATOR_LIST;
2335  w[jss::message] =
2336  "This server has an expired validator list. validators.txt "
2337  "may be incorrectly configured or some [validator_list_sites] "
2338  "may be unreachable.";
2339  }
2340  if (admin && isAmendmentWarned())
2341  {
2342  Json::Value& w = warnings.append(Json::objectValue);
2343  w[jss::id] = warnRPC_UNSUPPORTED_MAJORITY;
2344  w[jss::message] =
2345  "One or more unsupported amendments have reached majority. "
2346  "Upgrade to the latest version before they are activated "
2347  "to avoid being amendment blocked.";
2348  if (auto const expected =
2350  {
2351  auto& d = w[jss::details] = Json::objectValue;
2352  d[jss::expected_date] = expected->time_since_epoch().count();
2353  d[jss::expected_date_UTC] = to_string(*expected);
2354  }
2355  }
2356 
2357  if (warnings.size())
2358  info[jss::warnings] = std::move(warnings);
2359  }
2360 
2361  // hostid: unique string describing the machine
2362  if (human)
2363  info[jss::hostid] = getHostId(admin);
2364 
2365  // domain: if configured with a domain, report it:
2366  if (!app_.config().SERVER_DOMAIN.empty())
2367  info[jss::server_domain] = app_.config().SERVER_DOMAIN;
2368 
2369  info[jss::build_version] = BuildInfo::getVersionString();
2370 
2371  info[jss::server_state] = strOperatingMode(admin);
2372 
2373  info[jss::time] = to_string(std::chrono::floor<std::chrono::microseconds>(
2375 
2376  if (needNetworkLedger_)
2377  info[jss::network_ledger] = "waiting";
2378 
2379  info[jss::validation_quorum] =
2380  static_cast<Json::UInt>(app_.validators().quorum());
2381 
2382  if (admin)
2383  {
2384  switch (app_.config().NODE_SIZE)
2385  {
2386  case 0:
2387  info[jss::node_size] = "tiny";
2388  break;
2389  case 1:
2390  info[jss::node_size] = "small";
2391  break;
2392  case 2:
2393  info[jss::node_size] = "medium";
2394  break;
2395  case 3:
2396  info[jss::node_size] = "large";
2397  break;
2398  case 4:
2399  info[jss::node_size] = "huge";
2400  break;
2401  }
2402 
2403  auto when = app_.validators().expires();
2404 
2405  if (!human)
2406  {
2407  if (when)
2408  info[jss::validator_list_expires] =
2409  safe_cast<Json::UInt>(when->time_since_epoch().count());
2410  else
2411  info[jss::validator_list_expires] = 0;
2412  }
2413  else
2414  {
2415  auto& x = (info[jss::validator_list] = Json::objectValue);
2416 
2417  x[jss::count] = static_cast<Json::UInt>(app_.validators().count());
2418 
2419  if (when)
2420  {
2421  if (*when == TimeKeeper::time_point::max())
2422  {
2423  x[jss::expiration] = "never";
2424  x[jss::status] = "active";
2425  }
2426  else
2427  {
2428  x[jss::expiration] = to_string(*when);
2429 
2430  if (*when > app_.timeKeeper().now())
2431  x[jss::status] = "active";
2432  else
2433  x[jss::status] = "expired";
2434  }
2435  }
2436  else
2437  {
2438  x[jss::status] = "unknown";
2439  x[jss::expiration] = "unknown";
2440  }
2441  }
2442  }
2443  info[jss::io_latency_ms] =
2444  static_cast<Json::UInt>(app_.getIOLatency().count());
2445 
2446  if (admin)
2447  {
2449  {
2450  info[jss::pubkey_validator] = toBase58(
2452  }
2453  else
2454  {
2455  info[jss::pubkey_validator] = "none";
2456  }
2457  }
2458 
2459  if (counters)
2460  {
2461  info[jss::counters] = app_.getPerfLog().countersJson();
2462 
2463  Json::Value nodestore(Json::objectValue);
2464  if (app_.getShardStore())
2465  app_.getShardStore()->getCountsJson(nodestore);
2466  else
2467  app_.getNodeStore().getCountsJson(nodestore);
2468  info[jss::counters][jss::nodestore] = nodestore;
2469  info[jss::current_activities] = app_.getPerfLog().currentJson();
2470  }
2471 
2472  info[jss::pubkey_node] =
2474 
2475  info[jss::complete_ledgers] = app_.getLedgerMaster().getCompleteLedgers();
2476 
2477  if (amendmentBlocked_)
2478  info[jss::amendment_blocked] = true;
2479 
2480  auto const fp = m_ledgerMaster.getFetchPackCacheSize();
2481 
2482  if (fp != 0)
2483  info[jss::fetch_pack] = Json::UInt(fp);
2484 
2485  if (!app_.config().reporting())
2486  info[jss::peers] = Json::UInt(app_.overlay().size());
2487 
2488  Json::Value lastClose = Json::objectValue;
2489  lastClose[jss::proposers] = Json::UInt(mConsensus.prevProposers());
2490 
2491  if (human)
2492  {
2493  lastClose[jss::converge_time_s] =
2495  }
2496  else
2497  {
2498  lastClose[jss::converge_time] =
2500  }
2501 
2502  info[jss::last_close] = lastClose;
2503 
2504  // info[jss::consensus] = mConsensus.getJson();
2505 
2506  if (admin)
2507  info[jss::load] = m_job_queue.getJson();
2508 
2509  if (!app_.config().reporting())
2510  {
2511  if (auto const netid = app_.overlay().networkID())
2512  info[jss::network_id] = static_cast<Json::UInt>(*netid);
2513 
2514  auto const escalationMetrics =
2516 
2517  auto const loadFactorServer = app_.getFeeTrack().getLoadFactor();
2518  auto const loadBaseServer = app_.getFeeTrack().getLoadBase();
2519  /* Scale the escalated fee level to unitless "load factor".
2520  In practice, this just strips the units, but it will continue
2521  to work correctly if either base value ever changes. */
2522  auto const loadFactorFeeEscalation =
2523  mulDiv(
2524  escalationMetrics.openLedgerFeeLevel,
2525  loadBaseServer,
2526  escalationMetrics.referenceFeeLevel)
2527  .value_or(ripple::muldiv_max);
2528 
2529  auto const loadFactor = std::max(
2530  safe_cast<std::uint64_t>(loadFactorServer),
2531  loadFactorFeeEscalation);
2532 
2533  if (!human)
2534  {
2535  info[jss::load_base] = loadBaseServer;
2536  info[jss::load_factor] = trunc32(loadFactor);
2537  info[jss::load_factor_server] = loadFactorServer;
2538 
2539  /* Json::Value doesn't support uint64, so clamp to max
2540  uint32 value. This is mostly theoretical, since there
2541  probably isn't enough extant XRP to drive the factor
2542  that high.
2543  */
2544  info[jss::load_factor_fee_escalation] =
2545  escalationMetrics.openLedgerFeeLevel.jsonClipped();
2546  info[jss::load_factor_fee_queue] =
2547  escalationMetrics.minProcessingFeeLevel.jsonClipped();
2548  info[jss::load_factor_fee_reference] =
2549  escalationMetrics.referenceFeeLevel.jsonClipped();
2550  }
2551  else
2552  {
2553  info[jss::load_factor] =
2554  static_cast<double>(loadFactor) / loadBaseServer;
2555 
2556  if (loadFactorServer != loadFactor)
2557  info[jss::load_factor_server] =
2558  static_cast<double>(loadFactorServer) / loadBaseServer;
2559 
2560  if (admin)
2561  {
2563  if (fee != loadBaseServer)
2564  info[jss::load_factor_local] =
2565  static_cast<double>(fee) / loadBaseServer;
2566  fee = app_.getFeeTrack().getRemoteFee();
2567  if (fee != loadBaseServer)
2568  info[jss::load_factor_net] =
2569  static_cast<double>(fee) / loadBaseServer;
2570  fee = app_.getFeeTrack().getClusterFee();
2571  if (fee != loadBaseServer)
2572  info[jss::load_factor_cluster] =
2573  static_cast<double>(fee) / loadBaseServer;
2574  }
2575  if (escalationMetrics.openLedgerFeeLevel !=
2576  escalationMetrics.referenceFeeLevel &&
2577  (admin || loadFactorFeeEscalation != loadFactor))
2578  info[jss::load_factor_fee_escalation] =
2579  escalationMetrics.openLedgerFeeLevel.decimalFromReference(
2580  escalationMetrics.referenceFeeLevel);
2581  if (escalationMetrics.minProcessingFeeLevel !=
2582  escalationMetrics.referenceFeeLevel)
2583  info[jss::load_factor_fee_queue] =
2584  escalationMetrics.minProcessingFeeLevel
2585  .decimalFromReference(
2586  escalationMetrics.referenceFeeLevel);
2587  }
2588  }
2589 
2590  bool valid = false;
2591  auto lpClosed = m_ledgerMaster.getValidatedLedger();
2592 
2593  if (lpClosed)
2594  valid = true;
2595  else if (!app_.config().reporting())
2596  lpClosed = m_ledgerMaster.getClosedLedger();
2597 
2598  if (lpClosed)
2599  {
2600  XRPAmount const baseFee = lpClosed->fees().base;
2602  l[jss::seq] = Json::UInt(lpClosed->info().seq);
2603  l[jss::hash] = to_string(lpClosed->info().hash);
2604 
2605  if (!human)
2606  {
2607  l[jss::base_fee] = baseFee.jsonClipped();
2608  l[jss::reserve_base] =
2609  lpClosed->fees().accountReserve(0).jsonClipped();
2610  l[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
2611  l[jss::close_time] = Json::Value::UInt(
2612  lpClosed->info().closeTime.time_since_epoch().count());
2613  }
2614  else
2615  {
2616  l[jss::base_fee_xrp] = baseFee.decimalXRP();
2617  l[jss::reserve_base_xrp] =
2618  lpClosed->fees().accountReserve(0).decimalXRP();
2619  l[jss::reserve_inc_xrp] = lpClosed->fees().increment.decimalXRP();
2620 
2621  if (auto const closeOffset = app_.timeKeeper().closeOffset();
2622  std::abs(closeOffset.count()) >= 60)
2623  l[jss::close_time_offset] =
2624  static_cast<std::uint32_t>(closeOffset.count());
2625 
2626 #if RIPPLED_REPORTING
2627  std::int64_t const dbAge =
2629  l[jss::age] = Json::UInt(dbAge);
2630 #else
2631  constexpr std::chrono::seconds highAgeThreshold{1000000};
2633  {
2634  auto const age = m_ledgerMaster.getValidatedLedgerAge();
2635  l[jss::age] =
2636  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2637  }
2638  else
2639  {
2640  auto lCloseTime = lpClosed->info().closeTime;
2641  auto closeTime = app_.timeKeeper().closeTime();
2642  if (lCloseTime <= closeTime)
2643  {
2644  using namespace std::chrono_literals;
2645  auto age = closeTime - lCloseTime;
2646  l[jss::age] =
2647  Json::UInt(age < highAgeThreshold ? age.count() : 0);
2648  }
2649  }
2650 #endif
2651  }
2652 
2653  if (valid)
2654  info[jss::validated_ledger] = l;
2655  else
2656  info[jss::closed_ledger] = l;
2657 
2658  auto lpPublished = m_ledgerMaster.getPublishedLedger();
2659  if (!lpPublished)
2660  info[jss::published_ledger] = "none";
2661  else if (lpPublished->info().seq != lpClosed->info().seq)
2662  info[jss::published_ledger] = lpPublished->info().seq;
2663  }
2664 
2665  accounting_.json(info);
2666  info[jss::uptime] = UptimeClock::now().time_since_epoch().count();
2667  if (!app_.config().reporting())
2668  {
2669  info[jss::jq_trans_overflow] =
2671  info[jss::peer_disconnects] =
2673  info[jss::peer_disconnects_resources] =
2675  }
2676  else
2677  {
2678  info["reporting"] = app_.getReportingETL().getInfo();
2679  }
2680 
2681  // This array must be sorted in increasing order.
2682  static constexpr std::array<std::string_view, 7> protocols{
2683  "http", "https", "peer", "ws", "ws2", "wss", "wss2"};
2684  static_assert(std::is_sorted(std::begin(protocols), std::end(protocols)));
2685  {
2687  for (auto const& port : app_.getServerHandler().setup().ports)
2688  {
2689  // Don't publish admin ports for non-admin users
2690  if (!admin &&
2691  !(port.admin_nets_v4.empty() && port.admin_nets_v6.empty() &&
2692  port.admin_user.empty() && port.admin_password.empty()))
2693  continue;
2696  std::begin(port.protocol),
2697  std::end(port.protocol),
2698  std::begin(protocols),
2699  std::end(protocols),
2700  std::back_inserter(proto));
2701  if (!proto.empty())
2702  {
2703  auto& jv = ports.append(Json::Value(Json::objectValue));
2704  jv[jss::port] = std::to_string(port.port);
2705  jv[jss::protocol] = Json::Value{Json::arrayValue};
2706  for (auto const& p : proto)
2707  jv[jss::protocol].append(p);
2708  }
2709  }
2710 
2711  if (app_.config().exists("port_grpc"))
2712  {
2713  auto const& grpcSection = app_.config().section("port_grpc");
2714  auto const optPort = grpcSection.get("port");
2715  if (optPort && grpcSection.get("ip"))
2716  {
2717  auto& jv = ports.append(Json::Value(Json::objectValue));
2718  jv[jss::port] = *optPort;
2719  jv[jss::protocol] = Json::Value{Json::arrayValue};
2720  jv[jss::protocol].append("grpc");
2721  }
2722  }
2723  info[jss::ports] = std::move(ports);
2724  }
2725 
2726  return info;
2727 }
2728 
2729 void
2731 {
2733 }
2734 
2737 {
2738  return app_.getInboundLedgers().getInfo();
2739 }
2740 
2741 void
2743  std::shared_ptr<ReadView const> const& ledger,
2744  std::shared_ptr<STTx const> const& transaction,
2745  TER result)
2746 {
2747  Json::Value jvObj = transJson(*transaction, result, false, ledger);
2748 
2749  {
2751 
2752  auto it = mStreamMaps[sRTTransactions].begin();
2753  while (it != mStreamMaps[sRTTransactions].end())
2754  {
2755  InfoSub::pointer p = it->second.lock();
2756 
2757  if (p)
2758  {
2759  p->send(jvObj, true);
2760  ++it;
2761  }
2762  else
2763  {
2764  it = mStreamMaps[sRTTransactions].erase(it);
2765  }
2766  }
2767  }
2768 
2769  pubProposedAccountTransaction(ledger, transaction, result);
2770 }
2771 
2772 void
2774 {
2775  // reporting does not forward validated transactions
2776  // validated transactions will be published to the proper streams when the
2777  // etl process writes a validated ledger
2778  if (jvObj[jss::validated].asBool())
2779  return;
2780  {
2782 
2783  auto it = mStreamMaps[sRTTransactions].begin();
2784  while (it != mStreamMaps[sRTTransactions].end())
2785  {
2786  InfoSub::pointer p = it->second.lock();
2787 
2788  if (p)
2789  {
2790  p->send(jvObj, true);
2791  ++it;
2792  }
2793  else
2794  {
2795  it = mStreamMaps[sRTTransactions].erase(it);
2796  }
2797  }
2798  }
2799 
2801 }
2802 
2803 void
2805 {
2807 
2808  for (auto i = mStreamMaps[sValidations].begin();
2809  i != mStreamMaps[sValidations].end();)
2810  {
2811  if (auto p = i->second.lock())
2812  {
2813  p->send(jvObj, true);
2814  ++i;
2815  }
2816  else
2817  {
2818  i = mStreamMaps[sValidations].erase(i);
2819  }
2820  }
2821 }
2822 
2823 void
2825 {
2827 
2828  for (auto i = mStreamMaps[sManifests].begin();
2829  i != mStreamMaps[sManifests].end();)
2830  {
2831  if (auto p = i->second.lock())
2832  {
2833  p->send(jvObj, true);
2834  ++i;
2835  }
2836  else
2837  {
2838  i = mStreamMaps[sManifests].erase(i);
2839  }
2840  }
2841 }
2842 
2843 static void
2845 {
2846  for (auto& jv : jvObj)
2847  {
2848  if (jv.isObject())
2849  {
2850  getAccounts(jv, accounts);
2851  }
2852  else if (jv.isString())
2853  {
2854  auto account = RPC::accountFromStringStrict(jv.asString());
2855  if (account)
2856  accounts.push_back(*account);
2857  }
2858  }
2859 }
2860 
2861 void
2863 {
2865  int iProposed = 0;
2866  // check if there are any subscribers before attempting to parse the JSON
2867  {
2869 
2870  if (mSubRTAccount.empty())
2871  return;
2872  }
2873 
2874  // parse the JSON outside of the lock
2875  std::vector<AccountID> accounts;
2876  if (jvObj.isMember(jss::transaction))
2877  {
2878  try
2879  {
2880  getAccounts(jvObj[jss::transaction], accounts);
2881  }
2882  catch (...)
2883  {
2884  JLOG(m_journal.debug())
2885  << __func__ << " : "
2886  << "error parsing json for accounts affected";
2887  return;
2888  }
2889  }
2890  {
2892 
2893  if (!mSubRTAccount.empty())
2894  {
2895  for (auto const& affectedAccount : accounts)
2896  {
2897  auto simiIt = mSubRTAccount.find(affectedAccount);
2898  if (simiIt != mSubRTAccount.end())
2899  {
2900  auto it = simiIt->second.begin();
2901 
2902  while (it != simiIt->second.end())
2903  {
2904  InfoSub::pointer p = it->second.lock();
2905 
2906  if (p)
2907  {
2908  notify.insert(p);
2909  ++it;
2910  ++iProposed;
2911  }
2912  else
2913  it = simiIt->second.erase(it);
2914  }
2915  }
2916  }
2917  }
2918  }
2919  JLOG(m_journal.trace()) << "forwardProposedAccountTransaction:"
2920  << " iProposed=" << iProposed;
2921 
2922  if (!notify.empty())
2923  {
2924  for (InfoSub::ref isrListener : notify)
2925  isrListener->send(jvObj, true);
2926  }
2927 }
2928 
2929 void
2931 {
2932  // Ledgers are published only when they acquire sufficient validations
2933  // Holes are filled across connection loss or other catastrophe
2934 
2935  std::shared_ptr<AcceptedLedger> alpAccepted =
2936  app_.getAcceptedLedgerCache().fetch(lpAccepted->info().hash);
2937  if (!alpAccepted)
2938  {
2939  alpAccepted = std::make_shared<AcceptedLedger>(lpAccepted, app_);
2940  app_.getAcceptedLedgerCache().canonicalize_replace_client(
2941  lpAccepted->info().hash, alpAccepted);
2942  }
2943 
2944  assert(alpAccepted->getLedger().get() == lpAccepted.get());
2945 
2946  {
2947  JLOG(m_journal.debug())
2948  << "Publishing ledger " << lpAccepted->info().seq << " "
2949  << lpAccepted->info().hash;
2950 
2952 
2953  if (!mStreamMaps[sLedger].empty())
2954  {
2956 
2957  jvObj[jss::type] = "ledgerClosed";
2958  jvObj[jss::ledger_index] = lpAccepted->info().seq;
2959  jvObj[jss::ledger_hash] = to_string(lpAccepted->info().hash);
2960  jvObj[jss::ledger_time] = Json::Value::UInt(
2961  lpAccepted->info().closeTime.time_since_epoch().count());
2962 
2963  if (!lpAccepted->rules().enabled(featureXRPFees))
2964  jvObj[jss::fee_ref] = Config::FEE_UNITS_DEPRECATED;
2965  jvObj[jss::fee_base] = lpAccepted->fees().base.jsonClipped();
2966  jvObj[jss::reserve_base] =
2967  lpAccepted->fees().accountReserve(0).jsonClipped();
2968  jvObj[jss::reserve_inc] =
2969  lpAccepted->fees().increment.jsonClipped();
2970 
2971  jvObj[jss::txn_count] = Json::UInt(alpAccepted->size());
2972 
2974  {
2975  jvObj[jss::validated_ledgers] =
2977  }
2978 
2979  auto it = mStreamMaps[sLedger].begin();
2980  while (it != mStreamMaps[sLedger].end())
2981  {
2982  InfoSub::pointer p = it->second.lock();
2983  if (p)
2984  {
2985  p->send(jvObj, true);
2986  ++it;
2987  }
2988  else
2989  it = mStreamMaps[sLedger].erase(it);
2990  }
2991  }
2992 
2993  if (!mStreamMaps[sBookChanges].empty())
2994  {
2995  Json::Value jvObj = ripple::RPC::computeBookChanges(lpAccepted);
2996 
2997  auto it = mStreamMaps[sBookChanges].begin();
2998  while (it != mStreamMaps[sBookChanges].end())
2999  {
3000  InfoSub::pointer p = it->second.lock();
3001  if (p)
3002  {
3003  p->send(jvObj, true);
3004  ++it;
3005  }
3006  else
3007  it = mStreamMaps[sBookChanges].erase(it);
3008  }
3009  }
3010 
3011  {
3012  static bool firstTime = true;
3013  if (firstTime)
3014  {
3015  // First validated ledger, start delayed SubAccountHistory
3016  firstTime = false;
3017  for (auto& outer : mSubAccountHistory)
3018  {
3019  for (auto& inner : outer.second)
3020  {
3021  auto& subInfo = inner.second;
3022  if (subInfo.index_->separationLedgerSeq_ == 0)
3023  {
3025  alpAccepted->getLedger(), subInfo);
3026  }
3027  }
3028  }
3029  }
3030  }
3031  }
3032 
3033  // Don't lock since pubAcceptedTransaction is locking.
3034  for (auto const& accTx : *alpAccepted)
3035  {
3036  JLOG(m_journal.trace()) << "pubAccepted: " << accTx->getJson();
3038  lpAccepted, *accTx, accTx == *(--alpAccepted->end()));
3039  }
3040 }
3041 
3042 void
3044 {
3045  if (app_.config().reporting())
3046  return;
3047  ServerFeeSummary f{
3048  app_.openLedger().current()->fees().base,
3050  app_.getFeeTrack()};
3051 
3052  // only schedule the job if something has changed
3053  if (f != mLastFeeSummary)
3054  {
3056  jtCLIENT_FEE_CHANGE, "reportFeeChange->pubServer", [this]() {
3057  pubServer();
3058  });
3059  }
3060 }
3061 
3062 void
3064 {
3067  "reportConsensusStateChange->pubConsensus",
3068  [this, phase]() { pubConsensus(phase); });
3069 }
3070 
3071 inline void
3073 {
3074  m_localTX->sweep(view);
3075 }
3076 inline std::size_t
3078 {
3079  return m_localTX->size();
3080 }
3081 
3082 // This routine should only be used to publish accepted or validated
3083 // transactions.
3086  const STTx& transaction,
3087  TER result,
3088  bool validated,
3089  std::shared_ptr<ReadView const> const& ledger)
3090 {
3092  std::string sToken;
3093  std::string sHuman;
3094 
3095  transResultInfo(result, sToken, sHuman);
3096 
3097  jvObj[jss::type] = "transaction";
3098  jvObj[jss::transaction] = transaction.getJson(JsonOptions::none);
3099 
3100  if (validated)
3101  {
3102  jvObj[jss::ledger_index] = ledger->info().seq;
3103  jvObj[jss::ledger_hash] = to_string(ledger->info().hash);
3104  jvObj[jss::transaction][jss::date] =
3105  ledger->info().closeTime.time_since_epoch().count();
3106  jvObj[jss::validated] = true;
3107 
3108  // WRITEME: Put the account next seq here
3109  }
3110  else
3111  {
3112  jvObj[jss::validated] = false;
3113  jvObj[jss::ledger_current_index] = ledger->info().seq;
3114  }
3115 
3116  jvObj[jss::status] = validated ? "closed" : "proposed";
3117  jvObj[jss::engine_result] = sToken;
3118  jvObj[jss::engine_result_code] = result;
3119  jvObj[jss::engine_result_message] = sHuman;
3120 
3121  if (transaction.getTxnType() == ttOFFER_CREATE)
3122  {
3123  auto const account = transaction.getAccountID(sfAccount);
3124  auto const amount = transaction.getFieldAmount(sfTakerGets);
3125 
3126  // If the offer create is not self funded then add the owner balance
3127  if (account != amount.issue().account)
3128  {
3129  auto const ownerFunds = accountFunds(
3130  *ledger,
3131  account,
3132  amount,
3134  app_.journal("View"));
3135  jvObj[jss::transaction][jss::owner_funds] = ownerFunds.getText();
3136  }
3137  }
3138 
3139  return jvObj;
3140 }
3141 
3142 void
3144  std::shared_ptr<ReadView const> const& ledger,
3145  const AcceptedLedgerTx& transaction,
3146  bool last)
3147 {
3148  auto const& stTxn = transaction.getTxn();
3149 
3150  Json::Value jvObj =
3151  transJson(*stTxn, transaction.getResult(), true, ledger);
3152 
3153  {
3154  auto const& meta = transaction.getMeta();
3155  jvObj[jss::meta] = meta.getJson(JsonOptions::none);
3156  RPC::insertDeliveredAmount(jvObj[jss::meta], *ledger, stTxn, meta);
3157  }
3158 
3159  {
3161 
3162  auto it = mStreamMaps[sTransactions].begin();
3163  while (it != mStreamMaps[sTransactions].end())
3164  {
3165  InfoSub::pointer p = it->second.lock();
3166 
3167  if (p)
3168  {
3169  p->send(jvObj, true);
3170  ++it;
3171  }
3172  else
3173  it = mStreamMaps[sTransactions].erase(it);
3174  }
3175 
3176  it = mStreamMaps[sRTTransactions].begin();
3177 
3178  while (it != mStreamMaps[sRTTransactions].end())
3179  {
3180  InfoSub::pointer p = it->second.lock();
3181 
3182  if (p)
3183  {
3184  p->send(jvObj, true);
3185  ++it;
3186  }
3187  else
3188  it = mStreamMaps[sRTTransactions].erase(it);
3189  }
3190  }
3191 
3192  if (transaction.getResult() == tesSUCCESS)
3193  app_.getOrderBookDB().processTxn(ledger, transaction, jvObj);
3194 
3195  pubAccountTransaction(ledger, transaction, last);
3196 }
3197 
3198 void
3200  std::shared_ptr<ReadView const> const& ledger,
3201  AcceptedLedgerTx const& transaction,
3202  bool last)
3203 {
3205  int iProposed = 0;
3206  int iAccepted = 0;
3207 
3208  std::vector<SubAccountHistoryInfo> accountHistoryNotify;
3209  auto const currLedgerSeq = ledger->seq();
3210  {
3212 
3213  if (!mSubAccount.empty() || !mSubRTAccount.empty() ||
3215  {
3216  for (auto const& affectedAccount : transaction.getAffected())
3217  {
3218  if (auto simiIt = mSubRTAccount.find(affectedAccount);
3219  simiIt != mSubRTAccount.end())
3220  {
3221  auto it = simiIt->second.begin();
3222 
3223  while (it != simiIt->second.end())
3224  {
3225  InfoSub::pointer p = it->second.lock();
3226 
3227  if (p)
3228  {
3229  notify.insert(p);
3230  ++it;
3231  ++iProposed;
3232  }
3233  else
3234  it = simiIt->second.erase(it);
3235  }
3236  }
3237 
3238  if (auto simiIt = mSubAccount.find(affectedAccount);
3239  simiIt != mSubAccount.end())
3240  {
3241  auto it = simiIt->second.begin();
3242  while (it != simiIt->second.end())
3243  {
3244  InfoSub::pointer p = it->second.lock();
3245 
3246  if (p)
3247  {
3248  notify.insert(p);
3249  ++it;
3250  ++iAccepted;
3251  }
3252  else
3253  it = simiIt->second.erase(it);
3254  }
3255  }
3256 
3257  if (auto histoIt = mSubAccountHistory.find(affectedAccount);
3258  histoIt != mSubAccountHistory.end())
3259  {
3260  auto& subs = histoIt->second;
3261  auto it = subs.begin();
3262  while (it != subs.end())
3263  {
3264  SubAccountHistoryInfoWeak const& info = it->second;
3265  if (currLedgerSeq <= info.index_->separationLedgerSeq_)
3266  {
3267  ++it;
3268  continue;
3269  }
3270 
3271  if (auto isSptr = info.sinkWptr_.lock(); isSptr)
3272  {
3273  accountHistoryNotify.emplace_back(
3274  SubAccountHistoryInfo{isSptr, info.index_});
3275  ++it;
3276  }
3277  else
3278  {
3279  it = subs.erase(it);
3280  }
3281  }
3282  if (subs.empty())
3283  mSubAccountHistory.erase(histoIt);
3284  }
3285  }
3286  }
3287  }
3288 
3289  JLOG(m_journal.trace())
3290  << "pubAccountTransaction: "
3291  << "proposed=" << iProposed << ", accepted=" << iAccepted;
3292 
3293  if (!notify.empty() || !accountHistoryNotify.empty())
3294  {
3295  auto const& stTxn = transaction.getTxn();
3296 
3297  Json::Value jvObj =
3298  transJson(*stTxn, transaction.getResult(), true, ledger);
3299 
3300  {
3301  auto const& meta = transaction.getMeta();
3302 
3303  jvObj[jss::meta] = meta.getJson(JsonOptions::none);
3304  RPC::insertDeliveredAmount(jvObj[jss::meta], *ledger, stTxn, meta);
3305  }
3306 
3307  for (InfoSub::ref isrListener : notify)
3308  isrListener->send(jvObj, true);
3309 
3310  if (last)
3311  jvObj[jss::account_history_boundary] = true;
3312 
3313  assert(!jvObj.isMember(jss::account_history_tx_stream));
3314  for (auto& info : accountHistoryNotify)
3315  {
3316  auto& index = info.index_;
3317  if (index->forwardTxIndex_ == 0 && !index->haveHistorical_)
3318  jvObj[jss::account_history_tx_first] = true;
3319  jvObj[jss::account_history_tx_index] = index->forwardTxIndex_++;
3320  info.sink_->send(jvObj, true);
3321  }
3322  }
3323 }
3324 
3325 void
3327  std::shared_ptr<ReadView const> const& ledger,
3328  std::shared_ptr<STTx const> const& tx,
3329  TER result)
3330 {
3332  int iProposed = 0;
3333 
3334  std::vector<SubAccountHistoryInfo> accountHistoryNotify;
3335 
3336  {
3338 
3339  if (mSubRTAccount.empty())
3340  return;
3341 
3342  if (!mSubAccount.empty() || !mSubRTAccount.empty() ||
3344  {
3345  for (auto const& affectedAccount : tx->getMentionedAccounts())
3346  {
3347  if (auto simiIt = mSubRTAccount.find(affectedAccount);
3348  simiIt != mSubRTAccount.end())
3349  {
3350  auto it = simiIt->second.begin();
3351 
3352  while (it != simiIt->second.end())
3353  {
3354  InfoSub::pointer p = it->second.lock();
3355 
3356  if (p)
3357  {
3358  notify.insert(p);
3359  ++it;
3360  ++iProposed;
3361  }
3362  else
3363  it = simiIt->second.erase(it);
3364  }
3365  }
3366  }
3367  }
3368  }
3369 
3370  JLOG(m_journal.trace()) << "pubProposedAccountTransaction: " << iProposed;
3371 
3372  if (!notify.empty() || !accountHistoryNotify.empty())
3373  {
3374  Json::Value jvObj = transJson(*tx, result, false, ledger);
3375 
3376  for (InfoSub::ref isrListener : notify)
3377  isrListener->send(jvObj, true);
3378 
3379  assert(!jvObj.isMember(jss::account_history_tx_stream));
3380  for (auto& info : accountHistoryNotify)
3381  {
3382  auto& index = info.index_;
3383  if (index->forwardTxIndex_ == 0 && !index->haveHistorical_)
3384  jvObj[jss::account_history_tx_first] = true;
3385  jvObj[jss::account_history_tx_index] = index->forwardTxIndex_++;
3386  info.sink_->send(jvObj, true);
3387  }
3388  }
3389 }
3390 
3391 //
3392 // Monitoring
3393 //
3394 
3395 void
3397  InfoSub::ref isrListener,
3398  hash_set<AccountID> const& vnaAccountIDs,
3399  bool rt)
3400 {
3401  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3402 
3403  for (auto const& naAccountID : vnaAccountIDs)
3404  {
3405  JLOG(m_journal.trace())
3406  << "subAccount: account: " << toBase58(naAccountID);
3407 
3408  isrListener->insertSubAccountInfo(naAccountID, rt);
3409  }
3410 
3412 
3413  for (auto const& naAccountID : vnaAccountIDs)
3414  {
3415  auto simIterator = subMap.find(naAccountID);
3416  if (simIterator == subMap.end())
3417  {
3418  // Not found, note that account has a new single listner.
3419  SubMapType usisElement;
3420  usisElement[isrListener->getSeq()] = isrListener;
3421  // VFALCO NOTE This is making a needless copy of naAccountID
3422  subMap.insert(simIterator, make_pair(naAccountID, usisElement));
3423  }
3424  else
3425  {
3426  // Found, note that the account has another listener.
3427  simIterator->second[isrListener->getSeq()] = isrListener;
3428  }
3429  }
3430 }
3431 
3432 void
3434  InfoSub::ref isrListener,
3435  hash_set<AccountID> const& vnaAccountIDs,
3436  bool rt)
3437 {
3438  for (auto const& naAccountID : vnaAccountIDs)
3439  {
3440  // Remove from the InfoSub
3441  isrListener->deleteSubAccountInfo(naAccountID, rt);
3442  }
3443 
3444  // Remove from the server
3445  unsubAccountInternal(isrListener->getSeq(), vnaAccountIDs, rt);
3446 }
3447 
3448 void
3450  std::uint64_t uSeq,
3451  hash_set<AccountID> const& vnaAccountIDs,
3452  bool rt)
3453 {
3455 
3456  SubInfoMapType& subMap = rt ? mSubRTAccount : mSubAccount;
3457 
3458  for (auto const& naAccountID : vnaAccountIDs)
3459  {
3460  auto simIterator = subMap.find(naAccountID);
3461 
3462  if (simIterator != subMap.end())
3463  {
3464  // Found
3465  simIterator->second.erase(uSeq);
3466 
3467  if (simIterator->second.empty())
3468  {
3469  // Don't need hash entry.
3470  subMap.erase(simIterator);
3471  }
3472  }
3473  }
3474 }
3475 
3476 void
3478 {
3479  enum DatabaseType { Postgres, Sqlite, None };
3480  static const auto databaseType = [&]() -> DatabaseType {
3481 #ifdef RIPPLED_REPORTING
3482  if (app_.config().reporting())
3483  {
3484  // Use a dynamic_cast to return DatabaseType::None
3485  // on failure.
3486  if (dynamic_cast<PostgresDatabase*>(&app_.getRelationalDatabase()))
3487  {
3488  return DatabaseType::Postgres;
3489  }
3490  return DatabaseType::None;
3491  }
3492  else
3493  {
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  }
3502 #else
3503  // Use a dynamic_cast to return DatabaseType::None
3504  // on failure.
3505  if (dynamic_cast<SQLiteDatabase*>(&app_.getRelationalDatabase()))
3506  {
3507  return DatabaseType::Sqlite;
3508  }
3509  return DatabaseType::None;
3510 #endif
3511  }();
3512 
3513  if (databaseType == DatabaseType::None)
3514  {
3515  JLOG(m_journal.error())
3516  << "AccountHistory job for account "
3517  << toBase58(subInfo.index_->accountId_) << " no database";
3518  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3519  {
3520  sptr->send(rpcError(rpcINTERNAL), true);
3521  unsubAccountHistory(sptr, subInfo.index_->accountId_, false);
3522  }
3523  return;
3524  }
3525 
3528  "AccountHistoryTxStream",
3529  [this, dbType = databaseType, subInfo]() {
3530  auto const& accountId = subInfo.index_->accountId_;
3531  auto& lastLedgerSeq = subInfo.index_->historyLastLedgerSeq_;
3532  auto& txHistoryIndex = subInfo.index_->historyTxIndex_;
3533 
3534  JLOG(m_journal.trace())
3535  << "AccountHistory job for account " << toBase58(accountId)
3536  << " started. lastLedgerSeq=" << lastLedgerSeq;
3537 
3538  auto isFirstTx = [&](std::shared_ptr<Transaction> const& tx,
3539  std::shared_ptr<TxMeta> const& meta) -> bool {
3540  /*
3541  * genesis account: first tx is the one with seq 1
3542  * other account: first tx is the one created the account
3543  */
3544  if (accountId == genesisAccountId)
3545  {
3546  auto stx = tx->getSTransaction();
3547  if (stx->getAccountID(sfAccount) == accountId &&
3548  stx->getSeqProxy().value() == 1)
3549  return true;
3550  }
3551 
3552  for (auto& node : meta->getNodes())
3553  {
3554  if (node.getFieldU16(sfLedgerEntryType) != ltACCOUNT_ROOT)
3555  continue;
3556 
3557  if (node.isFieldPresent(sfNewFields))
3558  {
3559  if (auto inner = dynamic_cast<const STObject*>(
3560  node.peekAtPField(sfNewFields));
3561  inner)
3562  {
3563  if (inner->isFieldPresent(sfAccount) &&
3564  inner->getAccountID(sfAccount) == accountId)
3565  {
3566  return true;
3567  }
3568  }
3569  }
3570  }
3571 
3572  return false;
3573  };
3574 
3575  auto send = [&](Json::Value const& jvObj,
3576  bool unsubscribe) -> bool {
3577  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3578  {
3579  sptr->send(jvObj, true);
3580  if (unsubscribe)
3581  unsubAccountHistory(sptr, accountId, false);
3582  return true;
3583  }
3584 
3585  return false;
3586  };
3587 
3588  auto getMoreTxns =
3589  [&](std::uint32_t minLedger,
3590  std::uint32_t maxLedger,
3595  switch (dbType)
3596  {
3597  case Postgres: {
3598  auto db = static_cast<PostgresDatabase*>(
3601  args.account = accountId;
3602  LedgerRange range{minLedger, maxLedger};
3603  args.ledger = range;
3604  args.marker = marker;
3605  auto [txResult, status] = db->getAccountTx(args);
3606  if (status != rpcSUCCESS)
3607  {
3608  JLOG(m_journal.debug())
3609  << "AccountHistory job for account "
3610  << toBase58(accountId)
3611  << " getAccountTx failed";
3612  return {};
3613  }
3614 
3615  if (auto txns =
3616  std::get_if<RelationalDatabase::AccountTxs>(
3617  &txResult.transactions);
3618  txns)
3619  {
3620  return std::make_pair(*txns, txResult.marker);
3621  }
3622  else
3623  {
3624  JLOG(m_journal.debug())
3625  << "AccountHistory job for account "
3626  << toBase58(accountId)
3627  << " getAccountTx wrong data";
3628  return {};
3629  }
3630  }
3631  case Sqlite: {
3632  auto db = static_cast<SQLiteDatabase*>(
3635  accountId, minLedger, maxLedger, marker, 0, true};
3636  return db->newestAccountTxPage(options);
3637  }
3638  default: {
3639  assert(false);
3640  return {};
3641  }
3642  }
3643  };
3644 
3645  /*
3646  * search backward until the genesis ledger or asked to stop
3647  */
3648  while (lastLedgerSeq >= 2 && !subInfo.index_->stopHistorical_)
3649  {
3650  int feeChargeCount = 0;
3651  if (auto sptr = subInfo.sinkWptr_.lock(); sptr)
3652  {
3653  sptr->getConsumer().charge(Resource::feeMediumBurdenRPC);
3654  ++feeChargeCount;
3655  }
3656  else
3657  {
3658  JLOG(m_journal.trace())
3659  << "AccountHistory job for account "
3660  << toBase58(accountId) << " no InfoSub. Fee charged "
3661  << feeChargeCount << " times.";
3662  return;
3663  }
3664 
3665  // try to search in 1024 ledgers till reaching genesis ledgers
3666  auto startLedgerSeq =
3667  (lastLedgerSeq > 1024 + 2 ? lastLedgerSeq - 1024 : 2);
3668  JLOG(m_journal.trace())
3669  << "AccountHistory job for account " << toBase58(accountId)
3670  << ", working on ledger range [" << startLedgerSeq << ","
3671  << lastLedgerSeq << "]";
3672 
3673  auto haveRange = [&]() -> bool {
3674  std::uint32_t validatedMin = UINT_MAX;
3675  std::uint32_t validatedMax = 0;
3676  auto haveSomeValidatedLedgers =
3678  validatedMin, validatedMax);
3679 
3680  return haveSomeValidatedLedgers &&
3681  validatedMin <= startLedgerSeq &&
3682  lastLedgerSeq <= validatedMax;
3683  }();
3684 
3685  if (!haveRange)
3686  {
3687  JLOG(m_journal.debug())
3688  << "AccountHistory reschedule job for account "
3689  << toBase58(accountId) << ", incomplete ledger range ["
3690  << startLedgerSeq << "," << lastLedgerSeq << "]";
3691  setAccountHistoryJobTimer(subInfo);
3692  return;
3693  }
3694 
3696  while (!subInfo.index_->stopHistorical_)
3697  {
3698  auto dbResult =
3699  getMoreTxns(startLedgerSeq, lastLedgerSeq, marker);
3700  if (!dbResult)
3701  {
3702  JLOG(m_journal.debug())
3703  << "AccountHistory job for account "
3704  << toBase58(accountId) << " getMoreTxns failed.";
3705  send(rpcError(rpcINTERNAL), true);
3706  return;
3707  }
3708 
3709  auto const& txns = dbResult->first;
3710  marker = dbResult->second;
3711  size_t num_txns = txns.size();
3712  for (size_t i = 0; i < num_txns; ++i)
3713  {
3714  auto const& [tx, meta] = txns[i];
3715 
3716  if (!tx || !meta)
3717  {
3718  JLOG(m_journal.debug())
3719  << "AccountHistory job for account "
3720  << toBase58(accountId) << " empty tx or meta.";
3721  send(rpcError(rpcINTERNAL), true);
3722  return;
3723  }
3724  auto curTxLedger =
3726  tx->getLedger());
3727  if (!curTxLedger)
3728  {
3729  JLOG(m_journal.debug())
3730  << "AccountHistory job for account "
3731  << toBase58(accountId) << " no ledger.";
3732  send(rpcError(rpcINTERNAL), true);
3733  return;
3734  }
3736  tx->getSTransaction();
3737  if (!stTxn)
3738  {
3739  JLOG(m_journal.debug())
3740  << "AccountHistory job for account "
3741  << toBase58(accountId)
3742  << " getSTransaction failed.";
3743  send(rpcError(rpcINTERNAL), true);
3744  return;
3745  }
3746  Json::Value jvTx = transJson(
3747  *stTxn, meta->getResultTER(), true, curTxLedger);
3748  jvTx[jss::meta] = meta->getJson(JsonOptions::none);
3749  jvTx[jss::account_history_tx_index] = txHistoryIndex--;
3750 
3751  if (i + 1 == num_txns ||
3752  txns[i + 1].first->getLedger() != tx->getLedger())
3753  jvTx[jss::account_history_boundary] = true;
3754 
3756  jvTx[jss::meta], *curTxLedger, stTxn, *meta);
3757  if (isFirstTx(tx, meta))
3758  {
3759  jvTx[jss::account_history_tx_first] = true;
3760  send(jvTx, false);
3761 
3762  JLOG(m_journal.trace())
3763  << "AccountHistory job for account "
3764  << toBase58(accountId)
3765  << " done, found last tx.";
3766  return;
3767  }
3768  else
3769  {
3770  send(jvTx, false);
3771  }
3772  }
3773 
3774  if (marker)
3775  {
3776  JLOG(m_journal.trace())
3777  << "AccountHistory job for account "
3778  << toBase58(accountId)
3779  << " paging, marker=" << marker->ledgerSeq << ":"
3780  << marker->txnSeq;
3781  }
3782  else
3783  {
3784  break;
3785  }
3786  }
3787 
3788  if (!subInfo.index_->stopHistorical_)
3789  {
3790  lastLedgerSeq = startLedgerSeq - 1;
3791  if (lastLedgerSeq <= 1)
3792  {
3793  JLOG(m_journal.trace())
3794  << "AccountHistory job for account "
3795  << toBase58(accountId)
3796  << " done, reached genesis ledger.";
3797  return;
3798  }
3799  }
3800  }
3801  });
3802 }
3803 
3804 void
3806  std::shared_ptr<ReadView const> const& ledger,
3807  SubAccountHistoryInfoWeak& subInfo)
3808 {
3809  subInfo.index_->separationLedgerSeq_ = ledger->seq();
3810  auto const& accountId = subInfo.index_->accountId_;
3811  auto const accountKeylet = keylet::account(accountId);
3812  if (!ledger->exists(accountKeylet))
3813  {
3814  JLOG(m_journal.debug())
3815  << "subAccountHistoryStart, no account " << toBase58(accountId)
3816  << ", no need to add AccountHistory job.";
3817  return;
3818  }
3819  if (accountId == genesisAccountId)
3820  {
3821  if (auto const sleAcct = ledger->read(accountKeylet); sleAcct)
3822  {
3823  if (sleAcct->getFieldU32(sfSequence) == 1)
3824  {
3825  JLOG(m_journal.debug())
3826  << "subAccountHistoryStart, genesis account "
3827  << toBase58(accountId)
3828  << " does not have tx, no need to add AccountHistory job.";
3829  return;
3830  }
3831  }
3832  else
3833  {
3834  assert(false);
3835  return;
3836  }
3837  }
3838  subInfo.index_->historyLastLedgerSeq_ = ledger->seq();
3839  subInfo.index_->haveHistorical_ = true;
3840 
3841  JLOG(m_journal.debug())
3842  << "subAccountHistoryStart, add AccountHistory job: accountId="
3843  << toBase58(accountId) << ", currentLedgerSeq=" << ledger->seq();
3844 
3845  addAccountHistoryJob(subInfo);
3846 }
3847 
3850  InfoSub::ref isrListener,
3851  AccountID const& accountId)
3852 {
3853  if (!isrListener->insertSubAccountHistory(accountId))
3854  {
3855  JLOG(m_journal.debug())
3856  << "subAccountHistory, already subscribed to account "
3857  << toBase58(accountId);
3858  return rpcINVALID_PARAMS;
3859  }
3860 
3863  isrListener, std::make_shared<SubAccountHistoryIndex>(accountId)};
3864  auto simIterator = mSubAccountHistory.find(accountId);
3865  if (simIterator == mSubAccountHistory.end())
3866  {
3868  inner.emplace(isrListener->getSeq(), ahi);
3870  simIterator, std::make_pair(accountId, inner));
3871  }
3872  else
3873  {
3874  simIterator->second.emplace(isrListener->getSeq(), ahi);
3875  }
3876 
3877  auto const ledger = app_.getLedgerMaster().getValidatedLedger();
3878  if (ledger)
3879  {
3880  subAccountHistoryStart(ledger, ahi);
3881  }
3882  else
3883  {
3884  // The node does not have validated ledgers, so wait for
3885  // one before start streaming.
3886  // In this case, the subscription is also considered successful.
3887  JLOG(m_journal.debug())
3888  << "subAccountHistory, no validated ledger yet, delay start";
3889  }
3890 
3891  return rpcSUCCESS;
3892 }
3893 
3894 void
3896  InfoSub::ref isrListener,
3897  AccountID const& account,
3898  bool historyOnly)
3899 {
3900  if (!historyOnly)
3901  isrListener->deleteSubAccountHistory(account);
3902  unsubAccountHistoryInternal(isrListener->getSeq(), account, historyOnly);
3903 }
3904 
3905 void
3907  std::uint64_t seq,
3908  const AccountID& account,
3909  bool historyOnly)
3910 {
3912  auto simIterator = mSubAccountHistory.find(account);
3913  if (simIterator != mSubAccountHistory.end())
3914  {
3915  auto& subInfoMap = simIterator->second;
3916  auto subInfoIter = subInfoMap.find(seq);
3917  if (subInfoIter != subInfoMap.end())
3918  {
3919  subInfoIter->second.index_->stopHistorical_ = true;
3920  }
3921 
3922  if (!historyOnly)
3923  {
3924  simIterator->second.erase(seq);
3925  if (simIterator->second.empty())
3926  {
3927  mSubAccountHistory.erase(simIterator);
3928  }
3929  }
3930  JLOG(m_journal.debug())
3931  << "unsubAccountHistory, account " << toBase58(account)
3932  << ", historyOnly = " << (historyOnly ? "true" : "false");
3933  }
3934 }
3935 
3936 bool
3937 NetworkOPsImp::subBook(InfoSub::ref isrListener, Book const& book)
3938 {
3939  if (auto listeners = app_.getOrderBookDB().makeBookListeners(book))
3940  listeners->addSubscriber(isrListener);
3941  else
3942  assert(false);
3943  return true;
3944 }
3945 
3946 bool
3948 {
3949  if (auto listeners = app_.getOrderBookDB().getBookListeners(book))
3950  listeners->removeSubscriber(uSeq);
3951 
3952  return true;
3953 }
3954 
3958 {
3959  // This code-path is exclusively used when the server is in standalone
3960  // mode via `ledger_accept`
3961  assert(m_standalone);
3962 
3963  if (!m_standalone)
3964  Throw<std::runtime_error>(
3965  "Operation only possible in STANDALONE mode.");
3966 
3967  // FIXME Could we improve on this and remove the need for a specialized
3968  // API in Consensus?
3970  mConsensus.simulate(app_.timeKeeper().closeTime(), consensusDelay);
3971  return m_ledgerMaster.getCurrentLedger()->info().seq;
3972 }
3973 
3974 // <-- bool: true=added, false=already there
3975 bool
3977 {
3978  if (auto lpClosed = m_ledgerMaster.getValidatedLedger())
3979  {
3980  jvResult[jss::ledger_index] = lpClosed->info().seq;
3981  jvResult[jss::ledger_hash] = to_string(lpClosed->info().hash);
3982  jvResult[jss::ledger_time] = Json::Value::UInt(
3983  lpClosed->info().closeTime.time_since_epoch().count());
3984  if (!lpClosed->rules().enabled(featureXRPFees))
3985  jvResult[jss::fee_ref] = Config::FEE_UNITS_DEPRECATED;
3986  jvResult[jss::fee_base] = lpClosed->fees().base.jsonClipped();
3987  jvResult[jss::reserve_base] =
3988  lpClosed->fees().accountReserve(0).jsonClipped();
3989  jvResult[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
3990  }
3991 
3993  {
3994  jvResult[jss::validated_ledgers] =
3996  }
3997 
3999  return mStreamMaps[sLedger]
4000  .emplace(isrListener->getSeq(), isrListener)
4001  .second;
4002 }
4003 
4004 // <-- bool: true=added, false=already there
4005 bool
4007 {
4009  return mStreamMaps[sBookChanges]
4010  .emplace(isrListener->getSeq(), isrListener)
4011  .second;
4012 }
4013 
4014 // <-- bool: true=erased, false=was not there
4015 bool
4017 {
4019  return mStreamMaps[sLedger].erase(uSeq);
4020 }
4021 
4022 // <-- bool: true=erased, false=was not there
4023 bool
4025 {
4027  return mStreamMaps[sBookChanges].erase(uSeq);
4028 }
4029 
4030 // <-- bool: true=added, false=already there
4031 bool
4033 {
4035  return mStreamMaps[sManifests]
4036  .emplace(isrListener->getSeq(), isrListener)
4037  .second;
4038 }
4039 
4040 // <-- bool: true=erased, false=was not there
4041 bool
4043 {
4045  return mStreamMaps[sManifests].erase(uSeq);
4046 }
4047 
4048 // <-- bool: true=added, false=already there
4049 bool
4051  InfoSub::ref isrListener,
4052  Json::Value& jvResult,
4053  bool admin)
4054 {
4055  uint256 uRandom;
4056 
4057  if (m_standalone)
4058  jvResult[jss::stand_alone] = m_standalone;
4059 
4060  // CHECKME: is it necessary to provide a random number here?
4061  beast::rngfill(uRandom.begin(), uRandom.size(), crypto_prng());
4062 
4063  auto const& feeTrack = app_.getFeeTrack();
4064  jvResult[jss::random] = to_string(uRandom);
4065  jvResult[jss::server_status] = strOperatingMode(admin);
4066  jvResult[jss::load_base] = feeTrack.getLoadBase();
4067  jvResult[jss::load_factor] = feeTrack.getLoadFactor();
4068  jvResult[jss::hostid] = getHostId(admin);
4069  jvResult[jss::pubkey_node] =
4071 
4073  return mStreamMaps[sServer]
4074  .emplace(isrListener->getSeq(), isrListener)
4075  .second;
4076 }
4077 
4078 // <-- bool: true=erased, false=was not there
4079 bool
4081 {
4083  return mStreamMaps[sServer].erase(uSeq);
4084 }
4085 
4086 // <-- bool: true=added, false=already there
4087 bool
4089 {
4091  return mStreamMaps[sTransactions]
4092  .emplace(isrListener->getSeq(), isrListener)
4093  .second;
4094 }
4095 
4096 // <-- bool: true=erased, false=was not there
4097 bool
4099 {
4101  return mStreamMaps[sTransactions].erase(uSeq);
4102 }
4103 
4104 // <-- bool: true=added, false=already there
4105 bool
4107 {
4110  .emplace(isrListener->getSeq(), isrListener)
4111  .second;
4112 }
4113 
4114 // <-- bool: true=erased, false=was not there
4115 bool
4117 {
4119  return mStreamMaps[sRTTransactions].erase(uSeq);
4120 }
4121 
4122 // <-- bool: true=added, false=already there
4123 bool
4125 {
4127  return mStreamMaps[sValidations]
4128  .emplace(isrListener->getSeq(), isrListener)
4129  .second;
4130 }
4131 
4132 void
4134 {
4135  accounting_.json(obj);
4136 }
4137 
4138 // <-- bool: true=erased, false=was not there
4139 bool
4141 {
4143  return mStreamMaps[sValidations].erase(uSeq);
4144 }
4145 
4146 // <-- bool: true=added, false=already there
4147 bool
4149 {
4151  return mStreamMaps[sPeerStatus]
4152  .emplace(isrListener->getSeq(), isrListener)
4153  .second;
4154 }
4155 
4156 // <-- bool: true=erased, false=was not there
4157 bool
4159 {
4161  return mStreamMaps[sPeerStatus].erase(uSeq);
4162 }
4163 
4164 // <-- bool: true=added, false=already there
4165 bool
4167 {
4170  .emplace(isrListener->getSeq(), isrListener)
4171  .second;
4172 }
4173 
4174 // <-- bool: true=erased, false=was not there
4175 bool
4177 {
4179  return mStreamMaps[sConsensusPhase].erase(uSeq);
4180 }
4181 
4184 {
4186 
4187  subRpcMapType::iterator it = mRpcSubMap.find(strUrl);
4188 
4189  if (it != mRpcSubMap.end())
4190  return it->second;
4191 
4192  return InfoSub::pointer();
4193 }
4194 
4197 {
4199 
4200  mRpcSubMap.emplace(strUrl, rspEntry);
4201 
4202  return rspEntry;
4203 }
4204 
4205 bool
4207 {
4209  auto pInfo = findRpcSub(strUrl);
4210 
4211  if (!pInfo)
4212  return false;
4213 
4214  // check to see if any of the stream maps still hold a weak reference to
4215  // this entry before removing
4216  for (SubMapType const& map : mStreamMaps)
4217  {
4218  if (map.find(pInfo->getSeq()) != map.end())
4219  return false;
4220  }
4221  mRpcSubMap.erase(strUrl);
4222  return true;
4223 }
4224 
4225 #ifndef USE_NEW_BOOK_PAGE
4226 
4227 // NIKB FIXME this should be looked at. There's no reason why this shouldn't
4228 // work, but it demonstrated poor performance.
4229 //
4230 void
4233  Book const& book,
4234  AccountID const& uTakerID,
4235  bool const bProof,
4236  unsigned int iLimit,
4237  Json::Value const& jvMarker,
4238  Json::Value& jvResult)
4239 { // CAUTION: This is the old get book page logic
4240  Json::Value& jvOffers =
4241  (jvResult[jss::offers] = Json::Value(Json::arrayValue));
4242 
4244  const uint256 uBookBase = getBookBase(book);
4245  const uint256 uBookEnd = getQualityNext(uBookBase);
4246  uint256 uTipIndex = uBookBase;
4247 
4248  if (auto stream = m_journal.trace())
4249  {
4250  stream << "getBookPage:" << book;
4251  stream << "getBookPage: uBookBase=" << uBookBase;
4252  stream << "getBookPage: uBookEnd=" << uBookEnd;
4253  stream << "getBookPage: uTipIndex=" << uTipIndex;
4254  }
4255 
4256  ReadView const& view = *lpLedger;
4257 
4258  bool const bGlobalFreeze = isGlobalFrozen(view, book.out.account) ||
4259  isGlobalFrozen(view, book.in.account);
4260 
4261  bool bDone = false;
4262  bool bDirectAdvance = true;
4263 
4264  std::shared_ptr<SLE const> sleOfferDir;
4265  uint256 offerIndex;
4266  unsigned int uBookEntry;
4267  STAmount saDirRate;
4268 
4269  auto const rate = transferRate(view, book.out.account);
4270  auto viewJ = app_.journal("View");
4271 
4272  while (!bDone && iLimit-- > 0)
4273  {
4274  if (bDirectAdvance)
4275  {
4276  bDirectAdvance = false;
4277 
4278  JLOG(m_journal.trace()) << "getBookPage: bDirectAdvance";
4279 
4280  auto const ledgerIndex = view.succ(uTipIndex, uBookEnd);
4281  if (ledgerIndex)
4282  sleOfferDir = view.read(keylet::page(*ledgerIndex));
4283  else
4284  sleOfferDir.reset();
4285 
4286  if (!sleOfferDir)
4287  {
4288  JLOG(m_journal.trace()) << "getBookPage: bDone";
4289  bDone = true;
4290  }
4291  else
4292  {
4293  uTipIndex = sleOfferDir->key();
4294  saDirRate = amountFromQuality(getQuality(uTipIndex));
4295 
4296  cdirFirst(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex);
4297 
4298  JLOG(m_journal.trace())
4299  << "getBookPage: uTipIndex=" << uTipIndex;
4300  JLOG(m_journal.trace())
4301  << "getBookPage: offerIndex=" << offerIndex;
4302  }
4303  }
4304 
4305  if (!bDone)
4306  {
4307  auto sleOffer = view.read(keylet::offer(offerIndex));
4308 
4309  if (sleOffer)
4310  {
4311  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
4312  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
4313  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
4314  STAmount saOwnerFunds;
4315  bool firstOwnerOffer(true);
4316 
4317  if (book.out.account == uOfferOwnerID)
4318  {
4319  // If an offer is selling issuer's own IOUs, it is fully
4320  // funded.
4321  saOwnerFunds = saTakerGets;
4322  }
4323  else if (bGlobalFreeze)
4324  {
4325  // If either asset is globally frozen, consider all offers
4326  // that aren't ours to be totally unfunded
4327  saOwnerFunds.clear(book.out);
4328  }
4329  else
4330  {
4331  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
4332  if (umBalanceEntry != umBalance.end())
4333  {
4334  // Found in running balance table.
4335 
4336  saOwnerFunds = umBalanceEntry->second;
4337  firstOwnerOffer = false;
4338  }
4339  else
4340  {
4341  // Did not find balance in table.
4342 
4343  saOwnerFunds = accountHolds(
4344  view,
4345  uOfferOwnerID,
4346  book.out.currency,
4347  book.out.account,
4349  viewJ);
4350 
4351  if (saOwnerFunds < beast::zero)
4352  {
4353  // Treat negative funds as zero.
4354 
4355  saOwnerFunds.clear();
4356  }
4357  }
4358  }
4359 
4360  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
4361 
4362  STAmount saTakerGetsFunded;
4363  STAmount saOwnerFundsLimit = saOwnerFunds;
4364  Rate offerRate = parityRate;
4365 
4366  if (rate != parityRate
4367  // Have a tranfer fee.
4368  && uTakerID != book.out.account
4369  // Not taking offers of own IOUs.
4370  && book.out.account != uOfferOwnerID)
4371  // Offer owner not issuing ownfunds
4372  {
4373  // Need to charge a transfer fee to offer owner.
4374  offerRate = rate;
4375  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
4376  }
4377 
4378  if (saOwnerFundsLimit >= saTakerGets)
4379  {
4380  // Sufficient funds no shenanigans.
4381  saTakerGetsFunded = saTakerGets;
4382  }
4383  else
4384  {
4385  // Only provide, if not fully funded.
4386 
4387  saTakerGetsFunded = saOwnerFundsLimit;
4388 
4389  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
4390  std::min(
4391  saTakerPays,
4392  multiply(
4393  saTakerGetsFunded, saDirRate, saTakerPays.issue()))
4394  .setJson(jvOffer[jss::taker_pays_funded]);
4395  }
4396 
4397  STAmount saOwnerPays = (parityRate == offerRate)
4398  ? saTakerGetsFunded
4399  : std::min(
4400  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
4401 
4402  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
4403 
4404  // Include all offers funded and unfunded
4405  Json::Value& jvOf = jvOffers.append(jvOffer);
4406  jvOf[jss::quality] = saDirRate.getText();
4407 
4408  if (firstOwnerOffer)
4409  jvOf[jss::owner_funds] = saOwnerFunds.getText();
4410  }
4411  else
4412  {
4413  JLOG(m_journal.warn()) << "Missing offer";
4414  }
4415 
4416  if (!cdirNext(view, uTipIndex, sleOfferDir, uBookEntry, offerIndex))
4417  {
4418  bDirectAdvance = true;
4419  }
4420  else
4421  {
4422  JLOG(m_journal.trace())
4423  << "getBookPage: offerIndex=" << offerIndex;
4424  }
4425  }
4426  }
4427 
4428  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
4429  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
4430 }
4431 
4432 #else
4433 
4434 // This is the new code that uses the book iterators
4435 // It has temporarily been disabled
4436 
4437 void
4440  Book const& book,
4441  AccountID const& uTakerID,
4442  bool const bProof,
4443  unsigned int iLimit,
4444  Json::Value const& jvMarker,
4445  Json::Value& jvResult)
4446 {
4447  auto& jvOffers = (jvResult[jss::offers] = Json::Value(Json::arrayValue));
4448 
4450 
4451  MetaView lesActive(lpLedger, tapNONE, true);
4452  OrderBookIterator obIterator(lesActive, book);
4453 
4454  auto const rate = transferRate(lesActive, book.out.account);
4455 
4456  const bool bGlobalFreeze = lesActive.isGlobalFrozen(book.out.account) ||
4457  lesActive.isGlobalFrozen(book.in.account);
4458 
4459  while (iLimit-- > 0 && obIterator.nextOffer())
4460  {
4461  SLE::pointer sleOffer = obIterator.getCurrentOffer();
4462  if (sleOffer)
4463  {
4464  auto const uOfferOwnerID = sleOffer->getAccountID(sfAccount);
4465  auto const& saTakerGets = sleOffer->getFieldAmount(sfTakerGets);
4466  auto const& saTakerPays = sleOffer->getFieldAmount(sfTakerPays);
4467  STAmount saDirRate = obIterator.getCurrentRate();
4468  STAmount saOwnerFunds;
4469 
4470  if (book.out.account == uOfferOwnerID)
4471  {
4472  // If offer is selling issuer's own IOUs, it is fully funded.
4473  saOwnerFunds = saTakerGets;
4474  }
4475  else if (bGlobalFreeze)
4476  {
4477  // If either asset is globally frozen, consider all offers
4478  // that aren't ours to be totally unfunded
4479  saOwnerFunds.clear(book.out);
4480  }
4481  else
4482  {
4483  auto umBalanceEntry = umBalance.find(uOfferOwnerID);
4484 
4485  if (umBalanceEntry != umBalance.end())
4486  {
4487  // Found in running balance table.
4488 
4489  saOwnerFunds = umBalanceEntry->second;
4490  }
4491  else
4492  {
4493  // Did not find balance in table.
4494 
4495  saOwnerFunds = lesActive.accountHolds(
4496  uOfferOwnerID,
4497  book.out.currency,
4498  book.out.account,
4500 
4501  if (saOwnerFunds.isNegative())
4502  {
4503  // Treat negative funds as zero.
4504 
4505  saOwnerFunds.zero();
4506  }
4507  }
4508  }
4509 
4510  Json::Value jvOffer = sleOffer->getJson(JsonOptions::none);
4511 
4512  STAmount saTakerGetsFunded;
4513  STAmount saOwnerFundsLimit = saOwnerFunds;
4514  Rate offerRate = parityRate;
4515 
4516  if (rate != parityRate
4517  // Have a tranfer fee.
4518  && uTakerID != book.out.account
4519  // Not taking offers of own IOUs.
4520  && book.out.account != uOfferOwnerID)
4521  // Offer owner not issuing ownfunds
4522  {
4523  // Need to charge a transfer fee to offer owner.
4524  offerRate = rate;
4525  saOwnerFundsLimit = divide(saOwnerFunds, offerRate);
4526  }
4527 
4528  if (saOwnerFundsLimit >= saTakerGets)
4529  {
4530  // Sufficient funds no shenanigans.
4531  saTakerGetsFunded = saTakerGets;
4532  }
4533  else
4534  {
4535  // Only provide, if not fully funded.
4536  saTakerGetsFunded = saOwnerFundsLimit;
4537 
4538  saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
4539 
4540  // TOOD(tom): The result of this expression is not used - what's
4541  // going on here?
4542  std::min(
4543  saTakerPays,
4544  multiply(saTakerGetsFunded, saDirRate, saTakerPays.issue()))
4545  .setJson(jvOffer[jss::taker_pays_funded]);
4546  }
4547 
4548  STAmount saOwnerPays = (parityRate == offerRate)
4549  ? saTakerGetsFunded
4550  : std::min(
4551  saOwnerFunds, multiply(saTakerGetsFunded, offerRate));
4552 
4553  umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
4554 
4555  if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID)
4556  {
4557  // Only provide funded offers and offers of the taker.
4558  Json::Value& jvOf = jvOffers.append(jvOffer);
4559  jvOf[jss::quality] = saDirRate.getText();
4560  }
4561  }
4562  }
4563 
4564  // jvResult[jss::marker] = Json::Value(Json::arrayValue);
4565  // jvResult[jss::nodes] = Json::Value(Json::arrayValue);
4566 }
4567 
4568 #endif
4569 
4570 inline void
4572 {
4573  auto [counters, mode, start, initialSync] = accounting_.getCounterData();
4574  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
4575  std::chrono::steady_clock::now() - start);
4576  counters[static_cast<std::size_t>(mode)].dur += current;
4577 
4580  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
4581  .dur.count());
4583  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
4584  .dur.count());
4586  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].dur.count());
4588  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
4589  .dur.count());
4591  counters[static_cast<std::size_t>(OperatingMode::FULL)].dur.count());
4592 
4594  counters[static_cast<std::size_t>(OperatingMode::DISCONNECTED)]
4595  .transitions);
4597  counters[static_cast<std::size_t>(OperatingMode::CONNECTED)]
4598  .transitions);
4600  counters[static_cast<std::size_t>(OperatingMode::SYNCING)].transitions);
4602  counters[static_cast<std::size_t>(OperatingMode::TRACKING)]
4603  .transitions);
4605  counters[static_cast<std::size_t>(OperatingMode::FULL)].transitions);
4606 }
4607 
4608 void
4610 {
4611  auto now = std::chrono::steady_clock::now();
4612 
4613  std::lock_guard lock(mutex_);
4614  ++counters_[static_cast<std::size_t>(om)].transitions;
4615  if (om == OperatingMode::FULL &&
4616  counters_[static_cast<std::size_t>(om)].transitions == 1)
4617  {
4618  initialSyncUs_ = std::chrono::duration_cast<std::chrono::microseconds>(
4619  now - processStart_)
4620  .count();
4621  }
4622  counters_[static_cast<std::size_t>(mode_)].dur +=
4623  std::chrono::duration_cast<std::chrono::microseconds>(now - start_);
4624 
4625  mode_ = om;
4626  start_ = now;
4627 }
4628 
4629 void
4631 {
4632  auto [counters, mode, start, initialSync] = getCounterData();
4633  auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
4634  std::chrono::steady_clock::now() - start);
4635  counters[static_cast<std::size_t>(mode)].dur += current;
4636 
4637  obj[jss::state_accounting] = Json::objectValue;
4638  for (std::size_t i = static_cast<std::size_t>(OperatingMode::DISCONNECTED);
4639  i <= static_cast<std::size_t>(OperatingMode::FULL);
4640  ++i)
4641  {
4642  obj[jss::state_accounting][states_[i]] = Json::objectValue;
4643  auto& state = obj[jss::state_accounting][states_[i]];
4644  state[jss::transitions] = std::to_string(counters[i].transitions);
4645  state[jss::duration_us] = std::to_string(counters[i].dur.count());
4646  }
4647  obj[jss::server_state_duration_us] = std::to_string(current.count());
4648  if (initialSync)
4649  obj[jss::initial_sync_duration_us] = std::to_string(initialSync);
4650 }
4651 
4652 //------------------------------------------------------------------------------
4653 
4656  Application& app,
4657  NetworkOPs::clock_type& clock,
4658  bool standalone,
4659  std::size_t minPeerCount,
4660  bool startvalid,
4661  JobQueue& job_queue,
4662  LedgerMaster& ledgerMaster,
4663  ValidatorKeys const& validatorKeys,
4664  boost::asio::io_service& io_svc,
4665  beast::Journal journal,
4666  beast::insight::Collector::ptr const& collector)
4667 {
4668  return std::make_unique<NetworkOPsImp>(
4669  app,
4670  clock,
4671  standalone,
4672  minPeerCount,
4673  startvalid,
4674  job_queue,
4675  ledgerMaster,
4676  validatorKeys,
4677  io_svc,
4678  journal,
4679  collector);
4680 }
4681 
4682 } // namespace ripple
ripple::SQLiteDatabase
Definition: SQLiteDatabase.h:27
ripple::NetworkOPsImp::forwardManifest
void forwardManifest(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2824
ripple::NetworkOPsImp::unsubValidations
bool unsubValidations(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4140
ripple::NetworkOPsImp::Stats::hook
beast::insight::Hook hook
Definition: NetworkOPs.cpp:803
ripple::STTx::getTxnType
TxType getTxnType() const
Definition: STTx.h:179
ripple::NetworkOPsImp::subValidations
bool subValidations(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4124
ripple::NetworkOPsImp::processHeartbeatTimer
void processHeartbeatTimer()
Definition: NetworkOPs.cpp:1043
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:654
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:312
ripple::NetworkOPsImp::mapComplete
void mapComplete(std::shared_ptr< SHAMap > const &map, bool fromAcquire) override
Definition: NetworkOPs.cpp:1885
ripple::NetworkOPsImp::setClusterTimer
void setClusterTimer()
Definition: NetworkOPs.cpp:978
ripple::Application
Definition: Application.h:116
ripple::transferRate
Rate transferRate(ReadView const &view, AccountID const &issuer)
Definition: View.cpp:488
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:732
ripple::NetworkOPsImp::unsubConsensus
bool unsubConsensus(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4176
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:656
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:1879
std::lock
T lock(T... args)
ripple::NetworkOPsImp::setAccountHistoryJobTimer
void setAccountHistoryJobTimer(SubAccountHistoryInfoWeak subInfo)
Definition: NetworkOPs.cpp:994
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:4133
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:699
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:742
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:747
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:713
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:755
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:907
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:4630
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:308
ripple::STAmount::clear
void clear()
Definition: STAmount.h:412
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:818
ripple::NetworkOPsImp::pubAccountTransaction
void pubAccountTransaction(std::shared_ptr< ReadView const > const &ledger, AcceptedLedgerTx const &transaction, bool last)
Definition: NetworkOPs.cpp:3199
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:350
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:637
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:1623
ripple::NetworkOPsImp::pubManifest
void pubManifest(Manifest const &) override
Definition: NetworkOPs.cpp:1969
ripple::RelationalDatabase::AccountTxArgs
Definition: RelationalDatabase.h:96
ripple::Manifest
Definition: Manifest.h:80
ripple::NetworkOPsImp::collect_metrics
void collect_metrics()
Definition: NetworkOPs.cpp:4571
ripple::NetworkOPsImp::subPeerStatus
bool subPeerStatus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4148
std::unordered_set
STL class.
ripple::NetworkOPsImp::mDispatchState
DispatchState mDispatchState
Definition: NetworkOPs.cpp:760
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:1007
ripple::NetworkOPsImp::stop
void stop() override
Definition: NetworkOPs.cpp:537
std::pair::second
T second
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:726
ripple::NetworkOPsImp::amendmentWarned_
std::atomic< bool > amendmentWarned_
Definition: NetworkOPs.cpp:709
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:2264
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:91
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:3326
std::vector
STL class.
ripple::NetworkOPsImp::isUNLBlocked
bool isUNLBlocked() override
Definition: NetworkOPs.cpp:1635
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:864
ripple::NetworkOPsImp::tryRemoveRpcSub
bool tryRemoveRpcSub(std::string const &strUrl) override
Definition: NetworkOPs.cpp:4206
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:119
ripple::STAmount::getText
std::string getText() const override
Definition: STAmount.cpp:569
ripple::NetworkOPsImp::recvValidation
bool recvValidation(std::shared_ptr< STValidation > const &val, std::string const &source) override
Definition: NetworkOPs.cpp:2293
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:888
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:2773
ripple::ValidatorList::getQuorumKeys
QuorumKeys getQuorumKeys() const
Get the quorum and all of the trusted keys.
Definition: ValidatorList.h:658
ripple::NetworkOPsImp::batchApplyTimer_
boost::asio::steady_timer batchApplyTimer_
This timer is for applying transaction batches.
Definition: NetworkOPs.cpp:717
ripple::NetworkOPsImp::sValidations
@ sValidations
Definition: NetworkOPs.cpp:738
std::chrono::microseconds
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:29
ripple::AmendmentTable::trustChanged
virtual void trustChanged(hash_set< PublicKey > const &allTrusted)=0
ripple::Config::NODE_SIZE
std::size_t NODE_SIZE
Definition: Config.h:223
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:231
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:804
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:326
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:148
std::shared_ptr::get
T get(T... args)
ripple::NetworkOPsImp::consensusViewChange
void consensusViewChange() override
Definition: NetworkOPs.cpp:1960
std::lock_guard
STL class.
ripple::RPC::computeBookChanges
Json::Value computeBookChanges(std::shared_ptr< L const > const &lpAccepted)
Definition: BookChanges.h:38
ripple::TimeKeeper::closeOffset
std::chrono::seconds closeOffset() const
Definition: TimeKeeper.h:82
ripple::NetworkOPsImp::accounting_
StateAccounting accounting_
Definition: NetworkOPs.cpp:763
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:3906
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:673
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:1326
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:4655
ripple::NetworkOPsImp::Stats::syncing_transitions
beast::insight::Gauge syncing_transitions
Definition: NetworkOPs.cpp:812
std::function
ripple::LoadFeeTrack::getLoadBase
std::uint32_t getLoadBase() const
Definition: LoadFeeTrack.h:89
ripple::NetworkOPsImp::unlBlocked_
std::atomic< bool > unlBlocked_
Definition: NetworkOPs.cpp:710
ripple::NetworkOPsImp::SubAccountHistoryIndex::SubAccountHistoryIndex
SubAccountHistoryIndex(AccountID const &accountId)
Definition: NetworkOPs.cpp:659
ripple::getQualityNext
uint256 getQualityNext(uint256 const &uBase)
Definition: Indexes.cpp:109
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:2862
ripple::Application::openLedger
virtual OpenLedger & openLedger()=0
ripple::NetworkOPsImp::pubLedger
void pubLedger(std::shared_ptr< ReadView const > const &lpAccepted) override
Definition: NetworkOPs.cpp:2930
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:1761
ripple::tapNONE
@ tapNONE
Definition: ApplyView.h:30
ripple::NetworkOPsImp::setUNLBlocked
void setUNLBlocked() override
Definition: NetworkOPs.cpp:1641
ripple::NetworkOPsImp::SubAccountHistoryInfo
Definition: NetworkOPs.cpp:670
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::TimeKeeper::closeTime
time_point closeTime() const
Returns the predicted close time, in network time.
Definition: TimeKeeper.h:75
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:1101
ripple::NetworkOPsImp::unsubTransactions
bool unsubTransactions(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4098
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:218
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:631
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:2844
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:646
ripple::NetworkOPsImp::m_statsMutex
std::mutex m_statsMutex
Definition: NetworkOPs.cpp:817
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:806
ripple::NetworkOPsImp::isAmendmentBlocked
bool isAmendmentBlocked() override
Definition: NetworkOPs.cpp:1604
ripple::NetworkOPsImp::addRpcSub
InfoSub::pointer addRpcSub(std::string const &strUrl, InfoSub::ref) override
Definition: NetworkOPs.cpp:4196
ripple::rpcSUCCESS
@ rpcSUCCESS
Definition: ErrorCodes.h:44
ripple::NetworkOPsImp::forwardValidation
void forwardValidation(Json::Value const &jvObj) override
Definition: NetworkOPs.cpp:2804
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:351
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:1629
ripple::STAmount::setJson
void setJson(Json::Value &) const
Definition: STAmount.cpp:528
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:3805
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:672
ripple::NetworkOPsImp::getOwnerInfo
Json::Value getOwnerInfo(std::shared_ptr< ReadView const > lpLedger, AccountID const &account) override
Definition: NetworkOPs.cpp:1532
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:3043
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:3477
ripple::NetworkOPsImp::isBlocked
bool isBlocked() override
Definition: NetworkOPs.cpp:1598
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:142
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:652
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:677
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:917
ripple::JsonOptions::none
@ none
ripple::NetworkOPsImp::DispatchState
DispatchState
Synchronization states for transaction batches.
Definition: NetworkOPs.cpp:112
ripple::NetworkOPsImp::sServer
@ sServer
Definition: NetworkOPs.cpp:735
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:318
ripple::NetworkOPsImp::endConsensus
void endConsensus() override
Definition: NetworkOPs.cpp:1904
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:3433
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:4116
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
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:4032
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:1648
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:701
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:46
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:332
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:320
ripple::NetworkOPsImp::m_job_queue
JobQueue & m_job_queue
Definition: NetworkOPs.cpp:749
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:4006
ripple::STTx
Definition: STTx.h:45
ripple::setup_FeeVote
FeeSetup setup_FeeVote(Section const &section)
Definition: Config.cpp:1018
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:807
ripple::warnRPC_UNSUPPORTED_MAJORITY
@ warnRPC_UNSUPPORTED_MAJORITY
Definition: ErrorCodes.h:156
ripple::NetworkOPsImp::subTransactions
bool subTransactions(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4088
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:4016
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::NetworkOPsImp::isAmendmentWarned
bool isAmendmentWarned() override
Definition: NetworkOPs.cpp:1617
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:707
ripple::temBAD_SIGNATURE
@ temBAD_SIGNATURE
Definition: TER.h:104
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:2143
ripple::amountFromQuality
STAmount amountFromQuality(std::uint64_t rate)
Definition: STAmount.cpp:850
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:3396
ripple::NetworkOPsImp::m_standalone
const bool m_standalone
Definition: NetworkOPs.cpp:752
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::TimeKeeper::now
time_point now() const override
Returns the current time, using the server's clock.
Definition: TimeKeeper.h:63
ripple::NetworkOPsImp::Stats
Definition: NetworkOPs.cpp:766
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:170
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:655
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:876
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:2019
ripple::jtCLIENT_FEE_CHANGE
@ jtCLIENT_FEE_CHANGE
Definition: Job.h:47
ripple::NetworkOPsImp::mStreamMaps
std::array< SubMapType, SubTypes::sLastEntry > mStreamMaps
Definition: NetworkOPs.cpp:745
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:858
ripple::JobQueue
A pool of threads to perform work.
Definition: JobQueue.h:55
ripple::NetworkOPsImp::mSubLock
std::recursive_mutex mSubLock
Definition: NetworkOPs.cpp:703
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:650
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:740
ripple::NetworkOPsImp::mMutex
std::mutex mMutex
Definition: NetworkOPs.cpp:759
ripple::sfBaseFee
const SF_UINT64 sfBaseFee
ripple::NetworkOPsImp::Stats::tracking_transitions
beast::insight::Gauge tracking_transitions
Definition: NetworkOPs.cpp:813
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:811
ripple::NetworkOPsImp::clusterTimer_
boost::asio::steady_timer clusterTimer_
Definition: NetworkOPs.cpp:714
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:761
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:54
ripple::NetworkOPsImp::reportConsensusStateChange
void reportConsensusStateChange(ConsensusPhase phase)
Definition: NetworkOPs.cpp:3063
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:226
ripple::NetworkOPsImp::unsubServer
bool unsubServer(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4080
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:1224
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:288
ripple::NetworkOPsImp::Stats::Stats
Stats(Handler const &handler, beast::insight::Collector::ptr const &collector)
Definition: NetworkOPs.cpp:769
ripple::NetworkOPsImp::setHeartbeatTimer
void setHeartbeatTimer()
Definition: NetworkOPs.cpp:949
ripple::NetworkOPsImp::unsubBookChanges
bool unsubBookChanges(std::uint64_t uListener) override
Definition: NetworkOPs.cpp:4024
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:3077
ripple::NetworkOPsImp::StateAccounting::initialSyncUs_
std::uint64_t initialSyncUs_
Definition: NetworkOPs.cpp:150
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:2736
ripple::tapUNLIMITED
@ tapUNLIMITED
Definition: ApplyView.h:41
ripple::NetworkOPsImp::sManifests
@ sManifests
Definition: NetworkOPs.cpp:734
ripple::sfLedgerEntryType
const SF_UINT16 sfLedgerEntryType
ripple::NetworkOPsImp::StateAccounting::StateAccounting
StateAccounting()
Definition: NetworkOPs.cpp:154
ripple::NetworkOPsImp::SubAccountHistoryInfoWeak
Definition: NetworkOPs.cpp:675
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:2048
ripple::base_uint::begin
iterator begin()
Definition: base_uint.h:133
ripple::tefPAST_SEQ
@ tefPAST_SEQ
Definition: TER.h:169
ripple::NetworkOPsImp::unsubBook
bool unsubBook(std::uint64_t uListener, Book const &) override
Definition: NetworkOPs.cpp:3947
ripple::TransactionMaster::canonicalize
void canonicalize(std::shared_ptr< Transaction > *pTransaction)
Definition: TransactionMaster.cpp:143
ripple::terSUBMITTED
@ terSUBMITTED
Definition: TER.h:221
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:3956
ripple::NetworkOPsImp::sTransactions
@ sTransactions
Definition: NetworkOPs.cpp:736
ripple::NetworkOPsImp::mSubAccount
SubInfoMapType mSubAccount
Definition: NetworkOPs.cpp:725
ripple::Config::SERVER_DOMAIN
std::string SERVER_DOMAIN
Definition: Config.h:290
ripple::NetworkOPsImp::pubValidatedTransaction
void pubValidatedTransaction(std::shared_ptr< ReadView const > const &ledger, AcceptedLedgerTx const &transaction, bool last)
Definition: NetworkOPs.cpp:3143
ripple::AcceptedLedgerTx::getMeta
TxMeta const & getMeta() const
Definition: AcceptedLedgerTx.h:57
ripple::NetworkOPsImp::clearNeedNetworkLedger
void clearNeedNetworkLedger() override
Definition: NetworkOPs.cpp:870
ripple::NetworkOPsImp::sBookChanges
@ sBookChanges
Definition: NetworkOPs.cpp:741
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:1654
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:1149
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:4231
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:2235
ripple::NetworkOPsImp::mCond
std::condition_variable mCond
Definition: NetworkOPs.cpp:758
ripple::NetworkOPsImp::isFull
bool isFull() override
Definition: NetworkOPs.cpp:882
ripple::PostgresDatabase
Definition: PostgresDatabase.h:27
ripple::NodeStore::Database::getCountsJson
void getCountsJson(Json::Value &obj)
Definition: Database.cpp:378
ripple::LedgerMaster::getCurrentLedgerIndex
LedgerIndex getCurrentLedgerIndex()
Definition: LedgerMaster.cpp:207
ripple::NetworkOPsImp::subLedger
bool subLedger(InfoSub::ref ispListener, Json::Value &jvResult) override
Definition: NetworkOPs.cpp:3976
std::condition_variable
ripple::NetworkOPsImp::Stats::full_transitions
beast::insight::Gauge full_transitions
Definition: NetworkOPs.cpp:814
ripple::Config::RELAY_UNTRUSTED_VALIDATIONS
int RELAY_UNTRUSTED_VALIDATIONS
Definition: Config.h:179
ripple::stateNames
static const std::array< char const *, 5 > stateNames
Definition: NetworkOPs.cpp:827
ripple::NetworkOPsImp::sLedger
@ sLedger
Definition: NetworkOPs.cpp:733
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:3849
ripple::NetworkOPsImp::mConsensus
RCLConsensus mConsensus
Definition: NetworkOPs.cpp:719
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:739
std::chrono::milliseconds::count
T count(T... args)
ripple::NetworkOPsImp::mMode
std::atomic< OperatingMode > mMode
Definition: NetworkOPs.cpp:705
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:4042
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:708
ripple::NetworkOPsImp::submitTransaction
void submitTransaction(std::shared_ptr< STTx const > const &) override
Definition: NetworkOPs.cpp:1169
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:3085
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:721
ripple::NetworkOPsImp::updateLocalTx
void updateLocalTx(ReadView const &view) override
Definition: NetworkOPs.cpp:3072
std::optional
mutex
ripple::NetworkOPsImp::sRTTransactions
@ sRTTransactions
Definition: NetworkOPs.cpp:737
ripple::NetworkOPs::FailHard::yes
@ yes
beast::Journal::debug
Stream debug() const
Definition: Journal.h:314
ripple::NetworkOPsImp::pubConsensus
void pubConsensus(ConsensusPhase phase)
Definition: NetworkOPs.cpp:2116
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:4106
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:810
ripple::genesisAccountId
static const auto genesisAccountId
Definition: NetworkOPs.cpp:840
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:2742
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:2316
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:723
ripple::NetworkOPsImp::subServer
bool subServer(InfoSub::ref ispListener, Json::Value &jvResult, bool admin) override
Definition: NetworkOPs.cpp:4050
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:678
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:715
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:808
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:3937
ripple::NetworkOPsImp::subConsensus
bool subConsensus(InfoSub::ref ispListener) override
Definition: NetworkOPs.cpp:4166
ripple::NetworkOPsImp::getConsensusInfo
Json::Value getConsensusInfo() override
Definition: NetworkOPs.cpp:2310
ripple::NetworkOPsImp::Stats::connected_duration
beast::insight::Gauge connected_duration
Definition: NetworkOPs.cpp:805
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:712
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:657
ripple::NetworkOPsImp
Definition: NetworkOPs.cpp:82
ripple::NetworkOPsImp::mSubAccountHistory
SubAccountHistoryMapType mSubAccountHistory
Definition: NetworkOPs.cpp:730
ripple::NetworkOPsImp::StateAccounting::mode
void mode(OperatingMode om)
Record state transition.
Definition: NetworkOPs.cpp:4609
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:3449
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:3895
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:236
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:117
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:4158
ripple::NetworkOPsImp::app_
Application & app_
Definition: NetworkOPs.cpp:698
ripple::NetworkOPsImp::transactionBatch
bool transactionBatch(bool drain) override
Apply transactions in batches.
Definition: NetworkOPs.cpp:1310
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:648
ripple::isTemMalformed
bool isTemMalformed(TER x)
Definition: TER.h:619
ripple::trunc32
static std::uint32_t trunc32(std::uint64_t v)
Definition: NetworkOPs.cpp:2040
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:846
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:728
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::NetworkOPsImp::findRpcSub
InfoSub::pointer findRpcSub(std::string const &strUrl) override
Definition: NetworkOPs.cpp:4183
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:2730
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:1815
ripple::NetworkOPsImp::setAmendmentBlocked
void setAmendmentBlocked() override
Definition: NetworkOPs.cpp:1610
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)