From c2d6dc0ab78809c2e4e730575b7604688af5a752 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 1 Dec 2012 17:56:27 -0800 Subject: [PATCH 01/24] Add command line option --quiet. --- src/cpp/ripple/Config.cpp | 10 ++++- src/cpp/ripple/Config.h | 4 +- src/cpp/ripple/main.cpp | 92 ++++++++++++++++++++------------------- 3 files changed, 58 insertions(+), 48 deletions(-) diff --git a/src/cpp/ripple/Config.cpp b/src/cpp/ripple/Config.cpp index 4701634fbd..03c5453321 100644 --- a/src/cpp/ripple/Config.cpp +++ b/src/cpp/ripple/Config.cpp @@ -1,3 +1,6 @@ +// +// TODO: Check permissions on config file before using it. +// #include "Config.h" #include "utils.h" @@ -48,7 +51,7 @@ Config theConfig; -void Config::setup(const std::string& strConf) +void Config::setup(const std::string& strConf, bool bQuiet) { boost::system::error_code ec; @@ -58,6 +61,8 @@ void Config::setup(const std::string& strConf) // that with "db" as the data directory. // + QUIET = bQuiet; + if (!strConf.empty()) { // --conf= : everything is relative that file. @@ -172,7 +177,8 @@ void Config::setup(const std::string& strConf) void Config::load() { - std::cout << "Loading: " << CONFIG_FILE << std::endl; + if (!QUIET) + std::cerr << "Loading: " << CONFIG_FILE << std::endl; std::ifstream ifsConfig(CONFIG_FILE.c_str(), std::ios::in); diff --git a/src/cpp/ripple/Config.h b/src/cpp/ripple/Config.h index 9704396f72..b7e4898c03 100644 --- a/src/cpp/ripple/Config.h +++ b/src/cpp/ripple/Config.h @@ -46,6 +46,8 @@ class Config { public: // Configuration parameters + bool QUIET; + boost::filesystem::path CONFIG_FILE; boost::filesystem::path CONFIG_DIR; boost::filesystem::path DATA_DIR; @@ -113,7 +115,7 @@ public: // Client behavior int ACCOUNT_PROBE_MAX; // How far to scan for accounts. - void setup(const std::string& strConf); + void setup(const std::string& strConf, bool bQuiet); void load(); }; diff --git a/src/cpp/ripple/main.cpp b/src/cpp/ripple/main.cpp index 360c078570..6449079d25 100644 --- a/src/cpp/ripple/main.cpp +++ b/src/cpp/ripple/main.cpp @@ -33,51 +33,51 @@ bool init_unit_test() void printHelp(const po::options_description& desc) { - cout << SYSTEM_NAME "d [options] " << endl; + cerr << SYSTEM_NAME "d [options] " << endl; - cout << desc << endl; + cerr << desc << endl; - cout << "Commands: " << endl; - cout << " account_domain_set []" << endl; - cout << " account_email_set []" << endl; - cout << " account_info |" << endl; - cout << " account_info || []" << endl; - cout << " account_message_set " << endl; - cout << " account_publish_set " << endl; - cout << " account_rate_set " << endl; - cout << " account_wallet_set []" << endl; - cout << " connect []" << endl; - cout << " data_delete " << endl; - cout << " data_fetch " << endl; - cout << " data_store " << endl; - cout << " ledger [|current|lastclosed] [full]" << endl; - cout << " logrotate " << endl; - cout << " nickname_info " << endl; - cout << " nickname_set [] []" << endl; - cout << " offer_create [passive]" << endl; - cout << " offer_cancel " << endl; - cout << " password_fund []" << endl; - cout << " password_set []" << endl; - cout << " peers" << endl; - cout << " ripple ..." << endl; - cout << " ripple_lines_get || []" << endl; - cout << " ripple_line_set [] []" << endl; - cout << " send [] [] []" << endl; - cout << " stop" << endl; - cout << " tx " << endl; - cout << " unl_add | []" << endl; - cout << " unl_delete |" << endl; - cout << " unl_list" << endl; - cout << " unl_load" << endl; - cout << " unl_network" << endl; - cout << " unl_reset" << endl; - cout << " validation_create [||]" << endl; - cout << " validation_seed [||]" << endl; - cout << " wallet_add [] []" << endl; - cout << " wallet_accounts " << endl; - cout << " wallet_claim [] []" << endl; - cout << " wallet_seed [||]" << endl; - cout << " wallet_propose []" << endl; + cerr << "Commands: " << endl; + cerr << " account_domain_set []" << endl; + cerr << " account_email_set []" << endl; + cerr << " account_info |" << endl; + cerr << " account_info || []" << endl; + cerr << " account_message_set " << endl; + cerr << " account_publish_set " << endl; + cerr << " account_rate_set " << endl; + cerr << " account_wallet_set []" << endl; + cerr << " connect []" << endl; + cerr << " data_delete " << endl; + cerr << " data_fetch " << endl; + cerr << " data_store " << endl; + cerr << " ledger [|current|lastclosed] [full]" << endl; + cerr << " logrotate " << endl; + cerr << " nickname_info " << endl; + cerr << " nickname_set [] []" << endl; + cerr << " offer_create [passive]" << endl; + cerr << " offer_cancel " << endl; + cerr << " password_fund []" << endl; + cerr << " password_set []" << endl; + cerr << " peers" << endl; + cerr << " ripple ..." << endl; + cerr << " ripple_lines_get || []" << endl; + cerr << " ripple_line_set [] []" << endl; + cerr << " send [] [] []" << endl; + cerr << " stop" << endl; + cerr << " tx " << endl; + cerr << " unl_add | []" << endl; + cerr << " unl_delete |" << endl; + cerr << " unl_list" << endl; + cerr << " unl_load" << endl; + cerr << " unl_network" << endl; + cerr << " unl_reset" << endl; + cerr << " validation_create [||]" << endl; + cerr << " validation_seed [||]" << endl; + cerr << " wallet_add [] []" << endl; + cerr << " wallet_accounts " << endl; + cerr << " wallet_claim [] []" << endl; + cerr << " wallet_seed [||]" << endl; + cerr << " wallet_propose []" << endl; } int main(int argc, char* argv[]) @@ -96,6 +96,7 @@ int main(int argc, char* argv[]) ("standalone,a", "Run with no peers.") ("test,t", "Perform unit tests.") ("parameters", po::value< vector >(), "Specify comma separated parameters.") + ("quiet,q", "Reduce diagnotics.") ("verbose,v", "Increase log level.") ("load", "Load the current ledger from the local DB.") ("start", "Start from a fresh Ledger.") @@ -138,7 +139,6 @@ int main(int argc, char* argv[]) } } - if (vm.count("verbose")) Log::setMinSeverity(lsTRACE, true); else @@ -152,7 +152,9 @@ int main(int argc, char* argv[]) if (!iResult) { - theConfig.setup(vm.count("conf") ? vm["conf"].as() : ""); + theConfig.setup( + vm.count("conf") ? vm["conf"].as() : "", // Config file. + !!vm.count("quiet")); // Quiet flag. if (vm.count("standalone")) { From 17b2506cd755d91c1c1ef7db871bf96619419b08 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 1 Dec 2012 17:58:32 -0800 Subject: [PATCH 02/24] Work toward RPC refactor and do not print to cout. --- src/cpp/ripple/Application.cpp | 2 +- src/cpp/ripple/ConnectionPool.cpp | 2 +- src/cpp/ripple/PeerDoor.cpp | 2 +- src/cpp/ripple/RPCHandler.cpp | 427 ++++++++++++----------------- src/cpp/ripple/RPCHandler.h | 174 ++++-------- src/cpp/ripple/RippleLines.cpp | 6 +- src/cpp/ripple/SerializedTypes.cpp | 12 +- 7 files changed, 246 insertions(+), 379 deletions(-) diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index 826b55fa57..91dacfb385 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -282,7 +282,7 @@ void Application::loadOldLedger() if (!lastLedger) { - std::cout << "No Ledger found?" << std::endl; + cLog(lsFATAL) << "No Ledger found?" << std::endl; exit(-1); } lastLedger->setClosed(); diff --git a/src/cpp/ripple/ConnectionPool.cpp b/src/cpp/ripple/ConnectionPool.cpp index 85bc05ea5d..6de593b2b7 100644 --- a/src/cpp/ripple/ConnectionPool.cpp +++ b/src/cpp/ripple/ConnectionPool.cpp @@ -101,7 +101,7 @@ bool ConnectionPool::savePeer(const std::string& strIp, int iPort, char code) } else { - std::cout << "Error saving Peer" << std::endl; + std::cerr << "Error saving Peer" << std::endl; } if (bNew) diff --git a/src/cpp/ripple/PeerDoor.cpp b/src/cpp/ripple/PeerDoor.cpp index a3740846b8..97ddc1c2c0 100644 --- a/src/cpp/ripple/PeerDoor.cpp +++ b/src/cpp/ripple/PeerDoor.cpp @@ -54,7 +54,7 @@ void PeerDoor::handleConnect(Peer::pointer new_connection, { new_connection->connected(error); } - else cout << "Error: " << error; + else cerr << "Error: " << error; startListening(); } diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 99ce0e83d1..e2a5d1c951 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -10,6 +10,7 @@ #include "Wallet.h" #include "RippleAddress.h" #include "RippleCalc.h" +#include "RPCErr.h" #include "AccountState.h" #include "NicknameState.h" #include "InstanceCounter.h" @@ -20,77 +21,6 @@ SETUP_LOG(); -Json::Value RPCHandler::rpcError(int iError) -{ - static struct { - int iError; - const char* pToken; - const char* pMessage; - } errorInfoA[] = { - { rpcACT_EXISTS, "actExists", "Account already exists." }, - { rpcACT_MALFORMED, "actMalformed", "Account malformed." }, - { rpcACT_NOT_FOUND, "actNotFound", "Account not found." }, - { rpcBAD_SEED, "badSeed", "Disallowed seed." }, - { rpcDST_ACT_MALFORMED, "dstActMalformed", "Destination account is malformed." }, - { rpcDST_ACT_MISSING, "dstActMissing", "Destination account does not exists." }, - { rpcDST_AMT_MALFORMED, "dstAmtMalformed", "Destination amount/currency/issuer is malformed." }, - { rpcFAIL_GEN_DECRPYT, "failGenDecrypt", "Failed to decrypt generator." }, - { rpcGETS_ACT_MALFORMED, "getsActMalformed", "Gets account malformed." }, - { rpcGETS_AMT_MALFORMED, "getsAmtMalformed", "Gets amount malformed." }, - { rpcHOST_IP_MALFORMED, "hostIpMalformed", "Host IP is malformed." }, - { rpcINSUF_FUNDS, "insufFunds", "Insufficient funds." }, - { rpcINTERNAL, "internal", "Internal error." }, - { rpcINVALID_PARAMS, "invalidParams", "Invalid parameters." }, - { rpcLGR_IDXS_INVALID, "lgrIdxsInvalid", "Ledger indexes invalid." }, - { rpcLGR_IDX_MALFORMED, "lgrIdxMalformed", "Ledger index malformed." }, - { rpcLGR_NOT_FOUND, "lgrNotFound", "Ledger not found." }, - { rpcNICKNAME_MALFORMED, "nicknameMalformed","Nickname is malformed." }, - { rpcNICKNAME_MISSING, "nicknameMissing", "Nickname does not exist." }, - { rpcNICKNAME_PERM, "nicknamePerm", "Account does not control nickname." }, - { rpcNOT_IMPL, "notImpl", "Not implemented." }, - { rpcNO_ACCOUNT, "noAccount", "No such account." }, - { rpcNO_CLOSED, "noClosed", "Closed ledger is unavailable." }, - { rpcNO_CURRENT, "noCurrent", "Current ledger is unavailable." }, - { rpcNO_EVENTS, "noEvents", "Current transport does not support events." }, - { rpcNO_GEN_DECRPYT, "noGenDectypt", "Password failed to decrypt master public generator." }, - { rpcNO_NETWORK, "noNetwork", "Network not available." }, - { rpcNO_PATH, "noPath", "Unable to find a ripple path." }, - { rpcNO_PERMISSION, "noPermission", "You don't have permission for this command." }, - { rpcNOT_STANDALONE, "notStandAlone", "Operation valid in debug mode only." }, - { rpcPASSWD_CHANGED, "passwdChanged", "Wrong key, password changed." }, - { rpcPAYS_ACT_MALFORMED, "paysActMalformed", "Pays account malformed." }, - { rpcPAYS_AMT_MALFORMED, "paysAmtMalformed", "Pays amount malformed." }, - { rpcPORT_MALFORMED, "portMalformed", "Port is malformed." }, - { rpcPUBLIC_MALFORMED, "publicMalformed", "Public key is malformed." }, - { rpcQUALITY_MALFORMED, "qualityMalformed", "Quality malformed." }, - { rpcSRC_ACT_MALFORMED, "srcActMalformed", "Source account is malformed." }, - { rpcSRC_ACT_MISSING, "srcActMissing", "Source account does not exist." }, - { rpcSRC_AMT_MALFORMED, "srcAmtMalformed", "Source amount/currency/issuer is malformed." }, - { rpcSRC_UNCLAIMED, "srcUnclaimed", "Source account is not claimed." }, - { rpcSUCCESS, "success", "Success." }, - { rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found." }, - { rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown command." }, - { rpcWRONG_SEED, "wrongSeed", "The regular key does not point as the master key." }, - }; - - int i; - - for (i=NUMBER(errorInfoA); i-- && errorInfoA[i].iError != iError;) - ; - - Json::Value jsonResult(Json::objectValue); - - jsonResult["error"] = i >= 0 ? errorInfoA[i].pToken : lexical_cast_i(iError); - jsonResult["error_message"] = i >= 0 ? errorInfoA[i].pMessage : lexical_cast_i(iError); - jsonResult["error_code"] = iError; - if (i >= 0) - std::cerr << "rpcError: " - << errorInfoA[i].pToken << ": " << errorInfoA[i].pMessage << std::endl; - - return jsonResult; -} - - RPCHandler::RPCHandler(NetworkOPs* netOps) { mNetOps=netOps; @@ -103,7 +33,7 @@ RPCHandler::RPCHandler(NetworkOPs* netOps, InfoSub* infoSub) mInfoSub=infoSub; } -int RPCHandler::getParamCount(const Json::Value& params) +int RPCHandler::getParamCount(Json::Value params) { // If non-array, only counts strings if (params.isNull()) return 0; if (params.isArray()) return params.size(); @@ -325,19 +255,21 @@ Json::Value RPCHandler::accountFromString(const uint256& uLedger, RippleAddress& return Json::Value(Json::objectValue); } -Json::Value RPCHandler::doAcceptLedger(const Json::Value ¶ms) +Json::Value RPCHandler::doAcceptLedger(Json::Value jvRequest) { if (!theConfig.RUN_STANDALONE) return rpcError(rpcNOT_STANDALONE); Json::Value obj(Json::objectValue); - obj["newLedger"] = theApp->getOPs().acceptLedger(); - return obj; + + jvRequest["newLedger"] = theApp->getOPs().acceptLedger(); + + return jvRequest; } // account_info || // account_info || [] -Json::Value RPCHandler::doAccountInfo(const Json::Value ¶ms) +Json::Value RPCHandler::doAccountInfo(Json::Value params) { std::string strIdent = params[0u].asString(); bool bIndex; @@ -388,7 +320,7 @@ Json::Value RPCHandler::doAccountInfo(const Json::Value ¶ms) -Json::Value RPCHandler::doConnect(const Json::Value& params) +Json::Value RPCHandler::doConnect(Json::Value params) { if (theConfig.RUN_STANDALONE) return "cannot connect in standalone mode"; @@ -419,7 +351,7 @@ Json::Value RPCHandler::doConnect(const Json::Value& params) } // data_delete -Json::Value RPCHandler::doDataDelete(const Json::Value& params) +Json::Value RPCHandler::doDataDelete(Json::Value params) { std::string strKey = params[0u].asString(); @@ -438,7 +370,7 @@ Json::Value RPCHandler::doDataDelete(const Json::Value& params) } // data_fetch -Json::Value RPCHandler::doDataFetch(const Json::Value& params) +Json::Value RPCHandler::doDataFetch(Json::Value params) { std::string strKey = params[0u].asString(); std::string strValue; @@ -453,7 +385,7 @@ Json::Value RPCHandler::doDataFetch(const Json::Value& params) } // data_store -Json::Value RPCHandler::doDataStore(const Json::Value& params) +Json::Value RPCHandler::doDataStore(Json::Value params) { std::string strKey = params[0u].asString(); std::string strValue = params[1u].asString(); @@ -475,7 +407,7 @@ Json::Value RPCHandler::doDataStore(const Json::Value& params) // nickname_info // Note: Nicknames are not automatically looked up by commands as they are advisory and can be changed. -Json::Value RPCHandler::doNicknameInfo(const Json::Value& params) +Json::Value RPCHandler::doNicknameInfo(Json::Value params) { std::string strNickname = params[0u].asString(); boost::trim(strNickname); @@ -503,7 +435,7 @@ Json::Value RPCHandler::doNicknameInfo(const Json::Value& params) // owner_info || // owner_info || [] -Json::Value RPCHandler::doOwnerInfo(const Json::Value& params) +Json::Value RPCHandler::doOwnerInfo(Json::Value params) { std::string strIdent = params[0u].asString(); bool bIndex; @@ -527,7 +459,7 @@ Json::Value RPCHandler::doOwnerInfo(const Json::Value& params) } -Json::Value RPCHandler::doPeers(const Json::Value& params) +Json::Value RPCHandler::doPeers(Json::Value params) { Json::Value obj(Json::objectValue); @@ -541,7 +473,7 @@ Json::Value RPCHandler::doPeers(const Json::Value& params) // issuer is the offering account // --> submit: 'submit|true|false': defaults to false // Prior to running allow each to have a credit line of what they will be getting from the other account. -Json::Value RPCHandler::doProfile(const Json::Value ¶ms) +Json::Value RPCHandler::doProfile(Json::Value params) { /* need to fix now that sharedOfferCreate is gone int iArgs = params.size(); @@ -629,7 +561,7 @@ Json::Value RPCHandler::doProfile(const Json::Value ¶ms) } // ripple_lines_get || [] -Json::Value RPCHandler::doRippleLinesGet(const Json::Value ¶ms) +Json::Value RPCHandler::doRippleLinesGet(Json::Value params) { // uint256 uAccepted = mNetOps->getClosedLedgerHash(); @@ -702,7 +634,7 @@ Json::Value RPCHandler::doRippleLinesGet(const Json::Value ¶ms) // - Allows clients to verify path exists. // - Return canonicalized path. // - From a trusted server, allows clients to use path without manipulation. -Json::Value RPCHandler::doRipplePathFind(const Json::Value& jvRequest) +Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest) { Json::Value jvResult(Json::objectValue); RippleAddress raSrc; @@ -871,7 +803,7 @@ Json::Value RPCHandler::doRipplePathFind(const Json::Value& jvRequest) // submit any transaction to the network // submit private_key json -Json::Value RPCHandler::doSubmit(const Json::Value& params) +Json::Value RPCHandler::doSubmit(Json::Value params) { Json::Value txJSON; Json::Reader reader; @@ -891,13 +823,13 @@ Json::Value RPCHandler::doSubmit(const Json::Value& params) return rpcError(rpcINVALID_PARAMS); } -Json::Value RPCHandler::doSubmitJson(const Json::Value& jvRequest) +Json::Value RPCHandler::doSubmitJson(Json::Value jvRequest) { return handleJSONSubmit(jvRequest); } -Json::Value RPCHandler::handleJSONSubmit(const Json::Value& jvRequest) +Json::Value RPCHandler::handleJSONSubmit(Json::Value jvRequest) { Json::Value jvResult; RippleAddress naSeed; @@ -1142,7 +1074,7 @@ Json::Value RPCHandler::handleJSONSubmit(const Json::Value& jvRequest) } } -Json::Value RPCHandler::doServerInfo(const Json::Value& params) +Json::Value RPCHandler::doServerInfo(Json::Value params) { Json::Value ret(Json::objectValue); @@ -1151,7 +1083,7 @@ Json::Value RPCHandler::doServerInfo(const Json::Value& params) return ret; } -Json::Value RPCHandler::doTxHistory(const Json::Value& params) +Json::Value RPCHandler::doTxHistory(Json::Value params) { if (params.size() == 1) { @@ -1184,7 +1116,7 @@ Json::Value RPCHandler::doTxHistory(const Json::Value& params) return rpcError(rpcSRC_ACT_MALFORMED); } -Json::Value RPCHandler::doTx(const Json::Value& params) +Json::Value RPCHandler::doTx(Json::Value params) { // tx // tx @@ -1210,7 +1142,7 @@ Json::Value RPCHandler::doTx(const Json::Value& params) return rpcError(rpcNOT_IMPL); } -Json::Value RPCHandler::doLedgerClosed(const Json::Value& params) +Json::Value RPCHandler::doLedgerClosed(Json::Value params) { Json::Value jvResult; uint256 uLedger = mNetOps->getClosedLedgerHash(); @@ -1221,7 +1153,7 @@ Json::Value RPCHandler::doLedgerClosed(const Json::Value& params) return jvResult; } -Json::Value RPCHandler::doLedgerCurrent(const Json::Value& params) +Json::Value RPCHandler::doLedgerCurrent(Json::Value params) { Json::Value jvResult; jvResult["ledger_current_index"] = mNetOps->getCurrentLedgerID(); @@ -1229,7 +1161,7 @@ Json::Value RPCHandler::doLedgerCurrent(const Json::Value& params) } // ledger [id|current|lastclosed] [full] -Json::Value RPCHandler::doLedger(const Json::Value& params) +Json::Value RPCHandler::doLedger(Json::Value params) { if (getParamCount(params) == 0) { @@ -1268,7 +1200,7 @@ Json::Value RPCHandler::doLedger(const Json::Value& params) // account_tx // account_tx -Json::Value RPCHandler::doAccountTransactions(const Json::Value& params) +Json::Value RPCHandler::doAccountTransactions(Json::Value params) { std::string param; uint32 minLedger, maxLedger; @@ -1325,7 +1257,7 @@ Json::Value RPCHandler::doAccountTransactions(const Json::Value& params) } // unl_add | [] -Json::Value RPCHandler::doUnlAdd(const Json::Value& params) +Json::Value RPCHandler::doUnlAdd(Json::Value params) { std::string strNode = params[0u].asString(); std::string strComment = (params.size() == 2) ? params[1u].asString() : ""; @@ -1350,7 +1282,7 @@ Json::Value RPCHandler::doUnlAdd(const Json::Value& params) // // NOTE: It is poor security to specify secret information on the command line. This information might be saved in the command // shell history file (e.g. .bash_history) and it may be leaked via the process status command (i.e. ps). -Json::Value RPCHandler::doValidationCreate(const Json::Value& params) { +Json::Value RPCHandler::doValidationCreate(Json::Value params) { RippleAddress naSeed; Json::Value obj(Json::objectValue); @@ -1376,7 +1308,7 @@ Json::Value RPCHandler::doValidationCreate(const Json::Value& params) { // // NOTE: It is poor security to specify secret information on the command line. This information might be saved in the command // shell history file (e.g. .bash_history) and it may be leaked via the process status command (i.e. ps). -Json::Value RPCHandler::doValidationSeed(const Json::Value& params) { +Json::Value RPCHandler::doValidationSeed(Json::Value params) { Json::Value obj(Json::objectValue); if (params.empty()) @@ -1437,7 +1369,7 @@ Json::Value RPCHandler::accounts(const uint256& uLedger, const RippleAddress& na } // wallet_accounts -Json::Value RPCHandler::doWalletAccounts(const Json::Value& params) +Json::Value RPCHandler::doWalletAccounts(Json::Value params) { RippleAddress naSeed; @@ -1474,143 +1406,14 @@ Json::Value RPCHandler::doWalletAccounts(const Json::Value& params) } } -Json::Value RPCHandler::doLogRotate(const Json::Value& params) +Json::Value RPCHandler::doLogRotate(Json::Value params) { return Log::rotateLog(); } -Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& params, int role) -{ - cLog(lsTRACE) << "RPC:" << command; - cLog(lsTRACE) << "RPC params:" << params; - - LoadEvent::autoptr le(theApp->getJobQueue().getLoadEventAP(jtRPC)); - - mRole = role; - - static struct { - const char* pCommand; - doFuncPtr dfpFunc; - int iMinParams; - int iMaxParams; - bool bAdminRequired; - bool bEvented; - unsigned int iOptions; - } commandsA[] = { - // Request-response methods - { "accept_ledger", &RPCHandler::doAcceptLedger, 0, 0, true, false, optNone }, - { "account_info", &RPCHandler::doAccountInfo, 1, 2, false, false, optCurrent }, - { "account_tx", &RPCHandler::doAccountTransactions, 2, 3, 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 }, - { "data_store", &RPCHandler::doDataStore, 2, 2, true, false, optNone }, - { "get_counts", &RPCHandler::doGetCounts, 0, 1, true, false, optNone }, - { "ledger", &RPCHandler::doLedger, 0, 2, false, false, optNetwork }, - { "ledger_accept", &RPCHandler::doLedgerAccept, 0, 0, true, false, optCurrent }, - { "ledger_closed", &RPCHandler::doLedgerClosed, 0, 0, false, false, optClosed }, - { "ledger_current", &RPCHandler::doLedgerCurrent, 0, 0, false, false, optCurrent }, - { "ledger_entry", &RPCHandler::doLedgerEntry, -1, -1, false, false, optCurrent }, - { "ledger_header", &RPCHandler::doLedgerHeader, -1, -1, false, false, optCurrent }, - { "log_level", &RPCHandler::doLogLevel, 0, 2, true, false, optNone }, - { "logrotate", &RPCHandler::doLogRotate, 0, 0, true, false, optNone }, - { "nickname_info", &RPCHandler::doNicknameInfo, 1, 1, false, false, optCurrent }, - { "owner_info", &RPCHandler::doOwnerInfo, 1, 2, false, false, optCurrent }, - { "peers", &RPCHandler::doPeers, 0, 0, true, false, optNone }, - { "profile", &RPCHandler::doProfile, 1, 9, false, false, optCurrent }, - { "ripple_lines_get", &RPCHandler::doRippleLinesGet, 1, 2, false, false, optCurrent }, - { "ripple_path_find", &RPCHandler::doRipplePathFind, -1, -1, false, false, optCurrent }, - { "submit", &RPCHandler::doSubmit, 2, 2, false, false, optCurrent }, - { "submit_json", &RPCHandler::doSubmitJson, -1, -1, false, false, optCurrent }, - { "server_info", &RPCHandler::doServerInfo, 0, 0, true, false, optNone }, - { "stop", &RPCHandler::doStop, 0, 0, true, false, optNone }, - { "transaction_entry", &RPCHandler::doTransactionEntry, -1, -1, false, false, optCurrent }, - { "tx", &RPCHandler::doTx, 1, 1, true, false, optNone }, - { "tx_history", &RPCHandler::doTxHistory, 1, 1, false, false, optNone }, - - { "unl_add", &RPCHandler::doUnlAdd, 1, 2, true, false, optNone }, - { "unl_delete", &RPCHandler::doUnlDelete, 1, 1, true, false, optNone }, - { "unl_list", &RPCHandler::doUnlList, 0, 0, true, false, optNone }, - { "unl_load", &RPCHandler::doUnlLoad, 0, 0, true, false, optNone }, - { "unl_network", &RPCHandler::doUnlNetwork, 0, 0, true, false, optNone }, - { "unl_reset", &RPCHandler::doUnlReset, 0, 0, true, false, optNone }, - { "unl_score", &RPCHandler::doUnlScore, 0, 0, true, false, optNone }, - - { "validation_create", &RPCHandler::doValidationCreate, 0, 1, false, false, optNone }, - { "validation_seed", &RPCHandler::doValidationSeed, 0, 1, false, false, optNone }, - - { "wallet_accounts", &RPCHandler::doWalletAccounts, 1, 1, false, false, optCurrent }, - { "wallet_propose", &RPCHandler::doWalletPropose, 0, 1, false, false, optNone }, - { "wallet_seed", &RPCHandler::doWalletSeed, 0, 1, false, false, optNone }, - - { "login", &RPCHandler::doLogin, 2, 2, true, false, optNone }, - - // Evented methods - { "subscribe", &RPCHandler::doSubscribe, -1, -1, false, true, optNone }, - { "unsubscribe", &RPCHandler::doUnsubscribe, -1, -1, false, true, optNone }, - }; - - int i = NUMBER(commandsA); - - while (i-- && command != commandsA[i].pCommand) - ; - - if (i < 0) - { - return rpcError(rpcUNKNOWN_COMMAND); - } - else if (commandsA[i].bAdminRequired && mRole != ADMIN) - { - return rpcError(rpcNO_PERMISSION); - } - else if (commandsA[i].bEvented && mInfoSub == NULL) - { - return rpcError(rpcNO_EVENTS); - } - else if (commandsA[i].iMinParams >= 0 - ? commandsA[i].iMaxParams - ? (params.size() < commandsA[i].iMinParams - || (commandsA[i].iMaxParams >= 0 && params.size() > commandsA[i].iMaxParams)) - : false - : params.isArray()) - { - return rpcError(rpcINVALID_PARAMS); - } - else if ((commandsA[i].iOptions & optNetwork) && !mNetOps->available()) - { - return rpcError(rpcNO_NETWORK); - } - // XXX Should verify we have a current ledger. - - boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock()); - if ((commandsA[i].iOptions & optCurrent) && false) - { - return rpcError(rpcNO_CURRENT); - } - else if ((commandsA[i].iOptions & optClosed) && !mNetOps->getClosedLedger()) - { - return rpcError(rpcNO_CLOSED); - } - else - { - try { - return (this->*(commandsA[i].dfpFunc))(params); - } - catch (std::exception& e) - { - cLog(lsINFO) << "Caught throw: " << e.what(); - - return rpcError(rpcINTERNAL); - } - } -} - - - - // wallet_propose [] // is only for testing. Master seeds should only be generated randomly. -Json::Value RPCHandler::doWalletPropose(const Json::Value& params) +Json::Value RPCHandler::doWalletPropose(Json::Value params) { RippleAddress naSeed; RippleAddress naAccount; @@ -1637,7 +1440,7 @@ Json::Value RPCHandler::doWalletPropose(const Json::Value& params) } // wallet_seed [||] -Json::Value RPCHandler::doWalletSeed(const Json::Value& params) +Json::Value RPCHandler::doWalletSeed(Json::Value params) { RippleAddress naSeed; @@ -1672,7 +1475,7 @@ Json::Value RPCHandler::doWalletSeed(const Json::Value& params) // TODO: for now this simply checks if this is the admin account // TODO: need to prevent them hammering this over and over // TODO: maybe a better way is only allow admin from local host -Json::Value RPCHandler::doLogin(const Json::Value& params) +Json::Value RPCHandler::doLogin(Json::Value params) { std::string username = params[0u].asString(); std::string password = params[1u].asString(); @@ -1688,7 +1491,7 @@ Json::Value RPCHandler::doLogin(const Json::Value& params) } } -Json::Value RPCHandler::doGetCounts(const Json::Value& params) +Json::Value RPCHandler::doGetCounts(Json::Value params) { int minCount = 10; if (params.size() > 0) @@ -1702,7 +1505,7 @@ Json::Value RPCHandler::doGetCounts(const Json::Value& params) return ret; } -Json::Value RPCHandler::doLogLevel(const Json::Value& params) +Json::Value RPCHandler::doLogLevel(Json::Value params) { if (params.size() == 0) { // get log severities @@ -1745,7 +1548,7 @@ Json::Value RPCHandler::doLogLevel(const Json::Value& params) // Populate the UNL from ripple.com's validators.txt file. -Json::Value RPCHandler::doUnlNetwork(const Json::Value& params) +Json::Value RPCHandler::doUnlNetwork(Json::Value params) { theApp->getUNL().nodeNetwork(); @@ -1753,7 +1556,7 @@ Json::Value RPCHandler::doUnlNetwork(const Json::Value& params) } // unl_reset -Json::Value RPCHandler::doUnlReset(const Json::Value& params) +Json::Value RPCHandler::doUnlReset(Json::Value params) { theApp->getUNL().nodeReset(); @@ -1761,14 +1564,14 @@ Json::Value RPCHandler::doUnlReset(const Json::Value& params) } // unl_score -Json::Value RPCHandler::doUnlScore(const Json::Value& params) +Json::Value RPCHandler::doUnlScore(Json::Value params) { theApp->getUNL().nodeScore(); return "scoring requested"; } -Json::Value RPCHandler::doStop(const Json::Value& params) +Json::Value RPCHandler::doStop(Json::Value params) { theApp->stop(); @@ -1776,7 +1579,7 @@ Json::Value RPCHandler::doStop(const Json::Value& params) } // unl_delete | -Json::Value RPCHandler::doUnlDelete(const Json::Value& params) +Json::Value RPCHandler::doUnlDelete(Json::Value params) { std::string strNode = params[0u].asString(); @@ -1796,7 +1599,7 @@ Json::Value RPCHandler::doUnlDelete(const Json::Value& params) } } -Json::Value RPCHandler::doUnlList(const Json::Value& params) +Json::Value RPCHandler::doUnlList(Json::Value params) { Json::Value obj(Json::objectValue); @@ -1806,7 +1609,7 @@ Json::Value RPCHandler::doUnlList(const Json::Value& params) } // Populate the UNL from a local validators.txt file. -Json::Value RPCHandler::doUnlLoad(const Json::Value& params) +Json::Value RPCHandler::doUnlLoad(Json::Value params) { if (theConfig.VALIDATORS_FILE.empty() || !theApp->getUNL().nodeLoad(theConfig.VALIDATORS_FILE)) { @@ -1816,7 +1619,7 @@ Json::Value RPCHandler::doUnlLoad(const Json::Value& params) return "loading"; } -Json::Value RPCHandler::doLedgerAccept(const Json::Value& ) +Json::Value RPCHandler::doLedgerAccept(Json::Value ) { Json::Value jvResult; @@ -1834,7 +1637,7 @@ Json::Value RPCHandler::doLedgerAccept(const Json::Value& ) return jvResult; } -Json::Value RPCHandler::doTransactionEntry(const Json::Value& jvRequest) +Json::Value RPCHandler::doTransactionEntry(Json::Value jvRequest) { Json::Value jvResult; @@ -1884,7 +1687,7 @@ Json::Value RPCHandler::doTransactionEntry(const Json::Value& jvRequest) return jvResult; } -Json::Value RPCHandler::lookupLedger(const Json::Value& jvRequest, Ledger::pointer& lpLedger) +Json::Value RPCHandler::lookupLedger(Json::Value jvRequest, Ledger::pointer& lpLedger) { Json::Value jvResult; @@ -1936,7 +1739,7 @@ Json::Value RPCHandler::lookupLedger(const Json::Value& jvRequest, Ledger::point return jvResult; } -Json::Value RPCHandler::doLedgerEntry(const Json::Value& jvRequest) +Json::Value RPCHandler::doLedgerEntry(Json::Value jvRequest) { Ledger::pointer lpLedger; Json::Value jvResult = lookupLedger(jvRequest, lpLedger); @@ -2139,7 +1942,7 @@ Json::Value RPCHandler::doLedgerEntry(const Json::Value& jvRequest) return jvResult; } -Json::Value RPCHandler::doLedgerHeader(const Json::Value& jvRequest) +Json::Value RPCHandler::doLedgerHeader(Json::Value jvRequest) { Ledger::pointer lpLedger; Json::Value jvResult = lookupLedger(jvRequest, lpLedger); @@ -2189,7 +1992,7 @@ rt_transactions accounts rt_accounts */ -Json::Value RPCHandler::doSubscribe(const Json::Value& jvRequest) +Json::Value RPCHandler::doSubscribe(Json::Value jvRequest) { Json::Value jvResult(Json::objectValue); @@ -2263,7 +2066,7 @@ Json::Value RPCHandler::doSubscribe(const Json::Value& jvRequest) return jvResult; } -Json::Value RPCHandler::doUnsubscribe(const Json::Value& jvRequest) +Json::Value RPCHandler::doUnsubscribe(Json::Value jvRequest) { Json::Value jvResult(Json::objectValue); @@ -2337,4 +2140,130 @@ Json::Value RPCHandler::doUnsubscribe(const Json::Value& jvRequest) return jvResult; } +Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& params, int role) +{ + cLog(lsTRACE) << "RPC:" << command; + cLog(lsTRACE) << "RPC params:" << params; + + LoadEvent::autoptr le(theApp->getJobQueue().getLoadEventAP(jtRPC)); + + mRole = role; + + static struct { + const char* pCommand; + doFuncPtr dfpFunc; + int iMinParams; + int iMaxParams; + bool bAdminRequired; + bool bEvented; + unsigned int iOptions; + } commandsA[] = { + // Request-response methods + { "accept_ledger", &RPCHandler::doAcceptLedger, -1, -1, true, false, optNone }, + { "account_info", &RPCHandler::doAccountInfo, 1, 2, false, false, optCurrent }, + { "account_tx", &RPCHandler::doAccountTransactions, 2, 3, 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 }, + { "data_store", &RPCHandler::doDataStore, 2, 2, true, false, optNone }, + { "get_counts", &RPCHandler::doGetCounts, 0, 1, true, false, optNone }, + { "ledger", &RPCHandler::doLedger, 0, 2, false, false, optNetwork }, + { "ledger_accept", &RPCHandler::doLedgerAccept, 0, 0, true, false, optCurrent }, + { "ledger_closed", &RPCHandler::doLedgerClosed, 0, 0, false, false, optClosed }, + { "ledger_current", &RPCHandler::doLedgerCurrent, 0, 0, false, false, optCurrent }, + { "ledger_entry", &RPCHandler::doLedgerEntry, -1, -1, false, false, optCurrent }, + { "ledger_header", &RPCHandler::doLedgerHeader, -1, -1, false, false, optCurrent }, + { "log_level", &RPCHandler::doLogLevel, 0, 2, true, false, optNone }, + { "logrotate", &RPCHandler::doLogRotate, 0, 0, true, false, optNone }, + { "nickname_info", &RPCHandler::doNicknameInfo, 1, 1, false, false, optCurrent }, + { "owner_info", &RPCHandler::doOwnerInfo, 1, 2, false, false, optCurrent }, + { "peers", &RPCHandler::doPeers, 0, 0, true, false, optNone }, + { "profile", &RPCHandler::doProfile, 1, 9, false, false, optCurrent }, + { "ripple_lines_get", &RPCHandler::doRippleLinesGet, 1, 2, false, false, optCurrent }, + { "ripple_path_find", &RPCHandler::doRipplePathFind, -1, -1, false, false, optCurrent }, + { "submit", &RPCHandler::doSubmit, 2, 2, false, false, optCurrent }, + { "submit_json", &RPCHandler::doSubmitJson, -1, -1, false, false, optCurrent }, + { "server_info", &RPCHandler::doServerInfo, 0, 0, true, false, optNone }, + { "stop", &RPCHandler::doStop, 0, 0, true, false, optNone }, + { "transaction_entry", &RPCHandler::doTransactionEntry, -1, -1, false, false, optCurrent }, + { "tx", &RPCHandler::doTx, 1, 1, true, false, optNone }, + { "tx_history", &RPCHandler::doTxHistory, 1, 1, false, false, optNone }, + + { "unl_add", &RPCHandler::doUnlAdd, 1, 2, true, false, optNone }, + { "unl_delete", &RPCHandler::doUnlDelete, 1, 1, true, false, optNone }, + { "unl_list", &RPCHandler::doUnlList, 0, 0, true, false, optNone }, + { "unl_load", &RPCHandler::doUnlLoad, 0, 0, true, false, optNone }, + { "unl_network", &RPCHandler::doUnlNetwork, 0, 0, true, false, optNone }, + { "unl_reset", &RPCHandler::doUnlReset, 0, 0, true, false, optNone }, + { "unl_score", &RPCHandler::doUnlScore, 0, 0, true, false, optNone }, + + { "validation_create", &RPCHandler::doValidationCreate, 0, 1, false, false, optNone }, + { "validation_seed", &RPCHandler::doValidationSeed, 0, 1, false, false, optNone }, + + { "wallet_accounts", &RPCHandler::doWalletAccounts, 1, 1, false, false, optCurrent }, + { "wallet_propose", &RPCHandler::doWalletPropose, 0, 1, false, false, optNone }, + { "wallet_seed", &RPCHandler::doWalletSeed, 0, 1, false, false, optNone }, + + { "login", &RPCHandler::doLogin, 2, 2, true, false, optNone }, + + // Evented methods + { "subscribe", &RPCHandler::doSubscribe, -1, -1, false, true, optNone }, + { "unsubscribe", &RPCHandler::doUnsubscribe, -1, -1, false, true, optNone }, + }; + + int i = NUMBER(commandsA); + + while (i-- && command != commandsA[i].pCommand) + ; + + if (i < 0) + { + return rpcError(rpcUNKNOWN_COMMAND); + } + else if (commandsA[i].bAdminRequired && mRole != ADMIN) + { + return rpcError(rpcNO_PERMISSION); + } + else if (commandsA[i].bEvented && mInfoSub == NULL) + { + return rpcError(rpcNO_EVENTS); + } + else if (commandsA[i].iMinParams >= 0 + ? commandsA[i].iMaxParams + ? (params.size() < commandsA[i].iMinParams + || (commandsA[i].iMaxParams >= 0 && params.size() > commandsA[i].iMaxParams)) + : false + : params.isArray()) + { + return rpcError(rpcINVALID_PARAMS); + } + else if ((commandsA[i].iOptions & optNetwork) && !mNetOps->available()) + { + return rpcError(rpcNO_NETWORK); + } + // XXX Should verify we have a current ledger. + + boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock()); + if ((commandsA[i].iOptions & optCurrent) && false) + { + return rpcError(rpcNO_CURRENT); + } + else if ((commandsA[i].iOptions & optClosed) && !mNetOps->getClosedLedger()) + { + return rpcError(rpcNO_CLOSED); + } + else + { + try { + return (this->*(commandsA[i].dfpFunc))(params); + } + catch (std::exception& e) + { + cLog(lsINFO) << "Caught throw: " << e.what(); + + return rpcError(rpcINTERNAL); + } + } +} + // vim:ts=4 diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index 2ac0e3f96c..17671d5b31 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -1,5 +1,5 @@ -#ifndef RPCHANDLER__H -#define RPCHANDLER__H +#ifndef __RPCHANDLER__ +#define __RPCHANDLER__ // used by the RPCServer or WSDoor to carry out these RPC commands class NetworkOPs; @@ -10,7 +10,7 @@ class RPCHandler InfoSub* mInfoSub; int mRole; - typedef Json::Value (RPCHandler::*doFuncPtr)(const Json::Value& params); + typedef Json::Value (RPCHandler::*doFuncPtr)(Json::Value params); enum { optNone = 0, optNetwork = 1, // Need network @@ -21,10 +21,10 @@ class RPCHandler // Utilities void addSubmitPath(Json::Value& txJSON); boost::unordered_set parseAccountIds(const Json::Value& jvArray); - int getParamCount(const Json::Value& params); + int getParamCount(Json::Value params); bool extractString(std::string& param, const Json::Value& params, int index); - Json::Value lookupLedger(const Json::Value& jvRequest, Ledger::pointer& lpLedger); + Json::Value lookupLedger(Json::Value jvRequest, Ledger::pointer& lpLedger); Json::Value getMasterGenerator(const uint256& uLedger, const RippleAddress& naRegularSeed, RippleAddress& naMasterGenerator); Json::Value authorize(const uint256& uLedger, const RippleAddress& naRegularSeed, const RippleAddress& naSrcAccountID, @@ -35,131 +35,71 @@ class RPCHandler Json::Value accountFromString(const uint256& uLedger, RippleAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex); - Json::Value doAcceptLedger(const Json::Value& params); + Json::Value doAcceptLedger(Json::Value jvRequest); - Json::Value doAccountInfo(const Json::Value& params); - Json::Value doAccountTransactions(const Json::Value& params); - Json::Value doConnect(const Json::Value& params); - Json::Value doDataDelete(const Json::Value& params); - Json::Value doDataFetch(const Json::Value& params); - Json::Value doDataStore(const Json::Value& params); - Json::Value doGetCounts(const Json::Value& params); - Json::Value doLedger(const Json::Value& params); - Json::Value doLogRotate(const Json::Value& params); - Json::Value doNicknameInfo(const Json::Value& params); + Json::Value doAccountInfo(Json::Value params); + Json::Value doAccountTransactions(Json::Value params); + Json::Value doConnect(Json::Value params); + Json::Value doDataDelete(Json::Value params); + Json::Value doDataFetch(Json::Value params); + Json::Value doDataStore(Json::Value params); + Json::Value doGetCounts(Json::Value params); + Json::Value doLedger(Json::Value params); + Json::Value doLogRotate(Json::Value params); + Json::Value doNicknameInfo(Json::Value params); - Json::Value doOwnerInfo(const Json::Value& params); + Json::Value doOwnerInfo(Json::Value params); - Json::Value doProfile(const Json::Value& params); - Json::Value doPeers(const Json::Value& params); + Json::Value doProfile(Json::Value params); + Json::Value doPeers(Json::Value params); - Json::Value doRippleLinesGet(const Json::Value& params); - Json::Value doRipplePathFind(const Json::Value& jvRequest); - Json::Value doServerInfo(const Json::Value& params); - Json::Value doSessionClose(const Json::Value& params); - Json::Value doSessionOpen(const Json::Value& params); - Json::Value doLogLevel(const Json::Value& params); - Json::Value doStop(const Json::Value& params); - Json::Value doSubmit(const Json::Value& params); - Json::Value doSubmitJson(const Json::Value& jvRequest); - Json::Value doTx(const Json::Value& params); - Json::Value doTxHistory(const Json::Value& params); + Json::Value doRippleLinesGet(Json::Value params); + Json::Value doRipplePathFind(Json::Value jvRequest); + Json::Value doServerInfo(Json::Value params); + Json::Value doSessionClose(Json::Value params); + Json::Value doSessionOpen(Json::Value params); + Json::Value doLogLevel(Json::Value params); + Json::Value doStop(Json::Value params); + Json::Value doSubmit(Json::Value params); + Json::Value doSubmitJson(Json::Value jvRequest); + Json::Value doTx(Json::Value params); + Json::Value doTxHistory(Json::Value params); - Json::Value doUnlAdd(const Json::Value& params); - Json::Value doUnlDelete(const Json::Value& params); - Json::Value doUnlFetch(const Json::Value& params); - Json::Value doUnlList(const Json::Value& params); - Json::Value doUnlLoad(const Json::Value& params); - Json::Value doUnlNetwork(const Json::Value& params); - Json::Value doUnlReset(const Json::Value& params); - Json::Value doUnlScore(const Json::Value& params); + Json::Value doUnlAdd(Json::Value params); + Json::Value doUnlDelete(Json::Value params); + Json::Value doUnlFetch(Json::Value params); + Json::Value doUnlList(Json::Value params); + Json::Value doUnlLoad(Json::Value params); + Json::Value doUnlNetwork(Json::Value params); + Json::Value doUnlReset(Json::Value params); + Json::Value doUnlScore(Json::Value params); - Json::Value doValidationCreate(const Json::Value& params); - Json::Value doValidationSeed(const Json::Value& params); + Json::Value doValidationCreate(Json::Value params); + Json::Value doValidationSeed(Json::Value params); - Json::Value doWalletAccounts(const Json::Value& params); - Json::Value doWalletLock(const Json::Value& params); - Json::Value doWalletPropose(const Json::Value& params); - Json::Value doWalletSeed(const Json::Value& params); - Json::Value doWalletUnlock(const Json::Value& params); - Json::Value doWalletVerify(const Json::Value& params); + Json::Value doWalletAccounts(Json::Value params); + Json::Value doWalletLock(Json::Value params); + Json::Value doWalletPropose(Json::Value params); + Json::Value doWalletSeed(Json::Value params); + Json::Value doWalletUnlock(Json::Value params); + Json::Value doWalletVerify(Json::Value params); - Json::Value doLogin(const Json::Value& params); + Json::Value doLogin(Json::Value params); - Json::Value doLedgerAccept(const Json::Value& params); - Json::Value doLedgerClosed(const Json::Value& params); - Json::Value doLedgerCurrent(const Json::Value& params); - Json::Value doLedgerEntry(const Json::Value& params); - Json::Value doLedgerHeader(const Json::Value& params); - Json::Value doTransactionEntry(const Json::Value& params); + Json::Value doLedgerAccept(Json::Value params); + Json::Value doLedgerClosed(Json::Value params); + Json::Value doLedgerCurrent(Json::Value params); + Json::Value doLedgerEntry(Json::Value params); + Json::Value doLedgerHeader(Json::Value params); + Json::Value doTransactionEntry(Json::Value params); - Json::Value doSubscribe(const Json::Value& params); - Json::Value doUnsubscribe(const Json::Value& params); + Json::Value doSubscribe(Json::Value params); + Json::Value doUnsubscribe(Json::Value params); public: - enum { - rpcSUCCESS, - - // Misc failure - rpcLOAD_FAILED, - rpcNO_PERMISSION, - rpcNO_EVENTS, - rpcNOT_STANDALONE, - - // Networking - rpcNO_CLOSED, - rpcNO_CURRENT, - rpcNO_NETWORK, - - // Ledger state - rpcACT_EXISTS, - rpcACT_NOT_FOUND, - rpcINSUF_FUNDS, - rpcLGR_NOT_FOUND, - rpcNICKNAME_MISSING, - rpcNO_ACCOUNT, - rpcNO_PATH, - rpcPASSWD_CHANGED, - rpcSRC_MISSING, - rpcSRC_UNCLAIMED, - rpcTXN_NOT_FOUND, - rpcWRONG_SEED, - - // Malformed command - rpcINVALID_PARAMS, - rpcUNKNOWN_COMMAND, - - // Bad parameter - rpcACT_MALFORMED, - rpcQUALITY_MALFORMED, - rpcBAD_SEED, - rpcDST_ACT_MALFORMED, - rpcDST_ACT_MISSING, - rpcDST_AMT_MALFORMED, - rpcGETS_ACT_MALFORMED, - rpcGETS_AMT_MALFORMED, - rpcHOST_IP_MALFORMED, - rpcLGR_IDXS_INVALID, - rpcLGR_IDX_MALFORMED, - rpcNICKNAME_MALFORMED, - rpcNICKNAME_PERM, - rpcPAYS_ACT_MALFORMED, - rpcPAYS_AMT_MALFORMED, - rpcPORT_MALFORMED, - rpcPUBLIC_MALFORMED, - rpcSRC_ACT_MALFORMED, - rpcSRC_ACT_MISSING, - rpcSRC_AMT_MALFORMED, - - // Internal error (should never happen) - rpcINTERNAL, // Generic internal error. - rpcFAIL_GEN_DECRPYT, - rpcNOT_IMPL, - rpcNO_GEN_DECRPYT, - }; enum { GUEST, USER, ADMIN }; @@ -167,10 +107,8 @@ public: RPCHandler(NetworkOPs* netOps, InfoSub* infoSub); Json::Value doCommand(const std::string& command, Json::Value& params, int role); - Json::Value rpcError(int iError); - - Json::Value handleJSONSubmit(const Json::Value& jvRequest); + Json::Value handleJSONSubmit(Json::Value jvRequest); }; #endif diff --git a/src/cpp/ripple/RippleLines.cpp b/src/cpp/ripple/RippleLines.cpp index c15d12b97e..8d0a79af50 100644 --- a/src/cpp/ripple/RippleLines.cpp +++ b/src/cpp/ripple/RippleLines.cpp @@ -12,12 +12,12 @@ RippleLines::RippleLines(const uint160& accountID, Ledger::ref ledger) fillLines(accountID, ledger); } -void RippleLines::printRippleLines() +void RippleLines::printRippleLines() { for (unsigned int i =0; i < mLines.size(); i++) { - std::cout << i << ": " << mLines[i]->getAccountID().humanAccountID() << std::endl; + std::cerr << i << ": " << mLines[i]->getAccountID().humanAccountID() << std::endl; } - std::cout << std::endl; + std::cerr << std::endl; } RippleLines::RippleLines(const uint160& accountID ) diff --git a/src/cpp/ripple/SerializedTypes.cpp b/src/cpp/ripple/SerializedTypes.cpp index d56dd43d6f..11ed9794b2 100644 --- a/src/cpp/ripple/SerializedTypes.cpp +++ b/src/cpp/ripple/SerializedTypes.cpp @@ -30,25 +30,25 @@ SerializedType& SerializedType::operator=(const SerializedType& t) void STPathSet::printDebug() { for (int i = 0; i < value.size(); i++) { - std::cout << i << ": "; + std::cerr << i << ": "; for (int j = 0; j < value[i].mPath.size(); j++) { //STPathElement pe = value[i].mPath[j]; RippleAddress nad; nad.setAccountID(value[i].mPath[j].mAccountID); - std::cout << " " << nad.humanAccountID(); - //std::cout << " " << pe.mAccountID.GetHex(); + std::cerr << " " << nad.humanAccountID(); + //std::cerr << " " << pe.mAccountID.GetHex(); } - std::cout << std::endl; + std::cerr << std::endl; } } void STPath::printDebug() { - std::cout << "STPath:" << std::endl; + std::cerr << "STPath:" << std::endl; for(int i =0; i < mPath.size(); i++) { RippleAddress nad; nad.setAccountID(mPath[i].mAccountID); - std::cout << " " << i << ": " << nad.humanAccountID() << std::endl; + std::cerr << " " << i << ": " << nad.humanAccountID() << std::endl; } } From 78cd14234320eeb1b73e0bd8a5e17d8150334751 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 1 Dec 2012 18:00:27 -0800 Subject: [PATCH 03/24] Move RPC errors to own files. --- src/cpp/ripple/RPCErr.cpp | 81 +++++++++++++++++++++++++++++++++++++++ src/cpp/ripple/RPCErr.h | 71 ++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 src/cpp/ripple/RPCErr.cpp create mode 100644 src/cpp/ripple/RPCErr.h diff --git a/src/cpp/ripple/RPCErr.cpp b/src/cpp/ripple/RPCErr.cpp new file mode 100644 index 0000000000..cc0e6ba17a --- /dev/null +++ b/src/cpp/ripple/RPCErr.cpp @@ -0,0 +1,81 @@ + +#include "Log.h" + +#include "RPCErr.h" +#include "utils.h" + +#include "../json/writer.h" + +SETUP_LOG(); + +Json::Value rpcError(int iError, Json::Value jvResult) +{ + static struct { + int iError; + const char* pToken; + const char* pMessage; + } errorInfoA[] = { + { rpcACT_EXISTS, "actExists", "Account already exists." }, + { rpcACT_MALFORMED, "actMalformed", "Account malformed." }, + { rpcACT_NOT_FOUND, "actNotFound", "Account not found." }, + { rpcBAD_SEED, "badSeed", "Disallowed seed." }, + { rpcBAD_SYNTAX, "badSyntax", "Syntax error." }, + { rpcDST_ACT_MALFORMED, "dstActMalformed", "Destination account is malformed." }, + { rpcDST_ACT_MISSING, "dstActMissing", "Destination account does not exists." }, + { rpcDST_AMT_MALFORMED, "dstAmtMalformed", "Destination amount/currency/issuer is malformed." }, + { rpcFAIL_GEN_DECRPYT, "failGenDecrypt", "Failed to decrypt generator." }, + { rpcGETS_ACT_MALFORMED, "getsActMalformed", "Gets account malformed." }, + { rpcGETS_AMT_MALFORMED, "getsAmtMalformed", "Gets amount malformed." }, + { rpcHOST_IP_MALFORMED, "hostIpMalformed", "Host IP is malformed." }, + { rpcINSUF_FUNDS, "insufFunds", "Insufficient funds." }, + { rpcINTERNAL, "internal", "Internal error." }, + { rpcINVALID_PARAMS, "invalidParams", "Invalid parameters." }, + { rpcLGR_IDXS_INVALID, "lgrIdxsInvalid", "Ledger indexes invalid." }, + { rpcLGR_IDX_MALFORMED, "lgrIdxMalformed", "Ledger index malformed." }, + { rpcLGR_NOT_FOUND, "lgrNotFound", "Ledger not found." }, + { rpcNICKNAME_MALFORMED, "nicknameMalformed","Nickname is malformed." }, + { rpcNICKNAME_MISSING, "nicknameMissing", "Nickname does not exist." }, + { rpcNICKNAME_PERM, "nicknamePerm", "Account does not control nickname." }, + { rpcNOT_IMPL, "notImpl", "Not implemented." }, + { rpcNO_ACCOUNT, "noAccount", "No such account." }, + { rpcNO_CLOSED, "noClosed", "Closed ledger is unavailable." }, + { rpcNO_CURRENT, "noCurrent", "Current ledger is unavailable." }, + { rpcNO_EVENTS, "noEvents", "Current transport does not support events." }, + { rpcNO_GEN_DECRPYT, "noGenDectypt", "Password failed to decrypt master public generator." }, + { rpcNO_NETWORK, "noNetwork", "Network not available." }, + { rpcNO_PATH, "noPath", "Unable to find a ripple path." }, + { rpcNO_PERMISSION, "noPermission", "You don't have permission for this command." }, + { rpcNOT_STANDALONE, "notStandAlone", "Operation valid in debug mode only." }, + { rpcPASSWD_CHANGED, "passwdChanged", "Wrong key, password changed." }, + { rpcPAYS_ACT_MALFORMED, "paysActMalformed", "Pays account malformed." }, + { rpcPAYS_AMT_MALFORMED, "paysAmtMalformed", "Pays amount malformed." }, + { rpcPORT_MALFORMED, "portMalformed", "Port is malformed." }, + { rpcPUBLIC_MALFORMED, "publicMalformed", "Public key is malformed." }, + { rpcQUALITY_MALFORMED, "qualityMalformed", "Quality malformed." }, + { rpcSRC_ACT_MALFORMED, "srcActMalformed", "Source account is malformed." }, + { rpcSRC_ACT_MISSING, "srcActMissing", "Source account does not exist." }, + { rpcSRC_AMT_MALFORMED, "srcAmtMalformed", "Source amount/currency/issuer is malformed." }, + { rpcSRC_UNCLAIMED, "srcUnclaimed", "Source account is not claimed." }, + { rpcSUCCESS, "success", "Success." }, + { rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found." }, + { rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown command." }, + { rpcWRONG_SEED, "wrongSeed", "The regular key does not point as the master key." }, + }; + + int i; + + for (i=NUMBER(errorInfoA); i-- && errorInfoA[i].iError != iError;) + ; + + jvResult["error"] = i >= 0 ? errorInfoA[i].pToken : lexical_cast_i(iError); + jvResult["error_message"] = i >= 0 ? errorInfoA[i].pMessage : lexical_cast_i(iError); + jvResult["error_code"] = iError; + + if (i >= 0) + cLog(lsDEBUG) << "rpcError: " + << errorInfoA[i].pToken << ": " << errorInfoA[i].pMessage << std::endl; + + return jvResult; +} + +// vim:ts=4 diff --git a/src/cpp/ripple/RPCErr.h b/src/cpp/ripple/RPCErr.h new file mode 100644 index 0000000000..d22b66b02f --- /dev/null +++ b/src/cpp/ripple/RPCErr.h @@ -0,0 +1,71 @@ +#ifndef __RPCERR__ +#define __RPCERR__ + +#include "../json/value.h" + +enum { + rpcSUCCESS, + + rpcBAD_SYNTAX, // Must be 1 to print usage to command line. + + // Misc failure + rpcLOAD_FAILED, + rpcNO_PERMISSION, + rpcNO_EVENTS, + rpcNOT_STANDALONE, + + // Networking + rpcNO_CLOSED, + rpcNO_CURRENT, + rpcNO_NETWORK, + + // Ledger state + rpcACT_EXISTS, + rpcACT_NOT_FOUND, + rpcINSUF_FUNDS, + rpcLGR_NOT_FOUND, + rpcNICKNAME_MISSING, + rpcNO_ACCOUNT, + rpcNO_PATH, + rpcPASSWD_CHANGED, + rpcSRC_MISSING, + rpcSRC_UNCLAIMED, + rpcTXN_NOT_FOUND, + rpcWRONG_SEED, + + // Malformed command + rpcINVALID_PARAMS, + rpcUNKNOWN_COMMAND, + + // Bad parameter + rpcACT_MALFORMED, + rpcQUALITY_MALFORMED, + rpcBAD_SEED, + rpcDST_ACT_MALFORMED, + rpcDST_ACT_MISSING, + rpcDST_AMT_MALFORMED, + rpcGETS_ACT_MALFORMED, + rpcGETS_AMT_MALFORMED, + rpcHOST_IP_MALFORMED, + rpcLGR_IDXS_INVALID, + rpcLGR_IDX_MALFORMED, + rpcNICKNAME_MALFORMED, + rpcNICKNAME_PERM, + rpcPAYS_ACT_MALFORMED, + rpcPAYS_AMT_MALFORMED, + rpcPORT_MALFORMED, + rpcPUBLIC_MALFORMED, + rpcSRC_ACT_MALFORMED, + rpcSRC_ACT_MISSING, + rpcSRC_AMT_MALFORMED, + + // Internal error (should never happen) + rpcINTERNAL, // Generic internal error. + rpcFAIL_GEN_DECRPYT, + rpcNOT_IMPL, + rpcNO_GEN_DECRPYT, +}; + +Json::Value rpcError(int iError, Json::Value jvResult=Json::Value(Json::objectValue)); +#endif +// vim:ts=4 From d0e30b29d8773442b84efddd581924af9ff7741c Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 1 Dec 2012 18:01:21 -0800 Subject: [PATCH 04/24] Do not use cout. --- src/cpp/ripple/RPCServer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpp/ripple/RPCServer.cpp b/src/cpp/ripple/RPCServer.cpp index 3b87189a01..16daa4abc2 100644 --- a/src/cpp/ripple/RPCServer.cpp +++ b/src/cpp/ripple/RPCServer.cpp @@ -36,7 +36,7 @@ RPCServer::RPCServer(boost::asio::io_service& io_service , NetworkOPs* nopNetwor void RPCServer::connected() { - //std::cout << "RPC request" << std::endl; + //std::cerr << "RPC request" << std::endl; if (mSocket.remote_endpoint().address().to_string()=="127.0.0.1") mRole = RPCHandler::ADMIN; else mRole = RPCHandler::GUEST; @@ -145,7 +145,7 @@ std::string RPCServer::handleRequest(const std::string& requestStr) RPCHandler mRPCHandler(mNetOps); cLog(lsTRACE) << valParams; - Json::Value result = mRPCHandler.doCommand(strMethod, valParams,mRole); + Json::Value result = mRPCHandler.doCommand(strMethod, valParams, mRole); cLog(lsTRACE) << result; std::string strReply = JSONRPCReply(result, Json::Value(), id); @@ -167,7 +167,7 @@ bool RPCServer::parseAcceptRate(const std::string& sAcceptRate) void RPCServer::handle_write(const boost::system::error_code& e) { - //std::cout << "async_write complete " << e << std::endl; + //std::cerr << "async_write complete " << e << std::endl; if (!e) { From 8ffea0530a1b636b59a0c434d508dfa7534cf88c Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 1 Dec 2012 18:01:59 -0800 Subject: [PATCH 05/24] Begin moving CLI parsing to CallRPC. --- src/cpp/ripple/CallRPC.cpp | 194 +++++++++++++++++++++++++++++-------- src/cpp/ripple/CallRPC.h | 18 ++++ 2 files changed, 170 insertions(+), 42 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index a8337198e4..436f9c824a 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -13,11 +13,16 @@ #include "../json/value.h" #include "../json/reader.h" -#include "CallRPC.h" #include "RPC.h" +#include "Log.h" +#include "RPCErr.h" #include "Config.h" #include "BitcoinUtil.h" +#include "CallRPC.h" + +SETUP_LOG(); + static inline bool isSwitchChar(char c) { #ifdef __WXMSW__ @@ -46,73 +51,175 @@ std::string EncodeBase64(const std::string& s) return result; } +Json::Value RPCParser::parseAsIs(Json::Value jvReq, const Json::Value ¶ms) +{ + return jvReq; +} + +// Convert a command plus args to a json request. +Json::Value RPCParser::parseCommand(Json::Value jvRequest) +{ + std::string strCommand = jvRequest["method"].asString(); + Json::Value jvParams = jvRequest["params"]; + + cLog(lsTRACE) << "RPC:" << strCommand; + cLog(lsTRACE) << "RPC params:" << jvParams; + + static struct { + const char* pCommand; + parseFuncPtr pfpFunc; + int iMinParams; + int iMaxParams; + } commandsA[] = { + // Request-response methods + { "accept_ledger", &RPCParser::parseAsIs, 0, 0 }, +#if 0 + { "account_info", &RPCParser::doAccountInfo, 1, 2, false, false, optCurrent }, + { "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 }, + { "data_store", &RPCParser::doDataStore, 2, 2, true, false, optNone }, + { "get_counts", &RPCParser::doGetCounts, 0, 1, true, false, optNone }, + { "ledger", &RPCParser::doLedger, 0, 2, false, false, optNetwork }, + { "ledger_accept", &RPCParser::doLedgerAccept, 0, 0, true, false, optCurrent }, + { "ledger_closed", &RPCParser::doLedgerClosed, 0, 0, false, false, optClosed }, + { "ledger_current", &RPCParser::doLedgerCurrent, 0, 0, false, false, optCurrent }, + { "ledger_entry", &RPCParser::doLedgerEntry, -1, -1, false, false, optCurrent }, + { "ledger_header", &RPCParser::doLedgerHeader, -1, -1, false, false, optCurrent }, + { "log_level", &RPCParser::doLogLevel, 0, 2, true, false, optNone }, + { "logrotate", &RPCParser::doLogRotate, 0, 0, true, false, optNone }, + { "nickname_info", &RPCParser::doNicknameInfo, 1, 1, false, false, optCurrent }, + { "owner_info", &RPCParser::doOwnerInfo, 1, 2, false, false, optCurrent }, + { "peers", &RPCParser::doPeers, 0, 0, true, false, optNone }, + { "profile", &RPCParser::doProfile, 1, 9, false, false, optCurrent }, + { "ripple_lines_get", &RPCParser::doRippleLinesGet, 1, 2, false, false, optCurrent }, + { "ripple_path_find", &RPCParser::doRipplePathFind, -1, -1, false, false, optCurrent }, + { "submit", &RPCParser::doSubmit, 2, 2, false, false, optCurrent }, + { "submit_json", &RPCParser::doSubmitJson, -1, -1, false, false, optCurrent }, + { "server_info", &RPCParser::doServerInfo, 0, 0, true, false, optNone }, + { "stop", &RPCParser::doStop, 0, 0, true, false, optNone }, + { "transaction_entry", &RPCParser::doTransactionEntry, -1, -1, false, false, optCurrent }, + { "tx", &RPCParser::doTx, 1, 1, true, false, optNone }, + { "tx_history", &RPCParser::doTxHistory, 1, 1, false, false, optNone }, + + { "unl_add", &RPCParser::doUnlAdd, 1, 2, true, false, optNone }, + { "unl_delete", &RPCParser::doUnlDelete, 1, 1, true, false, optNone }, + { "unl_list", &RPCParser::doUnlList, 0, 0, true, false, optNone }, + { "unl_load", &RPCParser::doUnlLoad, 0, 0, true, false, optNone }, + { "unl_network", &RPCParser::doUnlNetwork, 0, 0, true, false, optNone }, + { "unl_reset", &RPCParser::doUnlReset, 0, 0, true, false, optNone }, + { "unl_score", &RPCParser::doUnlScore, 0, 0, true, false, optNone }, + + { "validation_create", &RPCParser::doValidationCreate, 0, 1, false, false, optNone }, + { "validation_seed", &RPCParser::doValidationSeed, 0, 1, false, false, optNone }, + + { "wallet_accounts", &RPCParser::doWalletAccounts, 1, 1, false, false, optCurrent }, + { "wallet_propose", &RPCParser::doWalletPropose, 0, 1, false, false, optNone }, + { "wallet_seed", &RPCParser::doWalletSeed, 0, 1, false, false, optNone }, + + { "login", &RPCParser::doLogin, 2, 2, true, false, optNone }, + + // Evented methods + { "subscribe", &RPCParser::doSubscribe, -1, -1, false, true, optNone }, + { "unsubscribe", &RPCParser::doUnsubscribe, -1, -1, false, true, optNone }, +#endif + }; + + int i = NUMBER(commandsA); + + while (i-- && strCommand != commandsA[i].pCommand) + ; + + if (i < 0) + { + return rpcError(rpcBAD_SYNTAX, jvRequest); + } + else if (commandsA[i].iMinParams >= 0 + ? commandsA[i].iMaxParams + ? (jvParams.size() < commandsA[i].iMinParams + || (commandsA[i].iMaxParams >= 0 && jvParams.size() > commandsA[i].iMaxParams)) + : false + : jvParams.isArray()) + { + return rpcError(rpcBAD_SYNTAX, jvRequest); + } + + return (this->*(commandsA[i].pfpFunc))(jvRequest, jvParams); +} + int commandLineRPC(const std::vector& vCmd) { - std::string strPrint; - int nRet = 0; + Json::Value jvOutput; + int nRet = 0; + Json::Value jvRequest(Json::objectValue); + try { - if (vCmd.empty()) return 1; + RPCParser rpParser; + Json::Value jvCliParams(Json::arrayValue); - std::string strMethod = vCmd[0]; + if (vCmd.empty()) return 1; // 1 = print usage. + + jvRequest["method"] = vCmd[0]; - // Parameters default to strings - Json::Value params(Json::arrayValue); for (int i = 1; i != vCmd.size(); i++) - params.append(vCmd[i]); + jvCliParams.append(vCmd[i]); - // Execute - Json::Value reply = callRPC(strMethod, params); + jvRequest["params"] = jvCliParams; - // Parse reply - Json::Value result = reply.get("result", Json::Value()); - Json::Value error = reply.get("error", Json::Value()); + jvRequest = rpParser.parseCommand(jvRequest); - if (result.isString() && (result.asString() == "unknown command")) - nRet=1; + // std::cerr << "Request: " << jvRequest << std::endl; - if (!error.isNull()) - { // Error - strPrint = "error: " + error.toStyledString(); - int code = error["code"].asInt(); - nRet = abs(code); - } - else - { // Result - if (result.isNull()) - strPrint = ""; - else if (result.isString()) - strPrint = result.asString(); - else - strPrint = result.toStyledString(); + Json::Value jvParams(Json::arrayValue); + + jvParams.append(jvRequest); + + Json::Value jvResult; + + jvResult = jvRequest.isMember("error") + ? jvRequest // Parse failed, return error. + : callRPC(jvRequest["method"].asString(), jvParams); // Parsed, execute. + + if (jvResult.isMember("error")) + { + nRet = jvResult.isMember("error_code") + ? lexical_cast_s(jvResult["error_code"].asString()) + : 1; } + + jvOutput = jvResult; } catch (std::exception& e) { - strPrint = std::string("error: ") + e.what(); - nRet = 87; + jvRequest["error_what"] = e.what(); + + jvOutput = rpcError(rpcINTERNAL, jvRequest); + nRet = rpcINTERNAL; } catch (...) { - std::cout << "Exception CommandLineRPC()" << std::endl; + jvRequest["error_what"] = "exception"; + + jvOutput = rpcError(rpcINTERNAL, jvRequest); + nRet = rpcINTERNAL; } - if (strPrint != "") - { - std::cout << strPrint << std::endl; - } + std::cout << jvOutput.toStyledString(); + return nRet; } - Json::Value callRPC(const std::string& strMethod, const Json::Value& params) { if (theConfig.RPC_USER.empty() && theConfig.RPC_PASSWORD.empty()) - throw std::runtime_error("You must set rpcpassword= in the configuration file" + throw std::runtime_error("You must set rpcpassword= in the configuration file. " "If the file does not exist, create it with owner-readable-only file permissions."); // Connect to localhost - std::cout << "Connecting to: " << theConfig.RPC_IP << ":" << theConfig.RPC_PORT << std::endl; + if (!theConfig.QUIET) + std::cerr << "Connecting to: " << theConfig.RPC_IP << ":" << theConfig.RPC_PORT << std::endl; boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(theConfig.RPC_IP), theConfig.RPC_PORT); @@ -128,11 +235,11 @@ Json::Value callRPC(const std::string& strMethod, const Json::Value& params) // Send request std::string strRequest = JSONRPCRequest(strMethod, params, Json::Value(1)); - std::cout << "send request " << strMethod << " : " << strRequest << std::endl; + cLog(lsDEBUG) << "send request " << strMethod << " : " << strRequest << std::endl; std::string strPost = createHTTPPost(strRequest, mapRequestHeaders); stream << strPost << std::flush; - // std::cout << "post " << strPost << std::endl; + // std::cerr << "post " << strPost << std::endl; // Receive reply std::map mapHeaders; @@ -146,11 +253,14 @@ Json::Value callRPC(const std::string& strMethod, const Json::Value& params) throw std::runtime_error("no response from server"); // Parse reply - std::cout << "RPC reply: " << strReply << std::endl; + cLog(lsDEBUG) << "RPC reply: " << strReply << std::endl; + Json::Reader reader; Json::Value valReply; + if (!reader.parse(strReply, valReply)) throw std::runtime_error("couldn't parse reply from server"); + if (valReply.isNull()) throw std::runtime_error("expected reply to have result, error and id properties"); diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index ac6fc3dae2..cbe288c185 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -1,7 +1,25 @@ +#ifndef __CALLRPC__ +#define __CALLRPC__ + #include #include "../json/value.h" +class RPCParser +{ +protected: + typedef Json::Value (RPCParser::*parseFuncPtr)(Json::Value jvRet, const Json::Value &jvParams); + + Json::Value parseAsIs(Json::Value jvRet, const Json::Value &jvParams); + +public: + Json::Value parseCommand(Json::Value jvRequest); +}; + extern int commandLineRPC(const std::vector& vCmd); extern Json::Value callRPC(const std::string& strMethod, const Json::Value& params); + +#endif + +// vim:ts=4 From e737dd16c54dfd08ca15a89675e552641a5556b5 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 2 Dec 2012 15:52:54 -0800 Subject: [PATCH 06/24] Do not output usage if --quiet. --- src/cpp/ripple/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ripple/main.cpp b/src/cpp/ripple/main.cpp index 6449079d25..7089b20329 100644 --- a/src/cpp/ripple/main.cpp +++ b/src/cpp/ripple/main.cpp @@ -187,7 +187,7 @@ int main(int argc, char* argv[]) iResult = commandLineRPC(vCmd); } - if (1 == iResult) + if (1 == iResult && !vm.count("quiet")) printHelp(desc); return iResult; From fed1250218e2d6c683975e081df5f4c9eb8d4d4e Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 2 Dec 2012 16:05:45 -0800 Subject: [PATCH 07/24] Regularize RPC handling. --- src/cpp/ripple/RPCHandler.cpp | 40 ++++++++++++++++++++++----------- src/cpp/ripple/RPCHandler.h | 3 ++- src/cpp/ripple/RPCServer.cpp | 2 +- src/cpp/ripple/WSConnection.cpp | 26 ++++++++++++++++----- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index e2a5d1c951..2474ee5373 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -317,9 +317,6 @@ Json::Value RPCHandler::doAccountInfo(Json::Value params) return ret; } - - - Json::Value RPCHandler::doConnect(Json::Value params) { if (theConfig.RUN_STANDALONE) @@ -458,7 +455,6 @@ Json::Value RPCHandler::doOwnerInfo(Json::Value params) return ret; } - Json::Value RPCHandler::doPeers(Json::Value params) { Json::Value obj(Json::objectValue); @@ -2140,14 +2136,31 @@ Json::Value RPCHandler::doUnsubscribe(Json::Value jvRequest) return jvResult; } -Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& params, int role) +Json::Value RPCHandler::doRpcCommand(const std::string& strCommand, Json::Value& jvParams, int iRole) { - cLog(lsTRACE) << "RPC:" << command; - cLog(lsTRACE) << "RPC params:" << params; + if (!jvParams.isArray() || jvParams.size() > 1) + return rpcError(rpcINVALID_PARAMS); + + Json::Value jvRequest = jvParams[0u]; + + jvRequest["command"] = strCommand; + + return doCommand(jvRequest, iRole); +} + +Json::Value RPCHandler::doCommand(Json::Value& jvParams, int iRole) +{ + if (!jvParams.isMember("command")) + return rpcError(rpcINVALID_PARAMS); + + std::string strCommand = jvParams["command"].asString(); + + cLog(lsTRACE) << "COMMAND:" << strCommand; + cLog(lsTRACE) << "REQUEST:" << jvParams; LoadEvent::autoptr le(theApp->getJobQueue().getLoadEventAP(jtRPC)); - mRole = role; + mRole = iRole; static struct { const char* pCommand; @@ -2213,7 +2226,7 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param int i = NUMBER(commandsA); - while (i-- && command != commandsA[i].pCommand) + while (i-- && strCommand != commandsA[i].pCommand) ; if (i < 0) @@ -2230,11 +2243,12 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param } else if (commandsA[i].iMinParams >= 0 ? commandsA[i].iMaxParams - ? (params.size() < commandsA[i].iMinParams - || (commandsA[i].iMaxParams >= 0 && params.size() > commandsA[i].iMaxParams)) + ? (jvParams.size() < commandsA[i].iMinParams + || (commandsA[i].iMaxParams >= 0 && jvParams.size() > commandsA[i].iMaxParams)) : false - : params.isArray()) + : jvParams.isArray()) { +cLog(lsDEBUG) << "params.size: " << jvParams.size() << " array: " << jvParams.isArray(); return rpcError(rpcINVALID_PARAMS); } else if ((commandsA[i].iOptions & optNetwork) && !mNetOps->available()) @@ -2255,7 +2269,7 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param else { try { - return (this->*(commandsA[i].dfpFunc))(params); + return (this->*(commandsA[i].dfpFunc))(jvParams); } catch (std::exception& e) { diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index 17671d5b31..4867955a7f 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -106,7 +106,8 @@ public: RPCHandler(NetworkOPs* netOps); RPCHandler(NetworkOPs* netOps, InfoSub* infoSub); - Json::Value doCommand(const std::string& command, Json::Value& params, int role); + Json::Value doCommand(Json::Value& jvRequest, int role); + Json::Value doRpcCommand(const std::string& strCommand, Json::Value& jvParams, int iRole); Json::Value handleJSONSubmit(Json::Value jvRequest); }; diff --git a/src/cpp/ripple/RPCServer.cpp b/src/cpp/ripple/RPCServer.cpp index 16daa4abc2..98e7e0399e 100644 --- a/src/cpp/ripple/RPCServer.cpp +++ b/src/cpp/ripple/RPCServer.cpp @@ -145,7 +145,7 @@ std::string RPCServer::handleRequest(const std::string& requestStr) RPCHandler mRPCHandler(mNetOps); cLog(lsTRACE) << valParams; - Json::Value result = mRPCHandler.doCommand(strMethod, valParams, mRole); + Json::Value result = mRPCHandler.doRpcCommand(strMethod, valParams, mRole); cLog(lsTRACE) << result; std::string strReply = JSONRPCReply(result, Json::Value(), id); diff --git a/src/cpp/ripple/WSConnection.cpp b/src/cpp/ripple/WSConnection.cpp index 875b18942f..59bb17751e 100644 --- a/src/cpp/ripple/WSConnection.cpp +++ b/src/cpp/ripple/WSConnection.cpp @@ -6,6 +6,7 @@ SETUP_LOG(); +#include "CallRPC.h" // XXX Remove this, don't provide support for RPC syntax. #include "WSConnection.h" #include "WSHandler.h" @@ -48,13 +49,28 @@ Json::Value WSConnection::invokeCommand(Json::Value& jvRequest) RPCHandler mRPCHandler(&mNetwork, this); Json::Value jvResult(Json::objectValue); - // Regular RPC command + // XXX Temporarily support RPC style commands over websocket. Remove this. + if (jvRequest.isMember("params")) + { + RPCParser rpParser; + + Json::Value jvRpcRequest = rpParser.parseCommand(jvRequest["command"].asString(), jvRequest["params"]); + + if (jvRpcRequest.isMember("error")) + { + jvResult = jvRpcRequest; + } + else + { + jvResult["result"] = mRPCHandler.doCommand( + jvRpcRequest, + mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN); + } + } + else { jvResult["result"] = mRPCHandler.doCommand( - jvRequest["command"].asString(), - jvRequest.isMember("params") - ? jvRequest["params"] - : jvRequest, + jvRequest, mHandler->getPublic() ? RPCHandler::GUEST : RPCHandler::ADMIN); } From ee3a2a08576a06de127e711baf98c5139300b8d1 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 2 Dec 2012 16:06:20 -0800 Subject: [PATCH 08/24] Regularize RPC calling. --- src/cpp/ripple/CallRPC.cpp | 96 ++++++++++++++++++++------------------ src/cpp/ripple/CallRPC.h | 6 +-- 2 files changed, 53 insertions(+), 49 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 436f9c824a..e4856b7213 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -51,18 +51,16 @@ std::string EncodeBase64(const std::string& s) return result; } -Json::Value RPCParser::parseAsIs(Json::Value jvReq, const Json::Value ¶ms) +Json::Value RPCParser::parseAsIs(const Json::Value ¶ms) { - return jvReq; + return Json::Value(Json::objectValue); } -// Convert a command plus args to a json request. -Json::Value RPCParser::parseCommand(Json::Value 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) { - std::string strCommand = jvRequest["method"].asString(); - Json::Value jvParams = jvRequest["params"]; - - cLog(lsTRACE) << "RPC:" << strCommand; + cLog(lsTRACE) << "RPC method:" << strMethod; cLog(lsTRACE) << "RPC params:" << jvParams; static struct { @@ -128,24 +126,20 @@ Json::Value RPCParser::parseCommand(Json::Value jvRequest) int i = NUMBER(commandsA); - while (i-- && strCommand != commandsA[i].pCommand) + while (i-- && strMethod != commandsA[i].pCommand) ; if (i < 0) { - return rpcError(rpcBAD_SYNTAX, jvRequest); + return rpcError(rpcBAD_SYNTAX); } - else if (commandsA[i].iMinParams >= 0 - ? commandsA[i].iMaxParams - ? (jvParams.size() < commandsA[i].iMinParams - || (commandsA[i].iMaxParams >= 0 && jvParams.size() > commandsA[i].iMaxParams)) - : false - : jvParams.isArray()) + else if ((commandsA[i].iMinParams >= 0 && jvParams.size() < commandsA[i].iMinParams) + || (commandsA[i].iMaxParams >= 0 && jvParams.size() > commandsA[i].iMaxParams)) { - return rpcError(rpcBAD_SYNTAX, jvRequest); + return rpcError(rpcBAD_SYNTAX); } - return (this->*(commandsA[i].pfpFunc))(jvRequest, jvParams); + return (this->*(commandsA[i].pfpFunc))(jvParams); } int commandLineRPC(const std::vector& vCmd) @@ -157,53 +151,63 @@ int commandLineRPC(const std::vector& vCmd) try { RPCParser rpParser; - Json::Value jvCliParams(Json::arrayValue); + Json::Value jvRpcParams(Json::arrayValue); if (vCmd.empty()) return 1; // 1 = print usage. - jvRequest["method"] = vCmd[0]; - for (int i = 1; i != vCmd.size(); i++) - jvCliParams.append(vCmd[i]); + jvRpcParams.append(vCmd[i]); - jvRequest["params"] = jvCliParams; + Json::Value jvRpc = Json::Value(Json::objectValue); - jvRequest = rpParser.parseCommand(jvRequest); + jvRpc["method"] = vCmd[0]; + jvRpc["params"] = jvRpcParams; + + jvRequest = rpParser.parseCommand(vCmd[0], jvRpcParams); // std::cerr << "Request: " << jvRequest << std::endl; - Json::Value jvParams(Json::arrayValue); - - jvParams.append(jvRequest); - - Json::Value jvResult; - - jvResult = jvRequest.isMember("error") - ? jvRequest // Parse failed, return error. - : callRPC(jvRequest["method"].asString(), jvParams); // Parsed, execute. - - if (jvResult.isMember("error")) + if (jvRequest.isMember("error")) { - nRet = jvResult.isMember("error_code") - ? lexical_cast_s(jvResult["error_code"].asString()) + jvOutput = jvRequest; + jvOutput["status"] = "error"; + jvOutput["rpc"] = jvRpc; + } + else + { + jvOutput = callRPC( + jvRequest.isMember("method") + ? jvRequest["method"].asString() + : vCmd[0], + jvRequest["params"]); // Parsed, execute. + + if (jvOutput.isMember("error")) + { + jvOutput["rpc"] = jvRpc; + } + } + + if (jvOutput.isMember("error")) + { + nRet = jvOutput.isMember("error_code") + ? lexical_cast_s(jvOutput["error_code"].asString()) : 1; } - jvOutput = jvResult; + // YYY We could have a command line flag for single line output for scripts. + // YYY We would intercept output here and simplify it. } catch (std::exception& e) { - jvRequest["error_what"] = e.what(); - - jvOutput = rpcError(rpcINTERNAL, jvRequest); - nRet = rpcINTERNAL; + jvOutput = rpcError(rpcINTERNAL); + jvOutput["error_what"] = e.what(); + nRet = rpcINTERNAL; } catch (...) { - jvRequest["error_what"] = "exception"; - - jvOutput = rpcError(rpcINTERNAL, jvRequest); - nRet = rpcINTERNAL; + jvOutput = rpcError(rpcINTERNAL); + jvOutput["error_what"] = "exception"; + nRet = rpcINTERNAL; } std::cout << jvOutput.toStyledString(); diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index cbe288c185..4247908b1e 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -9,12 +9,12 @@ class RPCParser { protected: - typedef Json::Value (RPCParser::*parseFuncPtr)(Json::Value jvRet, const Json::Value &jvParams); + typedef Json::Value (RPCParser::*parseFuncPtr)(const Json::Value &jvParams); - Json::Value parseAsIs(Json::Value jvRet, const Json::Value &jvParams); + Json::Value parseAsIs(const Json::Value &jvParams); public: - Json::Value parseCommand(Json::Value jvRequest); + Json::Value parseCommand(std::string strMethod, Json::Value jvParams); }; extern int commandLineRPC(const std::vector& vCmd); From f3bbe07572800601c835c1aea21aba6746be6889 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 2 Dec 2012 16:47:44 -0800 Subject: [PATCH 09/24] Refactor RPC account_info. --- src/cpp/ripple/CallRPC.cpp | 34 +++++++++++++++++++++++++---- src/cpp/ripple/CallRPC.h | 1 + src/cpp/ripple/RPCHandler.cpp | 40 ++++++++++++++++++++--------------- 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index e4856b7213..a48e834e16 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -56,6 +56,26 @@ Json::Value RPCParser::parseAsIs(const Json::Value ¶ms) return Json::Value(Json::objectValue); } +// account_info || +// account_info || [] +Json::Value RPCParser::parseAccountInfo(const Json::Value &jvParams) +{ + Json::Value jvRequest(Json::objectValue); + std::string strIdent = jvParams[0u].asString(); + // YYY This could be more strict and report casting errors. + int iIndex = 2 == jvParams.size() ? lexical_cast_s(jvParams[1u].asString()) : 0; + + RippleAddress raAddress; + + if (!raAddress.setAccountPublic(strIdent) && !raAddress.setAccountID(strIdent) && !raAddress.setSeedGeneric(strIdent)) + return rpcError(rpcACT_MALFORMED); + + jvRequest["ident"] = strIdent; + jvRequest["index"] = iIndex; + + 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) @@ -70,9 +90,11 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) int iMaxParams; } commandsA[] = { // Request-response methods - { "accept_ledger", &RPCParser::parseAsIs, 0, 0 }, + // - 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 }, #if 0 - { "account_info", &RPCParser::doAccountInfo, 1, 2, false, false, optCurrent }, { "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 }, @@ -175,11 +197,15 @@ int commandLineRPC(const std::vector& vCmd) } else { + Json::Value jvParams(Json::arrayValue); + + jvParams.append(jvRequest); + jvOutput = callRPC( - jvRequest.isMember("method") + jvRequest.isMember("method") // Allow parser to rewrite method. ? jvRequest["method"].asString() : vCmd[0], - jvRequest["params"]); // Parsed, execute. + jvParams); // Parsed, execute. if (jvOutput.isMember("error")) { diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 4247908b1e..5a7b346b7f 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -12,6 +12,7 @@ protected: typedef Json::Value (RPCParser::*parseFuncPtr)(const Json::Value &jvParams); Json::Value parseAsIs(const Json::Value &jvParams); + Json::Value parseAccountInfo(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 2474ee5373..1d90a55c61 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -260,23 +260,27 @@ Json::Value RPCHandler::doAcceptLedger(Json::Value jvRequest) if (!theConfig.RUN_STANDALONE) return rpcError(rpcNOT_STANDALONE); - Json::Value obj(Json::objectValue); + Json::Value jvResult(Json::objectValue); - jvRequest["newLedger"] = theApp->getOPs().acceptLedger(); + jvResult["newLedger"] = theApp->getOPs().acceptLedger(); - return jvRequest; + return jvResult; } -// account_info || -// account_info || [] -Json::Value RPCHandler::doAccountInfo(Json::Value params) +// { 'ident' : _indent_, 'index' : _index_ // optional } +Json::Value RPCHandler::doAccountInfo(Json::Value jvRequest) { - std::string strIdent = params[0u].asString(); + // cLog(lsDEBUG) << "doAccountInfo: " << jvRequest; + + if (!jvRequest.isMember("ident")) + return rpcError(rpcINVALID_PARAMS); + + std::string strIdent = jvRequest["ident"].asString(); bool bIndex; - int iIndex = 2 == params.size() ? lexical_cast_s(params[1u].asString()) : 0; + int iIndex = jvRequest.isMember("index") ? jvRequest["index"].asUInt() : 0; RippleAddress naAccount; - Json::Value ret; + Json::Value jvResult; // Get info on account. @@ -291,7 +295,7 @@ Json::Value RPCHandler::doAccountInfo(Json::Value params) asAccepted->addJson(jAccepted); } - ret["accepted"] = jAccepted; + jvResult["accepted"] = jAccepted; Json::Value jCurrent = accountFromString(uint256(0), naAccount, bIndex, strIdent, iIndex); @@ -303,18 +307,18 @@ Json::Value RPCHandler::doAccountInfo(Json::Value params) asCurrent->addJson(jCurrent); } - ret["current"] = jCurrent; + jvResult["current"] = jCurrent; #if 0 if (!jAccepted && !asCurrent) { - ret["account"] = naAccount.humanAccountID(); - ret["status"] = "NotFound"; + jvResult["account"] = naAccount.humanAccountID(); + jvResult["status"] = "NotFound"; if (bIndex) - ret["index"] = iIndex; + jvResult["index"] = iIndex; } #endif - return ret; + return jvResult; } Json::Value RPCHandler::doConnect(Json::Value params) @@ -2138,6 +2142,8 @@ Json::Value RPCHandler::doUnsubscribe(Json::Value jvRequest) Json::Value RPCHandler::doRpcCommand(const std::string& strCommand, Json::Value& jvParams, int iRole) { + // cLog(lsTRACE) << "doRpcCommand:" << strCommand << ":" << jvParams; + if (!jvParams.isArray() || jvParams.size() > 1) return rpcError(rpcINVALID_PARAMS); @@ -2172,8 +2178,8 @@ Json::Value RPCHandler::doCommand(Json::Value& jvParams, int iRole) unsigned int iOptions; } commandsA[] = { // Request-response methods - { "accept_ledger", &RPCHandler::doAcceptLedger, -1, -1, true, false, optNone }, - { "account_info", &RPCHandler::doAccountInfo, 1, 2, false, false, optCurrent }, + { "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 }, { "connect", &RPCHandler::doConnect, 1, 2, true, false, optNone }, { "data_delete", &RPCHandler::doDataDelete, 1, 1, true, false, optNone }, From 318c7d15cb7d6aa0e120b76ba964fc4617abad68 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 2 Dec 2012 17:21:03 -0800 Subject: [PATCH 10/24] Refactor RPC account_tx. --- src/cpp/ripple/CallRPC.cpp | 50 ++++++++++++++++++++++++++++++----- src/cpp/ripple/CallRPC.h | 5 ++-- src/cpp/ripple/RPCHandler.cpp | 44 +++++++++++++++--------------- 3 files changed, 70 insertions(+), 29 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index a48e834e16..1f19e7d1bd 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 5a7b346b7f..523c018ac6 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 1d90a55c61..4dbbadd3a9 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 }, From c6db85fb39c6b9f593ce5b383544f452d72e9253 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 2 Dec 2012 18:08:45 -0800 Subject: [PATCH 11/24] Refactor RPC commands with no arguments. --- src/cpp/ripple/CallRPC.cpp | 126 +++++++++++++++++++------------- src/cpp/ripple/CallRPC.h | 2 + src/cpp/ripple/RPCErr.cpp | 3 + src/cpp/ripple/RPCErr.h | 4 + src/cpp/ripple/RPCHandler.cpp | 45 ++++++++++-- src/cpp/ripple/WSConnection.cpp | 5 +- 6 files changed, 124 insertions(+), 61 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 1f19e7d1bd..e288fadae7 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -113,6 +113,11 @@ Json::Value RPCParser::parseAccountTransactions(const Json::Value& jvParams) return jvRequest; } +Json::Value RPCParser::parseEvented(const Json::Value& jvParams) +{ + return rpcError(rpcNO_EVENTS); +} + // Convert a rpc method and params to a request. // <-- { method: xyz, params: [... ] } or { error: ..., ... } Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) @@ -132,55 +137,53 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) { "accept_ledger", &RPCParser::parseAsIs, 0, 0 }, { "account_info", &RPCParser::parseAccountInfo, 1, 2 }, { "account_tx", &RPCParser::parseAccountTransactions, 2, 3 }, -#if 0 - { "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 }, - { "data_store", &RPCParser::doDataStore, 2, 2, true, false, optNone }, - { "get_counts", &RPCParser::doGetCounts, 0, 1, true, false, optNone }, - { "ledger", &RPCParser::doLedger, 0, 2, false, false, optNetwork }, - { "ledger_accept", &RPCParser::doLedgerAccept, 0, 0, true, false, optCurrent }, - { "ledger_closed", &RPCParser::doLedgerClosed, 0, 0, false, false, optClosed }, - { "ledger_current", &RPCParser::doLedgerCurrent, 0, 0, false, false, optCurrent }, - { "ledger_entry", &RPCParser::doLedgerEntry, -1, -1, false, false, optCurrent }, - { "ledger_header", &RPCParser::doLedgerHeader, -1, -1, false, false, optCurrent }, - { "log_level", &RPCParser::doLogLevel, 0, 2, true, false, optNone }, - { "logrotate", &RPCParser::doLogRotate, 0, 0, true, false, optNone }, - { "nickname_info", &RPCParser::doNicknameInfo, 1, 1, false, false, optCurrent }, - { "owner_info", &RPCParser::doOwnerInfo, 1, 2, false, false, optCurrent }, - { "peers", &RPCParser::doPeers, 0, 0, true, false, optNone }, - { "profile", &RPCParser::doProfile, 1, 9, false, false, optCurrent }, - { "ripple_lines_get", &RPCParser::doRippleLinesGet, 1, 2, false, false, optCurrent }, - { "ripple_path_find", &RPCParser::doRipplePathFind, -1, -1, false, false, optCurrent }, - { "submit", &RPCParser::doSubmit, 2, 2, false, false, optCurrent }, - { "submit_json", &RPCParser::doSubmitJson, -1, -1, false, false, optCurrent }, - { "server_info", &RPCParser::doServerInfo, 0, 0, true, false, optNone }, - { "stop", &RPCParser::doStop, 0, 0, true, false, optNone }, - { "transaction_entry", &RPCParser::doTransactionEntry, -1, -1, false, false, optCurrent }, - { "tx", &RPCParser::doTx, 1, 1, true, false, optNone }, - { "tx_history", &RPCParser::doTxHistory, 1, 1, false, false, optNone }, +// { "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 }, +// { "data_store", &RPCParser::doDataStore, 2, 2, true, false, optNone }, +// { "get_counts", &RPCParser::doGetCounts, 0, 1, true, false, optNone }, +// { "ledger", &RPCParser::doLedger, 0, 2, false, false, optNetwork }, + { "ledger_accept", &RPCParser::parseAsIs, 0, 0 }, + { "ledger_closed", &RPCParser::parseAsIs, 0, 0 }, + { "ledger_current", &RPCParser::parseAsIs, 0, 0 }, +// { "ledger_entry", &RPCParser::doLedgerEntry, -1, -1, false, false, optCurrent }, +// { "ledger_header", &RPCParser::doLedgerHeader, -1, -1, false, false, optCurrent }, +// { "log_level", &RPCParser::doLogLevel, 0, 2, true, false, optNone }, + { "logrotate", &RPCParser::parseAsIs, 0, 0 }, +// { "nickname_info", &RPCParser::doNicknameInfo, 1, 1, false, false, optCurrent }, +// { "owner_info", &RPCParser::doOwnerInfo, 1, 2, false, false, optCurrent }, + { "peers", &RPCParser::parseAsIs, 0, 0 }, +// { "profile", &RPCParser::doProfile, 1, 9, false, false, optCurrent }, +// { "ripple_lines_get", &RPCParser::doRippleLinesGet, 1, 2, false, false, optCurrent }, +// { "ripple_path_find", &RPCParser::doRipplePathFind, -1, -1, false, false, optCurrent }, +// { "submit", &RPCParser::doSubmit, 2, 2, false, false, optCurrent }, +// { "submit_json", &RPCParser::doSubmitJson, -1, -1, false, false, optCurrent }, + { "server_info", &RPCParser::parseAsIs, 0, 0 }, + { "stop", &RPCParser::parseAsIs, 0, 0 }, +// { "transaction_entry", &RPCParser::doTransactionEntry, -1, -1, false, false, optCurrent }, +// { "tx", &RPCParser::doTx, 1, 1, true, false, optNone }, +// { "tx_history", &RPCParser::doTxHistory, 1, 1, false, false, optNone }, +// +// { "unl_add", &RPCParser::doUnlAdd, 1, 2, true, false, optNone }, +// { "unl_delete", &RPCParser::doUnlDelete, 1, 1, true, false, optNone }, + { "unl_list", &RPCParser::parseAsIs, 0, 0 }, + { "unl_load", &RPCParser::parseAsIs, 0, 0 }, + { "unl_network", &RPCParser::parseAsIs, 0, 0 }, + { "unl_reset", &RPCParser::parseAsIs, 0, 0 }, + { "unl_score", &RPCParser::parseAsIs, 0, 0 }, - { "unl_add", &RPCParser::doUnlAdd, 1, 2, true, false, optNone }, - { "unl_delete", &RPCParser::doUnlDelete, 1, 1, true, false, optNone }, - { "unl_list", &RPCParser::doUnlList, 0, 0, true, false, optNone }, - { "unl_load", &RPCParser::doUnlLoad, 0, 0, true, false, optNone }, - { "unl_network", &RPCParser::doUnlNetwork, 0, 0, true, false, optNone }, - { "unl_reset", &RPCParser::doUnlReset, 0, 0, true, false, optNone }, - { "unl_score", &RPCParser::doUnlScore, 0, 0, true, false, optNone }, +// { "validation_create", &RPCParser::doValidationCreate, 0, 1, false, false, optNone }, +// { "validation_seed", &RPCParser::doValidationSeed, 0, 1, false, false, optNone }, - { "validation_create", &RPCParser::doValidationCreate, 0, 1, false, false, optNone }, - { "validation_seed", &RPCParser::doValidationSeed, 0, 1, false, false, optNone }, - - { "wallet_accounts", &RPCParser::doWalletAccounts, 1, 1, false, false, optCurrent }, - { "wallet_propose", &RPCParser::doWalletPropose, 0, 1, false, false, optNone }, - { "wallet_seed", &RPCParser::doWalletSeed, 0, 1, false, false, optNone }, - - { "login", &RPCParser::doLogin, 2, 2, true, false, optNone }, +// { "wallet_accounts", &RPCParser::doWalletAccounts, 1, 1, false, false, optCurrent }, +// { "wallet_propose", &RPCParser::doWalletPropose, 0, 1, false, false, optNone }, +// { "wallet_seed", &RPCParser::doWalletSeed, 0, 1, false, false, optNone }, +// +// { "login", &RPCParser::doLogin, 2, 2, true, false, optNone }, // Evented methods - { "subscribe", &RPCParser::doSubscribe, -1, -1, false, true, optNone }, - { "unsubscribe", &RPCParser::doUnsubscribe, -1, -1, false, true, optNone }, -#endif + { "subscribe", &RPCParser::parseEvented, -1, -1 }, + { "unsubscribe", &RPCParser::parseEvented, -1, -1 }, }; int i = NUMBER(commandsA); @@ -229,7 +232,6 @@ int commandLineRPC(const std::vector& vCmd) if (jvRequest.isMember("error")) { jvOutput = jvRequest; - jvOutput["status"] = "error"; jvOutput["rpc"] = jvRpc; } else @@ -242,20 +244,40 @@ int commandLineRPC(const std::vector& vCmd) jvRequest.isMember("method") // Allow parser to rewrite method. ? jvRequest["method"].asString() : vCmd[0], - jvParams); // Parsed, execute. + jvParams); // Parsed, execute. + if (jvOutput.isMember("result")) + { + // Had a successful JSON-RPC 2.0 call. + jvOutput = jvOutput["result"]; + + // jvOutput may report a server side error. + // It should report "status". + } + else + { + // Transport error. + Json::Value jvRpcError = jvOutput; + + jvOutput = rpcError(rpcJSON_RPC); + jvOutput["result"] = jvRpcError; + } + + // If had an error, supply invokation in result. if (jvOutput.isMember("error")) { - jvOutput["rpc"] = jvRpc; // How the command was seen as method + params. - jvOutput["request"] = jvRequest; // How the command was translated. + jvOutput["rpc"] = jvRpc; // How the command was seen as method + params. + jvOutput["request_sent"] = jvRequest; // How the command was translated. } } if (jvOutput.isMember("error")) { - nRet = jvOutput.isMember("error_code") - ? lexical_cast_s(jvOutput["error_code"].asString()) - : 1; + jvOutput["status"] = "error"; + + nRet = jvOutput.isMember("error_code") + ? lexical_cast_s(jvOutput["error_code"].asString()) + : 1; } // YYY We could have a command line flag for single line output for scripts. diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 523c018ac6..f799ce93cb 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -15,6 +15,8 @@ protected: Json::Value parseAccountInfo(const Json::Value& jvParams); Json::Value parseAccountTransactions(const Json::Value& jvParams); + Json::Value parseEvented(const Json::Value& jvParams); + public: Json::Value parseCommand(std::string strMethod, Json::Value jvParams); }; diff --git a/src/cpp/ripple/RPCErr.cpp b/src/cpp/ripple/RPCErr.cpp index cc0e6ba17a..9c4112db12 100644 --- a/src/cpp/ripple/RPCErr.cpp +++ b/src/cpp/ripple/RPCErr.cpp @@ -30,6 +30,7 @@ Json::Value rpcError(int iError, Json::Value jvResult) { rpcINSUF_FUNDS, "insufFunds", "Insufficient funds." }, { rpcINTERNAL, "internal", "Internal error." }, { rpcINVALID_PARAMS, "invalidParams", "Invalid parameters." }, + { rpcJSON_RPC, "json_rpc", "JSON-RPC transport error." }, { rpcLGR_IDXS_INVALID, "lgrIdxsInvalid", "Ledger indexes invalid." }, { rpcLGR_IDX_MALFORMED, "lgrIdxMalformed", "Ledger index malformed." }, { rpcLGR_NOT_FOUND, "lgrNotFound", "Ledger not found." }, @@ -72,8 +73,10 @@ Json::Value rpcError(int iError, Json::Value jvResult) jvResult["error_code"] = iError; if (i >= 0) + { cLog(lsDEBUG) << "rpcError: " << errorInfoA[i].pToken << ": " << errorInfoA[i].pMessage << std::endl; + } return jvResult; } diff --git a/src/cpp/ripple/RPCErr.h b/src/cpp/ripple/RPCErr.h index d22b66b02f..f2b73336e9 100644 --- a/src/cpp/ripple/RPCErr.h +++ b/src/cpp/ripple/RPCErr.h @@ -7,6 +7,10 @@ enum { rpcSUCCESS, rpcBAD_SYNTAX, // Must be 1 to print usage to command line. + rpcJSON_RPC, + + // Error numbers beyond this line are not stable between versions. + // Programs should use error tokens. // Misc failure rpcLOAD_FAILED, diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 4dbbadd3a9..09e2f7c84c 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -459,7 +459,7 @@ Json::Value RPCHandler::doOwnerInfo(Json::Value params) return ret; } -Json::Value RPCHandler::doPeers(Json::Value params) +Json::Value RPCHandler::doPeers(Json::Value) { Json::Value obj(Json::objectValue); @@ -1074,7 +1074,7 @@ Json::Value RPCHandler::handleJSONSubmit(Json::Value jvRequest) } } -Json::Value RPCHandler::doServerInfo(Json::Value params) +Json::Value RPCHandler::doServerInfo(Json::Value) { Json::Value ret(Json::objectValue); @@ -1142,7 +1142,7 @@ Json::Value RPCHandler::doTx(Json::Value params) return rpcError(rpcNOT_IMPL); } -Json::Value RPCHandler::doLedgerClosed(Json::Value params) +Json::Value RPCHandler::doLedgerClosed(Json::Value) { Json::Value jvResult; uint256 uLedger = mNetOps->getClosedLedgerHash(); @@ -1153,7 +1153,7 @@ Json::Value RPCHandler::doLedgerClosed(Json::Value params) return jvResult; } -Json::Value RPCHandler::doLedgerCurrent(Json::Value params) +Json::Value RPCHandler::doLedgerCurrent(Json::Value) { Json::Value jvResult; jvResult["ledger_current_index"] = mNetOps->getCurrentLedgerID(); @@ -1408,7 +1408,7 @@ Json::Value RPCHandler::doWalletAccounts(Json::Value params) } } -Json::Value RPCHandler::doLogRotate(Json::Value params) +Json::Value RPCHandler::doLogRotate(Json::Value) { return Log::rotateLog(); } @@ -1573,7 +1573,7 @@ Json::Value RPCHandler::doUnlScore(Json::Value params) return "scoring requested"; } -Json::Value RPCHandler::doStop(Json::Value params) +Json::Value RPCHandler::doStop(Json::Value) { theApp->stop(); @@ -1621,7 +1621,7 @@ Json::Value RPCHandler::doUnlLoad(Json::Value params) return "loading"; } -Json::Value RPCHandler::doLedgerAccept(Json::Value ) +Json::Value RPCHandler::doLedgerAccept(Json::Value) { Json::Value jvResult; @@ -2142,6 +2142,7 @@ Json::Value RPCHandler::doUnsubscribe(Json::Value jvRequest) return jvResult; } +// Provide the JSON-RPC "result" value. Json::Value RPCHandler::doRpcCommand(const std::string& strCommand, Json::Value& jvParams, int iRole) { // cLog(lsTRACE) << "doRpcCommand:" << strCommand << ":" << jvParams; @@ -2153,7 +2154,35 @@ Json::Value RPCHandler::doRpcCommand(const std::string& strCommand, Json::Value& jvRequest["command"] = strCommand; - return doCommand(jvRequest, iRole); + Json::Value jvResult; + + Json::Value jvRaw = doCommand(jvRequest, iRole); + + // Regularize result. + if (jvRaw.isObject()) + { + // Got an object. + jvResult = jvRaw; + } + else + { + // Probably got a string. + jvResult = Json::Value(Json::objectValue); + + jvResult["message"] = jvRaw; + } + + // Always report "status". On an error report the request as received. + if (jvResult.isMember("error")) + { + jvResult["status"] = "error"; + jvResult["request"] = jvRequest; + + } else { + jvResult["status"] = "success"; + } + + return jvResult; } Json::Value RPCHandler::doCommand(Json::Value& jvParams, int iRole) diff --git a/src/cpp/ripple/WSConnection.cpp b/src/cpp/ripple/WSConnection.cpp index 59bb17751e..0027fea285 100644 --- a/src/cpp/ripple/WSConnection.cpp +++ b/src/cpp/ripple/WSConnection.cpp @@ -77,11 +77,14 @@ Json::Value WSConnection::invokeCommand(Json::Value& jvRequest) // Currently we will simply unwrap errors returned by the RPC // API, in the future maybe we can make the responses // consistent. + // + // Regularize result. This is duplicate code. if (jvResult["result"].isObject() && jvResult["result"].isMember("error")) { - jvResult = jvResult["result"]; + jvResult = jvResult["result"]; jvResult["status"] = "error"; jvResult["request"] = jvRequest; + } else { jvResult["status"] = "success"; } From 14bf7d0ec22d7accf2a950910297828b70cd3491 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 2 Dec 2012 18:25:12 -0800 Subject: [PATCH 12/24] Regularize irregular results for websocket interface too. --- src/cpp/ripple/RPCHandler.cpp | 36 ++++++++++++++++----------------- src/cpp/ripple/WSConnection.cpp | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 09e2f7c84c..fac30b7d96 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -2154,23 +2154,7 @@ Json::Value RPCHandler::doRpcCommand(const std::string& strCommand, Json::Value& jvRequest["command"] = strCommand; - Json::Value jvResult; - - Json::Value jvRaw = doCommand(jvRequest, iRole); - - // Regularize result. - if (jvRaw.isObject()) - { - // Got an object. - jvResult = jvRaw; - } - else - { - // Probably got a string. - jvResult = Json::Value(Json::objectValue); - - jvResult["message"] = jvRaw; - } + Json::Value jvResult = doCommand(jvRequest, iRole); // Always report "status". On an error report the request as received. if (jvResult.isMember("error")) @@ -2306,7 +2290,23 @@ cLog(lsDEBUG) << "params.size: " << jvParams.size() << " array: " << jvParams.is else { try { - return (this->*(commandsA[i].dfpFunc))(jvParams); + Json::Value jvRaw = (this->*(commandsA[i].dfpFunc))(jvParams); + + // Regularize result. + if (jvRaw.isObject()) + { + // Got an object. + return jvRaw; + } + else + { + // Probably got a string. + Json::Value jvResult(Json::objectValue); + + jvResult["message"] = jvRaw; + + return jvResult; + } } catch (std::exception& e) { diff --git a/src/cpp/ripple/WSConnection.cpp b/src/cpp/ripple/WSConnection.cpp index 0027fea285..f217f07dae 100644 --- a/src/cpp/ripple/WSConnection.cpp +++ b/src/cpp/ripple/WSConnection.cpp @@ -79,7 +79,7 @@ Json::Value WSConnection::invokeCommand(Json::Value& jvRequest) // consistent. // // Regularize result. This is duplicate code. - if (jvResult["result"].isObject() && jvResult["result"].isMember("error")) + if (jvResult["result"].isMember("error")) { jvResult = jvResult["result"]; jvResult["status"] = "error"; From 65175b8e5420ad91db5a71d996802fb093dccf51 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 2 Dec 2012 19:46:32 -0800 Subject: [PATCH 13/24] Refactor RPC submit and submit_json. --- src/cpp/ripple/CallRPC.cpp | 23 +++++++++++++++++-- src/cpp/ripple/CallRPC.h | 1 + src/cpp/ripple/RPCHandler.cpp | 43 ++++++++++------------------------- src/cpp/ripple/RPCHandler.h | 3 --- src/js/remote.js | 2 +- 5 files changed, 35 insertions(+), 37 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index e288fadae7..37d480b945 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -113,6 +113,26 @@ Json::Value RPCParser::parseAccountTransactions(const Json::Value& jvParams) return jvRequest; } +// submit any transaction to the network +// submit private_key json +Json::Value RPCParser::parseSubmit(const Json::Value& jvParams) +{ + Json::Value txJSON; + Json::Reader reader; + + if (reader.parse(jvParams[1u].asString(), txJSON)) + { + Json::Value jvRequest; + + jvRequest["secret"] = params[0u].asString(); + jvRequest["tx_json"] = txJSON; + + return jvRequest; + } + + return rpcError(rpcINVALID_PARAMS); +} + Json::Value RPCParser::parseEvented(const Json::Value& jvParams) { return rpcError(rpcNO_EVENTS); @@ -156,8 +176,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) // { "profile", &RPCParser::doProfile, 1, 9, false, false, optCurrent }, // { "ripple_lines_get", &RPCParser::doRippleLinesGet, 1, 2, false, false, optCurrent }, // { "ripple_path_find", &RPCParser::doRipplePathFind, -1, -1, false, false, optCurrent }, -// { "submit", &RPCParser::doSubmit, 2, 2, false, false, optCurrent }, -// { "submit_json", &RPCParser::doSubmitJson, -1, -1, false, false, optCurrent }, + { "submit", &RPCParser::parseSubmit, 2, 2 }, { "server_info", &RPCParser::parseAsIs, 0, 0 }, { "stop", &RPCParser::parseAsIs, 0, 0 }, // { "transaction_entry", &RPCParser::doTransactionEntry, -1, -1, false, false, optCurrent }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index f799ce93cb..411a7496d6 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -15,6 +15,7 @@ protected: Json::Value parseAccountInfo(const Json::Value& jvParams); Json::Value parseAccountTransactions(const Json::Value& jvParams); + Json::Value parseSubmit(const Json::Value& jvParams); Json::Value parseEvented(const Json::Value& jvParams); public: diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index fac30b7d96..8ca5ac9ac0 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -801,39 +801,21 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest) return jvResult; } -// submit any transaction to the network -// submit private_key json -Json::Value RPCHandler::doSubmit(Json::Value params) -{ - Json::Value txJSON; - Json::Reader reader; - - //std::string hello=params[1u].asString(); - - if (reader.parse(params[1u].asString(), txJSON)) - { - Json::Value jvRequest; - - jvRequest["secret"] = params[0u].asString(); - jvRequest["tx_json"] = txJSON; - - return handleJSONSubmit(jvRequest); - } - - return rpcError(rpcINVALID_PARAMS); -} - -Json::Value RPCHandler::doSubmitJson(Json::Value jvRequest) -{ - return handleJSONSubmit(jvRequest); -} - - -Json::Value RPCHandler::handleJSONSubmit(Json::Value jvRequest) +// { +// tx_json: , +// secret: +// } +Json::Value RPCHandler::doSubmit(Json::Value jvRequest) { Json::Value jvResult; RippleAddress naSeed; RippleAddress raSrcAddressID; + + if (!jvRequest.isMember("secret") || !jvRequest.isMember("tx_json")) + { + return rpcError(rpcINVALID_PARAMS); + } + Json::Value txJSON = jvRequest["tx_json"]; if (!naSeed.setSeedGeneric(jvRequest["secret"].asString())) @@ -2215,8 +2197,7 @@ Json::Value RPCHandler::doCommand(Json::Value& jvParams, int iRole) { "profile", &RPCHandler::doProfile, 1, 9, false, false, optCurrent }, { "ripple_lines_get", &RPCHandler::doRippleLinesGet, 1, 2, false, false, optCurrent }, { "ripple_path_find", &RPCHandler::doRipplePathFind, -1, -1, false, false, optCurrent }, - { "submit", &RPCHandler::doSubmit, 2, 2, false, false, optCurrent }, - { "submit_json", &RPCHandler::doSubmitJson, -1, -1, false, false, optCurrent }, + { "submit", &RPCHandler::doSubmit, -1, -1, false, false, optCurrent }, { "server_info", &RPCHandler::doServerInfo, 0, 0, true, false, optNone }, { "stop", &RPCHandler::doStop, 0, 0, true, false, optNone }, { "transaction_entry", &RPCHandler::doTransactionEntry, -1, -1, false, false, optCurrent }, diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index 4867955a7f..080defe65f 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -61,7 +61,6 @@ class RPCHandler Json::Value doLogLevel(Json::Value params); Json::Value doStop(Json::Value params); Json::Value doSubmit(Json::Value params); - Json::Value doSubmitJson(Json::Value jvRequest); Json::Value doTx(Json::Value params); Json::Value doTxHistory(Json::Value params); @@ -108,8 +107,6 @@ public: Json::Value doCommand(Json::Value& jvRequest, int role); Json::Value doRpcCommand(const std::string& strCommand, Json::Value& jvParams, int iRole); - - Json::Value handleJSONSubmit(Json::Value jvRequest); }; #endif diff --git a/src/js/remote.js b/src/js/remote.js index be7614bd4a..aff05c2439 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -773,7 +773,7 @@ Remote.prototype.submit = function (transaction) { else { // Convert the transaction into a request and submit it. - (new Request(this, 'submit_json')) + (new Request(this, 'submit')) .build_path(transaction._build_path) .tx_json(transaction.tx_json) .secret(transaction._secret) From 2ef272b80532b3f0d167fb9573231388dc953378 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 3 Dec 2012 14:51:41 -0800 Subject: [PATCH 14/24] Refactor RPC unl_add. --- src/cpp/ripple/CallRPC.cpp | 35 ++++++++++++++++++++++++++---- src/cpp/ripple/CallRPC.h | 2 ++ src/cpp/ripple/RPCHandler.cpp | 41 +++++++++++++++++++---------------- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 37d480b945..5f9b1b9c39 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -113,6 +113,11 @@ Json::Value RPCParser::parseAccountTransactions(const Json::Value& jvParams) return jvRequest; } +Json::Value RPCParser::parseEvented(const Json::Value& jvParams) +{ + return rpcError(rpcNO_EVENTS); +} + // submit any transaction to the network // submit private_key json Json::Value RPCParser::parseSubmit(const Json::Value& jvParams) @@ -124,7 +129,7 @@ Json::Value RPCParser::parseSubmit(const Json::Value& jvParams) { Json::Value jvRequest; - jvRequest["secret"] = params[0u].asString(); + jvRequest["secret"] = jvParams[0u].asString(); jvRequest["tx_json"] = txJSON; return jvRequest; @@ -133,11 +138,33 @@ Json::Value RPCParser::parseSubmit(const Json::Value& jvParams) return rpcError(rpcINVALID_PARAMS); } -Json::Value RPCParser::parseEvented(const Json::Value& jvParams) +// unl_add | [] +Json::Value RPCParser::parseUnlAdd(const Json::Value& jvParams) { - return rpcError(rpcNO_EVENTS); + std::string strNode = jvParams[0u].asString(); + std::string strComment = (jvParams.size() == 2) ? jvParams[1u].asString() : ""; + + RippleAddress naNodePublic; + + if (strNode.length()) + { + Json::Value jvRequest; + + jvRequest["node"] = strNode; + + if (strComment.length()) + jvRequest["comment"] = strComment; + + return jvRequest; + } + + return rpcError(rpcINVALID_PARAMS); } +// +// parseCommand +// + // Convert a rpc method and params to a request. // <-- { method: xyz, params: [... ] } or { error: ..., ... } Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) @@ -183,7 +210,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) // { "tx", &RPCParser::doTx, 1, 1, true, false, optNone }, // { "tx_history", &RPCParser::doTxHistory, 1, 1, false, false, optNone }, // -// { "unl_add", &RPCParser::doUnlAdd, 1, 2, true, false, optNone }, + { "unl_add", &RPCParser::parseUnlAdd, 1, 2 }, // { "unl_delete", &RPCParser::doUnlDelete, 1, 1, true, false, optNone }, { "unl_list", &RPCParser::parseAsIs, 0, 0 }, { "unl_load", &RPCParser::parseAsIs, 0, 0 }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 411a7496d6..2f41757679 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -18,6 +18,8 @@ protected: Json::Value parseSubmit(const Json::Value& jvParams); Json::Value parseEvented(const Json::Value& jvParams); + Json::Value parseUnlAdd(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 8ca5ac9ac0..c37207b268 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1240,17 +1240,20 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest) #endif } -// unl_add | [] -Json::Value RPCHandler::doUnlAdd(Json::Value params) +// { +// node: |, +// comment: // optional +// } +Json::Value RPCHandler::doUnlAdd(Json::Value jvParams) { - std::string strNode = params[0u].asString(); - std::string strComment = (params.size() == 2) ? params[1u].asString() : ""; + std::string strNode = jvParams.isMember("node") ? jvParams["node"].asString() : ""; + std::string strComment = jvParams.isMember("comment") ? jvParams["comment"].asString() : ""; - RippleAddress naNodePublic; + RippleAddress raNodePublic; - if (naNodePublic.setNodePublic(strNode)) + if (raNodePublic.setNodePublic(strNode)) { - theApp->getUNL().nodeAddPublic(naNodePublic, UniqueNodeList::vsManual, strComment); + theApp->getUNL().nodeAddPublic(raNodePublic, UniqueNodeList::vsManual, strComment); return "adding node by public key"; } @@ -2184,33 +2187,33 @@ Json::Value RPCHandler::doCommand(Json::Value& jvParams, int iRole) { "data_store", &RPCHandler::doDataStore, 2, 2, true, false, optNone }, { "get_counts", &RPCHandler::doGetCounts, 0, 1, true, false, optNone }, { "ledger", &RPCHandler::doLedger, 0, 2, false, false, optNetwork }, - { "ledger_accept", &RPCHandler::doLedgerAccept, 0, 0, true, false, optCurrent }, - { "ledger_closed", &RPCHandler::doLedgerClosed, 0, 0, false, false, optClosed }, - { "ledger_current", &RPCHandler::doLedgerCurrent, 0, 0, false, false, optCurrent }, + { "ledger_accept", &RPCHandler::doLedgerAccept, -1, -1, true, false, optCurrent }, + { "ledger_closed", &RPCHandler::doLedgerClosed, -1, -1, false, false, optClosed }, + { "ledger_current", &RPCHandler::doLedgerCurrent, -1, -1, false, false, optCurrent }, { "ledger_entry", &RPCHandler::doLedgerEntry, -1, -1, false, false, optCurrent }, { "ledger_header", &RPCHandler::doLedgerHeader, -1, -1, false, false, optCurrent }, { "log_level", &RPCHandler::doLogLevel, 0, 2, true, false, optNone }, - { "logrotate", &RPCHandler::doLogRotate, 0, 0, true, false, optNone }, + { "logrotate", &RPCHandler::doLogRotate, -1, -1, true, false, optNone }, { "nickname_info", &RPCHandler::doNicknameInfo, 1, 1, false, false, optCurrent }, { "owner_info", &RPCHandler::doOwnerInfo, 1, 2, false, false, optCurrent }, - { "peers", &RPCHandler::doPeers, 0, 0, true, false, optNone }, + { "peers", &RPCHandler::doPeers, -1, -1, true, false, optNone }, { "profile", &RPCHandler::doProfile, 1, 9, false, false, optCurrent }, { "ripple_lines_get", &RPCHandler::doRippleLinesGet, 1, 2, false, false, optCurrent }, { "ripple_path_find", &RPCHandler::doRipplePathFind, -1, -1, false, false, optCurrent }, { "submit", &RPCHandler::doSubmit, -1, -1, false, false, optCurrent }, - { "server_info", &RPCHandler::doServerInfo, 0, 0, true, false, optNone }, - { "stop", &RPCHandler::doStop, 0, 0, true, false, optNone }, + { "server_info", &RPCHandler::doServerInfo, -1, -1, true, false, optNone }, + { "stop", &RPCHandler::doStop, -1, -1, true, false, optNone }, { "transaction_entry", &RPCHandler::doTransactionEntry, -1, -1, false, false, optCurrent }, { "tx", &RPCHandler::doTx, 1, 1, true, false, optNone }, { "tx_history", &RPCHandler::doTxHistory, 1, 1, false, false, optNone }, { "unl_add", &RPCHandler::doUnlAdd, 1, 2, true, false, optNone }, { "unl_delete", &RPCHandler::doUnlDelete, 1, 1, true, false, optNone }, - { "unl_list", &RPCHandler::doUnlList, 0, 0, true, false, optNone }, - { "unl_load", &RPCHandler::doUnlLoad, 0, 0, true, false, optNone }, - { "unl_network", &RPCHandler::doUnlNetwork, 0, 0, true, false, optNone }, - { "unl_reset", &RPCHandler::doUnlReset, 0, 0, true, false, optNone }, - { "unl_score", &RPCHandler::doUnlScore, 0, 0, true, false, optNone }, + { "unl_list", &RPCHandler::doUnlList, -1, -1, true, false, optNone }, + { "unl_load", &RPCHandler::doUnlLoad, -1, -1, true, false, optNone }, + { "unl_network", &RPCHandler::doUnlNetwork, -1, -1, true, false, optNone }, + { "unl_reset", &RPCHandler::doUnlReset, -1, -1, true, false, optNone }, + { "unl_score", &RPCHandler::doUnlScore, -1, -1, true, false, optNone }, { "validation_create", &RPCHandler::doValidationCreate, 0, 1, false, false, optNone }, { "validation_seed", &RPCHandler::doValidationSeed, 0, 1, false, false, optNone }, From 936f52d65425cc6e287d6dbe37392dc4b19d3d83 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 3 Dec 2012 14:59:12 -0800 Subject: [PATCH 15/24] Refactor RPC unl_delete. --- src/cpp/ripple/CallRPC.cpp | 11 ++- src/cpp/ripple/CallRPC.h | 1 + src/cpp/ripple/RPCHandler.cpp | 139 +++++++++++++++++----------------- 3 files changed, 81 insertions(+), 70 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 5f9b1b9c39..8a17dec37b 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -161,6 +161,15 @@ Json::Value RPCParser::parseUnlAdd(const Json::Value& jvParams) return rpcError(rpcINVALID_PARAMS); } +// unl_delete | +Json::Value RPCParser::parseUnlDelete(const Json::Value& jvParams) +{ + Json::Value jvRequest; + + jvRequest["node"] = jvParams[0u].asString(); + + return jvRequest; +} // // parseCommand // @@ -211,7 +220,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) // { "tx_history", &RPCParser::doTxHistory, 1, 1, false, false, optNone }, // { "unl_add", &RPCParser::parseUnlAdd, 1, 2 }, -// { "unl_delete", &RPCParser::doUnlDelete, 1, 1, true, false, optNone }, + { "unl_delete", &RPCParser::parseUnlDelete, 1, 1 }, { "unl_list", &RPCParser::parseAsIs, 0, 0 }, { "unl_load", &RPCParser::parseAsIs, 0, 0 }, { "unl_network", &RPCParser::parseAsIs, 0, 0 }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 2f41757679..81796733cf 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -19,6 +19,7 @@ protected: Json::Value parseEvented(const Json::Value& jvParams); Json::Value parseUnlAdd(const Json::Value& jvParams); + Json::Value parseUnlDelete(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 c37207b268..13dadb8f07 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1240,31 +1240,6 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest) #endif } -// { -// node: |, -// comment: // optional -// } -Json::Value RPCHandler::doUnlAdd(Json::Value jvParams) -{ - std::string strNode = jvParams.isMember("node") ? jvParams["node"].asString() : ""; - std::string strComment = jvParams.isMember("comment") ? jvParams["comment"].asString() : ""; - - RippleAddress raNodePublic; - - if (raNodePublic.setNodePublic(strNode)) - { - theApp->getUNL().nodeAddPublic(raNodePublic, UniqueNodeList::vsManual, strComment); - - return "adding node by public key"; - } - else - { - theApp->getUNL().nodeAddDomain(strNode, UniqueNodeList::vsManual, strComment); - - return "adding node by domain"; - } -} - // validation_create [||] // // NOTE: It is poor security to specify secret information on the command line. This information might be saved in the command @@ -1532,6 +1507,73 @@ Json::Value RPCHandler::doLogLevel(Json::Value params) return rpcError(rpcINVALID_PARAMS); } +// { +// node: |, +// comment: // optional +// } +Json::Value RPCHandler::doUnlAdd(Json::Value jvParams) +{ + std::string strNode = jvParams.isMember("node") ? jvParams["node"].asString() : ""; + std::string strComment = jvParams.isMember("comment") ? jvParams["comment"].asString() : ""; + + RippleAddress raNodePublic; + + if (raNodePublic.setNodePublic(strNode)) + { + theApp->getUNL().nodeAddPublic(raNodePublic, UniqueNodeList::vsManual, strComment); + + return "adding node by public key"; + } + else + { + theApp->getUNL().nodeAddDomain(strNode, UniqueNodeList::vsManual, strComment); + + return "adding node by domain"; + } +} + +// { +// node: | +// } +Json::Value RPCHandler::doUnlDelete(Json::Value jvParams) +{ + std::string strNode = jvParams[0u].asString(); + + RippleAddress raNodePublic; + + if (raNodePublic.setNodePublic(strNode)) + { + theApp->getUNL().nodeRemovePublic(raNodePublic); + + return "removing node by public key"; + } + else + { + theApp->getUNL().nodeRemoveDomain(strNode); + + return "removing node by domain"; + } +} + +Json::Value RPCHandler::doUnlList(Json::Value params) +{ + Json::Value obj(Json::objectValue); + + obj["unl"]=theApp->getUNL().getUnlJson(); + + return obj; +} + +// Populate the UNL from a local validators.txt file. +Json::Value RPCHandler::doUnlLoad(Json::Value params) +{ + if (theConfig.VALIDATORS_FILE.empty() || !theApp->getUNL().nodeLoad(theConfig.VALIDATORS_FILE)) + { + return rpcError(rpcLOAD_FAILED); + } + + return "loading"; +} // Populate the UNL from ripple.com's validators.txt file. @@ -1565,47 +1607,6 @@ Json::Value RPCHandler::doStop(Json::Value) return SYSTEM_NAME " server stopping"; } -// unl_delete | -Json::Value RPCHandler::doUnlDelete(Json::Value params) -{ - std::string strNode = params[0u].asString(); - - RippleAddress naNodePublic; - - if (naNodePublic.setNodePublic(strNode)) - { - theApp->getUNL().nodeRemovePublic(naNodePublic); - - return "removing node by public key"; - } - else - { - theApp->getUNL().nodeRemoveDomain(strNode); - - return "removing node by domain"; - } -} - -Json::Value RPCHandler::doUnlList(Json::Value params) -{ - Json::Value obj(Json::objectValue); - - obj["unl"]=theApp->getUNL().getUnlJson(); - - return obj; -} - -// Populate the UNL from a local validators.txt file. -Json::Value RPCHandler::doUnlLoad(Json::Value params) -{ - if (theConfig.VALIDATORS_FILE.empty() || !theApp->getUNL().nodeLoad(theConfig.VALIDATORS_FILE)) - { - return rpcError(rpcLOAD_FAILED); - } - - return "loading"; -} - Json::Value RPCHandler::doLedgerAccept(Json::Value) { Json::Value jvResult; @@ -2203,12 +2204,12 @@ Json::Value RPCHandler::doCommand(Json::Value& jvParams, int iRole) { "submit", &RPCHandler::doSubmit, -1, -1, false, false, optCurrent }, { "server_info", &RPCHandler::doServerInfo, -1, -1, true, false, optNone }, { "stop", &RPCHandler::doStop, -1, -1, true, false, optNone }, - { "transaction_entry", &RPCHandler::doTransactionEntry, -1, -1, false, false, optCurrent }, + { "transaction_entry", &RPCHandler::doTransactionEntry, -1, -1, false, false, optCurrent }, { "tx", &RPCHandler::doTx, 1, 1, true, false, optNone }, { "tx_history", &RPCHandler::doTxHistory, 1, 1, false, false, optNone }, - { "unl_add", &RPCHandler::doUnlAdd, 1, 2, true, false, optNone }, - { "unl_delete", &RPCHandler::doUnlDelete, 1, 1, true, false, optNone }, + { "unl_add", &RPCHandler::doUnlAdd, -1, -1, true, false, optNone }, + { "unl_delete", &RPCHandler::doUnlDelete, -1, -1, true, false, optNone }, { "unl_list", &RPCHandler::doUnlList, -1, -1, true, false, optNone }, { "unl_load", &RPCHandler::doUnlLoad, -1, -1, true, false, optNone }, { "unl_network", &RPCHandler::doUnlNetwork, -1, -1, true, false, optNone }, From c71b6756392779e858bce53f9f095b3efe607969 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 3 Dec 2012 15:09:04 -0800 Subject: [PATCH 16/24] Refactor RPC connect. --- src/cpp/ripple/CallRPC.cpp | 15 ++++++++++++++- src/cpp/ripple/CallRPC.h | 1 + src/cpp/ripple/RPCHandler.cpp | 27 ++++++++------------------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 8a17dec37b..be955d8a01 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -113,6 +113,19 @@ Json::Value RPCParser::parseAccountTransactions(const Json::Value& jvParams) return jvRequest; } +// connect [port] +Json::Value RPCParser::parseConnect(const Json::Value& jvParams) +{ + Json::Value jvRequest(Json::objectValue); + + jvRequest["ip"] = jvParams[0u].asString(); + + if (jvParams.size() == 2) + jvRequest["port"] = jvParams[1u].asUInt(); + + return jvRequest; +} + Json::Value RPCParser::parseEvented(const Json::Value& jvParams) { return rpcError(rpcNO_EVENTS); @@ -193,7 +206,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) { "accept_ledger", &RPCParser::parseAsIs, 0, 0 }, { "account_info", &RPCParser::parseAccountInfo, 1, 2 }, { "account_tx", &RPCParser::parseAccountTransactions, 2, 3 }, -// { "connect", &RPCParser::doConnect, 1, 2, true, false, optNone }, + { "connect", &RPCParser::parseConnect, 1, 2 }, // { "data_delete", &RPCParser::doDataDelete, 1, 1, true, false, optNone }, // { "data_fetch", &RPCParser::doDataFetch, 1, 1, true, false, optNone }, // { "data_store", &RPCParser::doDataStore, 2, 2, true, false, optNone }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 81796733cf..9a972662ad 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -14,6 +14,7 @@ protected: Json::Value parseAsIs(const Json::Value& jvParams); Json::Value parseAccountInfo(const Json::Value& jvParams); Json::Value parseAccountTransactions(const Json::Value& jvParams); + Json::Value parseConnect(const Json::Value& jvParams); Json::Value parseSubmit(const Json::Value& jvParams); Json::Value parseEvented(const Json::Value& jvParams); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 13dadb8f07..3716b8fca8 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -321,29 +321,18 @@ Json::Value RPCHandler::doAccountInfo(Json::Value jvRequest) return jvResult; } -Json::Value RPCHandler::doConnect(Json::Value params) +// { +// ip: , +// port: +// } +// XXX Might allow domain for manual connections. +Json::Value RPCHandler::doConnect(Json::Value jvParams) { if (theConfig.RUN_STANDALONE) return "cannot connect in standalone mode"; - // connect [port] - std::string strIp; - int iPort = -1; - - // XXX Might allow domain for manual connections. - if (!extractString(strIp, params, 0)) - return rpcError(rpcHOST_IP_MALFORMED); - - if (params.size() == 2) - { - std::string strPort; - - // YYY Should make an extract int. - if (!extractString(strPort, params, 1)) - return rpcError(rpcPORT_MALFORMED); - - iPort = lexical_cast_s(strPort); - } + std::string strIp = jvParams["ip"].asString(); + int iPort = jvParams.isMember("port") ? jvParams["port"].asInt() : -1; // XXX Validate legal IP and port theApp->getConnectionPool().connectTo(strIp, iPort); From e8f2efab93cdca2f199c2b9c319e96c4748c507a Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 3 Dec 2012 15:35:29 -0800 Subject: [PATCH 17/24] Refactor RPC ledger. --- src/cpp/ripple/CallRPC.cpp | 31 +++++++++++++++++++++++++++- src/cpp/ripple/CallRPC.h | 5 ++--- src/cpp/ripple/RPCHandler.cpp | 38 ++++++++++++++++++++--------------- src/js/remote.js | 11 +++++++--- 4 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index be955d8a01..eb9eae3e7d 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -131,6 +131,31 @@ Json::Value RPCParser::parseEvented(const Json::Value& jvParams) return rpcError(rpcNO_EVENTS); } +// ledger [id|ledger_current|ledger_closed] [full] +Json::Value RPCParser::parseLedger(const Json::Value& jvParams) +{ + Json::Value jvRequest(Json::objectValue); + + if (!jvParams.size()) + { + return jvRequest; + } + + std::string strLedger = jvParams[0u].asString(); + + if (strLedger == "current" || strLedger == "ledger_closed" || strLedger.length() > 12) + jvRequest["ledger"] = strLedger; + else + jvRequest["ledger"] = lexical_cast_s(strLedger); + + if (2 == jvParams.size() && jvParams[1u].asString() == "full") + { + jvRequest["full"] = bool(1); + } + + return jvRequest; +} + // submit any transaction to the network // submit private_key json Json::Value RPCParser::parseSubmit(const Json::Value& jvParams) @@ -211,7 +236,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) // { "data_fetch", &RPCParser::doDataFetch, 1, 1, true, false, optNone }, // { "data_store", &RPCParser::doDataStore, 2, 2, true, false, optNone }, // { "get_counts", &RPCParser::doGetCounts, 0, 1, true, false, optNone }, -// { "ledger", &RPCParser::doLedger, 0, 2, false, false, optNetwork }, + { "ledger", &RPCParser::parseLedger, 0, 2 }, { "ledger_accept", &RPCParser::parseAsIs, 0, 0 }, { "ledger_closed", &RPCParser::parseAsIs, 0, 0 }, { "ledger_current", &RPCParser::parseAsIs, 0, 0 }, @@ -266,6 +291,10 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) else if ((commandsA[i].iMinParams >= 0 && jvParams.size() < commandsA[i].iMinParams) || (commandsA[i].iMaxParams >= 0 && jvParams.size() > commandsA[i].iMaxParams)) { + cLog(lsWARNING) << "Wrong number of parameters: minimum=" << commandsA[i].iMinParams + << " maximum=" << commandsA[i].iMaxParams + << " actual=" << jvParams.size(); + return rpcError(rpcBAD_SYNTAX); } diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 9a972662ad..df7b4c4f07 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -15,10 +15,9 @@ protected: Json::Value parseAccountInfo(const Json::Value& jvParams); Json::Value parseAccountTransactions(const Json::Value& jvParams); Json::Value parseConnect(const Json::Value& jvParams); - - Json::Value parseSubmit(const Json::Value& jvParams); Json::Value parseEvented(const Json::Value& jvParams); - + Json::Value parseLedger(const Json::Value& jvParams); + Json::Value parseSubmit(const Json::Value& jvParams); Json::Value parseUnlAdd(const Json::Value& jvParams); Json::Value parseUnlDelete(const Json::Value& jvParams); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 3716b8fca8..c8715c46f0 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1131,41 +1131,47 @@ Json::Value RPCHandler::doLedgerCurrent(Json::Value) return jvResult; } -// ledger [id|current|lastclosed] [full] -Json::Value RPCHandler::doLedger(Json::Value params) +// ledger [id|ledger_current|lastclosed] [full] +// { +// ledger: 'ledger_current' | 'ledger_closed' | | , // optional +// full: true | false // optional, defaults to false. +// } +Json::Value RPCHandler::doLedger(Json::Value jvParams) { - if (getParamCount(params) == 0) + if (!jvParams.isMember("ledger")) { Json::Value ret(Json::objectValue), current(Json::objectValue), closed(Json::objectValue); + theApp->getLedgerMaster().getCurrentLedger()->addJson(current, 0); theApp->getLedgerMaster().getClosedLedger()->addJson(closed, 0); + ret["open"] = current; ret["closed"] = closed; + return ret; } - std::string param; - if (!extractString(param, params, 0)) - { - return "bad params"; - } - + std::string strLedger = jvParams["ledger"].asString(); Ledger::pointer ledger; - if (param == "current") + + if (strLedger == "ledger_current") ledger = theApp->getLedgerMaster().getCurrentLedger(); - else if ((param == "lastclosed") || (param == "lastaccepted")) + else if (strLedger == "ledger_closed") ledger = theApp->getLedgerMaster().getClosedLedger(); - else if (param.size() > 12) - ledger = theApp->getLedgerMaster().getLedgerByHash(uint256(param)); + else if (strLedger.size() > 12) + ledger = theApp->getLedgerMaster().getLedgerByHash(uint256(strLedger)); else - ledger = theApp->getLedgerMaster().getLedgerBySeq(lexical_cast_s(param)); + ledger = theApp->getLedgerMaster().getLedgerBySeq(jvParams["ledger"].asUInt()); if (!ledger) return rpcError(rpcLGR_NOT_FOUND); - bool full = extractString(param, params, 1) && (param == "full"); + bool full = jvParams.isMember("full") && jvParams["full"].asBool(); + Json::Value ret(Json::objectValue); + ledger->addJson(ret, full ? LEDGER_JSON_FULL : 0); + return ret; } @@ -2176,7 +2182,7 @@ Json::Value RPCHandler::doCommand(Json::Value& jvParams, int iRole) { "data_fetch", &RPCHandler::doDataFetch, 1, 1, true, false, optNone }, { "data_store", &RPCHandler::doDataStore, 2, 2, true, false, optNone }, { "get_counts", &RPCHandler::doGetCounts, 0, 1, true, false, optNone }, - { "ledger", &RPCHandler::doLedger, 0, 2, false, false, optNetwork }, + { "ledger", &RPCHandler::doLedger, -1, -1, false, false, optNetwork }, { "ledger_accept", &RPCHandler::doLedgerAccept, -1, -1, true, false, optCurrent }, { "ledger_closed", &RPCHandler::doLedgerClosed, -1, -1, false, false, optClosed }, { "ledger_current", &RPCHandler::doLedgerCurrent, -1, -1, false, false, optCurrent }, diff --git a/src/js/remote.js b/src/js/remote.js index aff05c2439..0912f40dfc 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -548,13 +548,18 @@ Remote.prototype.request_server_info = function () { return new Request(this, 'server_info'); }; -Remote.prototype.request_ledger = function (params) { - // XXX Does this require the server to be trusted? +// XXX This is a bad command. Some varients don't scale. +// XXX Require the server to be trusted. +Remote.prototype.request_ledger = function (ledger, full) { //assert(this.trusted); var request = new Request(this, 'ledger'); - request.message.params = params; + if (ledger) + request.message.ledger = ledger; + + if (full) + request.message.full = true; return request; }; From 125a1ae5d343f9c6fa2d66100659e021623b6932 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 3 Dec 2012 15:55:10 -0800 Subject: [PATCH 18/24] Refactor RPC ripple_lines_get. --- src/cpp/ripple/CallRPC.cpp | 22 +++++++++++++++++- src/cpp/ripple/CallRPC.h | 1 + src/cpp/ripple/RPCHandler.cpp | 42 +++++++++++++++++------------------ src/js/remote.js | 15 ++++++++----- 4 files changed, 53 insertions(+), 27 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index eb9eae3e7d..b0cbf5ffe0 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -156,6 +156,26 @@ Json::Value RPCParser::parseLedger(const Json::Value& jvParams) return jvRequest; } +// ripple_lines_get || [] +Json::Value RPCParser::parseRippleLinesGet(const Json::Value& jvParams) +{ + std::string strIdent = jvParams[0u].asString(); + bool bIndex = 2 == jvParams.size(); + int iIndex = bIndex ? lexical_cast_s(jvParams[1u].asString()) : 0; + + if (bIndex && !iIndex) // Don't send default. + bIndex = false; + + // Get info on account. + Json::Value jvRequest(Json::objectValue); + + jvRequest["account"] = strIdent; + if (bIndex) + jvRequest["index"] = iIndex; + + return jvRequest; +} + // submit any transaction to the network // submit private_key json Json::Value RPCParser::parseSubmit(const Json::Value& jvParams) @@ -248,7 +268,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) // { "owner_info", &RPCParser::doOwnerInfo, 1, 2, false, false, optCurrent }, { "peers", &RPCParser::parseAsIs, 0, 0 }, // { "profile", &RPCParser::doProfile, 1, 9, false, false, optCurrent }, -// { "ripple_lines_get", &RPCParser::doRippleLinesGet, 1, 2, false, false, optCurrent }, + { "ripple_lines_get", &RPCParser::parseRippleLinesGet, 1, 2 }, // { "ripple_path_find", &RPCParser::doRipplePathFind, -1, -1, false, false, optCurrent }, { "submit", &RPCParser::parseSubmit, 2, 2 }, { "server_info", &RPCParser::parseAsIs, 0, 0 }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index df7b4c4f07..0c8d12a773 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -17,6 +17,7 @@ protected: Json::Value parseConnect(const Json::Value& jvParams); Json::Value parseEvented(const Json::Value& jvParams); Json::Value parseLedger(const Json::Value& jvParams); + Json::Value parseRippleLinesGet(const Json::Value& jvParams); Json::Value parseSubmit(const Json::Value& jvParams); Json::Value parseUnlAdd(const Json::Value& jvParams); Json::Value parseUnlDelete(const Json::Value& jvParams); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index c8715c46f0..2ee5c92b47 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -549,42 +549,42 @@ Json::Value RPCHandler::doProfile(Json::Value params) return obj; } -// ripple_lines_get || [] -Json::Value RPCHandler::doRippleLinesGet(Json::Value params) +// { +// account: || [] +// index: // optional, defaults to 0. +// } +Json::Value RPCHandler::doRippleLinesGet(Json::Value jvRequest) { - // uint256 uAccepted = mNetOps->getClosedLedgerHash(); + std::string strIdent = jvRequest["account"].asString(); + bool bIndex = jvRequest.isMember("index"); + int iIndex = bIndex ? jvRequest["index"].asUInt() : 0; - std::string strIdent = params[0u].asString(); - bool bIndex; - int iIndex = 2 == params.size() ? lexical_cast_s(params[1u].asString()) : 0; + RippleAddress raAccount; - RippleAddress naAccount; + Json::Value jvResult; - Json::Value ret; + jvResult = accountFromString(uint256(0), raAccount, bIndex, strIdent, iIndex); - ret = accountFromString(uint256(0), naAccount, bIndex, strIdent, iIndex); - - if (!ret.empty()) - return ret; + if (!jvResult.empty()) + return jvResult; // Get info on account. - ret = Json::Value(Json::objectValue); - ret["account"] = naAccount.humanAccountID(); + jvResult["account"] = raAccount.humanAccountID(); if (bIndex) - ret["index"] = iIndex; + jvResult["index"] = iIndex; - AccountState::pointer as = mNetOps->getAccountState(uint256(0), naAccount); + AccountState::pointer as = mNetOps->getAccountState(uint256(0), raAccount); if (as) { Json::Value jsonLines(Json::arrayValue); - ret["account"] = naAccount.humanAccountID(); + jvResult["account"] = raAccount.humanAccountID(); // XXX This is wrong, we do access the current ledger and do need to worry about changes. // We access a committed ledger and need not worry about changes. - RippleLines rippleLines(naAccount.getAccountID()); + RippleLines rippleLines(raAccount.getAccountID()); BOOST_FOREACH(RippleState::pointer line, rippleLines.getLines()) { STAmount saBalance = line->getBalance(); @@ -607,14 +607,14 @@ Json::Value RPCHandler::doRippleLinesGet(Json::Value params) jsonLines.append(jPeer); } - ret["lines"] = jsonLines; + jvResult["lines"] = jsonLines; } else { - ret = rpcError(rpcACT_NOT_FOUND); + jvResult = rpcError(rpcACT_NOT_FOUND); } - return ret; + return jvResult; } // TODO: diff --git a/src/js/remote.js b/src/js/remote.js index 0912f40dfc..836f08b9a7 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -698,14 +698,16 @@ Remote.prototype.request_transaction_entry = function (hash) { .tx_hash(hash); }; -Remote.prototype.request_ripple_lines_get = function (accountID) { +Remote.prototype.request_ripple_lines_get = function (accountID, index) { // XXX Does this require the server to be trusted? //assert(this.trusted); var request = new Request(this, 'ripple_lines_get'); - // XXX Convert API call to JSON - request.message.params = [accountID]; + request.message.account = accountID; + + if (index) + request.message.index = index; return request; }; @@ -1001,10 +1003,13 @@ Remote.prototype.request_unl_list = function () { return new Request(this, 'unl_list'); }; -Remote.prototype.request_unl_add = function (addr, note) { +Remote.prototype.request_unl_add = function (addr, comment) { var request = new Request(this, 'unl_add'); - request.message.params = [addr, note]; + request.message.node = addr; + + if (comment !== undefined) + request.message.comment = note; return request; }; From 1696263bcfeb26f1f77eb5f1e577aa27f2fab1b7 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 3 Dec 2012 16:01:03 -0800 Subject: [PATCH 19/24] Update remote.js for RPC connect. --- src/js/remote.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/js/remote.js b/src/js/remote.js index 836f08b9a7..ae807b580d 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -1029,7 +1029,10 @@ Remote.prototype.request_peers = function () { Remote.prototype.request_connect = function (ip, port) { var request = new Request(this, 'connect'); - request.message.params = [ip, port]; + request.message.ip = ip; + + if (port) + request.message.port = port; return request; }; From 81e69c038cc64fba7fdf27f5461629f1345264c0 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 3 Dec 2012 16:03:41 -0800 Subject: [PATCH 20/24] Update remote.js for RPC unl_delete. --- src/js/remote.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/js/remote.js b/src/js/remote.js index ae807b580d..6b6f1e86f0 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -1014,10 +1014,11 @@ Remote.prototype.request_unl_add = function (addr, comment) { return request; }; -Remote.prototype.request_unl_delete = function (publicKey) { +// --> node: | +Remote.prototype.request_unl_delete = function (node) { var request = new Request(this, 'unl_delete'); - request.message.params = [publicKey]; + request.message.node = node; return request; }; From dc977d1bfd18024f01f8f885f18b4b90f95cc03d Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 3 Dec 2012 16:05:45 -0800 Subject: [PATCH 21/24] Update remote.js for RPC account_tx. --- src/js/remote.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/js/remote.js b/src/js/remote.js index 6b6f1e86f0..0d5a80b4b4 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -724,14 +724,22 @@ Remote.prototype.request_wallet_accounts = function (key) { return request; }; -Remote.prototype.request_account_tx = function (accountID, minLedger, maxLedger) { +Remote.prototype.request_account_tx = function (accountID, ledger_min, ledger_max) { // XXX Does this require the server to be trusted? //assert(this.trusted); var request = new Request(this, 'account_tx'); // XXX Convert API call to JSON - request.message.params = [accountID, minLedger, maxLedger]; + request.message.account = accountID; + + if (ledger_min === ledger_max) { + request.message.ledger = ledger_min; + } + else { + request.message.ledger_min = ledger_min; + request.message.ledger_max = ledger_max; + } return request; }; From f8a906ce9ab484927ed64e1ee2ab1a8a46442ca9 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 3 Dec 2012 16:12:32 -0800 Subject: [PATCH 22/24] Refactor RPC wallet_accounts. --- src/cpp/ripple/CallRPC.cpp | 13 ++++++++++++- src/cpp/ripple/CallRPC.h | 1 + src/cpp/ripple/RPCHandler.cpp | 10 ++++++---- src/js/remote.js | 9 +++------ 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index b0cbf5ffe0..1b10a077c0 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -228,6 +228,17 @@ Json::Value RPCParser::parseUnlDelete(const Json::Value& jvParams) return jvRequest; } + +// wallet_accounts +Json::Value RPCParser::parseWalletAccounts(const Json::Value& jvParams) +{ + Json::Value jvRequest; + + jvRequest["seed"] = jvParams[0u].asString(); + + return jvRequest; +} + // // parseCommand // @@ -288,7 +299,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) // { "validation_create", &RPCParser::doValidationCreate, 0, 1, false, false, optNone }, // { "validation_seed", &RPCParser::doValidationSeed, 0, 1, false, false, optNone }, -// { "wallet_accounts", &RPCParser::doWalletAccounts, 1, 1, false, false, optCurrent }, + { "wallet_accounts", &RPCParser::parseWalletAccounts, 1, 1 }, // { "wallet_propose", &RPCParser::doWalletPropose, 0, 1, false, false, optNone }, // { "wallet_seed", &RPCParser::doWalletSeed, 0, 1, false, false, optNone }, // diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 0c8d12a773..99d5caabdb 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -17,6 +17,7 @@ protected: Json::Value parseConnect(const Json::Value& jvParams); Json::Value parseEvented(const Json::Value& jvParams); Json::Value parseLedger(const Json::Value& jvParams); + Json::Value parseWalletAccounts(const Json::Value& jvParams); Json::Value parseRippleLinesGet(const Json::Value& jvParams); Json::Value parseSubmit(const Json::Value& jvParams); Json::Value parseUnlAdd(const Json::Value& jvParams); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 2ee5c92b47..12f9728575 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1325,12 +1325,14 @@ Json::Value RPCHandler::accounts(const uint256& uLedger, const RippleAddress& na return jsonAccounts; } -// wallet_accounts -Json::Value RPCHandler::doWalletAccounts(Json::Value params) +// { +// seed: +// } +Json::Value RPCHandler::doWalletAccounts(Json::Value jvParams) { RippleAddress naSeed; - if (!naSeed.setSeedGeneric(params[0u].asString())) + if (!jvParams.isMember("seed") || !naSeed.setSeedGeneric(jvParams["seed"].asString())) { return rpcError(rpcBAD_SEED); } @@ -2214,7 +2216,7 @@ Json::Value RPCHandler::doCommand(Json::Value& jvParams, int iRole) { "validation_create", &RPCHandler::doValidationCreate, 0, 1, false, false, optNone }, { "validation_seed", &RPCHandler::doValidationSeed, 0, 1, false, false, optNone }, - { "wallet_accounts", &RPCHandler::doWalletAccounts, 1, 1, false, false, optCurrent }, + { "wallet_accounts", &RPCHandler::doWalletAccounts, -1, -1, false, false, optCurrent }, { "wallet_propose", &RPCHandler::doWalletPropose, 0, 1, false, false, optNone }, { "wallet_seed", &RPCHandler::doWalletSeed, 0, 1, false, false, optNone }, diff --git a/src/js/remote.js b/src/js/remote.js index 0d5a80b4b4..a65aee2fe8 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -712,14 +712,12 @@ Remote.prototype.request_ripple_lines_get = function (accountID, index) { return request; }; -Remote.prototype.request_wallet_accounts = function (key) { - // XXX Does this require the server to be trusted? - //assert(this.trusted); +Remote.prototype.request_wallet_accounts = function (seed) { + assert(this.trusted); // Don't send secrets. var request = new Request(this, 'wallet_accounts'); - // XXX Convert API call to JSON - request.message.params = [key]; + request.message.seed = seed; return request; }; @@ -730,7 +728,6 @@ Remote.prototype.request_account_tx = function (accountID, ledger_min, ledger_ma var request = new Request(this, 'account_tx'); - // XXX Convert API call to JSON request.message.account = accountID; if (ledger_min === ledger_max) { From 2791f43b1dc21c48d8f4c65eb4d34736fa8e8a45 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 3 Dec 2012 16:46:27 -0800 Subject: [PATCH 23/24] Fixes for emit ledger_closed. --- src/js/remote.js | 8 +++++--- test/monitor-test.js | 2 +- test/offer-test.js | 18 +++++++++--------- test/send-test.js | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/js/remote.js b/src/js/remote.js index bc7b51d3bc..cd36c919c0 100644 --- a/src/js/remote.js +++ b/src/js/remote.js @@ -803,7 +803,7 @@ Remote.prototype._server_subscribe = function () { self._ledger_hash = message.ledger_hash; self._ledger_current_index = message.ledger_index+1; - self.emit('ledger_closed', self._ledger_hash, self._ledger_current_index-1); + self.emit('ledger_closed', message); } self.emit('subscribed'); @@ -1209,8 +1209,10 @@ Transaction.prototype.submit = function (callback) { this.submit_index = this.remote._ledger_current_index; // When a ledger closes, look for the result. - var on_ledger_closed = function (ledger_hash, ledger_index) { - var stop = false; + var on_ledger_closed = function (message) { + var ledger_hash = message.ledger_hash; + var ledger_index = message.ledger_index; + var stop = false; // XXX make sure self.hash is available. self.remote.request_transaction_entry(self.hash) diff --git a/test/monitor-test.js b/test/monitor-test.js index 6e4abc5a3e..daef55a658 100644 --- a/test/monitor-test.js +++ b/test/monitor-test.js @@ -29,7 +29,7 @@ buster.testCase("//Monitor account", { function (callback) { self.what = "Close ledger."; - self.remote.once('ledger_closed', function (ledger_closed, ledger_index) { + self.remote.once('ledger_closed', function () { callback(); }); diff --git a/test/offer-test.js b/test/offer-test.js index ccdfa31b6e..b139f318b8 100644 --- a/test/offer-test.js +++ b/test/offer-test.js @@ -57,7 +57,7 @@ buster.testCase("Offer tests", { }, function (m, callback) { self.remote - .once('ledger_closed', function (ledger_hash, ledger_index) { + .once('ledger_closed', function (message) { // console.log("LEDGER_CLOSED: %d: %s", ledger_index, ledger_hash); }) .ledger_accept(); @@ -101,7 +101,7 @@ buster.testCase("Offer tests", { function (callback) { if (!final_create) { self.remote - .once('ledger_closed', function (ledger_hash, ledger_index) { + .once('ledger_closed', function (mesage) { // console.log("LEDGER_CLOSED: %d: %s", ledger_index, ledger_hash); }) @@ -133,7 +133,7 @@ buster.testCase("Offer tests", { // See if ledger_accept will crash. function (callback) { self.remote - .once('ledger_closed', function (ledger_hash, ledger_index) { + .once('ledger_closed', function (mesage) { // console.log("LEDGER_CLOSED: A: %d: %s", ledger_index, ledger_hash); callback(); }) @@ -141,7 +141,7 @@ buster.testCase("Offer tests", { }, function (callback) { self.remote - .once('ledger_closed', function (ledger_hash, ledger_index) { + .once('ledger_closed', function (mesage) { // console.log("LEDGER_CLOSED: B: %d: %s", ledger_index, ledger_hash); callback(); }) @@ -198,7 +198,7 @@ buster.testCase("Offer tests", { function (callback) { if (!final_create) { self.remote - .once('ledger_closed', function (ledger_hash, ledger_index) { + .once('ledger_closed', function (mesage) { // console.log("LEDGER_CLOSED: %d: %s", ledger_index, ledger_hash); }) @@ -230,7 +230,7 @@ buster.testCase("Offer tests", { // See if ledger_accept will crash. function (callback) { self.remote - .once('ledger_closed', function (ledger_hash, ledger_index) { + .once('ledger_closed', function (mesage) { // console.log("LEDGER_CLOSED: A: %d: %s", ledger_index, ledger_hash); callback(); }) @@ -238,7 +238,7 @@ buster.testCase("Offer tests", { }, function (callback) { self.remote - .once('ledger_closed', function (ledger_hash, ledger_index) { + .once('ledger_closed', function (mesage) { // console.log("LEDGER_CLOSED: B: %d: %s", ledger_index, ledger_hash); callback(); }) @@ -309,7 +309,7 @@ buster.testCase("Offer tests", { // See if ledger_accept will crash. function (callback) { self.remote - .once('ledger_closed', function (ledger_hash, ledger_index) { + .once('ledger_closed', function (mesage) { // console.log("LEDGER_CLOSED: A: %d: %s", ledger_index, ledger_hash); callback(); }) @@ -317,7 +317,7 @@ buster.testCase("Offer tests", { }, function (callback) { self.remote - .once('ledger_closed', function (ledger_hash, ledger_index) { + .once('ledger_closed', function (mesage) { // console.log("LEDGER_CLOSED: B: %d: %s", ledger_index, ledger_hash); callback(); }) diff --git a/test/send-test.js b/test/send-test.js index b09ca26431..890f32a7e1 100644 --- a/test/send-test.js +++ b/test/send-test.js @@ -442,7 +442,7 @@ buster.testCase("Sending future", { // self.what = "Close the ledger and check balance."; // // self.remote -// .once('ledger_closed', function (ledger_closed, ledger_closed_index) { +// .once('ledger_closed', function (message) { // // console.log("LEDGER_CLOSED: A: %d: %s", ledger_closed_index, ledger_closed); // callback(); // }) From 33611cdede6cffd326bf49bfd81bfd3f6598332b Mon Sep 17 00:00:00 2001 From: Stefan Thomas Date: Mon, 3 Dec 2012 17:10:33 -0800 Subject: [PATCH 24/24] Add signed option to to_human output. --- src/js/amount.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/amount.js b/src/js/amount.js index b34018cf16..ee73ea1742 100644 --- a/src/js/amount.js +++ b/src/js/amount.js @@ -513,6 +513,7 @@ Amount.prototype.to_human = function (opts) } var formatted = ''; + if (opts.signed && this._is_negative) formatted += "- "; formatted += int_part.length ? int_part : '0'; formatted += fraction_part.length ? '.'+fraction_part : '';