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