diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index a48e834e1..1f19e7d1b 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -51,14 +51,14 @@ std::string EncodeBase64(const std::string& s) return result; } -Json::Value RPCParser::parseAsIs(const Json::Value ¶ms) +Json::Value RPCParser::parseAsIs(const Json::Value& jvParams) { return Json::Value(Json::objectValue); } // account_info || // account_info || [] -Json::Value RPCParser::parseAccountInfo(const Json::Value &jvParams) +Json::Value RPCParser::parseAccountInfo(const Json::Value& jvParams) { Json::Value jvRequest(Json::objectValue); std::string strIdent = jvParams[0u].asString(); @@ -76,6 +76,43 @@ Json::Value RPCParser::parseAccountInfo(const Json::Value &jvParams) return jvRequest; } +// account_tx +// account_tx +Json::Value RPCParser::parseAccountTransactions(const Json::Value& jvParams) +{ + Json::Value jvRequest(Json::objectValue); + RippleAddress raAccount; + + if (jvParams.size() < 2 || jvParams.size() > 3) + return rpcError(rpcINVALID_PARAMS); + + if (!raAccount.setAccountID(jvParams[0u].asString())) + return rpcError(rpcACT_MALFORMED); + + // YYY This could be more strict and report casting errors. + if (jvParams.size() == 2) + { + jvRequest["ledger"] = jvParams[1u].asUInt(); + } + else + { + uint32 uLedgerMin = jvParams[1u].asUInt(); + uint32 uLedgerMax = jvParams[2u].asUInt(); + + if ((uLedgerMax < uLedgerMin) || (uLedgerMax == 0)) + { + return rpcError(rpcLGR_IDXS_INVALID); + } + + jvRequest["ledger_min"] = uLedgerMin; + jvRequest["ledger_max"] = uLedgerMax; + } + + jvRequest["account"] = raAccount.humanAccountID(); + + return jvRequest; +} + // Convert a rpc method and params to a request. // <-- { method: xyz, params: [... ] } or { error: ..., ... } Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) @@ -92,10 +129,10 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) // Request-response methods // - Returns an error, or the request. // - To modify the method, provide a new method in the request. - { "accept_ledger", &RPCParser::parseAsIs, 0, 0 }, - { "account_info", &RPCParser::parseAccountInfo, 1, 2 }, + { "accept_ledger", &RPCParser::parseAsIs, 0, 0 }, + { "account_info", &RPCParser::parseAccountInfo, 1, 2 }, + { "account_tx", &RPCParser::parseAccountTransactions, 2, 3 }, #if 0 - { "account_tx", &RPCParser::doAccountTransactions, 2, 3, false, false, optNetwork }, { "connect", &RPCParser::doConnect, 1, 2, true, false, optNone }, { "data_delete", &RPCParser::doDataDelete, 1, 1, true, false, optNone }, { "data_fetch", &RPCParser::doDataFetch, 1, 1, true, false, optNone }, @@ -209,7 +246,8 @@ int commandLineRPC(const std::vector& vCmd) if (jvOutput.isMember("error")) { - jvOutput["rpc"] = jvRpc; + jvOutput["rpc"] = jvRpc; // How the command was seen as method + params. + jvOutput["request"] = jvRequest; // How the command was translated. } } diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 5a7b346b7..523c018ac 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -11,8 +11,9 @@ class RPCParser protected: typedef Json::Value (RPCParser::*parseFuncPtr)(const Json::Value &jvParams); - Json::Value parseAsIs(const Json::Value &jvParams); - Json::Value parseAccountInfo(const Json::Value &jvParams); + Json::Value parseAsIs(const Json::Value& jvParams); + Json::Value parseAccountInfo(const Json::Value& jvParams); + Json::Value parseAccountTransactions(const Json::Value& jvParams); public: Json::Value parseCommand(std::string strMethod, Json::Value jvParams); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 1d90a55c6..4dbbadd3a 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1198,34 +1198,36 @@ Json::Value RPCHandler::doLedger(Json::Value params) return ret; } -// account_tx -// account_tx -Json::Value RPCHandler::doAccountTransactions(Json::Value params) +// { account: , ledger: } +// { account: , ledger_min: , ledger_max: } +Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest) { - std::string param; - uint32 minLedger, maxLedger; + RippleAddress raAccount; + uint32 minLedger; + uint32 maxLedger; - if (!extractString(param, params, 0)) + if (!jvRequest.isMember("account")) return rpcError(rpcINVALID_PARAMS); - RippleAddress account; - if (!account.setAccountID(param)) + if (!raAccount.setAccountID(jvRequest["account"].asString())) return rpcError(rpcACT_MALFORMED); - if (!extractString(param, params, 1)) - return rpcError(rpcLGR_IDX_MALFORMED); - - minLedger = lexical_cast_s(param); - - if ((params.size() == 3) && extractString(param, params, 2)) - maxLedger = lexical_cast_s(param); + if (jvRequest.isMember("ledger")) + { + minLedger = maxLedger = jvRequest["ledger"].asUInt(); + } + else if (jvRequest.isMember("ledger_min") && jvRequest.isMember("ledger_max")) + { + minLedger = jvRequest["ledger_min"].asUInt(); + maxLedger = jvRequest["ledger_max"].asUInt(); + } else - maxLedger = minLedger; + { + return rpcError(rpcLGR_IDX_MALFORMED); + } if ((maxLedger < minLedger) || (maxLedger == 0)) { - std::cerr << "minL=" << minLedger << ", maxL=" << maxLedger << std::endl; - return rpcError(rpcLGR_IDXS_INVALID); } @@ -1233,9 +1235,9 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value params) try { #endif - std::vector< std::pair > txns = mNetOps->getAccountTxs(account, minLedger, maxLedger); + std::vector< std::pair > txns = mNetOps->getAccountTxs(raAccount, minLedger, maxLedger); Json::Value ret(Json::objectValue); - ret["account"] = account.humanAccountID(); + ret["account"] = raAccount.humanAccountID(); Json::Value ledgers(Json::arrayValue); // uint32 currentLedger = 0; @@ -2180,7 +2182,7 @@ Json::Value RPCHandler::doCommand(Json::Value& jvParams, int iRole) // Request-response methods { "accept_ledger", &RPCHandler::doAcceptLedger, -1, -1, true, false, optCurrent }, { "account_info", &RPCHandler::doAccountInfo, -1, -1, false, false, optCurrent }, - { "account_tx", &RPCHandler::doAccountTransactions, 2, 3, false, false, optNetwork }, + { "account_tx", &RPCHandler::doAccountTransactions, -1, -1, false, false, optNetwork }, { "connect", &RPCHandler::doConnect, 1, 2, true, false, optNone }, { "data_delete", &RPCHandler::doDataDelete, 1, 1, true, false, optNone }, { "data_fetch", &RPCHandler::doDataFetch, 1, 1, true, false, optNone },