int PathRequest::parseJson (Json::Value const& jvParams) { if (! jvParams.isMember(jss::source_account)) { jvStatus = rpcError(rpcSRC_ACT_MISSING); return PFR_PJ_INVALID; } if (! jvParams.isMember(jss::destination_account)) { jvStatus = rpcError(rpcDST_ACT_MISSING); return PFR_PJ_INVALID; } if (! jvParams.isMember(jss::destination_amount)) { jvStatus = rpcError(rpcDST_AMT_MISSING); return PFR_PJ_INVALID; } raSrcAccount = parseBase58<AccountID>( jvParams[jss::source_account].asString()); if (! raSrcAccount) { jvStatus = rpcError (rpcSRC_ACT_MALFORMED); return PFR_PJ_INVALID; } raDstAccount = parseBase58<AccountID>( jvParams[jss::destination_account].asString()); if (! raDstAccount) { jvStatus = rpcError (rpcDST_ACT_MALFORMED); return PFR_PJ_INVALID; } if (! amountFromJsonNoThrow ( saDstAmount, jvParams[jss::destination_amount])) { jvStatus = rpcError (rpcDST_AMT_MALFORMED); return PFR_PJ_INVALID; } convert_all_ = saDstAmount == STAmount(saDstAmount.issue(), 1u, 0, true); if ((saDstAmount.getCurrency ().isZero () && saDstAmount.getIssuer ().isNonZero ()) || (saDstAmount.getCurrency () == badCurrency ()) || (! convert_all_ && saDstAmount <= zero)) { jvStatus = rpcError (rpcDST_AMT_MALFORMED); return PFR_PJ_INVALID; } if (jvParams.isMember(jss::send_max)) { // Send_max requires destination amount to be -1. if (! convert_all_) { jvStatus = rpcError(rpcDST_AMT_MALFORMED); return PFR_PJ_INVALID; } saSendMax.emplace(); if (! amountFromJsonNoThrow( *saSendMax, jvParams[jss::send_max]) || (saSendMax->getCurrency().isZero() && saSendMax->getIssuer().isNonZero()) || (saSendMax->getCurrency() == badCurrency()) || (*saSendMax <= zero && *saSendMax != STAmount(saSendMax->issue(), 1u, 0, true))) { jvStatus = rpcError(rpcSENDMAX_MALFORMED); return PFR_PJ_INVALID; } } if (jvParams.isMember (jss::source_currencies)) { Json::Value const& jvSrcCurrencies = jvParams[jss::source_currencies]; if (! jvSrcCurrencies.isArray() || jvSrcCurrencies.size() == 0 || jvSrcCurrencies.size() > RPC::Tuning::max_src_cur) { jvStatus = rpcError (rpcSRC_CUR_MALFORMED); return PFR_PJ_INVALID; } sciSourceCurrencies.clear (); for (auto const& c : jvSrcCurrencies) { // Mandatory currency Currency srcCurrencyID; if (! c.isObject() || ! c.isMember(jss::currency) || ! to_currency(srcCurrencyID, c[jss::currency].asString())) { jvStatus = rpcError (rpcSRC_CUR_MALFORMED); return PFR_PJ_INVALID; } // Optional issuer AccountID srcIssuerID; if (c.isMember (jss::issuer) && (! c[jss::issuer].isString() || ! to_issuer(srcIssuerID, c[jss::issuer].asString()))) { jvStatus = rpcError (rpcSRC_ISR_MALFORMED); return PFR_PJ_INVALID; } if (srcCurrencyID.isZero()) { if (srcIssuerID.isNonZero()) { jvStatus = rpcError(rpcSRC_CUR_MALFORMED); return PFR_PJ_INVALID; } } else if (srcIssuerID.isZero()) { srcIssuerID = *raSrcAccount; } if (saSendMax) { // If the currencies don't match, ignore the source currency. if (srcCurrencyID == saSendMax->getCurrency()) { // If neither is the source and they are not equal, then the // source issuer is illegal. if (srcIssuerID != *raSrcAccount && saSendMax->getIssuer() != *raSrcAccount && srcIssuerID != saSendMax->getIssuer()) { jvStatus = rpcError (rpcSRC_ISR_MALFORMED); return PFR_PJ_INVALID; } // If both are the source, use the source. // Otherwise, use the one that's not the source. if (srcIssuerID != *raSrcAccount) { sciSourceCurrencies.insert( {srcCurrencyID, srcIssuerID}); } else if (saSendMax->getIssuer() != *raSrcAccount) { sciSourceCurrencies.insert( {srcCurrencyID, saSendMax->getIssuer()}); } else { sciSourceCurrencies.insert( {srcCurrencyID, *raSrcAccount}); } } } else { sciSourceCurrencies.insert({srcCurrencyID, srcIssuerID}); } } } if (jvParams.isMember ("id")) jvId = jvParams["id"]; return PFR_PJ_NOCHANGE; }
int PathRequest::parseJson (Json::Value const& jvParams, bool complete) { int ret = PFR_PJ_NOCHANGE; if (jvParams.isMember (jss::source_account)) { raSrcAccount = parseBase58<AccountID>( jvParams[jss::source_account].asString()); if (! raSrcAccount) { jvStatus = rpcError (rpcSRC_ACT_MALFORMED); return PFR_PJ_INVALID; } } else if (complete) { jvStatus = rpcError (rpcSRC_ACT_MISSING); return PFR_PJ_INVALID; } if (jvParams.isMember (jss::destination_account)) { raDstAccount = parseBase58<AccountID>( jvParams[jss::destination_account].asString()); if (! raDstAccount) { jvStatus = rpcError (rpcDST_ACT_MALFORMED); return PFR_PJ_INVALID; } } else if (complete) { jvStatus = rpcError (rpcDST_ACT_MISSING); return PFR_PJ_INVALID; } if (jvParams.isMember (jss::destination_amount)) { if (! amountFromJsonNoThrow ( saDstAmount, jvParams[jss::destination_amount]) || (saDstAmount.getCurrency ().isZero () && saDstAmount.getIssuer ().isNonZero ()) || (saDstAmount.getCurrency () == badCurrency ()) || saDstAmount <= zero) { jvStatus = rpcError (rpcDST_AMT_MALFORMED); return PFR_PJ_INVALID; } } else if (complete) { jvStatus = rpcError (rpcDST_ACT_MISSING); return PFR_PJ_INVALID; } if (jvParams.isMember (jss::source_currencies)) { Json::Value const& jvSrcCur = jvParams[jss::source_currencies]; if (!jvSrcCur.isArray ()) { jvStatus = rpcError (rpcSRC_CUR_MALFORMED); return PFR_PJ_INVALID; } sciSourceCurrencies.clear (); for (unsigned i = 0; i < jvSrcCur.size (); ++i) { Json::Value const& jvCur = jvSrcCur[i]; Currency uCur; AccountID uIss; if (!jvCur.isObject() || !jvCur.isMember (jss::currency) || !to_currency (uCur, jvCur[jss::currency].asString ())) { jvStatus = rpcError (rpcSRC_CUR_MALFORMED); return PFR_PJ_INVALID; } if (jvCur.isMember (jss::issuer) && !to_issuer (uIss, jvCur[jss::issuer].asString ())) { jvStatus = rpcError (rpcSRC_ISR_MALFORMED); } if (uCur.isZero () && uIss.isNonZero ()) { jvStatus = rpcError (rpcSRC_CUR_MALFORMED); return PFR_PJ_INVALID; } if (uCur.isNonZero() && uIss.isZero()) { uIss = *raSrcAccount; } sciSourceCurrencies.insert ({uCur, uIss}); } } if (jvParams.isMember ("id")) jvId = jvParams["id"]; return ret; }