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> 
   35 #include <ripple/rpc/impl/Tuning.h> 
   51     , wpSubscriber(subscriber)
 
   52     , consumer_(subscriber->getConsumer())
 
   53     , jvStatus(
Json::objectValue)
 
   59     , created_(
std::chrono::steady_clock::now())
 
   74     , fCompletion(completion)
 
   76     , jvStatus(
Json::objectValue)
 
   82     , created_(
std::chrono::steady_clock::now())
 
  110         << 
iIdentifier << 
" complete:" << fast << full << 
" total:" 
  111         << duration_cast<milliseconds>(steady_clock::now() - 
created_).count()
 
  184     auto const& lrLedger = crCache->getLedger();
 
  223         for (
auto const& currency : usDestCurrID)
 
  230     jvStatus[jss::ledger_index] = lrLedger->seq();
 
  276     if (!jvParams.
isMember(jss::source_account))
 
  279         return PFR_PJ_INVALID;
 
  282     if (!jvParams.
isMember(jss::destination_account))
 
  285         return PFR_PJ_INVALID;
 
  288     if (!jvParams.
isMember(jss::destination_amount))
 
  291         return PFR_PJ_INVALID;
 
  295         parseBase58<AccountID>(jvParams[jss::source_account].asString());
 
  299         return PFR_PJ_INVALID;
 
  303         parseBase58<AccountID>(jvParams[jss::destination_account].asString());
 
  307         return PFR_PJ_INVALID;
 
  313         return PFR_PJ_INVALID;
 
  324         return PFR_PJ_INVALID;
 
  327     if (jvParams.
isMember(jss::send_max))
 
  333             return PFR_PJ_INVALID;
 
  345             return PFR_PJ_INVALID;
 
  349     if (jvParams.
isMember(jss::source_currencies))
 
  351         Json::Value const& jvSrcCurrencies = jvParams[jss::source_currencies];
 
  352         if (!jvSrcCurrencies.
isArray() || jvSrcCurrencies.
size() == 0 ||
 
  356             return PFR_PJ_INVALID;
 
  361         for (
auto const& c : jvSrcCurrencies)
 
  365             if (!c.isObject() || !c.isMember(jss::currency) ||
 
  366                 !c[jss::currency].isString() ||
 
  367                 !
to_currency(srcCurrencyID, c[jss::currency].asString()))
 
  370                 return PFR_PJ_INVALID;
 
  375             if (c.isMember(jss::issuer) &&
 
  376                 (!c[jss::issuer].isString() ||
 
  377                  !
to_issuer(srcIssuerID, c[jss::issuer].asString())))
 
  380                 return PFR_PJ_INVALID;
 
  383             if (srcCurrencyID.
isZero())
 
  388                     return PFR_PJ_INVALID;
 
  391             else if (srcIssuerID.
isZero())
 
  399                 if (srcCurrencyID == 
saSendMax->getCurrency())
 
  408                         return PFR_PJ_INVALID;
 
  416                             {srcCurrencyID, srcIssuerID});
 
  421                             {srcCurrencyID, 
saSendMax->getIssuer()});
 
  438         jvId = jvParams[jss::id];
 
  440     return PFR_PJ_NOCHANGE;
 
  456     jvStatus[jss::status] = jss::success;
 
  475     auto i = currency_map.find(currency);
 
  476     if (i != currency_map.end())
 
  478     auto pathfinder = std::make_unique<Pathfinder>(
 
  487     if (pathfinder->findPaths(level, continueCallback))
 
  488         pathfinder->computePathRanks(
max_paths_, continueCallback);
 
  491     return currency_map[currency] = std::move(pathfinder);
 
  502     if (sourceCurrencies.empty() && 
saSendMax)
 
  504         sourceCurrencies.insert(
saSendMax->issue());
 
  506     if (sourceCurrencies.empty())
 
  510         for (
auto const& c : currencies)
 
  516                 sourceCurrencies.insert(
 
  524     for (
auto const& issue : sourceCurrencies)
 
  526         if (continueCallback && !continueCallback())
 
  541             assert(continueCallback && !continueCallback());
 
  547         auto ps = pathfinder->getBestPaths(
 
  555         auto const& sourceAccount = [&] {
 
  556             if (!
isXRP(issue.account))
 
  557                 return issue.account;
 
  559             if (
isXRP(issue.currency))
 
  566             STAmount({issue.currency, sourceAccount}, 1u, 0, 
true));
 
  569             << 
iIdentifier << 
" Paths found, calling rippleCalc";
 
  575             std::make_unique<PaymentSandbox>(&*cache->getLedger(), 
tapNONE);
 
  591                 << 
iIdentifier << 
" Trying with an extra path element";
 
  593             ps.push_back(fullLiquidityPath);
 
  595                 std::make_unique<PaymentSandbox>(&*cache->getLedger(), 
tapNONE);
 
  623             rc.actualAmountIn.setIssuer(sourceAccount);
 
  624             jvEntry[jss::source_amount] =
 
  629                 jvEntry[jss::destination_amount] =
 
  651     int const size = sourceCurrencies.size();
 
  664         << 
iIdentifier << 
" update " << (fast ? 
"fast" : 
"normal");
 
  678         auto& destCurrencies =
 
  681         for (
auto const& c : usCurrencies)
 
  688     newStatus[jss::full_reply] = !fast;
 
  691         newStatus[jss::id] = 
jvId;
 
  732         newStatus[jss::alternatives] = std::move(jvArray);
 
  745     else if (!fast && 
full_reply_ == steady_clock::time_point{})
 
  757         << 
iIdentifier << 
" update finished " << (fast ? 
"fast" : 
"normal");
 
  
Currency const  & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
static std::string const  & systemCurrencyCode()
bool to_currency(Currency ¤cy, std::string const &code)
Tries to convert a string to a Currency, returns true on success.
bool amountFromJsonNoThrow(STAmount &result, Json::Value const &jvSource)
std::map< Issue, STPathSet > mContext
Json::Value rpcError(int iError)
Issue const  & issue() const
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 &)
@ arrayValue
array value (ordered list)
hash_set< Currency > accountDestCurrencies(AccountID const &account, std::shared_ptr< RippleLineCache > const &lrCache, bool includeXRP)
Json::Value getJson(JsonOptions) const override
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
std::chrono::steady_clock::time_point full_reply_
std::recursive_mutex mIndexLock
Resource::Consumer & consumer_
std::function< void(void)> fCompletion
std::optional< AccountID > raDstAccount
Json::Value doStatus(Json::Value const &) override
Json::Value doUpdate(std::shared_ptr< RippleLineCache > const &, bool fast, std::function< bool(void)> const &continueCallback={})
virtual LoadFeeTrack & getFeeTrack()=0
AccountID const  & getIssuer() const
std::chrono::steady_clock::time_point quick_reply_
bool isLoadedLocal() const
std::string getFullText() const override
JSON (JavaScript Object Notation).
Value & append(const Value &value)
Append value to array at the end.
@ objectValue
object value (collection of name/value pairs).
PathRequest(Application &app, std::shared_ptr< InfoSub > const &subscriber, int id, PathRequests &, beast::Journal journal)
static unsigned const int max_paths_
Keylet account(AccountID const &id) noexcept
AccountID root.
std::set< Issue > sciSourceCurrencies
static constexpr int max_src_cur
Maximum number of source currencies allowed in a path find request.
virtual Config & config()=0
AccountID const  & xrpAccount()
Compute AccountID from public key.
UInt size() const
Number of values in array or object.
bool isXRP(AccountID const &c)
bool isMember(const char *key) const
Return true if the object has a member named key.
A generic endpoint for log messages.
std::optional< AccountID > raSrcAccount
bool isValid(std::shared_ptr< RippleLineCache > const &crCache)
std::string transHuman(TER code)
Json::Value doClose() override
std::pair< bool, Json::Value > doCreate(std::shared_ptr< RippleLineCache > const &, Json::Value const &)
bool native() const noexcept
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.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
void reportFast(std::chrono::milliseconds ms)
std::recursive_mutex mLock
const std::chrono::steady_clock::time_point created_
std::weak_ptr< InfoSub > wpSubscriber
static constexpr int max_auto_src_cur
Maximum number of auto source currencies in a path find request.
An endpoint that consumes resources.
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)
void reportFull(std::chrono::milliseconds ms)
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
hash_set< Currency > accountSourceCurrencies(AccountID const &account, std::shared_ptr< RippleLineCache > const &lrCache, bool includeXRP)
std::optional< STAmount > saSendMax
Disposition charge(Charge const &fee)
Apply a load charge to the consumer.
bool needsUpdate(bool newOnly, LedgerIndex index)
Currency const  & getCurrency() const
InfoSub::pointer getSubscriber() const
int parseJson(Json::Value const &)
bool to_issuer(AccountID &, std::string const &)
Convert hex or base58 string to AccountID.
STAmount convertAmount(STAmount const &amt, bool all)