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  assert(continueCallback && !continueCallback());
542  JLOG(m_journal.debug()) << iIdentifier << " No paths found";
543  continue;
544  }
545 
546  STPath fullLiquidityPath;
547  auto ps = pathfinder->getBestPaths(
548  max_paths_,
549  fullLiquidityPath,
550  mContext[issue],
551  issue.account,
552  continueCallback);
553  mContext[issue] = ps;
554 
555  auto& sourceAccount = !isXRP(issue.account)
556  ? issue.account
557  : isXRP(issue.currency) ? xrpAccount() : *raSrcAccount;
558  STAmount saMaxAmount = saSendMax.value_or(
559  STAmount({issue.currency, sourceAccount}, 1u, 0, true));
560 
561  JLOG(m_journal.debug())
562  << iIdentifier << " Paths found, calling rippleCalc";
563 
564  path::RippleCalc::Input rcInput;
565  if (convert_all_)
566  rcInput.partialPaymentAllowed = true;
567  auto sandbox =
568  std::make_unique<PaymentSandbox>(&*cache->getLedger(), tapNONE);
570  *sandbox,
571  saMaxAmount, // --> Amount to send is unlimited
572  // to get an estimate.
573  dst_amount, // --> Amount to deliver.
574  *raDstAccount, // --> Account to deliver to.
575  *raSrcAccount, // --> Account sending from.
576  ps, // --> Path set.
577  app_.logs(),
578  &rcInput);
579 
580  if (!convert_all_ && !fullLiquidityPath.empty() &&
581  (rc.result() == terNO_LINE || rc.result() == tecPATH_PARTIAL))
582  {
583  JLOG(m_journal.debug())
584  << iIdentifier << " Trying with an extra path element";
585 
586  ps.push_back(fullLiquidityPath);
587  sandbox =
588  std::make_unique<PaymentSandbox>(&*cache->getLedger(), tapNONE);
590  *sandbox,
591  saMaxAmount, // --> Amount to send is unlimited
592  // to get an estimate.
593  dst_amount, // --> Amount to deliver.
594  *raDstAccount, // --> Account to deliver to.
595  *raSrcAccount, // --> Account sending from.
596  ps, // --> Path set.
597  app_.logs());
598 
599  if (rc.result() != tesSUCCESS)
600  {
601  JLOG(m_journal.warn())
602  << iIdentifier << " Failed with covering path "
603  << transHuman(rc.result());
604  }
605  else
606  {
607  JLOG(m_journal.debug())
608  << iIdentifier << " Extra path element gives "
609  << transHuman(rc.result());
610  }
611  }
612 
613  if (rc.result() == tesSUCCESS)
614  {
616  rc.actualAmountIn.setIssuer(sourceAccount);
617  jvEntry[jss::source_amount] =
618  rc.actualAmountIn.getJson(JsonOptions::none);
619  jvEntry[jss::paths_computed] = ps.getJson(JsonOptions::none);
620 
621  if (convert_all_)
622  jvEntry[jss::destination_amount] =
623  rc.actualAmountOut.getJson(JsonOptions::none);
624 
625  if (hasCompletion())
626  {
627  // Old ripple_path_find API requires this
628  jvEntry[jss::paths_canonical] = Json::arrayValue;
629  }
630 
631  jvArray.append(jvEntry);
632  }
633  else
634  {
635  JLOG(m_journal.debug()) << iIdentifier << " rippleCalc returns "
636  << transHuman(rc.result());
637  }
638  }
639 
640  /* The resource fee is based on the number of source currencies used.
641  The minimum cost is 50 and the maximum is 400. The cost increases
642  after four source currencies, 50 - (4 * 4) = 34.
643  */
644  int const size = sourceCurrencies.size();
645  consumer_.charge({std::clamp(size * size + 34, 50, 400), "path update"});
646  return true;
647 }
648 
652  bool fast,
653  std::function<bool(void)> const& continueCallback)
654 {
655  using namespace std::chrono;
656  JLOG(m_journal.debug())
657  << iIdentifier << " update " << (fast ? "fast" : "normal");
658 
659  {
661 
662  if (!isValid(cache))
663  return jvStatus;
664  }
665 
666  Json::Value newStatus = Json::objectValue;
667 
668  if (hasCompletion())
669  {
670  // Old ripple_path_find API gives destination_currencies
671  auto& destCurrencies =
672  (newStatus[jss::destination_currencies] = Json::arrayValue);
673  auto usCurrencies = accountDestCurrencies(*raDstAccount, cache, true);
674  for (auto const& c : usCurrencies)
675  destCurrencies.append(to_string(c));
676  }
677 
678  newStatus[jss::source_account] =
680  newStatus[jss::destination_account] =
682  newStatus[jss::destination_amount] = saDstAmount.getJson(JsonOptions::none);
683  newStatus[jss::full_reply] = !fast;
684 
685  if (jvId)
686  newStatus[jss::id] = jvId;
687 
688  bool loaded = app_.getFeeTrack().isLoadedLocal();
689 
690  if (iLevel == 0)
691  {
692  // first pass
693  if (loaded || fast)
695  else
697  }
698  else if ((iLevel == app_.config().PATH_SEARCH_FAST) && !fast)
699  {
700  // leaving fast pathfinding
702  if (loaded && (iLevel > app_.config().PATH_SEARCH_FAST))
703  --iLevel;
704  }
705  else if (bLastSuccess)
706  {
707  // decrement, if possible
708  if (iLevel > app_.config().PATH_SEARCH ||
709  (loaded && (iLevel > app_.config().PATH_SEARCH_FAST)))
710  --iLevel;
711  }
712  else
713  {
714  // adjust as needed
715  if (!loaded && (iLevel < app_.config().PATH_SEARCH_MAX))
716  ++iLevel;
717  if (loaded && (iLevel > app_.config().PATH_SEARCH_FAST))
718  --iLevel;
719  }
720 
721  JLOG(m_journal.debug()) << iIdentifier << " processing at level " << iLevel;
722 
723  Json::Value jvArray = Json::arrayValue;
724  if (findPaths(cache, iLevel, jvArray, continueCallback))
725  {
726  bLastSuccess = jvArray.size() != 0;
727  newStatus[jss::alternatives] = std::move(jvArray);
728  }
729  else
730  {
731  bLastSuccess = false;
732  newStatus = rpcError(rpcINTERNAL);
733  }
734 
735  if (fast && quick_reply_ == steady_clock::time_point{})
736  {
737  quick_reply_ = steady_clock::now();
738  mOwner.reportFast(duration_cast<milliseconds>(quick_reply_ - created_));
739  }
740  else if (!fast && full_reply_ == steady_clock::time_point{})
741  {
742  full_reply_ = steady_clock::now();
743  mOwner.reportFull(duration_cast<milliseconds>(full_reply_ - created_));
744  }
745 
746  {
748  jvStatus = newStatus;
749  }
750 
751  JLOG(m_journal.debug())
752  << iIdentifier << " update finished " << (fast ? "fast" : "normal");
753  return newStatus;
754 }
755 
758 {
759  return wpSubscriber.lock();
760 }
761 
762 } // 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:135
ripple::Application
Definition: Application.h:115
ripple::systemCurrencyCode
static std::string const & systemCurrencyCode()
Definition: SystemParameters.h:54
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:975
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:178
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:536
ripple::PathRequest::mLastIndex
LedgerIndex mLastIndex
Definition: PathRequest.h:161
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:339
ripple::terNO_LINE
@ terNO_LINE
Definition: TER.h:197
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:614
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:29
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:327
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::Application::accountIDCache
virtual AccountIDCache const & accountIDCache() const =0
ripple::PathRequest::raDstAccount
std::optional< AccountID > raDstAccount
Definition: PathRequest.h:151
ripple::Config::PATH_SEARCH_MAX
int PATH_SEARCH_MAX
Definition: Config.h:180
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:650
ripple::Application::getFeeTrack
virtual LoadFeeTrack & getFeeTrack()=0
ripple::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:351
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:507
Json
JSON (JavaScript Object Notation).
Definition: json_reader.cpp:27
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:531
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:133
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::JsonOptions::none
@ none
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:44
ripple::xrpAccount
AccountID const & xrpAccount()
Compute AccountID from public key.
Definition: AccountID.cpp:90
beast::Journal::info
Stream info() const
Definition: Journal.h:321
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:89
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:246
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:216
ripple::lsfRequireDestTag
@ lsfRequireDestTag
Definition: LedgerFormats.h:224
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:321
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:179
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:315
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:228
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:345
ripple::PathRequest::getSubscriber
InfoSub::pointer getSubscriber() const
Definition: PathRequest.cpp:757
ripple::PathRequest::m_journal
beast::Journal m_journal
Definition: PathRequest.h:136
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:219
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::AccountIDCache::toBase58
std::string toBase58(AccountID const &) const
Return ripple::toBase58 for the AccountID.
Definition: AccountID.cpp:134
ripple::to_issuer
bool to_issuer(AccountID &, std::string const &)
Convert hex or base58 string to AccountID.
Definition: AccountID.cpp:104
ripple::convertAmount
STAmount convertAmount(STAmount const &amt, bool all)
Definition: PathfinderUtils.h:37
std::chrono