From 0f2d889987efb06cc387c8144a909ddff238ca41 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 14 Apr 2013 22:38:37 -0700 Subject: [PATCH 1/2] Cache RippleAddress validity. --- src/cpp/ripple/RippleAddress.cpp | 80 ++++++++++++++++++-------------- src/cpp/ripple/RippleAddress.h | 2 + 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/cpp/ripple/RippleAddress.cpp b/src/cpp/ripple/RippleAddress.cpp index 23948ad20b..f78f024531 100644 --- a/src/cpp/ripple/RippleAddress.cpp +++ b/src/cpp/ripple/RippleAddress.cpp @@ -30,39 +30,14 @@ std::size_t hash_value(const CBase58Data& b58) return seed; } -RippleAddress::RippleAddress() +RippleAddress::RippleAddress() : mIsValid(false) { nVersion = VER_NONE; } bool RippleAddress::isValid() const { - bool bValid = false; - - if (!vchData.empty()) - { - CKey key; - - switch (nVersion) { - case VER_NODE_PUBLIC: - bValid = key.SetPubKey(getNodePublic()); - break; - - case VER_ACCOUNT_PUBLIC: - bValid = key.SetPubKey(getAccountPublic()); - break; - - case VER_ACCOUNT_PRIVATE: - bValid = key.SetPrivateKeyU(getAccountPrivate()); - break; - - default: - bValid = true; - break; - } - } - - return bValid; + return mIsValid; } void RippleAddress::clear() @@ -165,11 +140,15 @@ std::string RippleAddress::humanNodePublic() const bool RippleAddress::setNodePublic(const std::string& strPublic) { - return SetString(strPublic.c_str(), VER_NODE_PUBLIC); + mIsValid = SetString(strPublic.c_str(), VER_NODE_PUBLIC); + + return mIsValid; } void RippleAddress::setNodePublic(const std::vector& vPublic) { + mIsValid = true; + SetData(VER_NODE_PUBLIC, vPublic); } @@ -259,15 +238,22 @@ std::string RippleAddress::humanNodePrivate() const bool RippleAddress::setNodePrivate(const std::string& strPrivate) { - return SetString(strPrivate.c_str(), VER_NODE_PRIVATE); + mIsValid = SetString(strPrivate.c_str(), VER_NODE_PRIVATE); + + return mIsValid; } -void RippleAddress::setNodePrivate(const std::vector& vPrivate) { +void RippleAddress::setNodePrivate(const std::vector& vPrivate) +{ + mIsValid = true; + SetData(VER_NODE_PRIVATE, vPrivate); } void RippleAddress::setNodePrivate(uint256 hash256) { + mIsValid = true; + SetData(VER_NODE_PRIVATE, hash256.begin(), 32); } @@ -343,16 +329,20 @@ bool RippleAddress::setAccountID(const std::string& strAccountID) { setAccountID(uint160()); - return true; + mIsValid = true; } else { - return SetString(strAccountID.c_str(), VER_ACCOUNT_ID); + mIsValid = SetString(strAccountID.c_str(), VER_ACCOUNT_ID); } + + return mIsValid; } void RippleAddress::setAccountID(const uint160& hash160) { + mIsValid = true; + SetData(VER_ACCOUNT_ID, hash160.begin(), 20); } @@ -407,11 +397,15 @@ std::string RippleAddress::humanAccountPublic() const bool RippleAddress::setAccountPublic(const std::string& strPublic) { - return SetString(strPublic.c_str(), VER_ACCOUNT_PUBLIC); + mIsValid = SetString(strPublic.c_str(), VER_ACCOUNT_PUBLIC); + + return mIsValid; } void RippleAddress::setAccountPublic(const std::vector& vPublic) { + mIsValid = true; + SetData(VER_ACCOUNT_PUBLIC, vPublic); } @@ -493,16 +487,22 @@ std::string RippleAddress::humanAccountPrivate() const bool RippleAddress::setAccountPrivate(const std::string& strPrivate) { - return SetString(strPrivate.c_str(), VER_ACCOUNT_PRIVATE); + mIsValid = SetString(strPrivate.c_str(), VER_ACCOUNT_PRIVATE); + + return mIsValid; } void RippleAddress::setAccountPrivate(const std::vector& vPrivate) { + mIsValid = true; + SetData(VER_ACCOUNT_PRIVATE, vPrivate); } void RippleAddress::setAccountPrivate(uint256 hash256) { + mIsValid = true; + SetData(VER_ACCOUNT_PRIVATE, hash256.begin(), 32); } @@ -673,11 +673,15 @@ std::string RippleAddress::humanGenerator() const bool RippleAddress::setGenerator(const std::string& strGenerator) { - return SetString(strGenerator.c_str(), VER_FAMILY_GENERATOR); + mIsValid = SetString(strGenerator.c_str(), VER_FAMILY_GENERATOR); + + return mIsValid; } void RippleAddress::setGenerator(const std::vector& vPublic) { + mIsValid = true; + SetData(VER_FAMILY_GENERATOR, vPublic); } @@ -768,7 +772,9 @@ int RippleAddress::setSeed1751(const std::string& strHuman1751) bool RippleAddress::setSeed(const std::string& strSeed) { - return SetString(strSeed.c_str(), VER_FAMILY_SEED); + mIsValid = SetString(strSeed.c_str(), VER_FAMILY_SEED); + + return mIsValid; } extern const char *ALPHABET; @@ -812,6 +818,8 @@ bool RippleAddress::setSeedGeneric(const std::string& strText) } void RippleAddress::setSeed(uint128 hash128) { + mIsValid = true; + SetData(VER_FAMILY_SEED, hash128.begin(), 16); } diff --git a/src/cpp/ripple/RippleAddress.h b/src/cpp/ripple/RippleAddress.h index d12cf101b4..ccdd38d339 100644 --- a/src/cpp/ripple/RippleAddress.h +++ b/src/cpp/ripple/RippleAddress.h @@ -22,6 +22,8 @@ private: VER_FAMILY_SEED = 33, } VersionEncoding; + bool mIsValid; + public: RippleAddress(); From ec081cd2dc404e9f8a9394d300af2925448fe46f Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sun, 14 Apr 2013 23:15:58 -0700 Subject: [PATCH 2/2] Make RPC account_lines support specify the peer account. --- src/cpp/ripple/CallRPC.cpp | 30 +++++++++++++++++--- src/cpp/ripple/CallRPC.h | 3 ++ src/cpp/ripple/RPCHandler.cpp | 52 ++++++++++++++++++++++------------- src/cpp/ripple/main.cpp | 2 +- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 41ba8a749b..5fba686ace 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -421,12 +421,24 @@ Json::Value RPCParser::parseLogLevel(const Json::Value& jvParams) // owner_info || [] // account_info || // account_info || [] -// account_lines || [] // account_offers || [] Json::Value RPCParser::parseAccountItems(const Json::Value& jvParams) +{ + return parseAccountRaw(jvParams, false); +} + +// account_lines |"" [] +Json::Value RPCParser::parseAccountLines(const Json::Value& jvParams) +{ + return parseAccountRaw(jvParams, true); +} + +// TODO: Get index from an alternate syntax: rXYZ: +Json::Value RPCParser::parseAccountRaw(const Json::Value& jvParams, bool bPeer) { std::string strIdent = jvParams[0u].asString(); - // TODO: Get index from an alternate syntax: rXYZ: + std::string strPeer = bPeer && jvParams.size() >= 2 ? jvParams[1u].asString() : ""; + int iIndex = 0; // int iIndex = jvParams.size() >= 2 ? lexical_cast_s(jvParams[1u].asString()) : 0; @@ -443,7 +455,17 @@ Json::Value RPCParser::parseAccountItems(const Json::Value& jvParams) if (iIndex) jvRequest["account_index"] = iIndex; - if (jvParams.size() == 2 && !jvParseLedger(jvRequest, jvParams[1u].asString())) + if (!strPeer.empty()) + { + RippleAddress raPeer; + + if (!raPeer.setAccountPublic(strPeer) && !raPeer.setAccountID(strPeer) && !raPeer.setSeedGeneric(strPeer)) + return rpcError(rpcACT_MALFORMED); + + jvRequest["peer"] = strPeer; + } + + if (jvParams.size() == (2+bPeer) && !jvParseLedger(jvRequest, jvParams[1u+bPeer].asString())) return rpcError(rpcLGR_IDX_MALFORMED); return jvRequest; @@ -655,7 +677,7 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams) // - Returns an error, or the request. // - To modify the method, provide a new method in the request. { "account_info", &RPCParser::parseAccountItems, 1, 2 }, - { "account_lines", &RPCParser::parseAccountItems, 1, 2 }, + { "account_lines", &RPCParser::parseAccountLines, 1, 3 }, { "account_offers", &RPCParser::parseAccountItems, 1, 2 }, { "account_tx", &RPCParser::parseAccountTransactions, 1, 8 }, { "book_offers", &RPCParser::parseBookOffers, 2, 7 }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 5860069418..ac726afdf9 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -10,7 +10,10 @@ class RPCParser protected: typedef Json::Value (RPCParser::*parseFuncPtr)(const Json::Value &jvParams); + Json::Value parseAccountRaw(const Json::Value& jvParams, bool bPeer); + Json::Value parseAccountItems(const Json::Value& jvParams); + Json::Value parseAccountLines(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); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 52462a39e2..8f38484cce 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -899,11 +899,23 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost) if (!jvResult.empty()) return jvResult; - // Get info on account. + std::string strPeer = jvRequest.isMember("peer") ? jvRequest["peer"].asString() : ""; + bool bPeerIndex = jvRequest.isMember("peer_index"); + int iPeerIndex = bIndex ? jvRequest["peer_index"].asUInt() : 0; - jvResult["account"] = raAccount.humanAccountID(); - if (bIndex) - jvResult["account_index"] = iIndex; + RippleAddress raPeer; + + if (!strPeer.empty()) + { + jvResult["peer"] = raAccount.humanAccountID(); + if (bPeerIndex) + jvResult["peer_index"] = iPeerIndex; + + jvResult = accountFromString(lpLedger, raPeer, bPeerIndex, strPeer, iPeerIndex, false); + + if (!jvResult.empty()) + return jvResult; + } AccountState::pointer as = mNetOps->getAccountState(lpLedger, raAccount); if (as) @@ -912,7 +924,6 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost) 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. @@ -922,23 +933,26 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost) { RippleState* line=(RippleState*)item.get(); - STAmount saBalance = line->getBalance(); - STAmount saLimit = line->getLimit(); - STAmount saLimitPeer = line->getLimitPeer(); + if (!raPeer.isValid() || raPeer.getAccountID() == line->getAccountIDPeer()) + { + STAmount saBalance = line->getBalance(); + STAmount saLimit = line->getLimit(); + STAmount saLimitPeer = line->getLimitPeer(); - Json::Value jPeer = Json::Value(Json::objectValue); + Json::Value jPeer = Json::Value(Json::objectValue); - jPeer["account"] = RippleAddress::createHumanAccountID(line->getAccountIDPeer()); - // Amount reported is positive if current account holds other account's IOUs. - // Amount reported is negative if other account holds current account's IOUs. - jPeer["balance"] = saBalance.getText(); - jPeer["currency"] = saBalance.getHumanCurrency(); - jPeer["limit"] = saLimit.getText(); - jPeer["limit_peer"] = saLimitPeer.getText(); - jPeer["quality_in"] = static_cast(line->getQualityIn()); - jPeer["quality_out"] = static_cast(line->getQualityOut()); + jPeer["account"] = RippleAddress::createHumanAccountID(line->getAccountIDPeer()); + // Amount reported is positive if current account holds other account's IOUs. + // Amount reported is negative if other account holds current account's IOUs. + jPeer["balance"] = saBalance.getText(); + jPeer["currency"] = saBalance.getHumanCurrency(); + jPeer["limit"] = saLimit.getText(); + jPeer["limit_peer"] = saLimitPeer.getText(); + jPeer["quality_in"] = static_cast(line->getQualityIn()); + jPeer["quality_out"] = static_cast(line->getQualityOut()); - jsonLines.append(jPeer); + jsonLines.append(jPeer); + } } jvResult["lines"] = jsonLines; } diff --git a/src/cpp/ripple/main.cpp b/src/cpp/ripple/main.cpp index 284c7f5d11..a112843cdb 100644 --- a/src/cpp/ripple/main.cpp +++ b/src/cpp/ripple/main.cpp @@ -71,7 +71,7 @@ void printHelp(const po::options_description& desc) cerr << "Commands: " << endl; cerr << " account_info |||| []" << endl; - cerr << " account_lines || []" << endl; + cerr << " account_lines |\"\" []" << endl; cerr << " account_offers || []" << endl; cerr << " account_tx accountID [ledger_min [ledger_max [limit [offset]]]] [binary] [count] [descending]" << endl; cerr << " book_offers [ [ [ []]]]]" << endl;