From d0c79083ab180094bf31a8ce3715beedd33bde46 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Thu, 28 Feb 2013 16:41:18 -0800 Subject: [PATCH] Add CLI support for RPC book_offers. --- src/cpp/ripple/CallRPC.cpp | 115 ++++++++++++++++++++++++++++++++++++- src/cpp/ripple/CallRPC.h | 1 + 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 50cd485fd6..cf30221c4c 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -1,3 +1,9 @@ +// +// This a trusted interface, the user is expected to provide valid input to perform valid requests. +// Error catching and reporting is not a requirement of this command line interface. +// +// Improvements to be more strict and to provide better diagnostics are welcome. +// #include #include @@ -9,6 +15,7 @@ #include #include #include +#include #include #include @@ -55,6 +62,65 @@ std::string EncodeBase64(const std::string& s) return result; } +// TODO New routine for parsing ledger parameters, other routines should standardize on this. +static bool jvParseLedger(Json::Value& jvRequest, const std::string& strLedger) +{ + if (strLedger == "closed") + { + jvRequest["ledger_index"] = -1; + } + else if (strLedger == "current") + { + jvRequest["ledger_index"] = -2; + } + else if (strLedger == "validated") + { + jvRequest["ledger_index"] = -3; + } + else if (strLedger.length() > 12) + { + // YYY Could confirm this is a uint256. + jvRequest["ledger_hash"] = strLedger; + } + else + { + jvRequest["ledger_index"] = lexical_cast_s(strLedger); + } + + return true; +} + +// Build a object { "currency" : "XYZ", "issuer" : "rXYX" } +static Json::Value jvParseCurrencyIssuer(const std::string& strCurrencyIssuer) +{ + static boost::regex reCurIss("\\`([[:alpha:]]{3})(?:/(.+))?\\'"); + + boost::smatch smMatch; + + bool bMatch = boost::regex_match(strCurrencyIssuer, smMatch, reCurIss); // Match status code. + + if (bMatch) + { + Json::Value jvResult(Json::objectValue); + std::string strCurrency = smMatch[1]; + std::string strIssuer = smMatch[2]; + + jvResult["currency"] = strCurrency; + + if (strIssuer.length()) + { + // Could confirm issuer is a valid Ripple address. + jvResult["issuer"] = strIssuer; + } + + return jvResult; + } + else + { + return rpcError(rpcINVALID_PARAMS); + } +} + Json::Value RPCParser::parseAsIs(const Json::Value& jvParams) { Json::Value v(Json::objectValue); @@ -145,6 +211,51 @@ Json::Value RPCParser::parseAccountTransactions(const Json::Value& jvParams) return jvRequest; } +// book_offers [ ] +// +// Mnemonic: taker puts --> offer --> taker gets +Json::Value RPCParser::parseBookOffers(const Json::Value& jvParams) +{ + Json::Value jvRequest(Json::objectValue); + + Json::Value jvTakerPuts = jvParseCurrencyIssuer(jvParams[0u].asString()); + Json::Value jvTakerGets = jvParseCurrencyIssuer(jvParams[1u].asString()); + + if (isRpcError(jvTakerPuts)) + { + return jvTakerPuts; + } + else + { + jvRequest["taker_puts"] = jvTakerPuts; + } + + if (isRpcError(jvTakerGets)) + { + return jvTakerGets; + } + else + { + jvRequest["taker_gets"] = jvTakerGets; + } + + if (!jvParseLedger(jvRequest, jvParams[2u].asString())) + return jvRequest; + + if (jvParams.size() >= 4) + { + int iLimit = jvParams[3u].asInt(); + + if (iLimit > 0) + jvRequest["limit"] = iLimit; + } + + if (jvParams.size() == 5) + jvRequest["marker"] = jvParams[4u]; + + return jvRequest; +} + // connect [port] Json::Value RPCParser::parseConnect(const Json::Value& jvParams) { @@ -509,11 +620,11 @@ 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 }, { "account_lines", &RPCParser::parseAccountItems, 1, 2 }, { "account_offers", &RPCParser::parseAccountItems, 1, 2 }, { "account_tx", &RPCParser::parseAccountTransactions, 2, 4 }, + { "book_offers", &RPCParser::parseBookOffers, 3, 5 }, { "connect", &RPCParser::parseConnect, 1, 2 }, { "consensus_info", &RPCParser::parseAsIs, 0, 0 }, { "get_counts", &RPCParser::parseGetCounts, 0, 1 }, @@ -622,7 +733,7 @@ int commandLineRPC(const std::vector& vCmd) jvRequest = rpParser.parseCommand(vCmd[0], jvRpcParams); - // std::cerr << "Request: " << jvRequest << std::endl; + std::cerr << "Request: " << jvRequest << std::endl; if (jvRequest.isMember("error")) { diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 11cf518128..adde89f708 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -14,6 +14,7 @@ protected: Json::Value parseAccountItems(const Json::Value& jvParams); Json::Value parseAccountTransactions(const Json::Value& jvParams); Json::Value parseAsIs(const Json::Value& jvParams); + Json::Value parseBookOffers(const Json::Value& jvParams); Json::Value parseConnect(const Json::Value& jvParams); #if ENABLE_INSECURE Json::Value parseDataDelete(const Json::Value& jvParams);