From 11117c75b72d98cc3a3cfe8dab5cbe6110fe9d22 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 28 Aug 2013 16:26:16 -0700 Subject: [PATCH] Infrastructure for the new tx_account command. --- modules/ripple_app/misc/NetworkOPs.cpp | 23 +++- modules/ripple_app/misc/NetworkOPs.h | 7 ++ modules/ripple_app/rpc/CallRPC.cpp | 67 +++++++++++ modules/ripple_app/rpc/CallRPC.h | 1 + modules/ripple_app/rpc/RPCHandler.cpp | 147 +++++++++++++++++++++++++ modules/ripple_app/rpc/RPCHandler.h | 1 + 6 files changed, 245 insertions(+), 1 deletion(-) diff --git a/modules/ripple_app/misc/NetworkOPs.cpp b/modules/ripple_app/misc/NetworkOPs.cpp index f7c595f787..0ea0d654f8 100644 --- a/modules/ripple_app/misc/NetworkOPs.cpp +++ b/modules/ripple_app/misc/NetworkOPs.cpp @@ -1324,7 +1324,8 @@ NetworkOPs::getAccountTxs (const RippleAddress& account, int32 minLedger, int32 rawMeta.resize (metaSize); db->getBinary ("TxnMeta", &*rawMeta.begin (), rawMeta.getLength ()); } - else rawMeta.resize (metaSize); + else + rawMeta.resize (metaSize); if (rawMeta.getLength() == 0) { // Work around a bug that could leave the metadata missing @@ -1336,7 +1337,13 @@ NetworkOPs::getAccountTxs (const RippleAddress& account, int32 minLedger, int32 } TransactionMetaSet::pointer meta = boost::make_shared (txn->getID (), txn->getLedger (), rawMeta.getData ()); + +#ifdef C11X + ret.push_back (std::pair (txn, meta)); +#else ret.push_back (std::pair (txn, meta)); +#endif + } } @@ -1410,6 +1417,20 @@ NetworkOPs::countAccountTxs (const RippleAddress& account, int32 minLedger, int3 return ret; } +std::vector< std::pair > +NetworkOPs::getTxsAccount (const RippleAddress& account, int32 minLedger, int32 maxLedger, bool forward, Json::Value& token, int limit, bool bAdmin) +{ // WRITEME + std::vector< std::pair > ret; + return ret; +} + +std::vector +NetworkOPs::getTxsAccountB (const RippleAddress& account, int32 minLedger, int32 maxLedger, bool forward, Json::Value& token, int limit, bool bAmind) +{ // WRITEME + std::vector ret; + return ret; +} + std::vector NetworkOPs::getLedgerAffectedAccounts (uint32 ledgerSeq) diff --git a/modules/ripple_app/misc/NetworkOPs.h b/modules/ripple_app/misc/NetworkOPs.h index d550220898..3d66506d50 100644 --- a/modules/ripple_app/misc/NetworkOPs.h +++ b/modules/ripple_app/misc/NetworkOPs.h @@ -335,10 +335,17 @@ public: std::vector< std::pair > getAccountTxs (const RippleAddress& account, int32 minLedger, int32 maxLedger, bool descending, uint32 offset, int limit, bool bAdmin); + std::vector< std::pair > + getTxsAccount (const RippleAddress& account, int32 minLedger, int32 maxLedger, bool forward, Json::Value& token, int limit, bool bAdmin); + typedef boost::tuple txnMetaLedgerType; + std::vector getAccountTxsB (const RippleAddress& account, int32 minLedger, int32 maxLedger, bool descending, uint32 offset, int limit, bool bAdmin); + std::vector + getTxsAccountB (const RippleAddress& account, int32 minLedger, int32 maxLedger, bool forward, Json::Value& token, int limit, bool bAdmin); + std::vector getLedgerAffectedAccounts (uint32 ledgerSeq); std::vector getLedgerTransactions (uint32 ledgerSeq); uint32 countAccountTxs (const RippleAddress& account, int32 minLedger, int32 maxLedger); diff --git a/modules/ripple_app/rpc/CallRPC.cpp b/modules/ripple_app/rpc/CallRPC.cpp index 127517df64..f1397d8991 100644 --- a/modules/ripple_app/rpc/CallRPC.cpp +++ b/modules/ripple_app/rpc/CallRPC.cpp @@ -197,6 +197,72 @@ Json::Value RPCParser::parseAccountTransactions (const Json::Value& jvParams) return jvRequest; } +// tx_account accountID [ledger_min [ledger_max [limit]]]] [binary] [count] [forward] +Json::Value RPCParser::parseTxAccount (const Json::Value& jvParams) +{ + Json::Value jvRequest (Json::objectValue); + RippleAddress raAccount; + unsigned int iParams = jvParams.size (); + + if (!raAccount.setAccountID (jvParams[0u].asString ())) + return rpcError (rpcACT_MALFORMED); + + jvRequest["account"] = raAccount.humanAccountID (); + + bool bDone = false; + + while (!bDone && iParams >= 2) + { + if (jvParams[iParams - 1].asString () == "binary") + { + jvRequest["binary"] = true; + --iParams; + } + else if (jvParams[iParams - 1].asString () == "count") + { + jvRequest["count"] = true; + --iParams; + } + else if (jvParams[iParams - 1].asString () == "forward") + { + jvRequest["forward"] = true; + --iParams; + } + else + { + bDone = true; + } + } + + if (1 == iParams) + { + nothing (); + } + else if (2 == iParams) + { + if (!jvParseLedger (jvRequest, jvParams[1u].asString ())) + return jvRequest; + } + else + { + int64 uLedgerMin = jvParams[1u].asInt (); + int64 uLedgerMax = jvParams[2u].asInt (); + + if (uLedgerMax != -1 && uLedgerMax < uLedgerMin) + { + return rpcError (rpcLGR_IDXS_INVALID); + } + + jvRequest["ledger_index_min"] = jvParams[1u].asInt (); + jvRequest["ledger_index_max"] = jvParams[2u].asInt (); + + if (iParams >= 4) + jvRequest["limit"] = jvParams[3u].asInt (); + } + + return jvRequest; +} + // book_offers [ [ [ [ []]]]] // limit: 0 = no limit // proof: 0 or 1 @@ -784,6 +850,7 @@ Json::Value RPCParser::parseCommand (std::string strMethod, Json::Value jvParams { "stop", &RPCParser::parseAsIs, 0, 0 }, // { "transaction_entry", &RPCParser::parseTransactionEntry, -1, -1 }, { "tx", &RPCParser::parseTx, 1, 2 }, + { "tx_account", &RPCParser::parseTxAccount, 1, 7 }, { "tx_history", &RPCParser::parseTxHistory, 1, 1 }, { "unl_add", &RPCParser::parseUnlAdd, 1, 2 }, diff --git a/modules/ripple_app/rpc/CallRPC.h b/modules/ripple_app/rpc/CallRPC.h index d61bf8224c..13e5661d30 100644 --- a/modules/ripple_app/rpc/CallRPC.h +++ b/modules/ripple_app/rpc/CallRPC.h @@ -50,6 +50,7 @@ private: Json::Value parseSignSubmit (const Json::Value& jvParams); Json::Value parseTx (const Json::Value& jvParams); Json::Value parseTxHistory (const Json::Value& jvParams); + Json::Value parseTxAccount (const Json::Value& jvParams); Json::Value parseUnlAdd (const Json::Value& jvParams); Json::Value parseUnlDelete (const Json::Value& jvParams); Json::Value parseValidationCreate (const Json::Value& jvParams); diff --git a/modules/ripple_app/rpc/RPCHandler.cpp b/modules/ripple_app/rpc/RPCHandler.cpp index 82595ffdcd..b160031425 100644 --- a/modules/ripple_app/rpc/RPCHandler.cpp +++ b/modules/ripple_app/rpc/RPCHandler.cpp @@ -2125,6 +2125,152 @@ Json::Value RPCHandler::doAccountTransactions (Json::Value params, LoadType* loa #endif } +// { +// account: account, +// ledger_index_min: ledger_index // optional, defaults to earliest +// ledger_index_max: ledger_index, // optional, defaults to latest +// binary: boolean, // optional, defaults to false +// forward: boolean, // optional, defaults to false +// limit: integer, // optional +// fwd_marker: opaque, // optional, resume forward +// rev_marker: opaque // optional, resume reverse +// } +Json::Value RPCHandler::doTxAccount (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder) +{ + RippleAddress raAccount; + int limit = params.isMember ("limit") ? params["limit"].asUInt () : -1; + bool bBinary = params.isMember ("binary") && params["binary"].asBool (); + bool bForward = params.isMember ("forward") && params["forward"].asBool (); + uint32 uLedgerMin; + uint32 uLedgerMax; + uint32 uValidatedMin; + uint32 uValidatedMax; + bool bValidated = mNetOps->getValidatedRange (uValidatedMin, uValidatedMax); + + if (!bValidated) + { + // Don't have a validated ledger range. + return rpcError (rpcLGR_IDXS_INVALID); + } + + if (!params.isMember ("account")) + return rpcError (rpcINVALID_PARAMS); + + if (!raAccount.setAccountID (params["account"].asString ())) + return rpcError (rpcACT_MALFORMED); + + if (params.isMember ("ledger_index_min") || params.isMember ("ledger_index_max")) + { + int64 iLedgerMin = params.isMember ("ledger_index_min") ? params["ledger_index_min"].asInt () : -1; + int64 iLedgerMax = params.isMember ("ledger_index_max") ? params["ledger_index_max"].asInt () : -1; + + + uLedgerMin = iLedgerMin == -1 ? uValidatedMin : iLedgerMin; + uLedgerMax = iLedgerMax == -1 ? uValidatedMax : iLedgerMax; + + if (uLedgerMax < uLedgerMin) + { + return rpcError (rpcLGR_IDXS_INVALID); + } + } + else + { + Ledger::pointer l; + Json::Value ret = lookupLedger (params, l); + + if (!l) + return ret; + + uLedgerMin = uLedgerMax = l->getLedgerSeq (); + } + + Json::Value resumeToken; + + if (params.isMember("fwd_marker")) + { + if ((!bForward) || params.isMember("rev_marker")) + return rpcError (rpcINVALID_PARAMS); + resumeToken = params["fwd_marker"]; + } + if (params.isMember("rev_marker")) + { + if (bForward || params.isMember("fwd_marker")) + return rpcError (rpcINVALID_PARAMS); + resumeToken = params["rev_marker"]; + } + +#ifndef BEAST_DEBUG + + try + { +#endif + masterLockHolder.unlock (); + + Json::Value ret (Json::objectValue); + + ret["account"] = raAccount.humanAccountID (); + Json::Value& jvTxns = (ret["transactions"] = Json::arrayValue); + + if (bBinary) + { + std::vector txns = + mNetOps->getTxsAccountB (raAccount, uLedgerMin, uLedgerMax, bForward, resumeToken, limit, mRole == ADMIN); + + for (std::vector::const_iterator it = txns.begin (), end = txns.end (); + it != end; ++it) + { + Json::Value& jvObj = jvTxns.append (Json::objectValue); + + uint32 uLedgerIndex = it->get<2> (); + jvObj["tx_blob"] = it->get<0> (); + jvObj["meta"] = it->get<1> (); + jvObj["ledger_index"] = uLedgerIndex; + jvObj["validated"] = bValidated && uValidatedMin <= uLedgerIndex && uValidatedMax >= uLedgerIndex; + + } + } + else + { + std::vector< std::pair > txns = + mNetOps->getTxsAccount (raAccount, uLedgerMin, uLedgerMax, bForward, resumeToken, limit, mRole == ADMIN); + + for (std::vector< std::pair >::iterator it = txns.begin (), end = txns.end (); it != end; ++it) + { + Json::Value& jvObj = jvTxns.append (Json::objectValue); + + if (it->first) + jvObj["tx"] = it->first->getJson (1); + + if (it->second) + { + uint32 uLedgerIndex = it->second->getLgrSeq (); + + jvObj["meta"] = it->second->getJson (0); + jvObj["validated"] = bValidated && uValidatedMin <= uLedgerIndex && uValidatedMax >= uLedgerIndex; + } + + } + } + + //Add information about the original query + ret["ledger_index_min"] = uLedgerMin; + ret["ledger_index_max"] = uLedgerMax; + if (params.isMember ("limit")) + ret["limit"] = limit; + if (!resumeToken.isNull()) + ret[bForward ? "fwd_token" : "rev_token"] = resumeToken; + + return ret; +#ifndef BEAST_DEBUG + } + catch (...) + { + return rpcError (rpcINTERNAL); + } + +#endif +} + // { // secret: // optional // } @@ -3676,6 +3822,7 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp { "stop", &RPCHandler::doStop, true, optNone }, { "transaction_entry", &RPCHandler::doTransactionEntry, false, optCurrent }, { "tx", &RPCHandler::doTx, false, optNetwork }, + { "tx_account", &RPCHandler::doTxAccount, false, optNetwork }, { "tx_history", &RPCHandler::doTxHistory, false, optNone }, { "unl_add", &RPCHandler::doUnlAdd, true, optNone }, diff --git a/modules/ripple_app/rpc/RPCHandler.h b/modules/ripple_app/rpc/RPCHandler.h index ea39664b1b..6522f989be 100644 --- a/modules/ripple_app/rpc/RPCHandler.h +++ b/modules/ripple_app/rpc/RPCHandler.h @@ -130,6 +130,7 @@ private: Json::Value doSubscribe (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doTransactionEntry (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doTx (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); + Json::Value doTxAccount (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doTxHistory (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doUnlAdd (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); Json::Value doUnlDelete (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);