mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Improved human readable JSON-RPC error messages
This commit is contained in:
@@ -90,53 +90,56 @@ int LegacyPathFind::maxInProgress (2);
|
||||
|
||||
Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool bFailHard, Application::ScopedLockType& mlh)
|
||||
{
|
||||
if (getApp().getFeeTrack().isLoadedCluster() && (mRole != Config::ADMIN))
|
||||
return rpcError(rpcTOO_BUSY);
|
||||
|
||||
Json::Value jvResult;
|
||||
RippleAddress naSeed;
|
||||
RippleAddress raSrcAddressID;
|
||||
bool bOffline = params.isMember ("offline") && params["offline"].asBool ();
|
||||
Json::Value jvResult;
|
||||
|
||||
WriteLog (lsDEBUG, RPCHandler) << boost::str (boost::format ("transactionSign: %s") % params);
|
||||
|
||||
if (!bOffline && !getConfig ().RUN_STANDALONE && (getApp().getLedgerMaster().getValidatedLedgerAge() > 120))
|
||||
{
|
||||
if (! params.isMember ("secret"))
|
||||
return RPC::missing_field_error ("secret");
|
||||
|
||||
if (! params.isMember ("tx_json"))
|
||||
return RPC::missing_field_error ("tx_json");
|
||||
|
||||
RippleAddress naSeed;
|
||||
|
||||
if (! naSeed.setSeedGeneric (params["secret"].asString ()))
|
||||
return RPC::make_error (rpcBAD_SEED,
|
||||
RPC::invalid_field_message ("secret"));
|
||||
|
||||
Json::Value tx_json (params ["tx_json"]);
|
||||
|
||||
if (! tx_json.isObject ())
|
||||
return RPC::object_field_error ("tx_json");
|
||||
|
||||
if (! tx_json.isMember ("TransactionType"))
|
||||
return RPC::missing_field_error ("tx_json.TransactionType");
|
||||
|
||||
std::string const sType = tx_json ["TransactionType"].asString ();
|
||||
|
||||
if (! tx_json.isMember ("Account"))
|
||||
return RPC::make_error (rpcSRC_ACT_MISSING,
|
||||
RPC::missing_field_message ("tx_json.Account"));
|
||||
|
||||
RippleAddress raSrcAddressID;
|
||||
|
||||
if (! raSrcAddressID.setAccountID (tx_json["Account"].asString ()))
|
||||
return RPC::make_error (rpcSRC_ACT_MALFORMED,
|
||||
RPC::invalid_field_message ("tx_json.Account"));
|
||||
|
||||
bool const bOffline (
|
||||
params.isMember ("offline") && params["offline"].asBool ());
|
||||
|
||||
if (! tx_json.isMember ("Sequence") && bOffline)
|
||||
return RPC::missing_field_error ("tx_json.Sequence");
|
||||
|
||||
// Check for current ledger
|
||||
if (!bOffline && !getConfig ().RUN_STANDALONE &&
|
||||
(getApp().getLedgerMaster().getValidatedLedgerAge() > 120))
|
||||
return rpcError (rpcNO_CURRENT);
|
||||
}
|
||||
|
||||
if (!params.isMember ("secret") || !params.isMember ("tx_json"))
|
||||
{
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
}
|
||||
|
||||
Json::Value txJSON = params["tx_json"];
|
||||
|
||||
if (!txJSON.isObject ())
|
||||
{
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
}
|
||||
|
||||
if (!naSeed.setSeedGeneric (params["secret"].asString ()))
|
||||
{
|
||||
return rpcError (rpcBAD_SEED);
|
||||
}
|
||||
|
||||
if (!txJSON.isMember ("Account"))
|
||||
{
|
||||
return rpcError (rpcSRC_ACT_MISSING);
|
||||
}
|
||||
|
||||
if (!raSrcAddressID.setAccountID (txJSON["Account"].asString ()))
|
||||
{
|
||||
return rpcError (rpcSRC_ACT_MALFORMED);
|
||||
}
|
||||
|
||||
if (!txJSON.isMember ("TransactionType"))
|
||||
{
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
}
|
||||
std::string sType = txJSON["TransactionType"].asString ();
|
||||
// Check for load
|
||||
if (getApp().getFeeTrack().isLoadedCluster() && (mRole != Config::ADMIN))
|
||||
return rpcError(rpcTOO_BUSY);
|
||||
|
||||
Ledger::pointer lSnapshot = mNetOps->getCurrentLedger ();
|
||||
AccountState::pointer asSrc = bOffline
|
||||
@@ -153,40 +156,41 @@ Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool
|
||||
return rpcError (rpcSRC_ACT_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!txJSON.isMember ("Fee")
|
||||
&& (
|
||||
"AccountSet" == sType
|
||||
|| "Payment" == sType
|
||||
|| "OfferCreate" == sType
|
||||
|| "OfferCancel" == sType
|
||||
|| "TrustSet" == sType))
|
||||
if (! tx_json.isMember ("Fee") && (
|
||||
"AccountSet" == sType
|
||||
|| "Payment" == sType
|
||||
|| "OfferCreate" == sType
|
||||
|| "OfferCancel" == sType
|
||||
|| "TrustSet" == sType))
|
||||
{
|
||||
// VFALCO TODO This needs to be fixed
|
||||
// feeReq = lSnapshot->scaleFeeLoad(,
|
||||
txJSON["Fee"] = (int) getConfig ().FEE_DEFAULT;
|
||||
tx_json["Fee"] = (int) getConfig ().FEE_DEFAULT;
|
||||
}
|
||||
|
||||
if ("Payment" == sType)
|
||||
{
|
||||
|
||||
RippleAddress dstAccountID;
|
||||
|
||||
if (!txJSON.isMember ("Destination"))
|
||||
{
|
||||
return rpcError (rpcDST_ACT_MISSING);
|
||||
}
|
||||
if (! tx_json.isMember ("Amount"))
|
||||
return RPC::missing_field_error ("tx_json.Amount");
|
||||
|
||||
if (!dstAccountID.setAccountID (txJSON["Destination"].asString ()))
|
||||
{
|
||||
return rpcError (rpcDST_ACT_MALFORMED);
|
||||
}
|
||||
STAmount amount;
|
||||
|
||||
if (txJSON.isMember ("Paths") && params.isMember ("build_path"))
|
||||
{
|
||||
// Asking to build a path when providing one is an error.
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
}
|
||||
if (! amount.bSetJson (tx_json ["Amount"]))
|
||||
return RPC::invalid_field_error ("tx_json.Amount");
|
||||
|
||||
if (!txJSON.isMember ("Paths") && txJSON.isMember ("Amount") && params.isMember ("build_path"))
|
||||
if (!tx_json.isMember ("Destination"))
|
||||
return RPC::missing_field_error ("tx_json.Destination");
|
||||
|
||||
if (!dstAccountID.setAccountID (tx_json["Destination"].asString ()))
|
||||
return RPC::invalid_field_error ("tx_json.Destination");
|
||||
|
||||
if (tx_json.isMember ("Paths") && params.isMember ("build_path"))
|
||||
return RPC::make_error (rpcINVALID_PARAMS,
|
||||
"Cannot specify both 'tx_json.Paths' and 'tx_json.build_path'");
|
||||
|
||||
if (!tx_json.isMember ("Paths") && tx_json.isMember ("Amount") && params.isMember ("build_path"))
|
||||
{
|
||||
// Need a ripple path.
|
||||
STPathSet spsPaths;
|
||||
@@ -194,29 +198,22 @@ Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool
|
||||
uint160 uSrcIssuerID;
|
||||
|
||||
STAmount saSendMax;
|
||||
STAmount saSend;
|
||||
|
||||
if (!txJSON.isMember ("Amount") // Amount required.
|
||||
|| !saSend.bSetJson (txJSON["Amount"])) // Must be valid.
|
||||
return rpcError (rpcDST_AMT_MALFORMED);
|
||||
|
||||
if (txJSON.isMember ("SendMax"))
|
||||
if (tx_json.isMember ("SendMax"))
|
||||
{
|
||||
if (!saSendMax.bSetJson (txJSON["SendMax"]))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
if (!saSendMax.bSetJson (tx_json ["SendMax"]))
|
||||
return RPC::invalid_field_error ("tx_json.SendMax");
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no SendMax, default to Amount with sender as issuer.
|
||||
saSendMax = saSend;
|
||||
saSendMax = amount;
|
||||
saSendMax.setIssuer (raSrcAddressID.getAccountID ());
|
||||
}
|
||||
|
||||
if (saSendMax.isNative () && saSend.isNative ())
|
||||
{
|
||||
// Asking to build a path for XRP to XRP is an error.
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
}
|
||||
if (saSendMax.isNative () && amount.isNative ())
|
||||
return RPC::make_error (rpcINVALID_PARAMS,
|
||||
"Cannot build XRP to XRP paths.");
|
||||
|
||||
{
|
||||
LegacyPathFind lpf (mRole == Config::ADMIN);
|
||||
@@ -226,7 +223,7 @@ Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool
|
||||
bool bValid;
|
||||
RippleLineCache::pointer cache = boost::make_shared<RippleLineCache> (lSnapshot);
|
||||
Pathfinder pf (cache, raSrcAddressID, dstAccountID,
|
||||
saSendMax.getCurrency (), saSendMax.getIssuer (), saSend, bValid);
|
||||
saSendMax.getCurrency (), saSendMax.getIssuer (), amount, bValid);
|
||||
|
||||
STPath extraPath;
|
||||
if (!bValid || !pf.findPaths (getConfig ().PATH_SEARCH_OLD, 4, spsPaths, extraPath))
|
||||
@@ -242,23 +239,23 @@ Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool
|
||||
|
||||
if (!spsPaths.isEmpty ())
|
||||
{
|
||||
txJSON["Paths"] = spsPaths.getJson (0);
|
||||
tx_json["Paths"] = spsPaths.getJson (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!txJSON.isMember ("Fee")
|
||||
if (!tx_json.isMember ("Fee")
|
||||
&& (
|
||||
"AccountSet" == txJSON["TransactionType"].asString ()
|
||||
|| "OfferCreate" == txJSON["TransactionType"].asString ()
|
||||
|| "OfferCancel" == txJSON["TransactionType"].asString ()
|
||||
|| "TrustSet" == txJSON["TransactionType"].asString ()))
|
||||
"AccountSet" == tx_json["TransactionType"].asString ()
|
||||
|| "OfferCreate" == tx_json["TransactionType"].asString ()
|
||||
|| "OfferCancel" == tx_json["TransactionType"].asString ()
|
||||
|| "TrustSet" == tx_json["TransactionType"].asString ()))
|
||||
{
|
||||
txJSON["Fee"] = (int) getConfig ().FEE_DEFAULT;
|
||||
tx_json["Fee"] = (int) getConfig ().FEE_DEFAULT;
|
||||
}
|
||||
|
||||
if (!txJSON.isMember ("Sequence"))
|
||||
if (!tx_json.isMember ("Sequence"))
|
||||
{
|
||||
if (bOffline)
|
||||
{
|
||||
@@ -267,11 +264,11 @@ Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool
|
||||
}
|
||||
else
|
||||
{
|
||||
txJSON["Sequence"] = asSrc->getSeq ();
|
||||
tx_json["Sequence"] = asSrc->getSeq ();
|
||||
}
|
||||
}
|
||||
|
||||
if (!txJSON.isMember ("Flags")) txJSON["Flags"] = 0;
|
||||
if (!tx_json.isMember ("Flags")) tx_json["Flags"] = 0;
|
||||
|
||||
if (!bOffline)
|
||||
{
|
||||
@@ -334,16 +331,21 @@ Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool
|
||||
|
||||
std::unique_ptr<STObject> sopTrans;
|
||||
|
||||
try
|
||||
{
|
||||
sopTrans = STObject::parseJson (txJSON);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
jvResult["error"] = "malformedTransaction";
|
||||
jvResult["error_exception"] = e.what ();
|
||||
|
||||
return jvResult;
|
||||
STParsedJSON parsed ("tx_json", tx_json);
|
||||
if (parsed.object.get() != nullptr)
|
||||
{
|
||||
// VFALCO NOTE No idea why this doesn't compile.
|
||||
//sopTrans = parsed.object;
|
||||
sopTrans.reset (parsed.object.release());
|
||||
}
|
||||
else
|
||||
{
|
||||
jvResult ["error"] = parsed.error ["error"];
|
||||
jvResult ["error_code"] = parsed.error ["error_code"];
|
||||
jvResult ["error_message"] = parsed.error ["error_message"];
|
||||
return jvResult;
|
||||
}
|
||||
}
|
||||
|
||||
sopTrans->setFieldVL (sfSigningPubKey, naAccountPublic.getAccountPublic ());
|
||||
@@ -634,24 +636,29 @@ Json::Value RPCHandler::accountFromString (Ledger::ref lrLedger, RippleAddress&
|
||||
Json::Value RPCHandler::doAccountCurrencies (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
masterLockHolder.unlock ();
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger (params, lpLedger);
|
||||
|
||||
// Get the current ledger
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult (lookupLedger (params, lpLedger));
|
||||
if (!lpLedger)
|
||||
return jvResult;
|
||||
|
||||
if (!params.isMember ("account") && !params.isMember ("ident"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
if (! params.isMember ("account") && ! params.isMember ("ident"))
|
||||
return RPC::missing_field_error ("account");
|
||||
|
||||
std::string strIdent = params.isMember ("account") ? params["account"].asString () : params["ident"].asString ();
|
||||
bool bIndex;
|
||||
int iIndex = params.isMember ("account_index") ? params["account_index"].asUInt () : 0;
|
||||
bool bStrict = params.isMember ("strict") && params["strict"].asBool ();
|
||||
RippleAddress naAccount;
|
||||
std::string const strIdent (params.isMember ("account")
|
||||
? params["account"].asString ()
|
||||
: params["ident"].asString ());
|
||||
|
||||
int const iIndex (params.isMember ("account_index")
|
||||
? params["account_index"].asUInt ()
|
||||
: 0);
|
||||
bool const bStrict (params.isMember ("strict") && params["strict"].asBool ());
|
||||
|
||||
// Get info on account.
|
||||
|
||||
Json::Value jvAccepted = accountFromString (lpLedger, naAccount, bIndex, strIdent, iIndex, bStrict);
|
||||
bool bIndex; // out param
|
||||
RippleAddress naAccount; // out param
|
||||
Json::Value jvAccepted (accountFromString (
|
||||
lpLedger, naAccount, bIndex, strIdent, iIndex, bStrict));
|
||||
|
||||
if (!jvAccepted.empty ())
|
||||
return jvAccepted;
|
||||
@@ -707,7 +714,7 @@ Json::Value RPCHandler::doAccountInfo (Json::Value params, Resource::Charge& loa
|
||||
return jvResult;
|
||||
|
||||
if (!params.isMember ("account") && !params.isMember ("ident"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("account");
|
||||
|
||||
std::string strIdent = params.isMember ("account") ? params["account"].asString () : params["ident"].asString ();
|
||||
bool bIndex;
|
||||
@@ -759,7 +766,7 @@ Json::Value RPCHandler::doConnect (Json::Value params, Resource::Charge& loadTyp
|
||||
return "cannot connect in standalone mode";
|
||||
|
||||
if (!params.isMember ("ip"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("ip");
|
||||
|
||||
std::string strIp = params["ip"].asString ();
|
||||
int iPort = params.isMember ("port") ? params["port"].asInt () : -1;
|
||||
@@ -777,7 +784,7 @@ Json::Value RPCHandler::doConnect (Json::Value params, Resource::Charge& loadTyp
|
||||
Json::Value RPCHandler::doDataDelete (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("key"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("key");
|
||||
|
||||
std::string strKey = params["key"].asString ();
|
||||
|
||||
@@ -803,7 +810,7 @@ Json::Value RPCHandler::doDataDelete (Json::Value params, Resource::Charge& load
|
||||
Json::Value RPCHandler::doDataFetch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("key"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("key");
|
||||
|
||||
std::string strKey = params["key"].asString ();
|
||||
std::string strValue;
|
||||
@@ -827,8 +834,9 @@ Json::Value RPCHandler::doDataFetch (Json::Value params, Resource::Charge& loadT
|
||||
Json::Value RPCHandler::doDataStore (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("key")
|
||||
|| !params.isMember ("value"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("key");
|
||||
if (!params.isMember ("value")
|
||||
return RPC::missing_field_error ("value");
|
||||
|
||||
std::string strKey = params["key"].asString ();
|
||||
std::string strValue = params["value"].asString ();
|
||||
@@ -888,7 +896,7 @@ Json::Value RPCHandler::doNicknameInfo (Json::Value params)
|
||||
Json::Value RPCHandler::doOwnerInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("account") && !params.isMember ("ident"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("account");
|
||||
|
||||
std::string strIdent = params.isMember ("account") ? params["account"].asString () : params["ident"].asString ();
|
||||
bool bIndex;
|
||||
@@ -1051,12 +1059,12 @@ Json::Value RPCHandler::doProofCreate (Json::Value params, Resource::Charge& loa
|
||||
if (params.isMember ("difficulty"))
|
||||
{
|
||||
if (!params["difficulty"].isIntegral ())
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::invalid_field_error ("difficulty");
|
||||
|
||||
int iDifficulty = params["difficulty"].asInt ();
|
||||
int const iDifficulty (params["difficulty"].asInt ());
|
||||
|
||||
if (iDifficulty < 0 || iDifficulty > ProofOfWorkFactory::kMaxDifficulty)
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::invalid_field_error ("difficulty");
|
||||
|
||||
pgGen->setDifficulty (iDifficulty);
|
||||
}
|
||||
@@ -1088,12 +1096,12 @@ Json::Value RPCHandler::doProofSolve (Json::Value params, Resource::Charge& load
|
||||
Json::Value jvResult;
|
||||
|
||||
if (!params.isMember ("token"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("token");
|
||||
|
||||
std::string strToken = params["token"].asString ();
|
||||
|
||||
if (!ProofOfWork::validateToken (strToken))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::invalid_field_error ("token");
|
||||
|
||||
ProofOfWork powProof (strToken);
|
||||
uint256 uSolution = powProof.solve ();
|
||||
@@ -1119,10 +1127,10 @@ Json::Value RPCHandler::doProofVerify (Json::Value params, Resource::Charge& loa
|
||||
Json::Value jvResult;
|
||||
|
||||
if (!params.isMember ("token"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("token");
|
||||
|
||||
if (!params.isMember ("solution"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("solution");
|
||||
|
||||
std::string strToken = params["token"].asString ();
|
||||
uint256 uSolution (params["solution"].asString ());
|
||||
@@ -1137,12 +1145,12 @@ Json::Value RPCHandler::doProofVerify (Json::Value params, Resource::Charge& loa
|
||||
if (params.isMember ("difficulty"))
|
||||
{
|
||||
if (!params["difficulty"].isIntegral ())
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::invalid_field_error ("difficulty");
|
||||
|
||||
int iDifficulty = params["difficulty"].asInt ();
|
||||
|
||||
if (iDifficulty < 0 || iDifficulty > ProofOfWorkFactory::kMaxDifficulty)
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("difficulty");
|
||||
|
||||
pgGen->setDifficulty (iDifficulty);
|
||||
}
|
||||
@@ -1192,7 +1200,7 @@ Json::Value RPCHandler::doAccountLines (Json::Value params, Resource::Charge& lo
|
||||
return jvResult;
|
||||
|
||||
if (!params.isMember ("account"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("account");
|
||||
|
||||
std::string strIdent = params["account"].asString ();
|
||||
bool bIndex = params.isMember ("account_index");
|
||||
@@ -1303,7 +1311,7 @@ Json::Value RPCHandler::doAccountOffers (Json::Value params, Resource::Charge& l
|
||||
return jvResult;
|
||||
|
||||
if (!params.isMember ("account"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return RPC::missing_field_error ("account");
|
||||
|
||||
std::string strIdent = params["account"].asString ();
|
||||
bool bIndex = params.isMember ("account_index");
|
||||
@@ -1334,6 +1342,33 @@ Json::Value RPCHandler::doAccountOffers (Json::Value params, Resource::Charge& l
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
template <class UnsignedInteger>
|
||||
inline bool is_xrp (UnsignedInteger const& value)
|
||||
{
|
||||
return value.isZero();
|
||||
}
|
||||
|
||||
template <class UnsignedInteger>
|
||||
inline bool is_not_xrp (UnsignedInteger const& value)
|
||||
{
|
||||
return ! is_xrp (value);
|
||||
}
|
||||
|
||||
inline uint160 const& xrp_issuer ()
|
||||
{
|
||||
return ACCOUNT_XRP;
|
||||
}
|
||||
|
||||
inline uint160 const& xrp_currency ()
|
||||
{
|
||||
return CURRENCY_XRP;
|
||||
}
|
||||
|
||||
inline uint160 const& neutral_issuer ()
|
||||
{
|
||||
return ACCOUNT_ONE;
|
||||
}
|
||||
|
||||
// {
|
||||
// "ledger_hash" : ledger, // Optional.
|
||||
// "ledger_index" : ledger_index, // Optional.
|
||||
@@ -1348,94 +1383,164 @@ Json::Value RPCHandler::doBookOffers (Json::Value params, Resource::Charge& load
|
||||
{
|
||||
masterLockHolder.unlock ();
|
||||
|
||||
// VFALCO TODO Here is a terrible place for this kind of business
|
||||
// logic. It needs to be moved elsewhere and documented,
|
||||
// and encapsulated into a function.
|
||||
if (getApp().getJobQueue ().getJobCountGE (jtCLIENT) > 200)
|
||||
{
|
||||
return rpcError (rpcTOO_BUSY);
|
||||
}
|
||||
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger (params, lpLedger);
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult (lookupLedger (params, lpLedger));
|
||||
|
||||
if (!lpLedger)
|
||||
return jvResult;
|
||||
|
||||
if (!params.isMember ("taker_pays") || !params.isMember ("taker_gets") || !params["taker_pays"].isObject () || !params["taker_gets"].isObject ())
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
if (!params.isMember ("taker_pays"))
|
||||
return RPC::missing_field_error ("taker_pays");
|
||||
|
||||
uint160 uTakerPaysCurrencyID;
|
||||
uint160 uTakerPaysIssuerID;
|
||||
const Json::Value& jvTakerPays = params["taker_pays"];
|
||||
if (!params.isMember ("taker_gets"))
|
||||
return RPC::missing_field_error ("taker_gets");
|
||||
|
||||
// Parse mandatory currency.
|
||||
if (!jvTakerPays.isMember ("currency")
|
||||
|| !STAmount::currencyFromString (uTakerPaysCurrencyID, jvTakerPays["currency"].asString ()))
|
||||
if (!params["taker_pays"].isObject ())
|
||||
return RPC::object_field_error ("taker_pays");
|
||||
|
||||
if (!params["taker_gets"].isObject ())
|
||||
return RPC::object_field_error ("taker_gets");
|
||||
|
||||
Json::Value const& taker_pays (params["taker_pays"]);
|
||||
|
||||
if (!taker_pays.isMember ("currency"))
|
||||
return RPC::missing_field_error ("taker_pays.currency");
|
||||
|
||||
if (! taker_pays ["currency"].isString ())
|
||||
return RPC::expected_field_error ("taker_pays.currency", "string");
|
||||
|
||||
Json::Value const& taker_gets = params["taker_gets"];
|
||||
|
||||
if (! taker_gets.isMember ("currency"))
|
||||
return RPC::missing_field_error ("taker_gets.currency");
|
||||
|
||||
if (! taker_gets ["currency"].isString ())
|
||||
return RPC::expected_field_error ("taker_gets.currency", "string");
|
||||
|
||||
uint160 pay_currency;
|
||||
|
||||
if (! STAmount::currencyFromString (
|
||||
pay_currency, taker_pays ["currency"].asString ()))
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency.";
|
||||
|
||||
return rpcError (rpcSRC_CUR_MALFORMED);
|
||||
return RPC::make_error (rpcSRC_CUR_MALFORMED,
|
||||
"Invalid field 'taker_pays.currency', bad currency.");
|
||||
}
|
||||
// Parse optional issuer.
|
||||
else if (((jvTakerPays.isMember ("issuer"))
|
||||
&& (!jvTakerPays["issuer"].isString ()
|
||||
|| !STAmount::issuerFromString (uTakerPaysIssuerID, jvTakerPays["issuer"].asString ())))
|
||||
// Don't allow illegal issuers.
|
||||
|| (!uTakerPaysCurrencyID != !uTakerPaysIssuerID)
|
||||
|| ACCOUNT_ONE == uTakerPaysIssuerID)
|
||||
|
||||
uint160 get_currency;
|
||||
|
||||
if (! STAmount::currencyFromString (
|
||||
get_currency, taker_gets ["currency"].asString ()))
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays issuer.";
|
||||
|
||||
return rpcError (rpcSRC_ISR_MALFORMED);
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_gets currency.";
|
||||
return RPC::make_error (rpcDST_AMT_MALFORMED,
|
||||
"Invalid field 'taker_gets.currency', bad currency.");
|
||||
}
|
||||
|
||||
uint160 uTakerGetsCurrencyID;
|
||||
uint160 uTakerGetsIssuerID;
|
||||
const Json::Value& jvTakerGets = params["taker_gets"];
|
||||
uint160 pay_issuer;
|
||||
|
||||
// Parse mandatory currency.
|
||||
if (!jvTakerGets.isMember ("currency")
|
||||
|| !STAmount::currencyFromString (uTakerGetsCurrencyID, jvTakerGets["currency"].asString ()))
|
||||
if (taker_pays.isMember ("issuer"))
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency.";
|
||||
if (! taker_pays ["issuer"].isString())
|
||||
return RPC::expected_field_error ("taker_pays.issuer", "string");
|
||||
|
||||
return rpcError (rpcSRC_CUR_MALFORMED);
|
||||
if (! STAmount::issuerFromString (
|
||||
pay_issuer, taker_pays ["issuer"].asString ()))
|
||||
return RPC::make_error (rpcSRC_ISR_MALFORMED,
|
||||
"Invalid field 'taker_pays.issuer', bad issuer.");
|
||||
|
||||
if (pay_issuer == neutral_issuer ())
|
||||
return RPC::make_error (rpcSRC_ISR_MALFORMED,
|
||||
"Invalid field 'taker_pays.issuer', bad issuer account one.");
|
||||
}
|
||||
// Parse optional issuer.
|
||||
else if (((jvTakerGets.isMember ("issuer"))
|
||||
&& (!jvTakerGets["issuer"].isString ()
|
||||
|| !STAmount::issuerFromString (uTakerGetsIssuerID, jvTakerGets["issuer"].asString ())))
|
||||
// Don't allow illegal issuers.
|
||||
|| (!uTakerGetsCurrencyID != !uTakerGetsIssuerID)
|
||||
|| ACCOUNT_ONE == uTakerGetsIssuerID)
|
||||
else
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_gets issuer.";
|
||||
|
||||
return rpcError (rpcDST_ISR_MALFORMED);
|
||||
pay_issuer = xrp_issuer ();
|
||||
}
|
||||
|
||||
if (uTakerPaysCurrencyID == uTakerGetsCurrencyID
|
||||
&& uTakerPaysIssuerID == uTakerGetsIssuerID)
|
||||
if (is_xrp (pay_currency) && ! is_xrp (pay_issuer))
|
||||
return RPC::make_error (rpcSRC_ISR_MALFORMED,
|
||||
"Unneeded field 'taker_pays.issuer' for XRP currency specification.");
|
||||
|
||||
if (is_not_xrp (pay_currency) && is_xrp (pay_issuer))
|
||||
return RPC::make_error (rpcSRC_ISR_MALFORMED,
|
||||
"Invalid field 'taker_pays.issuer', expected non-XRP issuer.");
|
||||
|
||||
uint160 get_issuer;
|
||||
|
||||
if (taker_gets.isMember ("issuer"))
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "taker_gets same as taker_pays.";
|
||||
if (! taker_gets ["issuer"].isString())
|
||||
return RPC::expected_field_error ("taker_gets.issuer", "string");
|
||||
|
||||
return rpcError (rpcBAD_MARKET);
|
||||
if (! STAmount::issuerFromString (
|
||||
get_issuer, taker_gets ["issuer"].asString ()))
|
||||
return RPC::make_error (rpcDST_ISR_MALFORMED,
|
||||
"Invalid field 'taker_gets.issuer', bad issuer.");
|
||||
|
||||
if (get_issuer == neutral_issuer ())
|
||||
return RPC::make_error (rpcDST_ISR_MALFORMED,
|
||||
"Invalid field 'taker_gets.issuer', bad issuer account one.");
|
||||
}
|
||||
else
|
||||
{
|
||||
get_issuer = xrp_issuer ();
|
||||
}
|
||||
|
||||
RippleAddress raTakerID;
|
||||
|
||||
if (!params.isMember ("taker"))
|
||||
if (is_xrp (get_currency) && ! is_xrp (get_issuer))
|
||||
return RPC::make_error (rpcDST_ISR_MALFORMED,
|
||||
"Unneeded field 'taker_gets.issuer' for XRP currency specification.");
|
||||
|
||||
if (is_not_xrp (get_currency) && is_xrp (get_issuer))
|
||||
return RPC::make_error (rpcDST_ISR_MALFORMED,
|
||||
"Invalid field 'taker_gets.issuer', expected non-XRP issuer.");
|
||||
|
||||
RippleAddress raTakerID;
|
||||
|
||||
if (params.isMember ("taker"))
|
||||
{
|
||||
if (! params ["taker"].isString ())
|
||||
return RPC::expected_field_error ("taker", "string");
|
||||
|
||||
if (! raTakerID.setAccountID (params ["taker"].asString ()))
|
||||
return RPC::invalid_field_error ("taker");
|
||||
}
|
||||
else
|
||||
{
|
||||
raTakerID.setAccountID (ACCOUNT_ONE);
|
||||
}
|
||||
else if (!raTakerID.setAccountID (params["taker"].asString ()))
|
||||
|
||||
if (pay_currency == get_currency && pay_issuer == get_issuer)
|
||||
{
|
||||
return rpcError (rpcBAD_ISSUER);
|
||||
WriteLog (lsINFO, RPCHandler) << "taker_gets same as taker_pays.";
|
||||
return RPC::make_error (rpcBAD_MARKET);
|
||||
}
|
||||
|
||||
const bool bProof = params.isMember ("proof");
|
||||
const unsigned int iLimit = params.isMember ("limit") ? params["limit"].asUInt () : 0;
|
||||
const Json::Value jvMarker = params.isMember ("marker") ? params["marker"] : Json::Value (Json::nullValue);
|
||||
if (params.isMember ("limit") && ! params ["limit"].isUInt())
|
||||
return RPC::expected_field_error (
|
||||
"taker_pays.currency", "unsigned integer");
|
||||
|
||||
unsigned int const iLimit (params.isMember ("limit")
|
||||
? params ["limit"].asUInt ()
|
||||
: 0);
|
||||
|
||||
bool const bProof (params.isMember ("proof"));
|
||||
|
||||
Json::Value const jvMarker (params.isMember ("marker")
|
||||
? params["marker"]
|
||||
: Json::Value (Json::nullValue));
|
||||
|
||||
mNetOps->getBookPage (lpLedger, pay_currency, pay_issuer,
|
||||
get_currency, get_issuer, raTakerID.getAccountID (),
|
||||
bProof, iLimit, jvMarker, jvResult);
|
||||
|
||||
mNetOps->getBookPage (lpLedger, uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID, raTakerID.getAccountID (), bProof, iLimit, jvMarker, jvResult);
|
||||
loadType = Resource::feeMediumBurdenRPC;
|
||||
|
||||
return jvResult;
|
||||
@@ -3573,33 +3678,35 @@ Json::Value RPCHandler::doSubscribe (Json::Value params, Resource::Charge& loadT
|
||||
|| !jvSubRequest["taker_gets"].isObject ())
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
|
||||
RippleCurrency uTakerPaysCurrencyID;
|
||||
RippleIssuer uTakerPaysIssuerID;
|
||||
RippleCurrency uTakerGetsCurrencyID;
|
||||
RippleIssuer uTakerGetsIssuerID;
|
||||
// VFALCO TODO Use RippleAsset here
|
||||
RippleCurrency pay_currency;
|
||||
RippleIssuer pay_issuer;
|
||||
RippleCurrency get_currency;
|
||||
RippleIssuer get_issuer;
|
||||
|
||||
bool bBoth = (jvSubRequest.isMember ("both") && jvSubRequest["both"].asBool ())
|
||||
|| (jvSubRequest.isMember ("both_sides") && jvSubRequest["both_sides"].asBool ()); // DEPRECATED
|
||||
bool bSnapshot = (jvSubRequest.isMember ("snapshot") && jvSubRequest["snapshot"].asBool ())
|
||||
|| (jvSubRequest.isMember ("state_now") && jvSubRequest["state_now"].asBool ()); // DEPRECATED
|
||||
|
||||
Json::Value jvTakerPays = jvSubRequest["taker_pays"];
|
||||
Json::Value jvTakerGets = jvSubRequest["taker_gets"];
|
||||
Json::Value taker_pays = jvSubRequest["taker_pays"];
|
||||
Json::Value taker_gets = jvSubRequest["taker_gets"];
|
||||
|
||||
// Parse mandatory currency.
|
||||
if (!jvTakerPays.isMember ("currency")
|
||||
|| !STAmount::currencyFromString (uTakerPaysCurrencyID, jvTakerPays["currency"].asString ()))
|
||||
if (!taker_pays.isMember ("currency")
|
||||
|| !STAmount::currencyFromString (pay_currency, taker_pays["currency"].asString ()))
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency.";
|
||||
|
||||
return rpcError (rpcSRC_CUR_MALFORMED);
|
||||
}
|
||||
// Parse optional issuer.
|
||||
else if (((jvTakerPays.isMember ("issuer"))
|
||||
&& (!jvTakerPays["issuer"].isString ()
|
||||
|| !STAmount::issuerFromString (uTakerPaysIssuerID, jvTakerPays["issuer"].asString ())))
|
||||
else if (((taker_pays.isMember ("issuer"))
|
||||
&& (!taker_pays["issuer"].isString ()
|
||||
|| !STAmount::issuerFromString (pay_issuer, taker_pays["issuer"].asString ())))
|
||||
// Don't allow illegal issuers.
|
||||
|| (!uTakerPaysCurrencyID != !uTakerPaysIssuerID)
|
||||
|| ACCOUNT_ONE == uTakerPaysIssuerID)
|
||||
|| (!pay_currency != !pay_issuer)
|
||||
|| ACCOUNT_ONE == pay_issuer)
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays issuer.";
|
||||
|
||||
@@ -3607,28 +3714,28 @@ Json::Value RPCHandler::doSubscribe (Json::Value params, Resource::Charge& loadT
|
||||
}
|
||||
|
||||
// Parse mandatory currency.
|
||||
if (!jvTakerGets.isMember ("currency")
|
||||
|| !STAmount::currencyFromString (uTakerGetsCurrencyID, jvTakerGets["currency"].asString ()))
|
||||
if (!taker_gets.isMember ("currency")
|
||||
|| !STAmount::currencyFromString (get_currency, taker_gets["currency"].asString ()))
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency.";
|
||||
|
||||
return rpcError (rpcSRC_CUR_MALFORMED);
|
||||
}
|
||||
// Parse optional issuer.
|
||||
else if (((jvTakerGets.isMember ("issuer"))
|
||||
&& (!jvTakerGets["issuer"].isString ()
|
||||
|| !STAmount::issuerFromString (uTakerGetsIssuerID, jvTakerGets["issuer"].asString ())))
|
||||
else if (((taker_gets.isMember ("issuer"))
|
||||
&& (!taker_gets["issuer"].isString ()
|
||||
|| !STAmount::issuerFromString (get_issuer, taker_gets["issuer"].asString ())))
|
||||
// Don't allow illegal issuers.
|
||||
|| (!uTakerGetsCurrencyID != !uTakerGetsIssuerID)
|
||||
|| ACCOUNT_ONE == uTakerGetsIssuerID)
|
||||
|| (!get_currency != !get_issuer)
|
||||
|| ACCOUNT_ONE == get_issuer)
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_gets issuer.";
|
||||
|
||||
return rpcError (rpcDST_ISR_MALFORMED);
|
||||
}
|
||||
|
||||
if (uTakerPaysCurrencyID == uTakerGetsCurrencyID
|
||||
&& uTakerPaysIssuerID == uTakerGetsIssuerID)
|
||||
if (pay_currency == get_currency
|
||||
&& pay_issuer == get_issuer)
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "taker_gets same as taker_pays.";
|
||||
|
||||
@@ -3646,17 +3753,17 @@ Json::Value RPCHandler::doSubscribe (Json::Value params, Resource::Charge& loadT
|
||||
return rpcError (rpcBAD_ISSUER);
|
||||
}
|
||||
|
||||
if (!Ledger::isValidBook (uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID))
|
||||
if (!Ledger::isValidBook (pay_currency, pay_issuer, get_currency, get_issuer))
|
||||
{
|
||||
WriteLog (lsWARNING, RPCHandler) << "Bad market: " <<
|
||||
uTakerPaysCurrencyID << ":" << uTakerPaysIssuerID << " -> " <<
|
||||
uTakerGetsCurrencyID << ":" << uTakerGetsIssuerID;
|
||||
pay_currency << ":" << pay_issuer << " -> " <<
|
||||
get_currency << ":" << get_issuer;
|
||||
return rpcError (rpcBAD_MARKET);
|
||||
}
|
||||
|
||||
mNetOps->subBook (ispSub, uTakerPaysCurrencyID, uTakerGetsCurrencyID, uTakerPaysIssuerID, uTakerGetsIssuerID);
|
||||
mNetOps->subBook (ispSub, pay_currency, get_currency, pay_issuer, get_issuer);
|
||||
|
||||
if (bBoth) mNetOps->subBook (ispSub, uTakerGetsCurrencyID, uTakerPaysCurrencyID, uTakerGetsIssuerID, uTakerPaysIssuerID);
|
||||
if (bBoth) mNetOps->subBook (ispSub, get_currency, pay_currency, get_issuer, pay_issuer);
|
||||
|
||||
if (bSnapshot)
|
||||
{
|
||||
@@ -3673,17 +3780,17 @@ Json::Value RPCHandler::doSubscribe (Json::Value params, Resource::Charge& loadT
|
||||
Json::Value jvBids (Json::objectValue);
|
||||
Json::Value jvAsks (Json::objectValue);
|
||||
|
||||
mNetOps->getBookPage (lpLedger, uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID, raTakerID.getAccountID (), false, 0, jvMarker, jvBids);
|
||||
mNetOps->getBookPage (lpLedger, pay_currency, pay_issuer, get_currency, get_issuer, raTakerID.getAccountID (), false, 0, jvMarker, jvBids);
|
||||
|
||||
if (jvBids.isMember ("offers")) jvResult["bids"] = jvBids["offers"];
|
||||
|
||||
mNetOps->getBookPage (lpLedger, uTakerGetsCurrencyID, uTakerGetsIssuerID, uTakerPaysCurrencyID, uTakerPaysIssuerID, raTakerID.getAccountID (), false, 0, jvMarker, jvAsks);
|
||||
mNetOps->getBookPage (lpLedger, get_currency, get_issuer, pay_currency, pay_issuer, raTakerID.getAccountID (), false, 0, jvMarker, jvAsks);
|
||||
|
||||
if (jvAsks.isMember ("offers")) jvResult["asks"] = jvAsks["offers"];
|
||||
}
|
||||
else
|
||||
{
|
||||
mNetOps->getBookPage (lpLedger, uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID, raTakerID.getAccountID (), false, 0, jvMarker, jvResult);
|
||||
mNetOps->getBookPage (lpLedger, pay_currency, pay_issuer, get_currency, get_issuer, raTakerID.getAccountID (), false, 0, jvMarker, jvResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3811,31 +3918,31 @@ Json::Value RPCHandler::doUnsubscribe (Json::Value params, Resource::Charge& loa
|
||||
|| !jvSubRequest["taker_gets"].isObject ())
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
|
||||
uint160 uTakerPaysCurrencyID;
|
||||
uint160 uTakerPaysIssuerID;
|
||||
uint160 uTakerGetsCurrencyID;
|
||||
uint160 uTakerGetsIssuerID;
|
||||
uint160 pay_currency;
|
||||
uint160 pay_issuer;
|
||||
uint160 get_currency;
|
||||
uint160 get_issuer;
|
||||
bool bBoth = (jvSubRequest.isMember ("both") && jvSubRequest["both"].asBool ())
|
||||
|| (jvSubRequest.isMember ("both_sides") && jvSubRequest["both_sides"].asBool ()); // DEPRECATED
|
||||
|
||||
Json::Value jvTakerPays = jvSubRequest["taker_pays"];
|
||||
Json::Value jvTakerGets = jvSubRequest["taker_gets"];
|
||||
Json::Value taker_pays = jvSubRequest["taker_pays"];
|
||||
Json::Value taker_gets = jvSubRequest["taker_gets"];
|
||||
|
||||
// Parse mandatory currency.
|
||||
if (!jvTakerPays.isMember ("currency")
|
||||
|| !STAmount::currencyFromString (uTakerPaysCurrencyID, jvTakerPays["currency"].asString ()))
|
||||
if (!taker_pays.isMember ("currency")
|
||||
|| !STAmount::currencyFromString (pay_currency, taker_pays["currency"].asString ()))
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency.";
|
||||
|
||||
return rpcError (rpcSRC_CUR_MALFORMED);
|
||||
}
|
||||
// Parse optional issuer.
|
||||
else if (((jvTakerPays.isMember ("issuer"))
|
||||
&& (!jvTakerPays["issuer"].isString ()
|
||||
|| !STAmount::issuerFromString (uTakerPaysIssuerID, jvTakerPays["issuer"].asString ())))
|
||||
else if (((taker_pays.isMember ("issuer"))
|
||||
&& (!taker_pays["issuer"].isString ()
|
||||
|| !STAmount::issuerFromString (pay_issuer, taker_pays["issuer"].asString ())))
|
||||
// Don't allow illegal issuers.
|
||||
|| (!uTakerPaysCurrencyID != !uTakerPaysIssuerID)
|
||||
|| ACCOUNT_ONE == uTakerPaysIssuerID)
|
||||
|| (!pay_currency != !pay_issuer)
|
||||
|| ACCOUNT_ONE == pay_issuer)
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays issuer.";
|
||||
|
||||
@@ -3843,37 +3950,37 @@ Json::Value RPCHandler::doUnsubscribe (Json::Value params, Resource::Charge& loa
|
||||
}
|
||||
|
||||
// Parse mandatory currency.
|
||||
if (!jvTakerGets.isMember ("currency")
|
||||
|| !STAmount::currencyFromString (uTakerGetsCurrencyID, jvTakerGets["currency"].asString ()))
|
||||
if (!taker_gets.isMember ("currency")
|
||||
|| !STAmount::currencyFromString (get_currency, taker_gets["currency"].asString ()))
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency.";
|
||||
|
||||
return rpcError (rpcSRC_CUR_MALFORMED);
|
||||
}
|
||||
// Parse optional issuer.
|
||||
else if (((jvTakerGets.isMember ("issuer"))
|
||||
&& (!jvTakerGets["issuer"].isString ()
|
||||
|| !STAmount::issuerFromString (uTakerGetsIssuerID, jvTakerGets["issuer"].asString ())))
|
||||
else if (((taker_gets.isMember ("issuer"))
|
||||
&& (!taker_gets["issuer"].isString ()
|
||||
|| !STAmount::issuerFromString (get_issuer, taker_gets["issuer"].asString ())))
|
||||
// Don't allow illegal issuers.
|
||||
|| (!uTakerGetsCurrencyID != !uTakerGetsIssuerID)
|
||||
|| ACCOUNT_ONE == uTakerGetsIssuerID)
|
||||
|| (!get_currency != !get_issuer)
|
||||
|| ACCOUNT_ONE == get_issuer)
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Bad taker_gets issuer.";
|
||||
|
||||
return rpcError (rpcDST_ISR_MALFORMED);
|
||||
}
|
||||
|
||||
if (uTakerPaysCurrencyID == uTakerGetsCurrencyID
|
||||
&& uTakerPaysIssuerID == uTakerGetsIssuerID)
|
||||
if (pay_currency == get_currency
|
||||
&& pay_issuer == get_issuer)
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "taker_gets same as taker_pays.";
|
||||
|
||||
return rpcError (rpcBAD_MARKET);
|
||||
}
|
||||
|
||||
mNetOps->unsubBook (ispSub->getSeq (), uTakerPaysCurrencyID, uTakerGetsCurrencyID, uTakerPaysIssuerID, uTakerGetsIssuerID);
|
||||
mNetOps->unsubBook (ispSub->getSeq (), pay_currency, get_currency, pay_issuer, get_issuer);
|
||||
|
||||
if (bBoth) mNetOps->unsubBook (ispSub->getSeq (), uTakerGetsCurrencyID, uTakerPaysCurrencyID, uTakerGetsIssuerID, uTakerPaysIssuerID);
|
||||
if (bBoth) mNetOps->unsubBook (ispSub->getSeq (), get_currency, pay_currency, get_issuer, pay_issuer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3889,12 +3996,12 @@ Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value
|
||||
WriteLog (lsTRACE, RPCHandler) << "doRpcCommand:" << strMethod << ":" << jvParams;
|
||||
|
||||
if (!jvParams.isArray () || jvParams.size () > 1)
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return logRPCError (rpcError (rpcINVALID_PARAMS));
|
||||
|
||||
Json::Value params = jvParams.size () ? jvParams[0u] : Json::Value (Json::objectValue);
|
||||
|
||||
if (!params.isObject ())
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
return logRPCError (rpcError (rpcINVALID_PARAMS));
|
||||
|
||||
// Provide the JSON-RPC method as the field "command" in the request.
|
||||
params["command"] = strMethod;
|
||||
@@ -3922,7 +4029,7 @@ Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value
|
||||
jvResult["status"] = "success";
|
||||
}
|
||||
|
||||
return jvResult;
|
||||
return logRPCError (jvResult);
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doInternal (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
|
||||
Reference in New Issue
Block a user