rippled
PathRequest.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/main/Application.h>
21 #include <ripple/app/misc/LoadFeeTrack.h>
22 #include <ripple/app/misc/NetworkOPs.h>
23 #include <ripple/app/paths/AccountCurrencies.h>
24 #include <ripple/app/paths/PathRequest.h>
25 #include <ripple/app/paths/PathRequests.h>
26 #include <ripple/app/paths/RippleCalc.h>
27 #include <ripple/app/paths/impl/PathfinderUtils.h>
28 #include <ripple/basics/Log.h>
29 #include <ripple/beast/core/LexicalCast.h>
30 #include <ripple/core/Config.h>
31 #include <ripple/net/RPCErr.h>
32 #include <ripple/protocol/ErrorCodes.h>
33 #include <ripple/protocol/UintTypes.h>
34 
35 #include <ripple/rpc/impl/Tuning.h>
36 #include <optional>
37 
38 #include <tuple>
39 
40 namespace ripple {
41 
43  Application& app,
44  const std::shared_ptr<InfoSub>& subscriber,
45  int id,
46  PathRequests& owner,
47  beast::Journal journal)
48  : app_(app)
49  , m_journal(journal)
50  , mOwner(owner)
51  , wpSubscriber(subscriber)
52  , consumer_(subscriber->getConsumer())
53  , jvStatus(Json::objectValue)
54  , mLastIndex(0)
55  , mInProgress(false)
56  , iLevel(0)
57  , bLastSuccess(false)
58  , iIdentifier(id)
59  , created_(std::chrono::steady_clock::now())
60 {
61  JLOG(m_journal.debug()) << iIdentifier << " created";
62 }
63 
65  Application& app,
66  std::function<void(void)> const& completion,
67  Resource::Consumer& consumer,
68  int id,
69  PathRequests& owner,
70  beast::Journal journal)
71  : app_(app)
72  , m_journal(journal)
73  , mOwner(owner)
74  , fCompletion(completion)
75  , consumer_(consumer)
76  , jvStatus(Json::objectValue)
77  , mLastIndex(0)
78  , mInProgress(false)
79  , iLevel(0)
80  , bLastSuccess(false)
81  , iIdentifier(id)
82  , created_(std::chrono::steady_clock::now())
83 {
84  JLOG(m_journal.debug()) << iIdentifier << " created";
85 }
86 
88 {
89  using namespace std::chrono;
90  auto stream = m_journal.info();
91  if (!stream)
92  return;
93 
94  std::string fast, full;
95  if (quick_reply_ != steady_clock::time_point{})
96  {
97  fast = " fast:";
98  fast += std::to_string(
99  duration_cast<milliseconds>(quick_reply_ - created_).count());
100  fast += "ms";
101  }
102  if (full_reply_ != steady_clock::time_point{})
103  {
104  full = " full:";
105  full += std::to_string(
106  duration_cast<milliseconds>(full_reply_ - created_).count());
107  full += "ms";
108  }
109  stream
110  << iIdentifier << " complete:" << fast << full << " total:"
111  << duration_cast<milliseconds>(steady_clock::now() - created_).count()
112  << "ms";
113 }
114 
115 bool
117 {
119 
120  // does this path request still need its first full path
121  return mLastIndex == 0;
122 }
123 
124 bool
126 {
128 
129  if (mInProgress)
130  {
131  // Another thread is handling this
132  return false;
133  }
134 
135  if (newOnly && (mLastIndex != 0))
136  {
137  // Only handling new requests, this isn't new
138  return false;
139  }
140 
141  if (mLastIndex >= index)
142  {
143  return false;
144  }
145 
146  mInProgress = true;
147  return true;
148 }
149 
150 bool
152 {
153  return bool(fCompletion);
154 }
155 
156 void
158 {
160 
161  assert(mInProgress);
162  mInProgress = false;
163 
164  if (fCompletion)
165  {
166  fCompletion();
168  }
169 }
170 
171 bool
173 {
174  if (!raSrcAccount || !raDstAccount)
175  return false;
176 
177  if (!convert_all_ && (saSendMax || saDstAmount <= beast::zero))
178  {
179  // If send max specified, dst amt must be -1.
181  return false;
182  }
183 
184  auto const& lrLedger = crCache->getLedger();
185 
186  if (!lrLedger->exists(keylet::account(*raSrcAccount)))
187  {
188  // Source account does not exist.
190  return false;
191  }
192 
193  auto const sleDest = lrLedger->read(keylet::account(*raDstAccount));
194 
195  Json::Value& jvDestCur =
196  (jvStatus[jss::destination_currencies] = Json::arrayValue);
197 
198  if (!sleDest)
199  {
200  jvDestCur.append(Json::Value(systemCurrencyCode()));
201  if (!saDstAmount.native())
202  {
203  // Only XRP can be send to a non-existent account.
205  return false;
206  }
207 
208  if (!convert_all_ &&
209  saDstAmount < STAmount(lrLedger->fees().accountReserve(0)))
210  {
211  // Payment must meet reserve.
213  return false;
214  }
215  }
216  else
217  {
218  bool const disallowXRP(sleDest->getFlags() & lsfDisallowXRP);
219 
220  auto usDestCurrID =
221  accountDestCurrencies(*raDstAccount, crCache, !disallowXRP);
222 
223  for (auto const& currency : usDestCurrID)
224  jvDestCur.append(to_string(currency));
225  jvStatus[jss::destination_tag] =
226  (sleDest->getFlags() & lsfRequireDestTag);
227  }
228 
229  jvStatus[jss::ledger_hash] = to_string(lrLedger->info().hash);
230  jvStatus[jss::ledger_index] = lrLedger->seq();
231  return true;
232 }
233 
234 /* If this is a normal path request, we want to run it once "fast" now
235  to give preliminary results.
236 
237  If this is a legacy path request, we are only going to run it once,
238  and we can't run it in full now, so we don't want to run it at all.
239 
240  If there's an error, we need to be sure to return it to the caller
241  in all cases.
242 */
246  Json::Value const& value)
247 {
248  bool valid = false;
249 
250  if (parseJson(value) != PFR_PJ_INVALID)
251  {
252  valid = isValid(cache);
253  if (!hasCompletion() && valid)
254  doUpdate(cache, true);
255  }
256 
257  if (auto stream = m_journal.debug())
258  {
259  if (valid)
260  {
261  stream << iIdentifier << " valid: " << toBase58(*raSrcAccount);
262  stream << iIdentifier << " deliver: " << saDstAmount.getFullText();
263  }
264  else
265  {
266  stream << iIdentifier << " invalid";
267  }
268  }
269 
270  return {valid, jvStatus};
271 }
272 
273 int
275 {
276  if (!jvParams.isMember(jss::source_account))
277  {
279  return PFR_PJ_INVALID;
280  }
281 
282  if (!jvParams.isMember(jss::destination_account))
283  {
285  return PFR_PJ_INVALID;
286  }
287 
288  if (!jvParams.isMember(jss::destination_amount))
289  {
291  return PFR_PJ_INVALID;
292  }
293 
294  raSrcAccount =
295  parseBase58<AccountID>(jvParams[jss::source_account].asString());
296  if (!raSrcAccount)
297  {
299  return PFR_PJ_INVALID;
300  }
301 
302  raDstAccount =
303  parseBase58<AccountID>(jvParams[jss::destination_account].asString());
304  if (!raDstAccount)
305  {
307  return PFR_PJ_INVALID;
308  }
309 
310  if (!amountFromJsonNoThrow(saDstAmount, jvParams[jss::destination_amount]))
311  {
313  return PFR_PJ_INVALID;
314  }
315 
316  convert_all_ = saDstAmount == STAmount(saDstAmount.issue(), 1u, 0, true);
317 
318  if ((saDstAmount.getCurrency().isZero() &&
321  (!convert_all_ && saDstAmount <= beast::zero))
322  {
324  return PFR_PJ_INVALID;
325  }
326 
327  if (jvParams.isMember(jss::send_max))
328  {
329  // Send_max requires destination amount to be -1.
330  if (!convert_all_)
331  {
333  return PFR_PJ_INVALID;
334  }
335 
336  saSendMax.emplace();
337  if (!amountFromJsonNoThrow(*saSendMax, jvParams[jss::send_max]) ||
338  (saSendMax->getCurrency().isZero() &&
339  saSendMax->getIssuer().isNonZero()) ||
340  (saSendMax->getCurrency() == badCurrency()) ||
341  (*saSendMax <= beast::zero &&
342  *saSendMax != STAmount(saSendMax->issue(), 1u, 0, true)))
343  {
345  return PFR_PJ_INVALID;
346  }
347  }
348 
349  if (jvParams.isMember(jss::source_currencies))
350  {
351  Json::Value const& jvSrcCurrencies = jvParams[jss::source_currencies];
352  if (!jvSrcCurrencies.isArray() || jvSrcCurrencies.size() == 0 ||
353  jvSrcCurrencies.size() > RPC::Tuning::max_src_cur)
354  {
356  return PFR_PJ_INVALID;
357  }
358 
359  sciSourceCurrencies.clear();
360 
361  for (auto const& c : jvSrcCurrencies)
362  {
363  // Mandatory currency
364  Currency srcCurrencyID;
365  if (!c.isObject() || !c.isMember(jss::currency) ||
366  !c[jss::currency].isString() ||
367  !to_currency(srcCurrencyID, c[jss::currency].asString()))
368  {
370  return PFR_PJ_INVALID;
371  }
372 
373  // Optional issuer
374  AccountID srcIssuerID;
375  if (c.isMember(jss::issuer) &&
376  (!c[jss::issuer].isString() ||
377  !to_issuer(srcIssuerID, c[jss::issuer].asString())))
378  {
380  return PFR_PJ_INVALID;
381  }
382 
383  if (srcCurrencyID.isZero())
384  {
385  if (srcIssuerID.isNonZero())
386  {
388  return PFR_PJ_INVALID;
389  }
390  }
391  else if (srcIssuerID.isZero())
392  {
393  srcIssuerID = *raSrcAccount;
394  }
395 
396  if (saSendMax)
397  {
398  // If the currencies don't match, ignore the source currency.
399  if (srcCurrencyID == saSendMax->getCurrency())
400  {
401  // If neither is the source and they are not equal, then the
402  // source issuer is illegal.
403  if (srcIssuerID != *raSrcAccount &&
404  saSendMax->getIssuer() != *raSrcAccount &&
405  srcIssuerID != saSendMax->getIssuer())
406  {
408  return PFR_PJ_INVALID;
409  }
410 
411  // If both are the source, use the source.
412  // Otherwise, use the one that's not the source.
413  if (srcIssuerID != *raSrcAccount)
414  {
415  sciSourceCurrencies.insert(
416  {srcCurrencyID, srcIssuerID});
417  }
418  else if (saSendMax->getIssuer() != *raSrcAccount)
419  {
420  sciSourceCurrencies.insert(
421  {srcCurrencyID, saSendMax->getIssuer()});
422  }
423  else
424  {
425  sciSourceCurrencies.insert(
426  {srcCurrencyID, *raSrcAccount});
427  }
428  }
429  }
430  else
431  {
432  sciSourceCurrencies.insert({srcCurrencyID, srcIssuerID});
433  }
434  }
435  }
436 
437  if (jvParams.isMember(jss::id))
438  jvId = jvParams[jss::id];
439 
440  return PFR_PJ_NOCHANGE;
441 }
442 
445 {
446  JLOG(m_journal.debug()) << iIdentifier << " closed";
448  jvStatus[jss::closed] = true;
449  return jvStatus;
450 }
451 
454 {
456  jvStatus[jss::status] = jss::success;
457  return jvStatus;
458 }
459 
460 void
462 {
463  JLOG(m_journal.info()) << iIdentifier << " aborting early";
464 }
465 
470  Currency const& currency,
471  STAmount const& dst_amount,
472  int const level,
473  std::function<bool(void)> const& continueCallback)
474 {
475  auto i = currency_map.find(currency);
476  if (i != currency_map.end())
477  return i->second;
478  auto pathfinder = std::make_unique<Pathfinder>(
479  cache,
480  *raSrcAccount,
481  *raDstAccount,
482  currency,
483  std::nullopt,
484  dst_amount,
485  saSendMax,
486  app_);
487  if (pathfinder->findPaths(level, continueCallback))
488  pathfinder->computePathRanks(max_paths_, continueCallback);
489  else
490  pathfinder.reset(); // It's a bad request - clear it.
491  return currency_map[currency] = std::move(pathfinder);
492 }
493 
494 bool
497  int const level,
498  Json::Value& jvArray,
499  std::function<bool(void)> const& continueCallback)
500 {
501  auto sourceCurrencies = sciSourceCurrencies;
502  if (sourceCurrencies.empty() && saSendMax)
503  {
504  sourceCurrencies.insert(saSendMax->issue());
505  }
506  if (sourceCurrencies.empty())
507  {
508  auto currencies = accountSourceCurrencies(*raSrcAccount, cache, true);
509  bool const sameAccount = *raSrcAccount == *raDstAccount;
510  for (auto const& c : currencies)
511  {
512  if (!sameAccount || c != saDstAmount.getCurrency())
513  {
514  if (sourceCurrencies.size() >= RPC::Tuning::max_auto_src_cur)
515  return false;
516  sourceCurrencies.insert(
517  {c, c.isZero() ? xrpAccount() : *raSrcAccount});
518  }
519  }
520  }
521 
522  auto const dst_amount = convertAmount(saDstAmount, convert_all_);
524  for (auto const& issue : sourceCurrencies)
525  {
526  if (continueCallback && !continueCallback())
527  break;
528  JLOG(m_journal.debug())
529  << iIdentifier
530  << " Trying to find paths: " << STAmount(issue, 1).getFullText();
531 
532  auto& pathfinder = getPathFinder(
533  cache,
534  currency_map,
535  issue.currency,
536  dst_amount,
537  level,
538  continueCallback);
539  if (!pathfinder)
540  {
541  JLOG(m_journal.debug()) << iIdentifier << " No paths found";
542  continue;
543  }
544 
545  STPath fullLiquidityPath;
546  auto ps = pathfinder->getBestPaths(
547  max_paths_,
548  fullLiquidityPath,
549  mContext[issue],
550  issue.account,
551  continueCallback);
552  mContext[issue] = ps;
553 
554  auto const& sourceAccount = [&] {
555  if (!isXRP(issue.account))
556  return issue.account;
557 
558  if (isXRP(issue.currency))
559  return xrpAccount();
560 
561  return *raSrcAccount;
562  }();
563 
564  STAmount saMaxAmount = saSendMax.value_or(
565  STAmount({issue.currency, sourceAccount}, 1u, 0, true));
566 
567  JLOG(m_journal.debug())
568  << iIdentifier << " Paths found, calling rippleCalc";
569 
570  path::RippleCalc::Input rcInput;
571  if (convert_all_)
572  rcInput.partialPaymentAllowed = true;
573  auto sandbox =
574  std::make_unique<PaymentSandbox>(&*cache->getLedger(), tapNONE);
576  *sandbox,
577  saMaxAmount, // --> Amount to send is unlimited
578  // to get an estimate.
579  dst_amount, // --> Amount to deliver.
580  *raDstAccount, // --> Account to deliver to.
581  *raSrcAccount, // --> Account sending from.
582  ps, // --> Path set.
583  app_.logs(),
584  &rcInput);
585 
586  if (!convert_all_ && !fullLiquidityPath.empty() &&
587  (rc.result() == terNO_LINE || rc.result() == tecPATH_PARTIAL))
588  {
589  JLOG(m_journal.debug())
590  << iIdentifier << " Trying with an extra path element";
591 
592  ps.push_back(fullLiquidityPath);
593  sandbox =
594  std::make_unique<PaymentSandbox>(&*cache->getLedger(), tapNONE);
596  *sandbox,
597  saMaxAmount, // --> Amount to send is unlimited
598  // to get an estimate.
599  dst_amount, // --> Amount to deliver.
600  *raDstAccount, // --> Account to deliver to.
601  *raSrcAccount, // --> Account sending from.
602  ps, // --> Path set.
603  app_.logs());
604 
605  if (rc.result() != tesSUCCESS)
606  {
607  JLOG(m_journal.warn())
608  << iIdentifier << " Failed with covering path "
609  << transHuman(rc.result());
610  }
611  else
612  {
613  JLOG(m_journal.debug())
614  << iIdentifier << " Extra path element gives "
615  << transHuman(rc.result());
616  }
617  }
618 
619  if (rc.result() == tesSUCCESS)
620  {
622  rc.actualAmountIn.setIssuer(sourceAccount);
623  jvEntry[jss::source_amount] =
624  rc.actualAmountIn.getJson(JsonOptions::none);
625  jvEntry[jss::paths_computed] = ps.getJson(JsonOptions::none);
626 
627  if (convert_all_)
628  jvEntry[jss::destination_amount] =
629  rc.actualAmountOut.getJson(JsonOptions::none);
630 
631  if (hasCompletion())
632  {
633  // Old ripple_path_find API requires this
634  jvEntry[jss::paths_canonical] = Json::arrayValue;
635  }
636 
637  jvArray.append(jvEntry);
638  }
639  else
640  {
641  JLOG(m_journal.debug()) << iIdentifier << " rippleCalc returns "
642  << transHuman(rc.result());
643  }
644  }
645 
646  /* The resource fee is based on the number of source currencies used.
647  The minimum cost is 50 and the maximum is 400. The cost increases
648  after four source currencies, 50 - (4 * 4) = 34.
649  */
650  int const size = sourceCurrencies.size();
651  consumer_.charge({std::clamp(size * size + 34, 50, 400), "path update"});
652  return true;
653 }
654 
658  bool fast,
659  std::function<bool(void)> const& continueCallback)
660 {
661  using namespace std::chrono;
662  JLOG(m_journal.debug())
663  << iIdentifier << " update " << (fast ? "fast" : "normal");
664 
665  {
667 
668  if (!isValid(cache))
669  return jvStatus;
670  }
671 
672  Json::Value newStatus = Json::objectValue;
673 
674  if (hasCompletion())
675  {
676  // Old ripple_path_find API gives destination_currencies
677  auto& destCurrencies =
678  (newStatus[jss::destination_currencies] = Json::arrayValue);
679  auto usCurrencies = accountDestCurrencies(*raDstAccount, cache, true);
680  for (auto const& c : usCurrencies)
681  destCurrencies.append(to_string(c));
682  }
683 
684  newStatus[jss::source_account] = toBase58(*raSrcAccount);
685  newStatus[jss::destination_account] = toBase58(*raDstAccount);
686  newStatus[jss::destination_amount] = saDstAmount.getJson(JsonOptions::none);
687  newStatus[jss::full_reply] = !fast;
688 
689  if (jvId)
690  newStatus[jss::id] = jvId;
691 
692  bool loaded = app_.getFeeTrack().isLoadedLocal();
693 
694  if (iLevel == 0)
695  {
696  // first pass
697  if (loaded || fast)
699  else
701  }
702  else if ((iLevel == app_.config().PATH_SEARCH_FAST) && !fast)
703  {
704  // leaving fast pathfinding
706  if (loaded && (iLevel > app_.config().PATH_SEARCH_FAST))
707  --iLevel;
708  }
709  else if (bLastSuccess)
710  {
711  // decrement, if possible
712  if (iLevel > app_.config().PATH_SEARCH ||
713  (loaded && (iLevel > app_.config().PATH_SEARCH_FAST)))
714  --iLevel;
715  }
716  else
717  {
718  // adjust as needed
719  if (!loaded && (iLevel < app_.config().PATH_SEARCH_MAX))
720  ++iLevel;
721  if (loaded && (iLevel > app_.config().PATH_SEARCH_FAST))
722  --iLevel;
723  }
724 
725  JLOG(m_journal.debug()) << iIdentifier << " processing at level " << iLevel;
726 
727  Json::Value jvArray = Json::arrayValue;
728  if (findPaths(cache, iLevel, jvArray, continueCallback))
729  {
730  bLastSuccess = jvArray.size() != 0;
731  newStatus[jss::alternatives] = std::move(jvArray);
732  }
733  else
734  {
735  bLastSuccess = false;
736  newStatus = rpcError(rpcINTERNAL);
737  }
738 
739  if (fast && quick_reply_ == steady_clock::time_point{})
740  {
741  quick_reply_ = steady_clock::now();
742  mOwner.reportFast(duration_cast<milliseconds>(quick_reply_ - created_));
743  }
744  else if (!fast && full_reply_ == steady_clock::time_point{})
745  {
746  full_reply_ = steady_clock::now();
747  mOwner.reportFull(duration_cast<milliseconds>(full_reply_ - created_));
748  }
749 
750  {
752  jvStatus = newStatus;
753  }
754 
755  JLOG(m_journal.debug())
756  << iIdentifier << " update finished " << (fast ? "fast" : "normal");
757  return newStatus;
758 }
759 
762 {
763  return wpSubscriber.lock();
764 }
765 
766 } // namespace ripple
ripple::badCurrency
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
Definition: UintTypes.cpp:129
ripple::Application
Definition: Application.h:116
ripple::systemCurrencyCode
static std::string const & systemCurrencyCode()
Definition: SystemParameters.h:62
ripple::to_currency
bool to_currency(Currency &currency, std::string const &code)
Tries to convert a string to a Currency, returns true on success.
Definition: UintTypes.cpp:80
ripple::amountFromJsonNoThrow
bool amountFromJsonNoThrow(STAmount &result, Json::Value const &jvSource)
Definition: STAmount.cpp:1032
std::weak_ptr::lock
T lock(T... args)
ripple::rpcDST_AMT_MALFORMED
@ rpcDST_AMT_MALFORMED
Definition: ErrorCodes.h:106
std::string
STL class.
std::shared_ptr< InfoSub >
ripple::PathRequest::mContext
std::map< Issue, STPathSet > mContext
Definition: PathRequest.h:156
ripple::rpcError
Json::Value rpcError(int iError)
Definition: RPCErr.cpp:29
ripple::Config::PATH_SEARCH
int PATH_SEARCH
Definition: Config.h:206
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:537
ripple::PathRequest::mLastIndex
LedgerIndex mLastIndex
Definition: PathRequest.h:161
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:350
ripple::terNO_LINE
@ terNO_LINE
Definition: TER.h:212
ripple::PathRequest::getPathFinder
std::unique_ptr< Pathfinder > const & getPathFinder(std::shared_ptr< RippleLineCache > const &, hash_map< Currency, std::unique_ptr< Pathfinder >> &, Currency const &, STAmount const &, int const, std::function< bool(void)> const &)
Definition: PathRequest.cpp:467
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
ripple::rpcSRC_ACT_NOT_FOUND
@ rpcSRC_ACT_NOT_FOUND
Definition: ErrorCodes.h:122
std::pair
ripple::PathRequest::saDstAmount
STAmount saDstAmount
Definition: PathRequest.h:152
ripple::accountDestCurrencies
hash_set< Currency > accountDestCurrencies(AccountID const &account, std::shared_ptr< RippleLineCache > const &lrCache, bool includeXRP)
Definition: AccountCurrencies.cpp:61
ripple::STAmount::getJson
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:653
std::optional::value_or
T value_or(T... args)
ripple::path::RippleCalc::Input
Definition: RippleCalc.h:46
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:104
ripple::PathRequest::jvStatus
Json::Value jvStatus
Definition: PathRequest.h:147
std::optional::emplace
T emplace(T... args)
ripple::PathRequest::convert_all_
bool convert_all_
Definition: PathRequest.h:158
beast::Journal::warn
Stream warn() const
Definition: Journal.h:326
std::lock_guard
STL class.
tuple
ripple::PathRequest::doAborting
void doAborting() const
Definition: PathRequest.cpp:461
ripple::PathRequest::full_reply_
std::chrono::steady_clock::time_point full_reply_
Definition: PathRequest.h:171
ripple::PathRequest::mIndexLock
std::recursive_mutex mIndexLock
Definition: PathRequest.h:160
std::function
ripple::PathRequest::consumer_
Resource::Consumer & consumer_
Definition: PathRequest.h:144
ripple::tapNONE
@ tapNONE
Definition: ApplyView.h:30
ripple::PathRequest::fCompletion
std::function< void(void)> fCompletion
Definition: PathRequest.h:143
ripple::PathRequest::raDstAccount
std::optional< AccountID > raDstAccount
Definition: PathRequest.h:151
ripple::Config::PATH_SEARCH_MAX
int PATH_SEARCH_MAX
Definition: Config.h:208
ripple::PathRequest::doStatus
Json::Value doStatus(Json::Value const &) override
Definition: PathRequest.cpp:453
ripple::PathRequest::doUpdate
Json::Value doUpdate(std::shared_ptr< RippleLineCache > const &, bool fast, std::function< bool(void)> const &continueCallback={})
Definition: PathRequest.cpp:656
ripple::Application::getFeeTrack
virtual LoadFeeTrack & getFeeTrack()=0
ripple::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:362
ripple::PathRequest::quick_reply_
std::chrono::steady_clock::time_point quick_reply_
Definition: PathRequest.h:170
ripple::base_uint< 160, detail::CurrencyTag >
ripple::LoadFeeTrack::isLoadedLocal
bool isLoadedLocal() const
Definition: LoadFeeTrack.h:126
ripple::STAmount::getFullText
std::string getFullText() const override
Definition: STAmount.cpp:559
Json
JSON (JavaScript Object Notation).
Definition: DeliverMax.h:28
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:532
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::PathRequest::PathRequest
PathRequest(Application &app, std::shared_ptr< InfoSub > const &subscriber, int id, PathRequests &, beast::Journal journal)
Definition: PathRequest.cpp:42
ripple::PathRequest::max_paths_
static unsigned const int max_paths_
Definition: PathRequest.h:173
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:142
ripple::PathRequest::sciSourceCurrencies
std::set< Issue > sciSourceCurrencies
Definition: PathRequest.h:155
ripple::PathRequest::~PathRequest
~PathRequest()
Definition: PathRequest.cpp:87
ripple::rpcSRC_ACT_MISSING
@ rpcSRC_ACT_MISSING
Definition: ErrorCodes.h:121
ripple::RPC::Tuning::max_src_cur
static constexpr int max_src_cur
Maximum number of source currencies allowed in a path find request.
Definition: rpc/impl/Tuning.h:81
ripple::Application::config
virtual Config & config()=0
ripple::rpcACT_NOT_FOUND
@ rpcACT_NOT_FOUND
Definition: ErrorCodes.h:70
std::to_string
T to_string(T... args)
ripple::PathRequest::bLastSuccess
bool bLastSuccess
Definition: PathRequest.h:165
ripple::rpcSRC_ISR_MALFORMED
@ rpcSRC_ISR_MALFORMED
Definition: ErrorCodes.h:125
ripple::STAmount
Definition: STAmount.h:46
ripple::xrpAccount
AccountID const & xrpAccount()
Compute AccountID from public key.
Definition: AccountID.cpp:168
beast::Journal::info
Stream info() const
Definition: Journal.h:320
Json::Value::size
UInt size() const
Number of values in array or object.
Definition: json_value.cpp:706
ripple::Application::logs
virtual Logs & logs()=0
ripple::PathRequest::app_
Application & app_
Definition: PathRequest.h:135
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:91
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint32_t
ripple::tecPATH_PARTIAL
@ tecPATH_PARTIAL
Definition: TER.h:263
ripple::PathRequest::raSrcAccount
std::optional< AccountID > raSrcAccount
Definition: PathRequest.h:150
ripple::rpcDST_ACT_MALFORMED
@ rpcDST_ACT_MALFORMED
Definition: ErrorCodes.h:103
ripple::PathRequest::isValid
bool isValid(std::shared_ptr< RippleLineCache > const &crCache)
Definition: PathRequest.cpp:172
ripple::transHuman
std::string transHuman(TER code)
Definition: TER.cpp:250
ripple::lsfRequireDestTag
@ lsfRequireDestTag
Definition: LedgerFormats.h:255
ripple::PathRequest::updateComplete
void updateComplete()
Definition: PathRequest.cpp:157
ripple::rpcINTERNAL
@ rpcINTERNAL
Definition: ErrorCodes.h:130
Json::Value::isArray
bool isArray() const
Definition: json_value.cpp:1015
ripple::PathRequest::doClose
Json::Value doClose() override
Definition: PathRequest.cpp:444
ripple::PathRequest::doCreate
std::pair< bool, Json::Value > doCreate(std::shared_ptr< RippleLineCache > const &, Json::Value const &)
Definition: PathRequest.cpp:244
ripple::rpcSRC_ACT_MALFORMED
@ rpcSRC_ACT_MALFORMED
Definition: ErrorCodes.h:120
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:332
ripple::STPath::empty
bool empty() const
Definition: STPathSet.h:399
ripple::PathRequest::findPaths
bool findPaths(std::shared_ptr< RippleLineCache > const &, int const, Json::Value &, std::function< bool(void)> const &)
Finds and sets a PathSet in the JSON argument.
Definition: PathRequest.cpp:495
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::PathRequests::reportFast
void reportFast(std::chrono::milliseconds ms)
Definition: PathRequests.h:90
ripple::Config::PATH_SEARCH_FAST
int PATH_SEARCH_FAST
Definition: Config.h:207
ripple::JsonOptions::none
@ none
Definition: STBase.h:42
ripple::PathRequest::mLock
std::recursive_mutex mLock
Definition: PathRequest.h:138
ripple::PathRequest::created_
const std::chrono::steady_clock::time_point created_
Definition: PathRequest.h:169
std::clamp
T clamp(T... args)
ripple::PathRequest::wpSubscriber
std::weak_ptr< InfoSub > wpSubscriber
Definition: PathRequest.h:142
std
STL namespace.
ripple::PathRequest::isNew
bool isNew()
Definition: PathRequest.cpp:116
ripple::RPC::Tuning::max_auto_src_cur
static constexpr int max_auto_src_cur
Maximum number of auto source currencies in a path find request.
Definition: rpc/impl/Tuning.h:84
ripple::Resource::Consumer
An endpoint that consumes resources.
Definition: Consumer.h:34
ripple::path::RippleCalc::rippleCalculate
static Output rippleCalculate(PaymentSandbox &view, STAmount const &saMaxAmountReq, STAmount const &saDstAmountReq, AccountID const &uDstAccountID, AccountID const &uSrcAccountID, STPathSet const &spsPaths, Logs &l, Input const *const pInputs=nullptr)
Definition: RippleCalc.cpp:31
ripple::PathRequests::reportFull
void reportFull(std::chrono::milliseconds ms)
Definition: PathRequests.h:96
ripple::path::RippleCalc::Input::partialPaymentAllowed
bool partialPaymentAllowed
Definition: RippleCalc.h:50
ripple::rpcDST_AMT_MISSING
@ rpcDST_AMT_MISSING
Definition: ErrorCodes.h:107
optional
beast::Journal::debug
Stream debug() const
Definition: Journal.h:314
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::lsfDisallowXRP
@ lsfDisallowXRP
Definition: LedgerFormats.h:259
ripple::accountSourceCurrencies
hash_set< Currency > accountSourceCurrencies(AccountID const &account, std::shared_ptr< RippleLineCache > const &lrCache, bool includeXRP)
Definition: AccountCurrencies.cpp:25
ripple::rpcSRC_CUR_MALFORMED
@ rpcSRC_CUR_MALFORMED
Definition: ErrorCodes.h:124
ripple::PathRequests
Definition: PathRequests.h:33
ripple::PathRequest::hasCompletion
bool hasCompletion()
Definition: PathRequest.cpp:151
ripple::rpcDST_ACT_MISSING
@ rpcDST_ACT_MISSING
Definition: ErrorCodes.h:104
ripple::PathRequest::saSendMax
std::optional< STAmount > saSendMax
Definition: PathRequest.h:153
ripple::PathRequest::jvId
Json::Value jvId
Definition: PathRequest.h:146
ripple::Resource::Consumer::charge
Disposition charge(Charge const &fee)
Apply a load charge to the consumer.
Definition: Consumer.cpp:99
ripple::PathRequest::iIdentifier
const int iIdentifier
Definition: PathRequest.h:167
ripple::PathRequest::mOwner
PathRequests & mOwner
Definition: PathRequest.h:140
std::unique_ptr
STL class.
ripple::STPath
Definition: STPathSet.h:118
ripple::PathRequest::needsUpdate
bool needsUpdate(bool newOnly, LedgerIndex index)
Definition: PathRequest.cpp:125
std::unordered_map
STL class.
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:356
ripple::PathRequest::getSubscriber
InfoSub::pointer getSubscriber() const
Definition: PathRequest.cpp:761
ripple::PathRequest::m_journal
beast::Journal m_journal
Definition: PathRequest.h:136
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:236
ripple::PathRequest::parseJson
int parseJson(Json::Value const &)
Definition: PathRequest.cpp:274
ripple::PathRequest::iLevel
int iLevel
Definition: PathRequest.h:164
ripple::PathRequest::mInProgress
bool mInProgress
Definition: PathRequest.h:162
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::rpcSENDMAX_MALFORMED
@ rpcSENDMAX_MALFORMED
Definition: ErrorCodes.h:119
ripple::to_issuer
bool to_issuer(AccountID &, std::string const &)
Convert hex or base58 string to AccountID.
Definition: AccountID.cpp:182
ripple::convertAmount
STAmount convertAmount(STAmount const &amt, bool all)
Definition: PathfinderUtils.h:37
std::chrono