diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj index 2736a26f66..d43197f18d 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj +++ b/Builds/VisualStudio2012/RippleD.vcxproj @@ -1762,7 +1762,7 @@ - + diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters index d75c96911a..bde464967b 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters @@ -600,9 +600,6 @@ 1. Modules\ripple_app\refactored - - 1. Modules\ripple_app\refactored - 1. Modules\ripple_app\refactored @@ -900,6 +897,9 @@ 1. Modules\ripple_core\functional + + 1. Modules\ripple_app\refactored + @@ -1409,9 +1409,6 @@ 1. Modules\ripple_app\refactored - - 1. Modules\ripple_app\refactored - 1. Modules\ripple_app\refactored @@ -1725,6 +1722,9 @@ 1. Modules\ripple_core\functional + + 1. Modules\ripple_app\refactored + diff --git a/modules/ripple_app/ripple_app.cpp b/modules/ripple_app/ripple_app.cpp index ba89ab17bf..5856c38bb2 100644 --- a/modules/ripple_app/ripple_app.cpp +++ b/modules/ripple_app/ripple_app.cpp @@ -135,7 +135,7 @@ #include "src/cpp/ripple/Ledger.h" #include "src/cpp/ripple/SerializedValidation.h" -#include "src/cpp/ripple/ripple_LoadManager.h" +#include "src/cpp/ripple/ripple_ILoadManager.h" // These have few dependencies #include "src/cpp/ripple/ripple_DatabaseCon.h" diff --git a/modules/ripple_client/ripple_client.cpp b/modules/ripple_client/ripple_client.cpp index e4d438f9c5..e626a4d7a2 100644 --- a/modules/ripple_client/ripple_client.cpp +++ b/modules/ripple_client/ripple_client.cpp @@ -10,6 +10,7 @@ @ingroup ripple_client */ +/* #include #include @@ -22,6 +23,8 @@ #include "../ripple_data/ripple_data.h" +*/ + /* #include "src/cpp/ripple/ripple_InfoSub.h" @@ -44,7 +47,7 @@ #include "src/cpp/ripple/Ledger.h" #include "src/cpp/ripple/ripple_LedgerEntrySet.h" #include "src/cpp/ripple/TransactionEngine.h" -#include "src/cpp/ripple/ripple_LoadManager.h" +#include "src/cpp/ripple/ripple_ILoadManager.h" #include "src/cpp/ripple/ripple_Peer.h" #include "src/cpp/ripple/ripple_PeerSet.h" #include "src/cpp/ripple/ripple_InboundLedger.h" diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 0ffd9e0fa5..a9e7f51965 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -616,6 +616,9 @@ void NetworkOPs::checkState (const boost::system::error_code& result) if ((result == boost::asio::error::operation_aborted) || theConfig.RUN_STANDALONE) { + // VFALCO NOTE Should never get here. This is probably dead code. + // If RUN_STANDALONE is set then this function isn't called. + // WriteLog (lsFATAL, NetworkOPs) << "Network state timer error: " << result; return; } @@ -623,7 +626,7 @@ void NetworkOPs::checkState (const boost::system::error_code& result) { ScopedLock sl (theApp->getMasterLock ()); - theApp->getLoadManager ().noDeadLock (); + theApp->getLoadManager ().resetDeadlockDetector (); std::vector peerList = theApp->getPeers ().getPeerVector (); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index f333559719..991fe22357 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -10,21 +10,17 @@ SETUP_LOG (RPCHandler) -static const int rpcCOST_DEFAULT = 10; -static const int rpcCOST_EXCEPTION = 20; -static const int rpcCOST_EXPENSIVE = 50; - -int iAdminGet (const Json::Value& jvRequest, const std::string& strRemoteIp) +int iAdminGet (const Json::Value& params, const std::string& strRemoteIp) { int iRole; - bool bPasswordSupplied = jvRequest.isMember ("admin_user") || jvRequest.isMember ("admin_password"); + bool bPasswordSupplied = params.isMember ("admin_user") || params.isMember ("admin_password"); bool bPasswordRequired = !theConfig.RPC_ADMIN_USER.empty () || !theConfig.RPC_ADMIN_PASSWORD.empty (); bool bPasswordWrong = bPasswordSupplied ? bPasswordRequired // Supplied, required, and incorrect. - ? theConfig.RPC_ADMIN_USER != (jvRequest.isMember ("admin_user") ? jvRequest["admin_user"].asString () : "") - || theConfig.RPC_ADMIN_PASSWORD != (jvRequest.isMember ("admin_user") ? jvRequest["admin_password"].asString () : "") + ? theConfig.RPC_ADMIN_USER != (params.isMember ("admin_user") ? params["admin_user"].asString () : "") + || theConfig.RPC_ADMIN_PASSWORD != (params.isMember ("admin_user") ? params["admin_password"].asString () : "") // Supplied and not required. : true : false; @@ -32,7 +28,7 @@ int iAdminGet (const Json::Value& jvRequest, const std::string& strRemoteIp) bool bAdminIP = false; BOOST_FOREACH (const std::string & strAllowIp, theConfig.RPC_ADMIN_ALLOW) -{ + { if (strAllowIp == strRemoteIp) bAdminIP = true; } @@ -62,28 +58,28 @@ RPCHandler::RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub) : mNetOps ; } -Json::Value RPCHandler::transactionSign (Json::Value jvRequest, bool bSubmit, bool bFailHard, ScopedLock& mlh) +Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool bFailHard, ScopedLock& mlh) { Json::Value jvResult; RippleAddress naSeed; RippleAddress raSrcAddressID; - bool bOffline = jvRequest.isMember ("offline") && jvRequest["offline"].asBool (); + bool bOffline = params.isMember ("offline") && params["offline"].asBool (); - WriteLog (lsDEBUG, RPCHandler) << boost::str (boost::format ("transactionSign: %s") % jvRequest); + WriteLog (lsDEBUG, RPCHandler) << boost::str (boost::format ("transactionSign: %s") % params); - if (!jvRequest.isMember ("secret") || !jvRequest.isMember ("tx_json")) + if (!params.isMember ("secret") || !params.isMember ("tx_json")) { return rpcError (rpcINVALID_PARAMS); } - Json::Value txJSON = jvRequest["tx_json"]; + Json::Value txJSON = params["tx_json"]; if (!txJSON.isObject ()) { return rpcError (rpcINVALID_PARAMS); } - if (!naSeed.setSeedGeneric (jvRequest["secret"].asString ())) + if (!naSeed.setSeedGeneric (params["secret"].asString ())) { return rpcError (rpcBAD_SEED); } @@ -137,13 +133,13 @@ Json::Value RPCHandler::transactionSign (Json::Value jvRequest, bool bSubmit, bo txJSON["Fee"] = (int) theConfig.FEE_DEFAULT; } - if (txJSON.isMember ("Paths") && jvRequest.isMember ("build_path")) + if (txJSON.isMember ("Paths") && params.isMember ("build_path")) { // Asking to build a path when providing one is an error. return rpcError (rpcINVALID_PARAMS); } - if (!txJSON.isMember ("Paths") && txJSON.isMember ("Amount") && jvRequest.isMember ("build_path")) + if (!txJSON.isMember ("Paths") && txJSON.isMember ("Amount") && params.isMember ("build_path")) { // Need a ripple path. STPathSet spsPaths; @@ -241,7 +237,7 @@ Json::Value RPCHandler::transactionSign (Json::Value jvRequest, bool bSubmit, bo bool bHaveAuthKey = false; RippleAddress naAuthorizedPublic; - RippleAddress naSecret = RippleAddress::createSeedGeneric (jvRequest["secret"].asString ()); + RippleAddress naSecret = RippleAddress::createSeedGeneric (params["secret"].asString ()); RippleAddress naMasterGenerator = RippleAddress::createGeneratorPublic (naSecret); // Find the index of Account from the master generator, so we can generate the public and private keys. @@ -316,7 +312,7 @@ Json::Value RPCHandler::transactionSign (Json::Value jvRequest, bool bSubmit, bo return jvResult; } - if (jvRequest.isMember ("debug_signing")) + if (params.isMember ("debug_signing")) { jvResult["tx_unsigned"] = strHex (stpTrans->getSerializer ().peekData ()); jvResult["tx_signing_hash"] = stpTrans->getSigningHash ().ToString (); @@ -592,21 +588,21 @@ Json::Value RPCHandler::accountFromString (Ledger::ref lrLedger, RippleAddress& // ledger_hash : // ledger_index : // } -Json::Value RPCHandler::doAccountInfo (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doAccountInfo (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { Ledger::pointer lpLedger; - Json::Value jvResult = lookupLedger (jvRequest, lpLedger); + Json::Value jvResult = lookupLedger (params, lpLedger); if (!lpLedger) return jvResult; - if (!jvRequest.isMember ("account") && !jvRequest.isMember ("ident")) + if (!params.isMember ("account") && !params.isMember ("ident")) return rpcError (rpcINVALID_PARAMS); - std::string strIdent = jvRequest.isMember ("account") ? jvRequest["account"].asString () : jvRequest["ident"].asString (); + std::string strIdent = params.isMember ("account") ? params["account"].asString () : params["ident"].asString (); bool bIndex; - int iIndex = jvRequest.isMember ("account_index") ? jvRequest["account_index"].asUInt () : 0; - bool bStrict = jvRequest.isMember ("strict") && jvRequest["strict"].asBool (); + int iIndex = params.isMember ("account_index") ? params["account_index"].asUInt () : 0; + bool bStrict = params.isMember ("strict") && params["strict"].asBool (); RippleAddress naAccount; // Get info on account. @@ -637,16 +633,16 @@ Json::Value RPCHandler::doAccountInfo (Json::Value jvRequest, int& cost, ScopedL // port: // } // XXX Might allow domain for manual connections. -Json::Value RPCHandler::doConnect (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doConnect (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { if (theConfig.RUN_STANDALONE) return "cannot connect in standalone mode"; - if (!jvRequest.isMember ("ip")) + if (!params.isMember ("ip")) return rpcError (rpcINVALID_PARAMS); - std::string strIp = jvRequest["ip"].asString (); - int iPort = jvRequest.isMember ("port") ? jvRequest["port"].asInt () : -1; + std::string strIp = params["ip"].asString (); + int iPort = params.isMember ("port") ? params["port"].asInt () : -1; // XXX Validate legal IP and port theApp->getPeers ().connectTo (strIp, iPort); @@ -658,12 +654,12 @@ Json::Value RPCHandler::doConnect (Json::Value jvRequest, int& cost, ScopedLock& // { // key: // } -Json::Value RPCHandler::doDataDelete (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doDataDelete (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("key")) + if (!params.isMember ("key")) return rpcError (rpcINVALID_PARAMS); - std::string strKey = jvRequest["key"].asString (); + std::string strKey = params["key"].asString (); Json::Value ret = Json::Value (Json::objectValue); @@ -684,12 +680,12 @@ Json::Value RPCHandler::doDataDelete (Json::Value jvRequest, int& cost, ScopedLo // { // key: // } -Json::Value RPCHandler::doDataFetch (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doDataFetch (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("key")) + if (!params.isMember ("key")) return rpcError (rpcINVALID_PARAMS); - std::string strKey = jvRequest["key"].asString (); + std::string strKey = params["key"].asString (); std::string strValue; Json::Value ret = Json::Value (Json::objectValue); @@ -708,14 +704,14 @@ Json::Value RPCHandler::doDataFetch (Json::Value jvRequest, int& cost, ScopedLoc // key: // value: // } -Json::Value RPCHandler::doDataStore (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doDataStore (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("key") - || !jvRequest.isMember ("value")) + if (!params.isMember ("key") + || !params.isMember ("value")) return rpcError (rpcINVALID_PARAMS); - std::string strKey = jvRequest["key"].asString (); - std::string strValue = jvRequest["value"].asString (); + std::string strKey = params["key"].asString (); + std::string strValue = params["value"].asString (); Json::Value ret = Json::Value (Json::objectValue); @@ -769,14 +765,14 @@ Json::Value RPCHandler::doNicknameInfo (Json::Value params) // 'account_index' : // optional // } // XXX This would be better if it took the ledger. -Json::Value RPCHandler::doOwnerInfo (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doOwnerInfo (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("account") && !jvRequest.isMember ("ident")) + if (!params.isMember ("account") && !params.isMember ("ident")) return rpcError (rpcINVALID_PARAMS); - std::string strIdent = jvRequest.isMember ("account") ? jvRequest["account"].asString () : jvRequest["ident"].asString (); + std::string strIdent = params.isMember ("account") ? params["account"].asString () : params["ident"].asString (); bool bIndex; - int iIndex = jvRequest.isMember ("account_index") ? jvRequest["account_index"].asUInt () : 0; + int iIndex = params.isMember ("account_index") ? params["account_index"].asUInt () : 0; RippleAddress raAccount; Json::Value ret; @@ -794,7 +790,7 @@ Json::Value RPCHandler::doOwnerInfo (Json::Value jvRequest, int& cost, ScopedLoc return ret; } -Json::Value RPCHandler::doPeers (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doPeers (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { Json::Value jvResult (Json::objectValue); @@ -803,7 +799,7 @@ Json::Value RPCHandler::doPeers (Json::Value, int& cost, ScopedLock& MasterLockH return jvResult; } -Json::Value RPCHandler::doPing (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doPing (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { return Json::Value (Json::objectValue); } @@ -813,10 +809,10 @@ Json::Value RPCHandler::doPing (Json::Value, int& cost, ScopedLock& MasterLockHo // 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 (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doProfile (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { /* need to fix now that sharedOfferCreate is gone - int iArgs = jvRequest.size(); + int iArgs = params.size(); RippleAddress naSeedA; RippleAddress naAccountA; uint160 uCurrencyOfferA; @@ -826,26 +822,26 @@ Json::Value RPCHandler::doProfile (Json::Value jvRequest, int& cost, ScopedLock& uint32 iCount = 100; bool bSubmit = false; - if (iArgs < 6 || "offers" != jvRequest[0u].asString()) + if (iArgs < 6 || "offers" != params[0u].asString()) { return rpcError(rpcINVALID_PARAMS); } - if (!naSeedA.setSeedGeneric(jvRequest[1u].asString())) // + if (!naSeedA.setSeedGeneric(params[1u].asString())) // return rpcError(rpcINVALID_PARAMS); - naAccountA.setAccountID(jvRequest[2u].asString()); // + naAccountA.setAccountID(params[2u].asString()); // - if (!STAmount::currencyFromString(uCurrencyOfferA, jvRequest[3u].asString())) // + if (!STAmount::currencyFromString(uCurrencyOfferA, params[3u].asString())) // return rpcError(rpcINVALID_PARAMS); - naAccountB.setAccountID(jvRequest[4u].asString()); // - if (!STAmount::currencyFromString(uCurrencyOfferB, jvRequest[5u].asString())) // + naAccountB.setAccountID(params[4u].asString()); // + if (!STAmount::currencyFromString(uCurrencyOfferB, params[5u].asString())) // return rpcError(rpcINVALID_PARAMS); - iCount = lexical_cast_s(jvRequest[6u].asString()); + iCount = lexical_cast_s(params[6u].asString()); - if (iArgs >= 8 && "false" != jvRequest[7u].asString()) + if (iArgs >= 8 && "false" != params[7u].asString()) bSubmit = true; Log::setMinSeverity(lsFATAL,true); @@ -905,24 +901,24 @@ Json::Value RPCHandler::doProfile (Json::Value jvRequest, int& cost, ScopedLock& // difficulty: // optional // secret: // optional // } -Json::Value RPCHandler::doProofCreate (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doProofCreate (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { MasterLockHolder.unlock (); // XXX: Add ability to create proof with arbitrary time Json::Value jvResult (Json::objectValue); - if (jvRequest.isMember ("difficulty") || jvRequest.isMember ("secret")) + if (params.isMember ("difficulty") || params.isMember ("secret")) { // VFALCO TODO why aren't we using the app's factory? beast::ScopedPointer pgGen (IProofOfWorkFactory::New ()); - if (jvRequest.isMember ("difficulty")) + if (params.isMember ("difficulty")) { - if (!jvRequest["difficulty"].isIntegral ()) + if (!params["difficulty"].isIntegral ()) return rpcError (rpcINVALID_PARAMS); - int iDifficulty = jvRequest["difficulty"].asInt (); + int iDifficulty = params["difficulty"].asInt (); if (iDifficulty < 0 || iDifficulty > ProofOfWork::sMaxDifficulty) return rpcError (rpcINVALID_PARAMS); @@ -930,9 +926,9 @@ Json::Value RPCHandler::doProofCreate (Json::Value jvRequest, int& cost, ScopedL pgGen->setDifficulty (iDifficulty); } - if (jvRequest.isMember ("secret")) + if (params.isMember ("secret")) { - uint256 uSecret (jvRequest["secret"].asString ()); + uint256 uSecret (params["secret"].asString ()); pgGen->setSecret (uSecret); } @@ -950,16 +946,16 @@ Json::Value RPCHandler::doProofCreate (Json::Value jvRequest, int& cost, ScopedL // { // token: // } -Json::Value RPCHandler::doProofSolve (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doProofSolve (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { MasterLockHolder.unlock (); Json::Value jvResult; - if (!jvRequest.isMember ("token")) + if (!params.isMember ("token")) return rpcError (rpcINVALID_PARAMS); - std::string strToken = jvRequest["token"].asString (); + std::string strToken = params["token"].asString (); if (!ProofOfWork::validateToken (strToken)) return rpcError (rpcINVALID_PARAMS); @@ -980,35 +976,35 @@ Json::Value RPCHandler::doProofSolve (Json::Value jvRequest, int& cost, ScopedLo // difficulty: // optional // secret: // optional // } -Json::Value RPCHandler::doProofVerify (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doProofVerify (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { MasterLockHolder.unlock (); // XXX Add ability to check proof against arbitrary time Json::Value jvResult; - if (!jvRequest.isMember ("token")) + if (!params.isMember ("token")) return rpcError (rpcINVALID_PARAMS); - if (!jvRequest.isMember ("solution")) + if (!params.isMember ("solution")) return rpcError (rpcINVALID_PARAMS); - std::string strToken = jvRequest["token"].asString (); - uint256 uSolution (jvRequest["solution"].asString ()); + std::string strToken = params["token"].asString (); + uint256 uSolution (params["solution"].asString ()); POWResult prResult; - if (jvRequest.isMember ("difficulty") || jvRequest.isMember ("secret")) + if (params.isMember ("difficulty") || params.isMember ("secret")) { // VFALCO TODO why aren't we using the app's factory? beast::ScopedPointer pgGen (IProofOfWorkFactory::New ()); - if (jvRequest.isMember ("difficulty")) + if (params.isMember ("difficulty")) { - if (!jvRequest["difficulty"].isIntegral ()) + if (!params["difficulty"].isIntegral ()) return rpcError (rpcINVALID_PARAMS); - int iDifficulty = jvRequest["difficulty"].asInt (); + int iDifficulty = params["difficulty"].asInt (); if (iDifficulty < 0 || iDifficulty > ProofOfWork::sMaxDifficulty) return rpcError (rpcINVALID_PARAMS); @@ -1016,9 +1012,9 @@ Json::Value RPCHandler::doProofVerify (Json::Value jvRequest, int& cost, ScopedL pgGen->setDifficulty (iDifficulty); } - if (jvRequest.isMember ("secret")) + if (params.isMember ("secret")) { - uint256 uSecret (jvRequest["secret"].asString ()); + uint256 uSecret (params["secret"].asString ()); pgGen->setSecret (uSecret); } @@ -1050,10 +1046,10 @@ Json::Value RPCHandler::doProofVerify (Json::Value jvRequest, int& cost, ScopedL // ledger_hash : // ledger_index : // } -Json::Value RPCHandler::doAccountLines (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doAccountLines (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { Ledger::pointer lpLedger; - Json::Value jvResult = lookupLedger (jvRequest, lpLedger); + Json::Value jvResult = lookupLedger (params, lpLedger); if (!lpLedger) return jvResult; @@ -1066,12 +1062,12 @@ Json::Value RPCHandler::doAccountLines (Json::Value jvRequest, int& cost, Scoped bUnlocked = true; } - if (!jvRequest.isMember ("account")) + if (!params.isMember ("account")) return rpcError (rpcINVALID_PARAMS); - std::string strIdent = jvRequest["account"].asString (); - bool bIndex = jvRequest.isMember ("account_index"); - int iIndex = bIndex ? jvRequest["account_index"].asUInt () : 0; + std::string strIdent = params["account"].asString (); + bool bIndex = params.isMember ("account_index"); + int iIndex = bIndex ? params["account_index"].asUInt () : 0; RippleAddress raAccount; @@ -1080,9 +1076,9 @@ Json::Value RPCHandler::doAccountLines (Json::Value jvRequest, int& cost, Scoped if (!jvResult.empty ()) return jvResult; - std::string strPeer = jvRequest.isMember ("peer") ? jvRequest["peer"].asString () : ""; - bool bPeerIndex = jvRequest.isMember ("peer_index"); - int iPeerIndex = bIndex ? jvRequest["peer_index"].asUInt () : 0; + std::string strPeer = params.isMember ("peer") ? params["peer"].asString () : ""; + bool bPeerIndex = params.isMember ("peer_index"); + int iPeerIndex = bIndex ? params["peer_index"].asUInt () : 0; RippleAddress raPeer; @@ -1172,10 +1168,10 @@ static void offerAdder (Json::Value& jvLines, SLE::ref offer) // ledger_hash : // ledger_index : // } -Json::Value RPCHandler::doAccountOffers (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doAccountOffers (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { Ledger::pointer lpLedger; - Json::Value jvResult = lookupLedger (jvRequest, lpLedger); + Json::Value jvResult = lookupLedger (params, lpLedger); if (!lpLedger) return jvResult; @@ -1188,12 +1184,12 @@ Json::Value RPCHandler::doAccountOffers (Json::Value jvRequest, int& cost, Scope bUnlocked = true; } - if (!jvRequest.isMember ("account")) + if (!params.isMember ("account")) return rpcError (rpcINVALID_PARAMS); - std::string strIdent = jvRequest["account"].asString (); - bool bIndex = jvRequest.isMember ("account_index"); - int iIndex = bIndex ? jvRequest["account_index"].asUInt () : 0; + std::string strIdent = params["account"].asString (); + bool bIndex = params.isMember ("account_index"); + int iIndex = bIndex ? params["account_index"].asUInt () : 0; RippleAddress raAccount; @@ -1240,7 +1236,7 @@ Json::Value RPCHandler::doAccountOffers (Json::Value jvRequest, int& cost, Scope // "limit" : integer, // Optional. // "proof" : boolean // Defaults to false. // } -Json::Value RPCHandler::doBookOffers (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doBookOffers (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { if (theApp->getJobQueue ().getJobCountGE (jtCLIENT) > 200) { @@ -1248,7 +1244,7 @@ Json::Value RPCHandler::doBookOffers (Json::Value jvRequest, int& cost, ScopedLo } Ledger::pointer lpLedger; - Json::Value jvResult = lookupLedger (jvRequest, lpLedger); + Json::Value jvResult = lookupLedger (params, lpLedger); if (!lpLedger) return jvResult; @@ -1256,12 +1252,12 @@ Json::Value RPCHandler::doBookOffers (Json::Value jvRequest, int& cost, ScopedLo if (lpLedger->isImmutable ()) MasterLockHolder.unlock (); - if (!jvRequest.isMember ("taker_pays") || !jvRequest.isMember ("taker_gets") || !jvRequest["taker_pays"].isObject () || !jvRequest["taker_gets"].isObject ()) + if (!params.isMember ("taker_pays") || !params.isMember ("taker_gets") || !params["taker_pays"].isObject () || !params["taker_gets"].isObject ()) return rpcError (rpcINVALID_PARAMS); uint160 uTakerPaysCurrencyID; uint160 uTakerPaysIssuerID; - const Json::Value& jvTakerPays = jvRequest["taker_pays"]; + const Json::Value& jvTakerPays = params["taker_pays"]; // Parse mandatory currency. if (!jvTakerPays.isMember ("currency") @@ -1286,7 +1282,7 @@ Json::Value RPCHandler::doBookOffers (Json::Value jvRequest, int& cost, ScopedLo uint160 uTakerGetsCurrencyID; uint160 uTakerGetsIssuerID; - const Json::Value& jvTakerGets = jvRequest["taker_gets"]; + const Json::Value& jvTakerGets = params["taker_gets"]; // Parse mandatory currency. if (!jvTakerGets.isMember ("currency") @@ -1319,18 +1315,18 @@ Json::Value RPCHandler::doBookOffers (Json::Value jvRequest, int& cost, ScopedLo RippleAddress raTakerID; - if (!jvRequest.isMember ("taker")) + if (!params.isMember ("taker")) { raTakerID.setAccountID (ACCOUNT_ONE); } - else if (!raTakerID.setAccountID (jvRequest["taker"].asString ())) + else if (!raTakerID.setAccountID (params["taker"].asString ())) { return rpcError (rpcBAD_ISSUER); } - const bool bProof = jvRequest.isMember ("proof"); - const unsigned int iLimit = jvRequest.isMember ("limit") ? jvRequest["limit"].asUInt () : 0; - const Json::Value jvMarker = jvRequest.isMember ("marker") ? jvRequest["marker"] : Json::Value (Json::nullValue); + const bool bProof = params.isMember ("proof"); + const unsigned int iLimit = params.isMember ("limit") ? params["limit"].asUInt () : 0; + const Json::Value jvMarker = params.isMember ("marker") ? params["marker"] : Json::Value (Json::nullValue); mNetOps->getBookPage (lpLedger, uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID, raTakerID.getAccountID (), bProof, iLimit, jvMarker, jvResult); @@ -1341,7 +1337,7 @@ Json::Value RPCHandler::doBookOffers (Json::Value jvRequest, int& cost, ScopedLo // { // random: // } -Json::Value RPCHandler::doRandom (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doRandom (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { MasterLockHolder.unlock (); uint256 uRandom; @@ -1362,21 +1358,21 @@ Json::Value RPCHandler::doRandom (Json::Value jvRequest, int& cost, ScopedLock& } } -Json::Value RPCHandler::doPathFind (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doPathFind (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("subcommand") || !jvRequest["subcommand"].isString ()) + if (!params.isMember ("subcommand") || !params["subcommand"].isString ()) return rpcError (rpcINVALID_PARAMS); if (!mInfoSub) return rpcError (rpcNO_EVENTS); - std::string sSubCommand = jvRequest["subcommand"].asString (); + std::string sSubCommand = params["subcommand"].asString (); if (sSubCommand == "create") { mInfoSub->clearPathRequest (); PathRequest::pointer request = boost::make_shared (mInfoSub); - Json::Value result = request->doCreate (mNetOps->getClosedLedger (), jvRequest); + Json::Value result = request->doCreate (mNetOps->getClosedLedger (), params); if (request->isValid ()) { @@ -1395,7 +1391,7 @@ Json::Value RPCHandler::doPathFind (Json::Value jvRequest, int& cost, ScopedLock return rpcError (rpcNO_PF_REQUEST); mInfoSub->clearPathRequest (); - return request->doClose (jvRequest); + return request->doClose (params); } if (sSubCommand == "status") @@ -1405,7 +1401,7 @@ Json::Value RPCHandler::doPathFind (Json::Value jvRequest, int& cost, ScopedLock if (!request) return rpcNO_PF_REQUEST; - return request->doStatus (jvRequest); + return request->doStatus (params); } return rpcError (rpcINVALID_PARAMS); @@ -1417,7 +1413,7 @@ Json::Value RPCHandler::doPathFind (Json::Value jvRequest, int& cost, ScopedLock // - Allows clients to verify path exists. // - Return canonicalized path. // - From a trusted server, allows clients to use path without manipulation. -Json::Value RPCHandler::doRipplePathFind (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doRipplePathFind (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { int jc = theApp->getJobQueue ().getJobCountGE (jtCLIENT); @@ -1431,33 +1427,33 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value jvRequest, int& cost, Scop RippleAddress raDst; STAmount saDstAmount; Ledger::pointer lpLedger; - Json::Value jvResult = lookupLedger (jvRequest, lpLedger); + Json::Value jvResult = lookupLedger (params, lpLedger); if (!lpLedger) return jvResult; - if (!jvRequest.isMember ("source_account")) + if (!params.isMember ("source_account")) { jvResult = rpcError (rpcSRC_ACT_MISSING); } - else if (!jvRequest["source_account"].isString () - || !raSrc.setAccountID (jvRequest["source_account"].asString ())) + else if (!params["source_account"].isString () + || !raSrc.setAccountID (params["source_account"].asString ())) { jvResult = rpcError (rpcSRC_ACT_MALFORMED); } - else if (!jvRequest.isMember ("destination_account")) + else if (!params.isMember ("destination_account")) { jvResult = rpcError (rpcDST_ACT_MISSING); } - else if (!jvRequest["destination_account"].isString () - || !raDst.setAccountID (jvRequest["destination_account"].asString ())) + else if (!params["destination_account"].isString () + || !raDst.setAccountID (params["destination_account"].asString ())) { jvResult = rpcError (rpcDST_ACT_MALFORMED); } else if ( // Parse saDstAmount. - !jvRequest.isMember ("destination_amount") - || !saDstAmount.bSetJson (jvRequest["destination_amount"]) + !params.isMember ("destination_amount") + || !saDstAmount.bSetJson (params["destination_amount"]) || (!!saDstAmount.getCurrency () && (!saDstAmount.getIssuer () || ACCOUNT_ONE == saDstAmount.getIssuer ()))) { WriteLog (lsINFO, RPCHandler) << "Bad destination_amount."; @@ -1465,9 +1461,9 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value jvRequest, int& cost, Scop } else if ( // Checks on source_currencies. - jvRequest.isMember ("source_currencies") - && (!jvRequest["source_currencies"].isArray () - || !jvRequest["source_currencies"].size ()) // Don't allow empty currencies. + params.isMember ("source_currencies") + && (!params["source_currencies"].isArray () + || !params["source_currencies"].size ()) // Don't allow empty currencies. ) { WriteLog (lsINFO, RPCHandler) << "Bad source_currencies."; @@ -1477,9 +1473,9 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value jvRequest, int& cost, Scop { Json::Value jvSrcCurrencies; - if (jvRequest.isMember ("source_currencies")) + if (params.isMember ("source_currencies")) { - jvSrcCurrencies = jvRequest["source_currencies"]; + jvSrcCurrencies = params["source_currencies"]; } else { @@ -1497,7 +1493,7 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value jvRequest, int& cost, Scop } } - cost = rpcCOST_EXPENSIVE; + *loadType = LT_RPCBurden; Ledger::pointer lSnapShot = boost::make_shared (boost::ref (*lpLedger), false); MasterLockHolder.unlock (); // As long as we have a locked copy of the ledger, we can unlock. @@ -1649,35 +1645,35 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value jvRequest, int& cost, Scop // tx_json: , // secret: // } -Json::Value RPCHandler::doSign (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doSign (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - cost = rpcCOST_EXPENSIVE; - bool bFailHard = jvRequest.isMember ("fail_hard") && jvRequest["fail_hard"].asBool (); - return transactionSign (jvRequest, false, bFailHard, MasterLockHolder); + *loadType = LT_RPCBurden; + bool bFailHard = params.isMember ("fail_hard") && params["fail_hard"].asBool (); + return transactionSign (params, false, bFailHard, MasterLockHolder); } // { // tx_json: , // secret: // } -Json::Value RPCHandler::doSubmit (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doSubmit (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("tx_blob")) + if (!params.isMember ("tx_blob")) { - bool bFailHard = jvRequest.isMember ("fail_hard") && jvRequest["fail_hard"].asBool (); - return transactionSign (jvRequest, true, bFailHard, MasterLockHolder); + bool bFailHard = params.isMember ("fail_hard") && params["fail_hard"].asBool (); + return transactionSign (params, true, bFailHard, MasterLockHolder); } Json::Value jvResult; - Blob vucBlob (strUnHex (jvRequest["tx_blob"].asString ())); + Blob vucBlob (strUnHex (params["tx_blob"].asString ())); if (!vucBlob.size ()) { return rpcError (rpcINVALID_PARAMS); } - cost = rpcCOST_EXPENSIVE; + *loadType = LT_RPCBurden; Serializer sTrans (vucBlob); SerializerIterator sitTrans (sTrans); @@ -1713,7 +1709,7 @@ Json::Value RPCHandler::doSubmit (Json::Value jvRequest, int& cost, ScopedLock& try { (void) mNetOps->processTransaction (tpTrans, mRole == ADMIN, - jvRequest.isMember ("fail_hard") && jvRequest["fail_hard"].asBool ()); + params.isMember ("fail_hard") && params["fail_hard"].asBool ()); } catch (std::exception& e) { @@ -1753,7 +1749,7 @@ Json::Value RPCHandler::doSubmit (Json::Value jvRequest, int& cost, ScopedLock& } } -Json::Value RPCHandler::doConsensusInfo (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doConsensusInfo (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { Json::Value ret (Json::objectValue); @@ -1762,7 +1758,7 @@ Json::Value RPCHandler::doConsensusInfo (Json::Value, int& cost, ScopedLock& Mas return ret; } -Json::Value RPCHandler::doServerInfo (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doServerInfo (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { Json::Value ret (Json::objectValue); @@ -1771,7 +1767,7 @@ Json::Value RPCHandler::doServerInfo (Json::Value, int& cost, ScopedLock& Master return ret; } -Json::Value RPCHandler::doServerState (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doServerState (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { Json::Value ret (Json::objectValue); @@ -1783,14 +1779,14 @@ Json::Value RPCHandler::doServerState (Json::Value, int& cost, ScopedLock& Maste // { // start: // } -Json::Value RPCHandler::doTxHistory (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doTxHistory (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { MasterLockHolder.unlock (); - if (!jvRequest.isMember ("start")) + if (!params.isMember ("start")) return rpcError (rpcINVALID_PARAMS); - unsigned int startIndex = jvRequest["start"].asUInt (); + unsigned int startIndex = params["start"].asUInt (); Json::Value obj; Json::Value txs; @@ -1820,14 +1816,14 @@ Json::Value RPCHandler::doTxHistory (Json::Value jvRequest, int& cost, ScopedLoc // { // transaction: // } -Json::Value RPCHandler::doTx (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doTx (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("transaction")) + if (!params.isMember ("transaction")) return rpcError (rpcINVALID_PARAMS); - bool binary = jvRequest.isMember ("binary") && jvRequest["binary"].asBool (); + bool binary = params.isMember ("binary") && params["binary"].asBool (); - std::string strTransaction = jvRequest["transaction"].asString (); + std::string strTransaction = params["transaction"].asString (); if (Transaction::isHexTxID (strTransaction)) { @@ -1886,7 +1882,7 @@ Json::Value RPCHandler::doTx (Json::Value jvRequest, int& cost, ScopedLock& Mast return rpcError (rpcNOT_IMPL); } -Json::Value RPCHandler::doLedgerClosed (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doLedgerClosed (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { Json::Value jvResult; @@ -1899,7 +1895,7 @@ Json::Value RPCHandler::doLedgerClosed (Json::Value, int& cost, ScopedLock& Mast return jvResult; } -Json::Value RPCHandler::doLedgerCurrent (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doLedgerCurrent (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { Json::Value jvResult; @@ -1913,9 +1909,9 @@ Json::Value RPCHandler::doLedgerCurrent (Json::Value, int& cost, ScopedLock& Mas // ledger: 'current' | 'closed' | | , // optional // full: true | false // optional, defaults to false. // } -Json::Value RPCHandler::doLedger (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doLedger (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("ledger") && !jvRequest.isMember ("ledger_hash") && !jvRequest.isMember ("ledger_index")) + if (!params.isMember ("ledger") && !params.isMember ("ledger_hash") && !params.isMember ("ledger_index")) { Json::Value ret (Json::objectValue), current (Json::objectValue), closed (Json::objectValue); @@ -1929,7 +1925,7 @@ Json::Value RPCHandler::doLedger (Json::Value jvRequest, int& cost, ScopedLock& } Ledger::pointer lpLedger; - Json::Value jvResult = lookupLedger (jvRequest, lpLedger); + Json::Value jvResult = lookupLedger (params, lpLedger); if (!lpLedger) return jvResult; @@ -1937,10 +1933,10 @@ Json::Value RPCHandler::doLedger (Json::Value jvRequest, int& cost, ScopedLock& if (lpLedger->isImmutable ()) MasterLockHolder.unlock (); - bool bFull = jvRequest.isMember ("full") && jvRequest["full"].asBool (); - bool bTransactions = jvRequest.isMember ("transactions") && jvRequest["transactions"].asBool (); - bool bAccounts = jvRequest.isMember ("accounts") && jvRequest["accounts"].asBool (); - bool bExpand = jvRequest.isMember ("expand") && jvRequest["expand"].asBool (); + bool bFull = params.isMember ("full") && params["full"].asBool (); + bool bTransactions = params.isMember ("transactions") && params["transactions"].asBool (); + bool bAccounts = params.isMember ("accounts") && params["accounts"].asBool (); + bool bExpand = params.isMember ("expand") && params["expand"].asBool (); int iOptions = (bFull ? LEDGER_JSON_FULL : 0) | (bExpand ? LEDGER_JSON_EXPAND : 0) | (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0) @@ -1962,44 +1958,44 @@ Json::Value RPCHandler::doLedger (Json::Value jvRequest, int& cost, ScopedLock& // offset: integer, // optional, defaults to 0 // limit: integer // optional // } -Json::Value RPCHandler::doAccountTransactions (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doAccountTransactions (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { RippleAddress raAccount; - uint32 offset = jvRequest.isMember ("offset") ? jvRequest["offset"].asUInt () : 0; - int limit = jvRequest.isMember ("limit") ? jvRequest["limit"].asUInt () : -1; - bool bBinary = jvRequest.isMember ("binary") && jvRequest["binary"].asBool (); - bool bDescending = jvRequest.isMember ("descending") && jvRequest["descending"].asBool (); - bool bCount = jvRequest.isMember ("count") && jvRequest["count"].asBool (); + uint32 offset = params.isMember ("offset") ? params["offset"].asUInt () : 0; + int limit = params.isMember ("limit") ? params["limit"].asUInt () : -1; + bool bBinary = params.isMember ("binary") && params["binary"].asBool (); + bool bDescending = params.isMember ("descending") && params["descending"].asBool (); + bool bCount = params.isMember ("count") && params["count"].asBool (); uint32 uLedgerMin; uint32 uLedgerMax; uint32 uValidatedMin; uint32 uValidatedMax; bool bValidated = mNetOps->getValidatedRange (uValidatedMin, uValidatedMax); - if (!jvRequest.isMember ("account")) + if (!params.isMember ("account")) return rpcError (rpcINVALID_PARAMS); - if (!raAccount.setAccountID (jvRequest["account"].asString ())) + if (!raAccount.setAccountID (params["account"].asString ())) return rpcError (rpcACT_MALFORMED); // DEPRECATED - if (jvRequest.isMember ("ledger_min")) + if (params.isMember ("ledger_min")) { - jvRequest["ledger_index_min"] = jvRequest["ledger_min"]; + params["ledger_index_min"] = params["ledger_min"]; bDescending = true; } // DEPRECATED - if (jvRequest.isMember ("ledger_max")) + if (params.isMember ("ledger_max")) { - jvRequest["ledger_index_max"] = jvRequest["ledger_max"]; + params["ledger_index_max"] = params["ledger_max"]; bDescending = true; } - if (jvRequest.isMember ("ledger_index_min") || jvRequest.isMember ("ledger_index_max")) + if (params.isMember ("ledger_index_min") || params.isMember ("ledger_index_max")) { - int64 iLedgerMin = jvRequest.isMember ("ledger_index_min") ? jvRequest["ledger_index_min"].asInt () : -1; - int64 iLedgerMax = jvRequest.isMember ("ledger_index_max") ? jvRequest["ledger_index_max"].asInt () : -1; + 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; if (!bValidated && (iLedgerMin == -1 || iLedgerMax == -1)) { @@ -2018,7 +2014,7 @@ Json::Value RPCHandler::doAccountTransactions (Json::Value jvRequest, int& cost, else { Ledger::pointer l; - Json::Value ret = lookupLedger (jvRequest, l); + Json::Value ret = lookupLedger (params, l); if (!l) return ret; @@ -2087,7 +2083,7 @@ Json::Value RPCHandler::doAccountTransactions (Json::Value jvRequest, int& cost, if (bCount) ret["count"] = mNetOps->countAccountTxs (raAccount, uLedgerMin, uLedgerMax); - if (jvRequest.isMember ("limit")) + if (params.isMember ("limit")) ret["limit"] = limit; @@ -2107,18 +2103,18 @@ Json::Value RPCHandler::doAccountTransactions (Json::Value jvRequest, int& cost, // } // // This command requires admin access because it makes no sense to ask an untrusted server for this. -Json::Value RPCHandler::doValidationCreate (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doValidationCreate (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { RippleAddress raSeed; Json::Value obj (Json::objectValue); - if (!jvRequest.isMember ("secret")) + if (!params.isMember ("secret")) { WriteLog (lsDEBUG, RPCHandler) << "Creating random validation seed."; raSeed.setSeedRandom (); // Get a random seed. } - else if (!raSeed.setSeedGeneric (jvRequest["secret"].asString ())) + else if (!raSeed.setSeedGeneric (params["secret"].asString ())) { return rpcError (rpcBAD_SEED); } @@ -2133,11 +2129,11 @@ Json::Value RPCHandler::doValidationCreate (Json::Value jvRequest, int& cost, Sc // { // secret: // } -Json::Value RPCHandler::doValidationSeed (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doValidationSeed (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { Json::Value obj (Json::objectValue); - if (!jvRequest.isMember ("secret")) + if (!params.isMember ("secret")) { std::cerr << "Unset validation seed." << std::endl; @@ -2145,7 +2141,7 @@ Json::Value RPCHandler::doValidationSeed (Json::Value jvRequest, int& cost, Scop theConfig.VALIDATION_PUB.clear (); theConfig.VALIDATION_PRIV.clear (); } - else if (!theConfig.VALIDATION_SEED.setSeedGeneric (jvRequest["secret"].asString ())) + else if (!theConfig.VALIDATION_SEED.setSeedGeneric (params["secret"].asString ())) { theConfig.VALIDATION_PUB.clear (); theConfig.VALIDATION_PRIV.clear (); @@ -2204,17 +2200,17 @@ Json::Value RPCHandler::accounts (Ledger::ref lrLedger, const RippleAddress& naM // ledger_hash : // ledger_index : // } -Json::Value RPCHandler::doWalletAccounts (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doWalletAccounts (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { Ledger::pointer lpLedger; - Json::Value jvResult = lookupLedger (jvRequest, lpLedger); + Json::Value jvResult = lookupLedger (params, lpLedger); if (!lpLedger) return jvResult; RippleAddress naSeed; - if (!jvRequest.isMember ("seed") || !naSeed.setSeedGeneric (jvRequest["seed"].asString ())) + if (!params.isMember ("seed") || !naSeed.setSeedGeneric (params["seed"].asString ())) { return rpcError (rpcBAD_SEED); } @@ -2247,7 +2243,7 @@ Json::Value RPCHandler::doWalletAccounts (Json::Value jvRequest, int& cost, Scop } } -Json::Value RPCHandler::doLogRotate (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doLogRotate (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { return Log::rotateLog (); } @@ -2255,16 +2251,16 @@ Json::Value RPCHandler::doLogRotate (Json::Value, int& cost, ScopedLock& MasterL // { // passphrase: // } -Json::Value RPCHandler::doWalletPropose (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doWalletPropose (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { MasterLockHolder.unlock (); RippleAddress naSeed; RippleAddress naAccount; - if (jvRequest.isMember ("passphrase")) + if (params.isMember ("passphrase")) { - naSeed = RippleAddress::createSeedGeneric (jvRequest["passphrase"].asString ()); + naSeed = RippleAddress::createSeedGeneric (params["passphrase"].asString ()); } else { @@ -2287,12 +2283,12 @@ Json::Value RPCHandler::doWalletPropose (Json::Value jvRequest, int& cost, Scope // { // secret: // } -Json::Value RPCHandler::doWalletSeed (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doWalletSeed (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { RippleAddress raSeed; - bool bSecret = jvRequest.isMember ("secret"); + bool bSecret = params.isMember ("secret"); - if (bSecret && !raSeed.setSeedGeneric (jvRequest["secret"].asString ())) + if (bSecret && !raSeed.setSeedGeneric (params["secret"].asString ())) { return rpcError (rpcBAD_SEED); } @@ -2326,13 +2322,13 @@ Json::Value RPCHandler::doWalletSeed (Json::Value jvRequest, int& cost, ScopedLo // username: , // password: // } -Json::Value RPCHandler::doLogin (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doLogin (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("username") - || !jvRequest.isMember ("password")) + if (!params.isMember ("username") + || !params.isMember ("password")) return rpcError (rpcINVALID_PARAMS); - if (jvRequest["username"].asString () == theConfig.RPC_USER && jvRequest["password"].asString () == theConfig.RPC_PASSWORD) + if (params["username"].asString () == theConfig.RPC_USER && params["password"].asString () == theConfig.RPC_PASSWORD) { //mRole=ADMIN; return "logged in"; @@ -2364,26 +2360,26 @@ static void textTime (std::string& text, int& seconds, const char* unitName, int text += "s"; } -Json::Value RPCHandler::doFeature (Json::Value jvRequest, int& cost, ScopedLock& mlh) +Json::Value RPCHandler::doFeature (Json::Value params, LoadType* loadType, ScopedLock& mlh) { - if (!jvRequest.isMember ("feature")) + if (!params.isMember ("feature")) { Json::Value jvReply = Json::objectValue; jvReply["features"] = theApp->getFeatureTable ().getJson (0); return jvReply; } - uint256 uFeature = theApp->getFeatureTable ().getFeature (jvRequest["feature"].asString ()); + uint256 uFeature = theApp->getFeatureTable ().getFeature (params["feature"].asString ()); if (uFeature.isZero ()) { - uFeature.SetHex (jvRequest["feature"].asString ()); + uFeature.SetHex (params["feature"].asString ()); if (uFeature.isZero ()) return rpcError (rpcBAD_FEATURE); } - if (!jvRequest.isMember ("vote")) + if (!params.isMember ("vote")) return theApp->getFeatureTable ().getJson (uFeature); // WRITEME @@ -2393,12 +2389,12 @@ Json::Value RPCHandler::doFeature (Json::Value jvRequest, int& cost, ScopedLock& // { // min_count: // optional, defaults to 10 // } -Json::Value RPCHandler::doGetCounts (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doGetCounts (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { int minCount = 10; - if (jvRequest.isMember ("min_count")) - minCount = jvRequest["min_count"].asUInt (); + if (params.isMember ("min_count")) + minCount = params["min_count"].asUInt (); CountedObjects::List objectCounts = CountedObjects::getInstance ().getCounts (minCount); @@ -2455,10 +2451,10 @@ Json::Value RPCHandler::doGetCounts (Json::Value jvRequest, int& cost, ScopedLoc return ret; } -Json::Value RPCHandler::doLogLevel (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doLogLevel (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { // log_level - if (!jvRequest.isMember ("severity")) + if (!params.isMember ("severity")) { // get log severities Json::Value ret (Json::objectValue); @@ -2474,13 +2470,13 @@ Json::Value RPCHandler::doLogLevel (Json::Value jvRequest, int& cost, ScopedLock return ret; } - LogSeverity sv = Log::stringToSeverity (jvRequest["severity"].asString ()); + LogSeverity sv = Log::stringToSeverity (params["severity"].asString ()); if (sv == lsINVALID) return rpcError (rpcINVALID_PARAMS); // log_level severity - if (!jvRequest.isMember ("partition")) + if (!params.isMember ("partition")) { // set base log severity Log::setMinSeverity (sv, true); @@ -2488,10 +2484,10 @@ Json::Value RPCHandler::doLogLevel (Json::Value jvRequest, int& cost, ScopedLock } // log_level partition severity base? - if (jvRequest.isMember ("partition")) + if (params.isMember ("partition")) { // set partition severity - std::string partition (jvRequest["partition"].asString ()); + std::string partition (params["partition"].asString ()); if (boost::iequals (partition, "base")) Log::setMinSeverity (sv, false); @@ -2508,10 +2504,10 @@ Json::Value RPCHandler::doLogLevel (Json::Value jvRequest, int& cost, ScopedLock // node: |, // comment: // optional // } -Json::Value RPCHandler::doUnlAdd (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doUnlAdd (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - std::string strNode = jvRequest.isMember ("node") ? jvRequest["node"].asString () : ""; - std::string strComment = jvRequest.isMember ("comment") ? jvRequest["comment"].asString () : ""; + std::string strNode = params.isMember ("node") ? params["node"].asString () : ""; + std::string strComment = params.isMember ("comment") ? params["comment"].asString () : ""; RippleAddress raNodePublic; @@ -2532,12 +2528,12 @@ Json::Value RPCHandler::doUnlAdd (Json::Value jvRequest, int& cost, ScopedLock& // { // node: | // } -Json::Value RPCHandler::doUnlDelete (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doUnlDelete (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("node")) + if (!params.isMember ("node")) return rpcError (rpcINVALID_PARAMS); - std::string strNode = jvRequest["node"].asString (); + std::string strNode = params["node"].asString (); RippleAddress raNodePublic; @@ -2555,7 +2551,7 @@ Json::Value RPCHandler::doUnlDelete (Json::Value jvRequest, int& cost, ScopedLoc } } -Json::Value RPCHandler::doUnlList (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doUnlList (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { Json::Value obj (Json::objectValue); @@ -2565,7 +2561,7 @@ Json::Value RPCHandler::doUnlList (Json::Value, int& cost, ScopedLock& MasterLoc } // Populate the UNL from a local validators.txt file. -Json::Value RPCHandler::doUnlLoad (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doUnlLoad (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { if (theConfig.VALIDATORS_FILE.empty () || !theApp->getUNL ().nodeLoad (theConfig.VALIDATORS_FILE)) { @@ -2577,7 +2573,7 @@ Json::Value RPCHandler::doUnlLoad (Json::Value, int& cost, ScopedLock& MasterLoc // Populate the UNL from ripple.com's validators.txt file. -Json::Value RPCHandler::doUnlNetwork (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doUnlNetwork (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { theApp->getUNL ().nodeNetwork (); @@ -2585,7 +2581,7 @@ Json::Value RPCHandler::doUnlNetwork (Json::Value jvRequest, int& cost, ScopedLo } // unl_reset -Json::Value RPCHandler::doUnlReset (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doUnlReset (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { theApp->getUNL ().nodeReset (); @@ -2593,30 +2589,30 @@ Json::Value RPCHandler::doUnlReset (Json::Value jvRequest, int& cost, ScopedLock } // unl_score -Json::Value RPCHandler::doUnlScore (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doUnlScore (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { theApp->getUNL ().nodeScore (); return "scoring requested"; } -Json::Value RPCHandler::doSMS (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doSMS (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { - if (!jvRequest.isMember ("text")) + if (!params.isMember ("text")) return rpcError (rpcINVALID_PARAMS); - HttpsClient::sendSMS (theApp->getIOService (), jvRequest["text"].asString ()); + HttpsClient::sendSMS (theApp->getIOService (), params["text"].asString ()); return "sms dispatched"; } -Json::Value RPCHandler::doStop (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doStop (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { theApp->stop (); return SYSTEM_NAME " server stopping"; } -Json::Value RPCHandler::doLedgerAccept (Json::Value, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doLedgerAccept (Json::Value, LoadType* loadType, ScopedLock& MasterLockHolder) { Json::Value jvResult; @@ -2639,19 +2635,19 @@ Json::Value RPCHandler::doLedgerAccept (Json::Value, int& cost, ScopedLock& Mast // ledger_index : // } // XXX In this case, not specify either ledger does not mean ledger current. It means any ledger. -Json::Value RPCHandler::doTransactionEntry (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doTransactionEntry (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { Ledger::pointer lpLedger; - Json::Value jvResult = lookupLedger (jvRequest, lpLedger); + Json::Value jvResult = lookupLedger (params, lpLedger); if (!lpLedger) return jvResult; - if (!jvRequest.isMember ("tx_hash")) + if (!params.isMember ("tx_hash")) { jvResult["error"] = "fieldNotFoundTransaction"; } - else if (!jvRequest.isMember ("ledger_hash") && !jvRequest.isMember ("ledger_index")) + else if (!params.isMember ("ledger_hash") && !params.isMember ("ledger_index")) { // We don't work on ledger current. @@ -2661,7 +2657,7 @@ Json::Value RPCHandler::doTransactionEntry (Json::Value jvRequest, int& cost, Sc { uint256 uTransID; // XXX Relying on trusted WSS client. Would be better to have a strict routine, returning success or failure. - uTransID.SetHex (jvRequest["tx_hash"].asString ()); + uTransID.SetHex (params["tx_hash"].asString ()); if (!lpLedger) { @@ -2690,34 +2686,34 @@ Json::Value RPCHandler::doTransactionEntry (Json::Value jvRequest, int& cost, Sc return jvResult; } -Json::Value RPCHandler::lookupLedger (Json::Value jvRequest, Ledger::pointer& lpLedger) +Json::Value RPCHandler::lookupLedger (Json::Value params, Ledger::pointer& lpLedger) { Json::Value jvResult; - uint256 uLedger = jvRequest.isMember ("ledger_hash") ? uint256 (jvRequest["ledger_hash"].asString ()) : 0; - int32 iLedgerIndex = jvRequest.isMember ("ledger_index") && jvRequest["ledger_index"].isNumeric () ? jvRequest["ledger_index"].asInt () : LEDGER_CURRENT; + uint256 uLedger = params.isMember ("ledger_hash") ? uint256 (params["ledger_hash"].asString ()) : 0; + int32 iLedgerIndex = params.isMember ("ledger_index") && params["ledger_index"].isNumeric () ? params["ledger_index"].asInt () : LEDGER_CURRENT; std::string strLedger; - if (jvRequest.isMember ("ledger_index") && !jvRequest["ledger_index"].isNumeric ()) - strLedger = jvRequest["ledger_index"].asString (); + if (params.isMember ("ledger_index") && !params["ledger_index"].isNumeric ()) + strLedger = params["ledger_index"].asString (); // Support for DEPRECATED "ledger". - if (!jvRequest.isMember ("ledger")) + if (!params.isMember ("ledger")) { nothing (); } - else if (jvRequest["ledger"].asString ().size () > 12) + else if (params["ledger"].asString ().size () > 12) { - uLedger = uint256 (jvRequest["ledger"].asString ()); + uLedger = uint256 (params["ledger"].asString ()); } - else if (jvRequest["ledger"].isNumeric ()) + else if (params["ledger"].isNumeric ()) { - iLedgerIndex = jvRequest["ledger"].asInt (); + iLedgerIndex = params["ledger"].asInt (); } else { - strLedger = jvRequest["ledger"].asString (); + strLedger = params["ledger"].asString (); } if (strLedger == "current") @@ -2808,10 +2804,10 @@ Json::Value RPCHandler::lookupLedger (Json::Value jvRequest, Ledger::pointer& lp // ledger_index : // ... // } -Json::Value RPCHandler::doLedgerEntry (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doLedgerEntry (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { Ledger::pointer lpLedger; - Json::Value jvResult = lookupLedger (jvRequest, lpLedger); + Json::Value jvResult = lookupLedger (params, lpLedger); if (!lpLedger) return jvResult; @@ -2822,17 +2818,17 @@ Json::Value RPCHandler::doLedgerEntry (Json::Value jvRequest, int& cost, ScopedL uint256 uNodeIndex; bool bNodeBinary = false; - if (jvRequest.isMember ("index")) + if (params.isMember ("index")) { // XXX Needs to provide proof. - uNodeIndex.SetHex (jvRequest["index"].asString ()); + uNodeIndex.SetHex (params["index"].asString ()); bNodeBinary = true; } - else if (jvRequest.isMember ("account_root")) + else if (params.isMember ("account_root")) { RippleAddress naAccount; - if (!naAccount.setAccountID (jvRequest["account_root"].asString ()) + if (!naAccount.setAccountID (params["account_root"].asString ()) || !naAccount.getAccountID ()) { jvResult["error"] = "malformedAddress"; @@ -2842,36 +2838,36 @@ Json::Value RPCHandler::doLedgerEntry (Json::Value jvRequest, int& cost, ScopedL uNodeIndex = Ledger::getAccountRootIndex (naAccount.getAccountID ()); } } - else if (jvRequest.isMember ("directory")) + else if (params.isMember ("directory")) { - if (!jvRequest["directory"].isObject ()) + if (!params["directory"].isObject ()) { - uNodeIndex.SetHex (jvRequest["directory"].asString ()); + uNodeIndex.SetHex (params["directory"].asString ()); } - else if (jvRequest["directory"].isMember ("sub_index") - && !jvRequest["directory"]["sub_index"].isIntegral ()) + else if (params["directory"].isMember ("sub_index") + && !params["directory"]["sub_index"].isIntegral ()) { jvResult["error"] = "malformedRequest"; } else { - uint64 uSubIndex = jvRequest["directory"].isMember ("sub_index") - ? jvRequest["directory"]["sub_index"].asUInt () + uint64 uSubIndex = params["directory"].isMember ("sub_index") + ? params["directory"]["sub_index"].asUInt () : 0; - if (jvRequest["directory"].isMember ("dir_root")) + if (params["directory"].isMember ("dir_root")) { uint256 uDirRoot; - uDirRoot.SetHex (jvRequest["dir_root"].asString ()); + uDirRoot.SetHex (params["dir_root"].asString ()); uNodeIndex = Ledger::getDirNodeIndex (uDirRoot, uSubIndex); } - else if (jvRequest["directory"].isMember ("owner")) + else if (params["directory"].isMember ("owner")) { RippleAddress naOwnerID; - if (!naOwnerID.setAccountID (jvRequest["directory"]["owner"].asString ())) + if (!naOwnerID.setAccountID (params["directory"]["owner"].asString ())) { jvResult["error"] = "malformedAddress"; } @@ -2888,19 +2884,19 @@ Json::Value RPCHandler::doLedgerEntry (Json::Value jvRequest, int& cost, ScopedL } } } - else if (jvRequest.isMember ("generator")) + else if (params.isMember ("generator")) { RippleAddress naGeneratorID; - if (!jvRequest["generator"].isObject ()) + if (!params["generator"].isObject ()) { - uNodeIndex.SetHex (jvRequest["generator"].asString ()); + uNodeIndex.SetHex (params["generator"].asString ()); } - else if (!jvRequest["generator"].isMember ("regular_seed")) + else if (!params["generator"].isMember ("regular_seed")) { jvResult["error"] = "malformedRequest"; } - else if (!naGeneratorID.setSeedGeneric (jvRequest["generator"]["regular_seed"].asString ())) + else if (!naGeneratorID.setSeedGeneric (params["generator"]["regular_seed"].asString ())) { jvResult["error"] = "malformedAddress"; } @@ -2914,37 +2910,37 @@ Json::Value RPCHandler::doLedgerEntry (Json::Value jvRequest, int& cost, ScopedL uNodeIndex = Ledger::getGeneratorIndex (na0Public.getAccountID ()); } } - else if (jvRequest.isMember ("offer")) + else if (params.isMember ("offer")) { RippleAddress naAccountID; - if (!jvRequest["offer"].isObject ()) + if (!params["offer"].isObject ()) { - uNodeIndex.SetHex (jvRequest["offer"].asString ()); + uNodeIndex.SetHex (params["offer"].asString ()); } - else if (!jvRequest["offer"].isMember ("account") - || !jvRequest["offer"].isMember ("seq") - || !jvRequest["offer"]["seq"].isIntegral ()) + else if (!params["offer"].isMember ("account") + || !params["offer"].isMember ("seq") + || !params["offer"]["seq"].isIntegral ()) { jvResult["error"] = "malformedRequest"; } - else if (!naAccountID.setAccountID (jvRequest["offer"]["account"].asString ())) + else if (!naAccountID.setAccountID (params["offer"]["account"].asString ())) { jvResult["error"] = "malformedAddress"; } else { - uint32 uSequence = jvRequest["offer"]["seq"].asUInt (); + uint32 uSequence = params["offer"]["seq"].asUInt (); uNodeIndex = Ledger::getOfferIndex (naAccountID.getAccountID (), uSequence); } } - else if (jvRequest.isMember ("ripple_state")) + else if (params.isMember ("ripple_state")) { RippleAddress naA; RippleAddress naB; uint160 uCurrency; - Json::Value jvRippleState = jvRequest["ripple_state"]; + Json::Value jvRippleState = params["ripple_state"]; if (!jvRippleState.isObject () || !jvRippleState.isMember ("currency") @@ -3021,10 +3017,10 @@ Json::Value RPCHandler::doLedgerEntry (Json::Value jvRequest, int& cost, ScopedL // ledger_hash : // ledger_index : // } -Json::Value RPCHandler::doLedgerHeader (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doLedgerHeader (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { Ledger::pointer lpLedger; - Json::Value jvResult = lookupLedger (jvRequest, lpLedger); + Json::Value jvResult = lookupLedger (params, lpLedger); if (!lpLedger) return jvResult; @@ -3063,15 +3059,15 @@ boost::unordered_set RPCHandler::parseAccountIds (const Json::Val return usnaResult; } -Json::Value RPCHandler::doSubscribe (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doSubscribe (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { InfoSub::pointer ispSub; Json::Value jvResult (Json::objectValue); - uint32 uLedgerIndex = jvRequest.isMember ("ledger_index") && jvRequest["ledger_index"].isNumeric () - ? jvRequest["ledger_index"].asUInt () + uint32 uLedgerIndex = params.isMember ("ledger_index") && params["ledger_index"].isNumeric () + ? params["ledger_index"].asUInt () : 0; - if (!mInfoSub && !jvRequest.isMember ("url")) + if (!mInfoSub && !params.isMember ("url")) { // Must be a JSON-RPC call. WriteLog (lsINFO, RPCHandler) << boost::str (boost::format ("doSubscribe: RPC subscribe requires a url")); @@ -3079,22 +3075,22 @@ Json::Value RPCHandler::doSubscribe (Json::Value jvRequest, int& cost, ScopedLoc return rpcError (rpcINVALID_PARAMS); } - if (jvRequest.isMember ("url")) + if (params.isMember ("url")) { if (mRole != ADMIN) return rpcError (rpcNO_PERMISSION); - std::string strUrl = jvRequest["url"].asString (); - std::string strUsername = jvRequest.isMember ("url_username") ? jvRequest["url_username"].asString () : ""; - std::string strPassword = jvRequest.isMember ("url_password") ? jvRequest["url_password"].asString () : ""; + std::string strUrl = params["url"].asString (); + std::string strUsername = params.isMember ("url_username") ? params["url_username"].asString () : ""; + std::string strPassword = params.isMember ("url_password") ? params["url_password"].asString () : ""; // DEPRECATED - if (jvRequest.isMember ("username")) - strUsername = jvRequest["username"].asString (); + if (params.isMember ("username")) + strUsername = params["username"].asString (); // DEPRECATED - if (jvRequest.isMember ("password")) - strPassword = jvRequest["password"].asString (); + if (params.isMember ("password")) + strPassword = params["password"].asString (); ispSub = mNetOps->findRpcSub (strUrl); @@ -3109,10 +3105,10 @@ Json::Value RPCHandler::doSubscribe (Json::Value jvRequest, int& cost, ScopedLoc { WriteLog (lsTRACE, RPCHandler) << boost::str (boost::format ("doSubscribe: reusing: %s") % strUrl); - if (jvRequest.isMember ("username")) + if (params.isMember ("username")) dynamic_cast (&*ispSub)->setUsername (strUsername); - if (jvRequest.isMember ("password")) + if (params.isMember ("password")) dynamic_cast (&*ispSub)->setPassword (strPassword); } } @@ -3121,11 +3117,11 @@ Json::Value RPCHandler::doSubscribe (Json::Value jvRequest, int& cost, ScopedLoc ispSub = mInfoSub; } - if (!jvRequest.isMember ("streams")) + if (!params.isMember ("streams")) { nothing (); } - else if (!jvRequest["streams"].isArray ()) + else if (!params["streams"].isArray ()) { WriteLog (lsINFO, RPCHandler) << boost::str (boost::format ("doSubscribe: streams requires an array.")); @@ -3133,7 +3129,7 @@ Json::Value RPCHandler::doSubscribe (Json::Value jvRequest, int& cost, ScopedLoc } else { - for (Json::Value::iterator it = jvRequest["streams"].begin (); it != jvRequest["streams"].end (); it++) + for (Json::Value::iterator it = params["streams"].begin (); it != params["streams"].end (); it++) { if ((*it).isString ()) { @@ -3168,21 +3164,21 @@ Json::Value RPCHandler::doSubscribe (Json::Value jvRequest, int& cost, ScopedLoc } } - std::string strAccountsProposed = jvRequest.isMember ("accounts_proposed") + std::string strAccountsProposed = params.isMember ("accounts_proposed") ? "accounts_proposed" : "rt_accounts"; // DEPRECATED - if (!jvRequest.isMember (strAccountsProposed)) + if (!params.isMember (strAccountsProposed)) { nothing (); } - else if (!jvRequest[strAccountsProposed].isArray ()) + else if (!params[strAccountsProposed].isArray ()) { return rpcError (rpcINVALID_PARAMS); } else { - boost::unordered_set usnaAccoundIds = parseAccountIds (jvRequest[strAccountsProposed]); + boost::unordered_set usnaAccoundIds = parseAccountIds (params[strAccountsProposed]); if (usnaAccoundIds.empty ()) { @@ -3194,18 +3190,18 @@ Json::Value RPCHandler::doSubscribe (Json::Value jvRequest, int& cost, ScopedLoc } } - if (!jvRequest.isMember ("accounts")) + if (!params.isMember ("accounts")) { nothing (); } - else if (!jvRequest["accounts"].isArray ()) + else if (!params["accounts"].isArray ()) { return rpcError (rpcINVALID_PARAMS); } else { - boost::unordered_set usnaAccoundIds = parseAccountIds (jvRequest["accounts"]); + boost::unordered_set usnaAccoundIds = parseAccountIds (params["accounts"]); if (usnaAccoundIds.empty ()) { @@ -3219,17 +3215,17 @@ Json::Value RPCHandler::doSubscribe (Json::Value jvRequest, int& cost, ScopedLoc } } - if (!jvRequest.isMember ("books")) + if (!params.isMember ("books")) { nothing (); } - else if (!jvRequest["books"].isArray ()) + else if (!params["books"].isArray ()) { return rpcError (rpcINVALID_PARAMS); } else { - for (Json::Value::iterator it = jvRequest["books"].begin (); it != jvRequest["books"].end (); it++) + for (Json::Value::iterator it = params["books"].begin (); it != params["books"].end (); it++) { Json::Value& jvSubRequest = *it; @@ -3355,23 +3351,23 @@ Json::Value RPCHandler::doSubscribe (Json::Value jvRequest, int& cost, ScopedLoc } // FIXME: This leaks RPCSub objects for JSON-RPC. Shouldn't matter for anyone sane. -Json::Value RPCHandler::doUnsubscribe (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doUnsubscribe (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { InfoSub::pointer ispSub; Json::Value jvResult (Json::objectValue); - if (!mInfoSub && !jvRequest.isMember ("url")) + if (!mInfoSub && !params.isMember ("url")) { // Must be a JSON-RPC call. return rpcError (rpcINVALID_PARAMS); } - if (jvRequest.isMember ("url")) + if (params.isMember ("url")) { if (mRole != ADMIN) return rpcError (rpcNO_PERMISSION); - std::string strUrl = jvRequest["url"].asString (); + std::string strUrl = params["url"].asString (); ispSub = mNetOps->findRpcSub (strUrl); @@ -3383,9 +3379,9 @@ Json::Value RPCHandler::doUnsubscribe (Json::Value jvRequest, int& cost, ScopedL ispSub = mInfoSub; } - if (jvRequest.isMember ("streams")) + if (params.isMember ("streams")) { - for (Json::Value::iterator it = jvRequest["streams"].begin (); it != jvRequest["streams"].end (); it++) + for (Json::Value::iterator it = params["streams"].begin (); it != params["streams"].end (); it++) { if ((*it).isString ()) { @@ -3420,12 +3416,12 @@ Json::Value RPCHandler::doUnsubscribe (Json::Value jvRequest, int& cost, ScopedL } } - if (jvRequest.isMember ("accounts_proposed") || jvRequest.isMember ("rt_accounts")) + if (params.isMember ("accounts_proposed") || params.isMember ("rt_accounts")) { boost::unordered_set usnaAccoundIds = parseAccountIds ( - jvRequest.isMember ("accounts_proposed") - ? jvRequest["accounts_proposed"] - : jvRequest["rt_accounts"]); // DEPRECATED + params.isMember ("accounts_proposed") + ? params["accounts_proposed"] + : params["rt_accounts"]); // DEPRECATED if (usnaAccoundIds.empty ()) { @@ -3437,9 +3433,9 @@ Json::Value RPCHandler::doUnsubscribe (Json::Value jvRequest, int& cost, ScopedL } } - if (jvRequest.isMember ("accounts")) + if (params.isMember ("accounts")) { - boost::unordered_set usnaAccoundIds = parseAccountIds (jvRequest["accounts"]); + boost::unordered_set usnaAccoundIds = parseAccountIds (params["accounts"]); if (usnaAccoundIds.empty ()) { @@ -3451,17 +3447,17 @@ Json::Value RPCHandler::doUnsubscribe (Json::Value jvRequest, int& cost, ScopedL } } - if (!jvRequest.isMember ("books")) + if (!params.isMember ("books")) { nothing (); } - else if (!jvRequest["books"].isArray ()) + else if (!params["books"].isArray ()) { return rpcError (rpcINVALID_PARAMS); } else { - for (Json::Value::iterator it = jvRequest["books"].begin (); it != jvRequest["books"].end (); it++) + for (Json::Value::iterator it = params["books"].begin (); it != params["books"].end (); it++) { Json::Value& jvSubRequest = *it; @@ -3545,31 +3541,28 @@ Json::Value RPCHandler::doUnsubscribe (Json::Value jvRequest, int& cost, ScopedL // // JSON-RPC provides a method and an array of params. JSON-RPC is used as a transport for a command and a request object. The // command is the method. The request object is supplied as the first element of the params. -Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value& jvParams, int iRole, int& cost) +Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value& jvParams, int iRole, LoadType* loadType) { - if (cost == 0) - cost = rpcCOST_DEFAULT; - WriteLog (lsTRACE, RPCHandler) << "doRpcCommand:" << strMethod << ":" << jvParams; if (!jvParams.isArray () || jvParams.size () > 1) return rpcError (rpcINVALID_PARAMS); - Json::Value jvRequest = jvParams.size () ? jvParams[0u] : Json::Value (Json::objectValue); + Json::Value params = jvParams.size () ? jvParams[0u] : Json::Value (Json::objectValue); - if (!jvRequest.isObject ()) + if (!params.isObject ()) return rpcError (rpcINVALID_PARAMS); // Provide the JSON-RPC method as the field "command" in the request. - jvRequest["command"] = strMethod; + params["command"] = strMethod; - Json::Value jvResult = doCommand (jvRequest, iRole, cost); + Json::Value jvResult = doCommand (params, iRole, loadType); // Always report "status". On an error report the request as received. if (jvResult.isMember ("error")) { jvResult["status"] = "error"; - jvResult["request"] = jvRequest; + jvResult["request"] = params; } else @@ -3580,20 +3573,17 @@ Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value& return jvResult; } -Json::Value RPCHandler::doInternal (Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) +Json::Value RPCHandler::doInternal (Json::Value params, LoadType* loadType, ScopedLock& MasterLockHolder) { // Used for debug or special-purpose RPC commands - if (!jvRequest.isMember ("internal_command")) + if (!params.isMember ("internal_command")) return rpcError (rpcINVALID_PARAMS); - return RPCInternalHandler::runHandler (jvRequest["internal_command"].asString (), jvRequest["params"]); + return RPCInternalHandler::runHandler (params["internal_command"].asString (), params["params"]); } -Json::Value RPCHandler::doCommand (const Json::Value& jvRequest, int iRole, int& cost) +Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadType* loadType) { - if (cost == 0) - cost = rpcCOST_DEFAULT; - if (iRole != ADMIN) { int jc = theApp->getJobQueue ().getJobCountGE (jtCLIENT); @@ -3605,13 +3595,13 @@ Json::Value RPCHandler::doCommand (const Json::Value& jvRequest, int iRole, int& } } - if (!jvRequest.isMember ("command")) + if (!params.isMember ("command")) return rpcError (rpcCOMMAND_MISSING); - std::string strCommand = jvRequest["command"].asString (); + std::string strCommand = params["command"].asString (); WriteLog (lsTRACE, RPCHandler) << "COMMAND:" << strCommand; - WriteLog (lsTRACE, RPCHandler) << "REQUEST:" << jvRequest; + WriteLog (lsTRACE, RPCHandler) << "REQUEST:" << params; mRole = iRole; @@ -3728,7 +3718,7 @@ Json::Value RPCHandler::doCommand (const Json::Value& jvRequest, int iRole, int& { try { - Json::Value jvRaw = (this->* (commandsA[i].dfpFunc)) (jvRequest, cost, MasterLockHolder); + Json::Value jvRaw = (this->* (commandsA[i].dfpFunc)) (params, loadType, MasterLockHolder); // Regularize result. if (jvRaw.isObject ()) @@ -3750,8 +3740,8 @@ Json::Value RPCHandler::doCommand (const Json::Value& jvRequest, int iRole, int& { WriteLog (lsINFO, RPCHandler) << "Caught throw: " << e.what (); - if (cost == rpcCOST_DEFAULT) - cost = rpcCOST_EXCEPTION; + if (*loadType == LT_RPCReference) + *loadType = LT_RPCException; return rpcError (rpcINTERNAL); } diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index 8a7bd6c82e..c9298e07b2 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -15,13 +15,34 @@ class NetworkOPs; class InfoSub; +// VFALCO TODO Refactor to abstract interface IRPCHandler +// class RPCHandler { - NetworkOPs* mNetOps; - InfoSub::pointer mInfoSub; - int mRole; +public: + enum + { + GUEST, + USER, + ADMIN, + FORBID + }; - typedef Json::Value (RPCHandler::*doFuncPtr) (Json::Value params, int& cost, ScopedLock& MasterLockHolder); + explicit RPCHandler (NetworkOPs* netOps); + + RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub); + + Json::Value doCommand (const Json::Value& jvRequest, int role, LoadType* loadType); + + Json::Value doRpcCommand (const std::string& strCommand, Json::Value& jvParams, int iRole, LoadType* loadType); + +private: + typedef Json::Value (RPCHandler::*doFuncPtr) ( + Json::Value params, + LoadType* loadType, + ScopedLock& MasterLockHolder); + + // VFALCO TODO Document these and give the enumeration a label. enum { optNone = 0, @@ -31,102 +52,115 @@ class RPCHandler }; // Utilities + void addSubmitPath (Json::Value& txJSON); - boost::unordered_set parseAccountIds (const Json::Value& jvArray); + + boost::unordered_set parseAccountIds (const Json::Value& jvArray); + Json::Value transactionSign (Json::Value jvRequest, bool bSubmit, bool bFailHard, ScopedLock& mlh); Json::Value lookupLedger (Json::Value jvRequest, Ledger::pointer& lpLedger); - Json::Value getMasterGenerator (Ledger::ref lrLedger, const RippleAddress& naRegularSeed, RippleAddress& naMasterGenerator); - Json::Value authorize (Ledger::ref lrLedger, const RippleAddress& naRegularSeed, const RippleAddress& naSrcAccountID, - RippleAddress& naAccountPublic, RippleAddress& naAccountPrivate, - STAmount& saSrcBalance, const STAmount& saFee, AccountState::pointer& asSrc, - const RippleAddress& naVerifyGenerator); - Json::Value accounts (Ledger::ref lrLedger, const RippleAddress& naMasterGenerator); + Json::Value getMasterGenerator ( + Ledger::ref lrLedger, + const RippleAddress& naRegularSeed, + RippleAddress& naMasterGenerator); - Json::Value accountFromString (Ledger::ref lrLedger, RippleAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex, const bool bStrict); + Json::Value authorize ( + Ledger::ref lrLedger, + const RippleAddress& naRegularSeed, + const RippleAddress& naSrcAccountID, + RippleAddress& naAccountPublic, + RippleAddress& naAccountPrivate, + STAmount& saSrcBalance, + const STAmount& saFee, + AccountState::pointer& asSrc, + const RippleAddress& naVerifyGenerator); - Json::Value doAccountInfo (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doAccountLines (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doAccountOffers (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doAccountTransactions (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doBookOffers (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doConnect (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doConsensusInfo (Json::Value params, int& cost, ScopedLock& mlh); -#if ENABLE_INSECURE - Json::Value doDataDelete (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doDataFetch (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doDataStore (Json::Value params, int& cost, ScopedLock& mlh); -#endif - Json::Value doFeature (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doGetCounts (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doInternal (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doLedger (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doLogLevel (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doLogRotate (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doNicknameInfo (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doOwnerInfo (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doPeers (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doPathFind (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doPing (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doProfile (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doProofCreate (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doProofSolve (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doProofVerify (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doRandom (Json::Value jvRequest, int& cost, ScopedLock& mlh); - Json::Value doRipplePathFind (Json::Value jvRequest, int& cost, ScopedLock& mlh); - Json::Value doServerInfo (Json::Value params, int& cost, ScopedLock& mlh); // for humans - Json::Value doServerState (Json::Value params, int& cost, ScopedLock& mlh); // for machines - Json::Value doSessionClose (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doSessionOpen (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doSMS (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doStop (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doSign (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doSubmit (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doTx (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doTxHistory (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doUnlAdd (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doUnlDelete (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doUnlFetch (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doUnlList (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doUnlLoad (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doUnlNetwork (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doUnlReset (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doUnlScore (Json::Value params, int& cost, ScopedLock& mlh); + Json::Value accounts ( + Ledger::ref lrLedger, + const RippleAddress& naMasterGenerator); - Json::Value doValidationCreate (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doValidationSeed (Json::Value params, int& cost, ScopedLock& mlh); + Json::Value accountFromString ( + Ledger::ref lrLedger, + RippleAddress& naAccount, + bool& bIndex, + const std::string& strIdent, + const int iIndex, + const bool bStrict); - Json::Value doWalletAccounts (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doWalletLock (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doWalletPropose (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doWalletSeed (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doWalletUnlock (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doWalletVerify (Json::Value params, int& cost, ScopedLock& mlh); + Json::Value doAccountInfo (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doAccountLines (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doAccountOffers (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doAccountTransactions (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doBookOffers (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doConnect (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doConsensusInfo (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doFeature (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doGetCounts (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doInternal (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doLedger (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doLedgerAccept (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doLedgerClosed (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doLedgerCurrent (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doLedgerEntry (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doLedgerHeader (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doLogLevel (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doLogRotate (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doNicknameInfo (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doOwnerInfo (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doPathFind (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doPeers (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doPing (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doProfile (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doProofCreate (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doProofSolve (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doProofVerify (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doRandom (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doRipplePathFind (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doSMS (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doServerInfo (Json::Value params, LoadType* loadType, ScopedLock& mlh); // for humans + Json::Value doServerState (Json::Value params, LoadType* loadType, ScopedLock& mlh); // for machines + Json::Value doSessionClose (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doSessionOpen (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doSign (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doStop (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doSubmit (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doSubscribe (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doTransactionEntry (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doTx (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doTxHistory (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doUnlAdd (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doUnlDelete (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doUnlFetch (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doUnlList (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doUnlLoad (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doUnlNetwork (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doUnlReset (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doUnlScore (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doUnsubscribe (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doValidationCreate (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doValidationSeed (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doWalletAccounts (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doWalletLock (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doWalletPropose (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doWalletSeed (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doWalletUnlock (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doWalletVerify (Json::Value params, LoadType* loadType, ScopedLock& mlh); #if ENABLE_INSECURE - Json::Value doLogin (Json::Value params, int& cost, ScopedLock& mlh); + Json::Value doDataDelete (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doDataFetch (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doDataStore (Json::Value params, LoadType* loadType, ScopedLock& mlh); + Json::Value doLogin (Json::Value params, LoadType* loadType, ScopedLock& mlh); #endif - Json::Value doLedgerAccept (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doLedgerClosed (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doLedgerCurrent (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doLedgerEntry (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doLedgerHeader (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doTransactionEntry (Json::Value params, int& cost, ScopedLock& mlh); +private: + NetworkOPs* mNetOps; + InfoSub::pointer mInfoSub; - Json::Value doSubscribe (Json::Value params, int& cost, ScopedLock& mlh); - Json::Value doUnsubscribe (Json::Value params, int& cost, ScopedLock& mlh); - -public: - - enum { GUEST, USER, ADMIN, FORBID }; - - RPCHandler (NetworkOPs* netOps); - RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub); - - Json::Value doCommand (const Json::Value& jvRequest, int role, int& cost); - Json::Value doRpcCommand (const std::string& strCommand, Json::Value& jvParams, int iRole, int& cost); + // VFALCO TODO Create an enumeration for this. + int mRole; }; class RPCInternalHandler diff --git a/src/cpp/ripple/RPCServer.cpp b/src/cpp/ripple/RPCServer.cpp index 47acb3a900..b5671a665c 100644 --- a/src/cpp/ripple/RPCServer.cpp +++ b/src/cpp/ripple/RPCServer.cpp @@ -153,8 +153,11 @@ std::string RPCServer::handleRequest (const std::string& requestStr) RPCHandler mRPCHandler (mNetOps); WriteLog (lsINFO, RPCServer) << valParams; - int cost = 10; - Json::Value result = mRPCHandler.doRpcCommand (strMethod, valParams, mRole, cost); + LoadType loadType = LT_RPCReference; + Json::Value result = mRPCHandler.doRpcCommand (strMethod, valParams, mRole, &loadType); + + // VFALCO NOTE We discard loadType since there is no endpoint to punish + WriteLog (lsINFO, RPCServer) << result; std::string strReply = JSONRPCReply (result, Json::Value (), id); diff --git a/src/cpp/ripple/WSConnection.h b/src/cpp/ripple/WSConnection.h index 1b55345b1f..fbfa63aa9b 100644 --- a/src/cpp/ripple/WSConnection.h +++ b/src/cpp/ripple/WSConnection.h @@ -86,6 +86,8 @@ public: { if (theApp->getLoadManager ().shouldCutoff (mLoadSource)) { + // VFALCO TODO This must be implemented before open sourcing + #if SHOULD_DISCONNECT // FIXME: Must dispatch to strand connection_ptr ptr = mConnection.lock (); @@ -97,6 +99,8 @@ public: #endif } + // Requests without "command" are invalid. + // if (!jvRequest.isMember ("command")) { Json::Value jvResult (Json::objectValue); @@ -111,11 +115,12 @@ public: jvResult["id"] = jvRequest["id"]; } - theApp->getLoadManager ().adjust (mLoadSource, -5); + theApp->getLoadManager ().applyLoadCharge (mLoadSource, LT_RPCInvalid); + return jvResult; } - int cost = 10; + LoadType loadType = LT_RPCReference; RPCHandler mRPCHandler (&mNetwork, boost::dynamic_pointer_cast (this->shared_from_this ())); Json::Value jvResult (Json::objectValue); @@ -129,11 +134,16 @@ public: } else { - jvResult["result"] = mRPCHandler.doCommand (jvRequest, iRole, cost); + jvResult["result"] = mRPCHandler.doCommand (jvRequest, iRole, &loadType); } - if (theApp->getLoadManager ().adjust (mLoadSource, -cost) && theApp->getLoadManager ().shouldWarn (mLoadSource)) + // Debit/credit the load and see if we should include a warning. + // + if (theApp->getLoadManager ().applyLoadCharge (mLoadSource, loadType) && + theApp->getLoadManager ().shouldWarn (mLoadSource)) + { jvResult["warning"] = "load"; + } // Currently we will simply unwrap errors returned by the RPC // API, in the future maybe we can make the responses diff --git a/src/cpp/ripple/main.cpp b/src/cpp/ripple/main.cpp index 5dd2aee2e7..bd4c586283 100644 --- a/src/cpp/ripple/main.cpp +++ b/src/cpp/ripple/main.cpp @@ -35,8 +35,9 @@ void startServer () RPCHandler rhHandler (&theApp->getOPs ()); - int cost = 10; - Json::Value jvResult = rhHandler.doCommand (jvCommand, RPCHandler::ADMIN, cost); + // VFALCO TODO Clean up this magic number + LoadType loadType = LT_RPCReference; + Json::Value jvResult = rhHandler.doCommand (jvCommand, RPCHandler::ADMIN, &loadType); if (!theConfig.QUIET) std::cerr << "Result: " << jvResult << std::endl; diff --git a/src/cpp/ripple/ripple_Application.cpp b/src/cpp/ripple/ripple_Application.cpp index a965142c4f..49cbeecd04 100644 --- a/src/cpp/ripple/ripple_Application.cpp +++ b/src/cpp/ripple/ripple_Application.cpp @@ -4,8 +4,11 @@ */ //============================================================================== -// VFALCO TODO Wrap this up in something neater. Replace NULL with nullptr -IApplication* theApp = NULL; +// VFALCO TODO Clean this global up +volatile bool doShutdown = false; + +// VFALCO TODO Wrap this up in something neater. +IApplication* theApp = nullptr; class Application; @@ -73,9 +76,9 @@ public: return mMasterLock; } - LoadManager& getLoadManager () + ILoadManager& getLoadManager () { - return mLoadMgr; + return *m_loadManager; } TXQueue& getTxnQueue () @@ -218,7 +221,6 @@ private: SLECache mSLECache; SNTPClient mSNTPClient; JobQueue mJobQueue; - LoadManager mLoadMgr; TXQueue mTxnQueue; OrderBookDB mOrderBookDB; @@ -231,6 +233,7 @@ private: beast::ScopedPointer mUNL; beast::ScopedPointer mProofOfWorkFactory; beast::ScopedPointer mPeers; + beast::ScopedPointer m_loadManager; // VFALCO End Clean stuff DatabaseCon* mRpcDB; @@ -274,6 +277,7 @@ Application::Application () , mUNL (IUniqueNodeList::New (mIOService)) , mProofOfWorkFactory (IProofOfWorkFactory::New ()) , mPeers (IPeers::New (mIOService)) + , m_loadManager (ILoadManager::New ()) // VFALCO End new stuff // VFALCO TODO replace all NULL with nullptr , mRpcDB (NULL) @@ -296,7 +300,8 @@ Application::Application () HashMaps::getInstance ().initializeNonce (); } - +// VFALCO TODO Tidy these up into some class with accessors. +// extern const char* RpcDBInit[], *TxnDBInit[], *LedgerDBInit[], *WalletDBInit[], *HashNodeDBInit[], *NetNodeDBInit[], *PathFindDBInit[]; extern int RpcDBCount, TxnDBCount, LedgerDBCount, WalletDBCount, HashNodeDBCount, @@ -327,8 +332,6 @@ static void InitDB (DatabaseCon** dbCon, const char* fileName, const char* dbIni *dbCon = new DatabaseCon (fileName, dbInit, dbCount); } -volatile bool doShutdown = false; - #ifdef SIGINT void sigIntHandler (int) { @@ -349,6 +352,10 @@ static void runIO (boost::asio::io_service& io) io.run (); } +// VFALCO TODO Break this function up into many small initialization segments. +// Or better yet refactor these initializations into RAII classes +// which are members of the Application object. +// void Application::setup () { // VFALCO NOTE: 0 means use heuristics to determine the thread count. @@ -356,7 +363,8 @@ void Application::setup () mSweepTimer.expires_from_now (boost::posix_time::seconds (10)); mSweepTimer.async_wait (boost::bind (&Application::sweep, this)); - mLoadMgr.init (); + + m_loadManager->startThread (); #ifndef WIN32 #ifdef SIGINT @@ -617,6 +625,8 @@ void Application::setup () } else { + // VFALCO NOTE the state timer resets the deadlock detector. + // mNetOps.setStateTimer (); } } @@ -629,7 +639,12 @@ void Application::run () } if (!theConfig.RUN_STANDALONE) - theApp->getLoadManager ().arm (); + { + // VFALCO NOTE This seems unnecessary. If we properly refactor the load + // manager then the deadlock detector can just always be "armed" + // + theApp->getLoadManager ().activateDeadlockDetector (); + } mIOService.run (); // This blocks diff --git a/src/cpp/ripple/ripple_IApplication.h b/src/cpp/ripple/ripple_IApplication.h index af77f8841b..7ed252969e 100644 --- a/src/cpp/ripple/ripple_IApplication.h +++ b/src/cpp/ripple/ripple_IApplication.h @@ -65,6 +65,7 @@ public: virtual IFeeVote& getFeeVote () = 0; virtual IHashRouter& getHashRouter () = 0; virtual ILoadFeeTrack& getFeeTrack () = 0; + virtual ILoadManager& getLoadManager () = 0; virtual IPeers& getPeers () = 0; virtual IProofOfWorkFactory& getProofOfWorkFactory () = 0; virtual IUniqueNodeList& getUNL () = 0; @@ -72,22 +73,23 @@ public: virtual HashedObjectStore& getHashedObjectStore () = 0; virtual JobQueue& getJobQueue () = 0; - virtual InboundLedgers& getInboundLedgers () = 0; + virtual InboundLedgers& getInboundLedgers () = 0; virtual LedgerMaster& getLedgerMaster () = 0; - virtual LoadManager& getLoadManager () = 0; virtual NetworkOPs& getOPs () = 0; virtual OrderBookDB& getOrderBookDB () = 0; virtual PeerDoor& getPeerDoor () = 0; virtual TransactionMaster& getMasterTransaction () = 0; virtual TXQueue& getTxnQueue () = 0; - virtual LocalCredentials& getLocalCredentials () = 0; + virtual LocalCredentials& getLocalCredentials () = 0; virtual DatabaseCon* getRpcDB () = 0; virtual DatabaseCon* getTxnDB () = 0; virtual DatabaseCon* getLedgerDB () = 0; virtual DatabaseCon* getWalletDB () = 0; - virtual DatabaseCon* getNetNodeDB () = 0; - virtual DatabaseCon* getPathFindDB () = 0; + // VFALCO NOTE It looks like this isn't used... + //virtual DatabaseCon* getNetNodeDB () = 0; + // VFALCO NOTE It looks like this isn't used... + //virtual DatabaseCon* getPathFindDB () = 0; virtual DatabaseCon* getHashNodeDB () = 0; virtual leveldb::DB* getHashNodeLDB () = 0; diff --git a/src/cpp/ripple/ripple_ILoadManager.h b/src/cpp/ripple/ripple_ILoadManager.h new file mode 100644 index 0000000000..54e24350eb --- /dev/null +++ b/src/cpp/ripple/ripple_ILoadManager.h @@ -0,0 +1,265 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_ILOADMANAGER_H +#define RIPPLE_ILOADMANAGER_H + +// types of load that can be placed on the server +// VFALCO TODO replace LT_ with loadType in constants +enum LoadType +{ + // Bad things + LT_InvalidRequest, // A request that we can immediately tell is invalid + LT_RequestNoReply, // A request that we cannot satisfy + LT_InvalidSignature, // An object whose signature we had to check and it failed + LT_UnwantedData, // Data we have no use for + LT_BadPoW, // Proof of work not valid + LT_BadData, // Data we have to verify before rejecting + + // RPC loads + LT_RPCInvalid, // An RPC request that we can immediately tell is invalid. + LT_RPCReference, // A default "reference" unspecified load + LT_RPCException, // An RPC load that causes an exception + LT_RPCBurden, // A particularly burdensome RPC load + + // Good things + LT_NewTrusted, // A new transaction/validation/proposal we trust + LT_NewTransaction, // A new, valid transaction + LT_NeededData, // Data we requested + + // Requests + LT_RequestData, // A request that is hard to satisfy, disk access + LT_CheapQuery, // A query that is trivial, cached data + + LT_MAX // MUST BE LAST +}; + +//------------------------------------------------------------------------------ + +/** Tracks the consumption of resources at an endpoint. + + To prevent monopolization of server resources or attacks on servers, + resource consumption is monitored at each endpoint. When consumption + exceeds certain thresholds, costs are imposed. Costs include charging + additional XRP for transactions, requiring a proof of work to be + performed, or simply disconnecting the endpoint. + + Currently, consumption endpoints include websocket connections used to + service clients, and peer connections used to create the peer to peer + overlay network implementing the Ripple protcool. + + The current "balance" of a LoadSource represents resource consumption + debt or credit. Debt is accrued when bad loads are imposed. Credit is + granted when good loads are imposed. When the balance crosses heuristic + thresholds, costs are increased on the endpoint. + + The balance is represented as a unitless relative quantity. + + @note Although RPC connections consume resources, they are transient and + cannot be rate limited. It is advised not to expose RPC interfaces + to the general public. +*/ +class LoadSource +{ +public: + // VFALCO TODO Why even bother with a warning? Why can't we just drop? + // VFALCO TODO Use these dispositions + /* + enum Disposition + { + none, + shouldWarn, + shouldDrop, + }; + */ + + /** Construct a load source. + + Sources with admin privileges have relaxed or no restrictions + on resource consumption. + + @param admin `true` if the source should have admin privileges. + */ + // VFALCO TODO See who is constructing this with a parameter + explicit LoadSource (bool admin) + : mBalance (0) + , mFlags (admin ? lsfPrivileged : 0) + , mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ()) + , mLastWarning (0) + , mLogged (false) + { + } + + /** Construct a load source with a given name. + + The endpoint is considered non-privileged. + */ + explicit LoadSource (std::string const& name) + : mName (name) + , mBalance (0) + , mFlags (0) + , mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ()) + , mLastWarning (0) + , mLogged (false) + { + } + + /** Change the name of the source. + + An endpoint can be created before it's name is known. For example, + on an incoming connection before the IP and port have been determined. + */ + // VFALCO TODO Figure out a way to construct the LoadSource object with + // the proper name instead of renaming it later. + // + void rename (std::string const& name) + { + mName = name; + } + + /** Retrieve the name of this endpoint. + */ + std::string const& getName () const + { + return mName; + } + + /** Determine if this endpoint is privileged. + */ + bool isPrivileged () const + { + return (mFlags & lsfPrivileged) != 0; + } + + /** Grant the privileged attribute on this endpoint. + */ + void setPrivileged () + { + mFlags |= lsfPrivileged; + } + + /** Retrieve the load debit or credit associated with the endpoint. + + The balance is represented in a unitless relative quantity + indicating the heuristically weighted amount of resource consumption. + */ + int getBalance () const + { + return mBalance; + } + + /** Returns true if the endpoint received a log warning. + */ + bool isLogged () const + { + return mLogged; + } + + /** Reset the flag indicating the endpoint received a log warning. + */ + void clearLogged () + { + mLogged = false; + } + + /** Indicate that this endpoint is an outgoing connection. + */ + void setOutbound () + { + mFlags |= lsfOutbound; + } + + /** Returns true if this endpoint is an outgoing connection. + */ + bool isOutbound () const + { + return (mFlags & lsfOutbound) != 0; + } + +private: + // VFALCO Make this not a friend + friend class LoadManager; + + static const int lsfPrivileged = 1; + static const int lsfOutbound = 2; + +private: + std::string mName; + int mBalance; + int mFlags; + int mLastUpdate; + int mLastWarning; + bool mLogged; +}; + +//------------------------------------------------------------------------------ + +/** Manages load sources. + + This object creates an associated thread to maintain a clock. + + @see LoadSource, LoadType +*/ +class ILoadManager +{ +public: + /** Create a new manager. + + @note The thresholds for warnings and punishments are in + the ctor-initializer + */ + static ILoadManager* New (); + + virtual ~ILoadManager () { } + + /** Start the associated thread. + + This is here to prevent the deadlock detector from activating during + a lengthy program initialization. + + @note In stand-alone mode, this might not get called. + */ + // VFALCO TODO Simplify the two stage initialization to one stage (construction). + virtual void startThread () = 0; + + /** Turn on deadlock detection. + + The deadlock detector begins in a disabled state. After this function + is called, it will report deadlocks using a separate thread whenever + the reset function is not called at least once per 10 seconds. + + @see resetDeadlockDetector + */ + // VFALCO NOTE it seems that the deadlock detector has an "armed" state to prevent it + // from going off during program startup if there's a lengthy initialization + // operation taking place? + // + virtual void activateDeadlockDetector () = 0; + + /** Reset the deadlock detection timer. + + A dedicated thread monitors the deadlock timer, and if too much + time passes it will produce log warnings. + */ + virtual void resetDeadlockDetector () = 0; + + /** Update an endpoint to reflect an imposed load. + + The balance of the endpoint is adjusted based on the heuristic cost + of the indicated load. + + @return `true` if the endpoint should be warned or punished. + */ + virtual bool applyLoadCharge (LoadSource& sourceToAdjust, LoadType loadToImpose) const = 0; + + // VFALCO TODO Eliminate these two functions and just make applyLoadCharge() + // return a LoadSource::Disposition + // + virtual bool shouldWarn (LoadSource&) const = 0; + virtual bool shouldCutoff (LoadSource&) const = 0; +}; + +#endif diff --git a/src/cpp/ripple/ripple_InboundLedgers.cpp b/src/cpp/ripple/ripple_InboundLedgers.cpp index 8fe09abbf6..e78619eb47 100644 --- a/src/cpp/ripple/ripple_InboundLedgers.cpp +++ b/src/cpp/ripple/ripple_InboundLedgers.cpp @@ -90,7 +90,7 @@ void InboundLedgers::gotLedgerData (Job&, uint256 hash, WriteLog (lsTRACE, InboundLedger) << "Got data for ledger we're not acquiring"; if (peer) - peer->punishPeer (LT_InvalidRequest); + peer->applyLoadCharge (LT_InvalidRequest); return; } @@ -105,14 +105,14 @@ void InboundLedgers::gotLedgerData (Job&, uint256 hash, if (packet.nodes_size () < 1) { WriteLog (lsWARNING, InboundLedger) << "Got empty base data"; - peer->punishPeer (LT_InvalidRequest); + peer->applyLoadCharge (LT_InvalidRequest); return; } if (!ledger->takeBase (packet.nodes (0).nodedata ())) { WriteLog (lsWARNING, InboundLedger) << "Got invalid base data"; - peer->punishPeer (LT_InvalidRequest); + peer->applyLoadCharge (LT_InvalidRequest); return; } @@ -147,7 +147,7 @@ void InboundLedgers::gotLedgerData (Job&, uint256 hash, if (packet.nodes ().size () <= 0) { WriteLog (lsINFO, InboundLedger) << "Got response with no nodes"; - peer->punishPeer (LT_InvalidRequest); + peer->applyLoadCharge (LT_InvalidRequest); return; } @@ -158,7 +158,7 @@ void InboundLedgers::gotLedgerData (Job&, uint256 hash, if (!node.has_nodeid () || !node.has_nodedata ()) { WriteLog (lsWARNING, InboundLedger) << "Got bad node"; - peer->punishPeer (LT_InvalidRequest); + peer->applyLoadCharge (LT_InvalidRequest); return; } @@ -185,7 +185,7 @@ void InboundLedgers::gotLedgerData (Job&, uint256 hash, } WriteLog (lsWARNING, InboundLedger) << "Not sure what ledger data we got"; - peer->punishPeer (LT_InvalidRequest); + peer->applyLoadCharge (LT_InvalidRequest); } void InboundLedgers::sweep () diff --git a/src/cpp/ripple/ripple_LoadManager.cpp b/src/cpp/ripple/ripple_LoadManager.cpp index 1457708b15..6bd6004c15 100644 --- a/src/cpp/ripple/ripple_LoadManager.cpp +++ b/src/cpp/ripple/ripple_LoadManager.cpp @@ -6,302 +6,426 @@ SETUP_LOG (LoadManager) -LoadManager::LoadManager (int creditRate, int creditLimit, int debitWarn, int debitLimit) - : mCreditRate (creditRate) - , mCreditLimit (creditLimit) - , mDebitWarn (debitWarn) - , mDebitLimit (debitLimit) - , mShutdown (false) - , mArmed (false) - , mDeadLock (0) - , mCosts (LT_MAX) +//------------------------------------------------------------------------------ + +class LoadManager : public ILoadManager { - addCost (Cost (LT_InvalidRequest, -10, LC_CPU | LC_Network)); - addCost (Cost (LT_RequestNoReply, -1, LC_CPU | LC_Disk)); - addCost (Cost (LT_InvalidSignature, -100, LC_CPU)); - addCost (Cost (LT_UnwantedData, -5, LC_CPU | LC_Network)); - addCost (Cost (LT_BadData, -20, LC_CPU)); +private: + /* Entry mapping utilization to cost. - addCost (Cost (LT_NewTrusted, -10, 0)); - addCost (Cost (LT_NewTransaction, -2, 0)); - addCost (Cost (LT_NeededData, -10, 0)); - - addCost (Cost (LT_RequestData, -5, LC_Disk | LC_Network)); - addCost (Cost (LT_CheapQuery, -1, LC_CPU)); -} - -void LoadManager::init () -{ - UptimeTimer::getInstance ().beginManualUpdates (); - - boost::thread (boost::bind (&LoadManager::threadEntry, this)).detach (); -} - -LoadManager::~LoadManager () -{ - UptimeTimer::getInstance ().endManualUpdates (); - - // VFALCO What is this loop? it doesn't seem to do anything useful. - do + The cost is expressed as a unitless relative quantity. These + mappings are statically loaded at startup with heuristic values. + */ + class Cost { - boost::this_thread::sleep (boost::posix_time::milliseconds (100)); + public: + // VFALCO TODO Eliminate this default ctor somehow + Cost () + : m_loadType () + , m_cost (0) + , m_resourceFlags (0) { - boost::mutex::scoped_lock sl (mLock); - - if (!mShutdown) - return; } - } - while (1); -} - -void LoadManager::noDeadLock () -{ - boost::mutex::scoped_lock sl (mLock); - //mDeadLock = mUptime; - mDeadLock = UptimeTimer::getInstance ().getElapsedSeconds (); -} - -int LoadManager::getCreditRate () const -{ - boost::mutex::scoped_lock sl (mLock); - return mCreditRate; -} - -int LoadManager::getCreditLimit () const -{ - boost::mutex::scoped_lock sl (mLock); - return mCreditLimit; -} - -int LoadManager::getDebitWarn () const -{ - boost::mutex::scoped_lock sl (mLock); - return mDebitWarn; -} - -int LoadManager::getDebitLimit () const -{ - boost::mutex::scoped_lock sl (mLock); - return mDebitLimit; -} - -void LoadManager::setCreditRate (int r) -{ - boost::mutex::scoped_lock sl (mLock); - mCreditRate = r; -} - -void LoadManager::setCreditLimit (int r) -{ - boost::mutex::scoped_lock sl (mLock); - mCreditLimit = r; -} - -void LoadManager::setDebitWarn (int r) -{ - boost::mutex::scoped_lock sl (mLock); - mDebitWarn = r; -} - -void LoadManager::setDebitLimit (int r) -{ - boost::mutex::scoped_lock sl (mLock); - mDebitLimit = r; -} - -void LoadManager::canonicalize (LoadSource& source, int now) const -{ - if (source.mLastUpdate != now) - { - if (source.mLastUpdate < now) + + Cost (LoadType loadType, int cost, int resourceFlags) + : m_loadType (loadType) + , m_cost (cost) + , m_resourceFlags (resourceFlags) { - source.mBalance += mCreditRate * (now - source.mLastUpdate); - - if (source.mBalance > mCreditLimit) - { - source.mBalance = mCreditLimit; - source.mLogged = false; - } } - source.mLastUpdate = now; - } -} - -bool LoadManager::shouldWarn (LoadSource& source) const -{ - { - boost::mutex::scoped_lock sl (mLock); - - int now = UptimeTimer::getInstance ().getElapsedSeconds (); - canonicalize (source, now); - - if (source.isPrivileged () || (source.mBalance > mDebitWarn) || (source.mLastWarning == now)) - return false; - - source.mLastWarning = now; - } - logWarning (source.getName ()); - return true; -} - -bool LoadManager::shouldCutoff (LoadSource& source) const -{ - { - boost::mutex::scoped_lock sl (mLock); - int now = UptimeTimer::getInstance ().getElapsedSeconds (); - canonicalize (source, now); - - if (source.isPrivileged () || (source.mBalance > mDebitLimit)) - return false; - - if (source.mLogged) - return true; - - source.mLogged = true; - } - logDisconnect (source.getName ()); - return true; -} - -bool LoadManager::adjust (LoadSource& source, LoadType t) const -{ - // FIXME: Scale by category - Cost cost = mCosts[static_cast (t)]; - return adjust (source, cost.mCost); -} - -bool LoadManager::adjust (LoadSource& source, int credits) const -{ - // return: true = need to warn/cutoff - - // We do it this way in case we want to add exponential decay later - int now = UptimeTimer::getInstance ().getElapsedSeconds (); - canonicalize (source, now); - source.mBalance += credits; - - if (source.mBalance > mCreditLimit) - source.mBalance = mCreditLimit; - - if (source.isPrivileged ()) // privileged sources never warn/cutoff - return false; - - if ((source.mBalance >= mDebitLimit) && (source.mLastWarning == now)) // no need to warn - return false; - - return true; -} - -static void LogDeadLock (int dlTime) -{ - WriteLog (lsWARNING, LoadManager) << "Server stalled for " << dlTime << " seconds."; -} - -void LoadManager::threadEntry () -{ - setCallingThreadName ("loadmgr"); - - // VFALCO TODO replace this with a beast Time object? - // - // Initialize the clock to the current time. - boost::posix_time::ptime t = boost::posix_time::microsec_clock::universal_time (); - - for (;;) - { + LoadType getLoadType () const { - // VFALCO NOTE What is this lock protecting? - boost::mutex::scoped_lock sl (mLock); + return m_loadType; + } - // Check for the shutdown flag. - if (mShutdown) + int getCost () const + { + return m_cost; + } + + int getResourceFlags () const + { + return m_resourceFlags; + } + + public: + // VFALCO TODO Make these private and const + LoadType m_loadType; + int m_cost; + int m_resourceFlags; + }; + +public: + LoadManager () + : mCreditRate (100) + , mCreditLimit (500) + , mDebitWarn (-500) + , mDebitLimit (-1000) + , mShutdown (false) + , mArmed (false) + , mDeadLock (0) + , mCosts (LT_MAX) + { + /** Flags indicating the type of load. + + Utilization may include any combination of: + + - CPU + - Storage space + - Network transfer + */ + // VFALCO NOTE These flags are not used... + enum + { + flagDisk = 1, + flagCpu = 2, + flagNet = 4 + }; + + // VFALCO TODO Replace this with a function that uses a simple switch statement... + // + addCost (Cost (LT_InvalidRequest, -10, flagCpu | flagNet)); + addCost (Cost (LT_RequestNoReply, -1, flagCpu | flagDisk)); + addCost (Cost (LT_InvalidSignature, -100, flagCpu)); + addCost (Cost (LT_UnwantedData, -5, flagCpu | flagNet)); + addCost (Cost (LT_BadData, -20, flagCpu)); + + addCost (Cost (LT_RPCInvalid, -10, flagCpu | flagNet)); + addCost (Cost (LT_RPCReference, -10, flagCpu | flagNet)); + addCost (Cost (LT_RPCException, -20, flagCpu | flagNet)); + addCost (Cost (LT_RPCBurden, -50, flagCpu | flagNet)); + + // VFALCO NOTE Why do these supposedly "good" load types still have a negative cost? + // + addCost (Cost (LT_NewTrusted, -10, 0)); + addCost (Cost (LT_NewTransaction, -2, 0)); + addCost (Cost (LT_NeededData, -10, 0)); + + addCost (Cost (LT_RequestData, -5, flagDisk | flagNet)); + addCost (Cost (LT_CheapQuery, -1, flagCpu)); + } + +private: + ~LoadManager () + { + UptimeTimer::getInstance ().endManualUpdates (); + + // VFALCO TODO What is the purpose of this loop? Figure out + // a better way to do it. + for (;;) + { + boost::this_thread::sleep (boost::posix_time::milliseconds (100)); { - // VFALCO NOTE Why clear the flag now? - mShutdown = false; - return; + boost::mutex::scoped_lock sl (mLock); + + if (!mShutdown) + return; } + } + } - // VFALCO NOTE I think this is to reduce calls to the operating system - // for retrieving the current time. - // - // TODO Instead of incrementing can't we just retrieve the current - // time again? - // - // Manually update the timer. - UptimeTimer::getInstance ().incrementElapsedTime (); + void startThread () + { + UptimeTimer::getInstance ().beginManualUpdates (); - // Measure the amount of time we have been deadlocked, in seconds. - // - // VFALCO NOTE mDeadLock is a canary for detecting the condition. - int const timeSpentDeadlocked = UptimeTimer::getInstance ().getElapsedSeconds () - mDeadLock; + boost::thread (boost::bind (&LoadManager::threadEntry, this)).detach (); + } - if (mArmed && (timeSpentDeadlocked >= 10)) + void canonicalize (LoadSource& source, int now) const + { + if (source.mLastUpdate != now) + { + if (source.mLastUpdate < now) { - // Report the deadlocked condition every 10 seconds - if ((timeSpentDeadlocked % 10) == 0) + source.mBalance += mCreditRate * (now - source.mLastUpdate); + + if (source.mBalance > mCreditLimit) { - // VFALCO TODO Replace this with a dedicated thread with call queue. - // - boost::thread (BIND_TYPE (&LogDeadLock, timeSpentDeadlocked)).detach (); + source.mBalance = mCreditLimit; + source.mLogged = false; + } + } + + source.mLastUpdate = now; + } + } + + bool shouldWarn (LoadSource& source) const + { + { + boost::mutex::scoped_lock sl (mLock); + + int now = UptimeTimer::getInstance ().getElapsedSeconds (); + canonicalize (source, now); + + if (source.isPrivileged () || (source.mBalance > mDebitWarn) || (source.mLastWarning == now)) + return false; + + source.mLastWarning = now; + } + logWarning (source.getName ()); + return true; + } + + bool shouldCutoff (LoadSource& source) const + { + { + boost::mutex::scoped_lock sl (mLock); + int now = UptimeTimer::getInstance ().getElapsedSeconds (); + canonicalize (source, now); + + if (source.isPrivileged () || (source.mBalance > mDebitLimit)) + return false; + + if (source.mLogged) + return true; + + source.mLogged = true; + } + logDisconnect (source.getName ()); + return true; + } + + bool applyLoadCharge (LoadSource& source, LoadType loadType) const + { + // FIXME: Scale by category + Cost cost = mCosts[static_cast (loadType)]; + + return adjust (source, cost.m_cost); + } + + bool adjust (LoadSource& source, int credits) const + { + // return: true = need to warn/cutoff + + // We do it this way in case we want to add exponential decay later + int now = UptimeTimer::getInstance ().getElapsedSeconds (); + canonicalize (source, now); + source.mBalance += credits; + + if (source.mBalance > mCreditLimit) + source.mBalance = mCreditLimit; + + if (source.isPrivileged ()) // privileged sources never warn/cutoff + return false; + + if ((source.mBalance >= mDebitLimit) && (source.mLastWarning == now)) // no need to warn + return false; + + return true; + } + + void logWarning (const std::string& source) const + { + if (source.empty ()) + WriteLog (lsDEBUG, LoadManager) << "Load warning from empty source"; + else + WriteLog (lsINFO, LoadManager) << "Load warning: " << source; + } + + void logDisconnect (const std::string& source) const + { + if (source.empty ()) + WriteLog (lsINFO, LoadManager) << "Disconnect for empty source"; + else + WriteLog (lsWARNING, LoadManager) << "Disconnect for: " << source; + } + + // VFALCO TODO Implement this and stop accessing the vector directly + //Cost const& getCost (LoadType loadType) const; + int getCost (LoadType t) const + { + return mCosts [static_cast (t)].getCost (); + } + + void resetDeadlockDetector () + { + boost::mutex::scoped_lock sl (mLock); + mDeadLock = UptimeTimer::getInstance ().getElapsedSeconds (); + } + + void activateDeadlockDetector () + { + mArmed = true; + } + + static void logDeadlock (int dlTime) + { + WriteLog (lsWARNING, LoadManager) << "Server stalled for " << dlTime << " seconds."; + } + +private: + // VFALCO TODO These used to be public but are apparently not used. Find out why. + /* + int getCreditRate () const + { + boost::mutex::scoped_lock sl (mLock); + return mCreditRate; + } + + int getCreditLimit () const + { + boost::mutex::scoped_lock sl (mLock); + return mCreditLimit; + } + + int getDebitWarn () const + { + boost::mutex::scoped_lock sl (mLock); + return mDebitWarn; + } + + int getDebitLimit () const + { + boost::mutex::scoped_lock sl (mLock); + return mDebitLimit; + } + + void setCreditRate (int r) + { + boost::mutex::scoped_lock sl (mLock); + mCreditRate = r; + } + + void setCreditLimit (int r) + { + boost::mutex::scoped_lock sl (mLock); + mCreditLimit = r; + } + + void setDebitWarn (int r) + { + boost::mutex::scoped_lock sl (mLock); + mDebitWarn = r; + } + + void setDebitLimit (int r) + { + boost::mutex::scoped_lock sl (mLock); + mDebitLimit = r; + } + */ + +private: + void addCost (const Cost& c) + { + mCosts [static_cast (c.getLoadType ())] = c; + } + + // VFALCO NOTE Where's the thread object? It's not a data member... + // + void threadEntry () + { + setCallingThreadName ("loadmgr"); + + // VFALCO TODO replace this with a beast Time object? + // + // Initialize the clock to the current time. + boost::posix_time::ptime t = boost::posix_time::microsec_clock::universal_time (); + + for (;;) + { + { + // VFALCO NOTE What is this lock protecting? + boost::mutex::scoped_lock sl (mLock); + + // Check for the shutdown flag. + if (mShutdown) + { + // VFALCO NOTE Why clear the flag now? + mShutdown = false; + return; } - // If we go over 500 seconds spent deadlocked, it means that the - // deadlock resolution code has failed, which qualifies as undefined - // behavior. + // VFALCO NOTE I think this is to reduce calls to the operating system + // for retrieving the current time. // - assert (timeSpentDeadlocked < 500); + // TODO Instead of incrementing can't we just retrieve the current + // time again? + // + // Manually update the timer. + UptimeTimer::getInstance ().incrementElapsedTime (); + + // Measure the amount of time we have been deadlocked, in seconds. + // + // VFALCO NOTE mDeadLock is a canary for detecting the condition. + int const timeSpentDeadlocked = UptimeTimer::getInstance ().getElapsedSeconds () - mDeadLock; + + // VFALCO NOTE I think that "armed" refers to the deadlock detector + // + if (mArmed && (timeSpentDeadlocked >= 10)) + { + // Report the deadlocked condition every 10 seconds + if ((timeSpentDeadlocked % 10) == 0) + { + // VFALCO TODO Replace this with a dedicated thread with call queue. + // + boost::thread (BIND_TYPE (&logDeadlock, timeSpentDeadlocked)).detach (); + } + + // If we go over 500 seconds spent deadlocked, it means that the + // deadlock resolution code has failed, which qualifies as undefined + // behavior. + // + assert (timeSpentDeadlocked < 500); + } + } - } + bool change; - bool change; + // VFALCO TODO Eliminate the dependence on the Application object. + // Choices include constructing with the job queue / feetracker. + // Another option is using an observer pattern to invert the dependency. + if (theApp->getJobQueue ().isOverloaded ()) + { + WriteLog (lsINFO, LoadManager) << theApp->getJobQueue ().getJson (0); + change = theApp->getFeeTrack ().raiseLocalFee (); + } + else + { + change = theApp->getFeeTrack ().lowerLocalFee (); + } - // VFALCO TODO Eliminate the dependence on the Application object. - // Choices include constructing with the job queue / feetracker. - // Another option is using an observer pattern to invert the dependency. - if (theApp->getJobQueue ().isOverloaded ()) - { - WriteLog (lsINFO, LoadManager) << theApp->getJobQueue ().getJson (0); - change = theApp->getFeeTrack ().raiseLocalFee (); - } - else - { - change = theApp->getFeeTrack ().lowerLocalFee (); - } + if (change) + { + // VFALCO TODO replace this with a Listener / observer and subscribe in NetworkOPs or Application + theApp->getOPs ().reportFeeChange (); + } - if (change) - { - // VFALCO TODO replace this with a Listener / observer and subscribe in NetworkOPs or Application - theApp->getOPs ().reportFeeChange (); - } + t += boost::posix_time::seconds (1); + boost::posix_time::time_duration when = t - boost::posix_time::microsec_clock::universal_time (); - t += boost::posix_time::seconds (1); - boost::posix_time::time_duration when = t - boost::posix_time::microsec_clock::universal_time (); - - if ((when.is_negative ()) || (when.total_seconds () > 1)) - { - WriteLog (lsWARNING, LoadManager) << "time jump"; - t = boost::posix_time::microsec_clock::universal_time (); + if ((when.is_negative ()) || (when.total_seconds () > 1)) + { + WriteLog (lsWARNING, LoadManager) << "time jump"; + t = boost::posix_time::microsec_clock::universal_time (); + } + else + boost::this_thread::sleep (when); } - else - boost::this_thread::sleep (when); } -} -void LoadManager::logWarning (const std::string& source) const +private: + int mCreditRate; // credits gained/lost per second + int mCreditLimit; // the most credits a source can have + int mDebitWarn; // when a source drops below this, we warn + int mDebitLimit; // when a source drops below this, we cut it off (should be negative) + + bool mShutdown; + bool mArmed; + + int mDeadLock; // Detect server deadlocks + + mutable boost::mutex mLock; // VFALCO TODO Replace with juce::Mutex and remove the mutable attribute + + std::vector mCosts; +}; + +//------------------------------------------------------------------------------ + +ILoadManager* ILoadManager::New () { - if (source.empty ()) - WriteLog (lsDEBUG, LoadManager) << "Load warning from empty source"; - else - WriteLog (lsINFO, LoadManager) << "Load warning: " << source; + return new LoadManager; } - -void LoadManager::logDisconnect (const std::string& source) const -{ - if (source.empty ()) - WriteLog (lsINFO, LoadManager) << "Disconnect for empty source"; - else - WriteLog (lsWARNING, LoadManager) << "Disconnect for: " << source; -} - -// vim:ts=4 diff --git a/src/cpp/ripple/ripple_LoadManager.h b/src/cpp/ripple/ripple_LoadManager.h deleted file mode 100644 index b2044f09c2..0000000000 --- a/src/cpp/ripple/ripple_LoadManager.h +++ /dev/null @@ -1,257 +0,0 @@ -//------------------------------------------------------------------------------ -/* - Copyright (c) 2011-2013, OpenCoin, Inc. -*/ -//============================================================================== - -#ifndef RIPPLE_LOADMANAGER_H -#define RIPPLE_LOADMANAGER_H - -// types of load that can be placed on the server -// VFALCO TODO replace LT_ with loadType in constants -enum LoadType -{ - // Bad things - LT_InvalidRequest, // A request that we can immediately tell is invalid - LT_RequestNoReply, // A request that we cannot satisfy - LT_InvalidSignature, // An object whose signature we had to check and it failed - LT_UnwantedData, // Data we have no use for - LT_BadPoW, // Proof of work not valid - LT_BadData, // Data we have to verify before rejecting - - // Good things - LT_NewTrusted, // A new transaction/validation/proposal we trust - LT_NewTransaction, // A new, valid transaction - LT_NeededData, // Data we requested - - // Requests - LT_RequestData, // A request that is hard to satisfy, disk access - LT_CheapQuery, // A query that is trivial, cached data - - LT_MAX // MUST BE LAST -}; - -// load categories -// VFALCO NOTE These look like bit flags, name them accordingly -enum -{ - LC_Disk = 1, - LC_CPU = 2, - LC_Network = 4 -}; - -/** Tracks the consumption of resources at an endpoint. - - To prevent monopolization of server resources or attacks on servers, - resource consumption is monitored at each endpoint. When consumption - exceeds certain thresholds, costs are imposed. Costs include charging - additional XRP for transactions, requiring a proof of work to be - performed, or simply disconnecting the endpoint. - - Currently, consumption endpoints include: - - - WebSocket connections - - Peer connections - - @note Although RPC connections consume resources, they are transient and - cannot be rate limited. It is advised not to expose RPC interfaces - to the general public. -*/ -class LoadSource -{ -private: - // VFALCO Make this not a friend - friend class LoadManager; - -public: - // load source flags - static const int lsfPrivileged = 1; - static const int lsfOutbound = 2; // outbound connection - -public: - /** Construct a load source. - - Sources with admin privileges have relaxed or no restrictions - on resource consumption. - - @param admin `true` if the source has admin privileges. - */ - explicit LoadSource (bool admin) - : mBalance (0) - , mFlags (admin ? lsfPrivileged : 0) - , mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ()) - , mLastWarning (0) - , mLogged (false) - { - } - - explicit LoadSource (std::string const& name) - : mName (name) - , mBalance (0) - , mFlags (0) - , mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ()) - , mLastWarning (0) - , mLogged (false) - { - } - - // VFALCO TODO Figure out a way to construct the LoadSource object with - // the proper name instead of renaming it later. - // - void rename (std::string const& name) - { - mName = name; - } - - std::string const& getName () const - { - return mName; - } - - bool isPrivileged () const - { - return (mFlags & lsfPrivileged) != 0; - } - - void setPrivileged () - { - mFlags |= lsfPrivileged; - } - - int getBalance () const - { - return mBalance; - } - - bool isLogged () const - { - return mLogged; - } - - void clearLogged () - { - mLogged = false; - } - - void setOutbound () - { - mFlags |= lsfOutbound; - } - - bool isOutbound () const - { - return (mFlags & lsfOutbound) != 0; - } - -private: - std::string mName; - int mBalance; - int mFlags; - int mLastUpdate; - int mLastWarning; - bool mLogged; -}; - -// a collection of load sources -class LoadManager -{ -public: - LoadManager (int creditRate = 100, - int creditLimit = 500, - int debitWarn = -500, - int debitLimit = -1000); - - ~LoadManager (); - - void init (); - - bool shouldWarn (LoadSource&) const; - - bool shouldCutoff (LoadSource&) const; - - bool adjust (LoadSource&, int credits) const; // return value: false=balance okay, true=warn/cutoff - - bool adjust (LoadSource&, LoadType l) const; - - void logWarning (const std::string&) const; - - void logDisconnect (const std::string&) const; - - int getCost (LoadType t) const - { - return mCosts [static_cast (t)].mCost; - } - - void noDeadLock (); - - void arm () - { - mArmed = true; - } - -private: - // VFALCO TODO These used to be public but are apparently not used. Find out why. - int getCreditRate () const; - int getCreditLimit () const; - int getDebitWarn () const; - int getDebitLimit () const; - void setCreditRate (int); - void setCreditLimit (int); - void setDebitWarn (int); - void setDebitLimit (int); - -private: - class Cost - { - public: - Cost () - : mType () - , mCost (0) - , mCategories (0) - { - } - - Cost (LoadType typeOfLoad, int cost, int category) - : mType (typeOfLoad) - , mCost (cost) - , mCategories (category) - { - } - - public: - // VFALCO TODO Make these private and const - LoadType mType; - int mCost; - int mCategories; - }; - - void canonicalize (LoadSource&, int upTime) const; - - void addCost (const Cost& c) - { - mCosts [static_cast (c.mType)] = c; - } - - // VFALCO NOTE Where's the thread object? It's not a data member... - // - void threadEntry (); - -private: - int mCreditRate; // credits gained/lost per second - int mCreditLimit; // the most credits a source can have - int mDebitWarn; // when a source drops below this, we warn - int mDebitLimit; // when a source drops below this, we cut it off (should be negative) - - bool mShutdown; - bool mArmed; - - int mDeadLock; // Detect server deadlocks - - mutable boost::mutex mLock; // VFALCO TODO Replace with juce::Mutex and remove the mutable attribute - - std::vector mCosts; -}; - -#endif - -// vim:ts=4 diff --git a/src/cpp/ripple/ripple_Peer.cpp b/src/cpp/ripple/ripple_Peer.cpp index b288f27a8c..ffb26889e1 100644 --- a/src/cpp/ripple/ripple_Peer.cpp +++ b/src/cpp/ripple/ripple_Peer.cpp @@ -63,7 +63,7 @@ public: void sendGetPeers (); - void punishPeer (LoadType); + void applyLoadCharge (LoadType); Json::Value getJson (); bool isConnected () const @@ -1070,7 +1070,7 @@ static void checkTransaction (Job&, int flags, SerializedTransaction::pointer st if (tx->getStatus () == INVALID) { theApp->getHashRouter ().setFlag (stx->getTransactionID (), SF_BAD); - Peer::punishPeer (peer, LT_InvalidSignature); + Peer::applyLoadCharge (peer, LT_InvalidSignature); return; } else @@ -1083,7 +1083,7 @@ static void checkTransaction (Job&, int flags, SerializedTransaction::pointer st catch (...) { theApp->getHashRouter ().setFlags (stx->getTransactionID (), SF_BAD); - punishPeer (peer, LT_InvalidRequest); + applyLoadCharge (peer, LT_InvalidRequest); } #endif @@ -1109,7 +1109,7 @@ void PeerImp::recvTransaction (protocol::TMTransaction& packet, ScopedLock& Mast // we have seen this transaction recently if (isSetBit (flags, SF_BAD)) { - punishPeer (LT_InvalidSignature); + applyLoadCharge (LT_InvalidSignature); return; } @@ -1166,7 +1166,7 @@ static void checkPropose (Job& job, boost::shared_ptr pa Peer::pointer p = peer.lock (); WriteLog (lsWARNING, Peer) << "proposal with previous ledger fails signature check: " << (p ? p->getIP () : std::string ("???")); - Peer::punishPeer (peer, LT_InvalidSignature); + Peer::applyLoadCharge (peer, LT_InvalidSignature); return; } else @@ -1210,14 +1210,14 @@ void PeerImp::recvPropose (const boost::shared_ptr& pack (set.signature ().size () < 56) || (set.nodepubkey ().size () > 128) || (set.signature ().size () > 128)) { WriteLog (lsWARNING, Peer) << "Received proposal is malformed"; - punishPeer (LT_InvalidSignature); + applyLoadCharge (LT_InvalidSignature); return; } if (set.has_previousledger () && (set.previousledger ().size () != 32)) { WriteLog (lsWARNING, Peer) << "Received proposal is malformed"; - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -1278,7 +1278,7 @@ void PeerImp::recvHaveTxSet (protocol::TMHaveTransactionSet& packet) if (packet.hash ().size () != (256 / 8)) { - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -1289,7 +1289,7 @@ void PeerImp::recvHaveTxSet (protocol::TMHaveTransactionSet& packet) addTxSet (hash); if (!theApp->getOPs ().hasTXSet (shared_from_this (), hash, packet.status ())) - punishPeer (LT_UnwantedData); + applyLoadCharge (LT_UnwantedData); } static void checkValidation (Job&, SerializedValidation::pointer val, uint256 signingHash, @@ -1303,7 +1303,7 @@ static void checkValidation (Job&, SerializedValidation::pointer val, uint256 si if (!isCluster && !val->isValid (signingHash)) { WriteLog (lsWARNING, Peer) << "Validation is invalid"; - Peer::punishPeer (peer, LT_InvalidRequest); + Peer::applyLoadCharge (peer, LT_InvalidRequest); return; } @@ -1329,7 +1329,7 @@ static void checkValidation (Job&, SerializedValidation::pointer val, uint256 si catch (...) { WriteLog (lsWARNING, Peer) << "Exception processing validation"; - Peer::punishPeer (peer, LT_InvalidRequest); + Peer::applyLoadCharge (peer, LT_InvalidRequest); } #endif @@ -1342,7 +1342,7 @@ void PeerImp::recvValidation (const boost::shared_ptr& p if (packet->validation ().size () < 50) { WriteLog (lsWARNING, Peer) << "Too small validation from peer"; - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -1376,7 +1376,7 @@ void PeerImp::recvValidation (const boost::shared_ptr& p catch (...) { WriteLog (lsWARNING, Peer) << "Exception processing validation"; - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); } #endif @@ -1591,7 +1591,7 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet) // this is an answer to a proof of work we requested if (packet.response ().size () != (256 / 8)) { - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -1609,7 +1609,7 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet) // return error message // WRITEME if (r != powTOOEASY) - punishPeer (LT_BadPoW); + applyLoadCharge (LT_BadPoW); return; } @@ -1629,7 +1629,7 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet) if ((packet.challenge ().size () != (256 / 8)) || (packet.target ().size () != (256 / 8))) { - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -1640,7 +1640,7 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet) if (!pow->isValid ()) { - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -1731,7 +1731,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, ScopedLock& MasterLo if ((!packet.has_ledgerhash () || packet.ledgerhash ().size () != 32)) { - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); WriteLog (lsWARNING, Peer) << "invalid request for TX candidate set data"; return; } @@ -1766,7 +1766,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, ScopedLock& MasterLo } WriteLog (lsERROR, Peer) << "We do not have the map our peer wants " << getIP (); - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -1788,7 +1788,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, ScopedLock& MasterLo if (packet.ledgerhash ().size () != 32) { - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); WriteLog (lsWARNING, Peer) << "Invalid request"; return; } @@ -1844,14 +1844,14 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, ScopedLock& MasterLo } else { - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); WriteLog (lsWARNING, Peer) << "Can't figure out what ledger they want"; return; } if ((!ledger) || (packet.has_ledgerseq () && (packet.ledgerseq () != ledger->getLedgerSeq ()))) { - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); if (ShouldLog (lsWARNING, Peer)) { @@ -1931,7 +1931,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, ScopedLock& MasterLo if ((!map) || (packet.nodeids_size () == 0)) { WriteLog (lsWARNING, Peer) << "Can't find map or empty request"; - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -1944,7 +1944,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, ScopedLock& MasterLo if (!mn.isValid ()) { WriteLog (lsWARNING, Peer) << "Request for invalid node: " << logMe; - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -2005,7 +2005,7 @@ void PeerImp::recvLedger (const boost::shared_ptr& packe if (packet.nodes ().size () <= 0) { WriteLog (lsWARNING, Peer) << "Ledger/TXset data with no nodes"; - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -2021,7 +2021,7 @@ void PeerImp::recvLedger (const boost::shared_ptr& packe else { WriteLog (lsINFO, Peer) << "Unable to route TX/ledger data reply"; - punishPeer (LT_UnwantedData); + applyLoadCharge (LT_UnwantedData); } return; @@ -2032,7 +2032,7 @@ void PeerImp::recvLedger (const boost::shared_ptr& packe if (packet.ledgerhash ().size () != 32) { WriteLog (lsWARNING, Peer) << "TX candidate reply with invalid hash size"; - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -2051,7 +2051,7 @@ void PeerImp::recvLedger (const boost::shared_ptr& packe if (!node.has_nodeid () || !node.has_nodedata () || (node.nodeid ().size () != 33)) { WriteLog (lsWARNING, Peer) << "LedgerData request with invalid node ID"; - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -2062,7 +2062,7 @@ void PeerImp::recvLedger (const boost::shared_ptr& packe SHAMapAddNode san = theApp->getOPs ().gotTXData (shared_from_this (), hash, nodeIDs, nodeData); if (san.isInvalid ()) - punishPeer (LT_UnwantedData); + applyLoadCharge (LT_UnwantedData); return; } @@ -2072,7 +2072,7 @@ void PeerImp::recvLedger (const boost::shared_ptr& packe BIND_TYPE (&InboundLedgers::gotLedgerData, &theApp->getInboundLedgers (), P_1, hash, packet_ptr, boost::weak_ptr (shared_from_this ()))); else - punishPeer (LT_UnwantedData); + applyLoadCharge (LT_UnwantedData); } bool PeerImp::hasLedger (uint256 const& hash, uint32 seq) const @@ -2203,11 +2203,13 @@ void PeerImp::sendGetPeers () sendPacket (packet, true); } -void PeerImp::punishPeer (LoadType l) +void PeerImp::applyLoadCharge (LoadType loadType) { - if (theApp->getLoadManager ().adjust (mLoad, l)) + if (theApp->getLoadManager ().applyLoadCharge (mLoad, loadType)) { - // WRITEME + // UNIMPLEMENTED + + // VFALCO TODO This needs to implemented before open sourcing. } } @@ -2251,7 +2253,7 @@ void PeerImp::doFetchPack (const boost::shared_ptr& if (packet->ledgerhash ().size () != 32) { WriteLog (lsWARNING, Peer) << "FetchPack hash size malformed"; - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -2263,14 +2265,14 @@ void PeerImp::doFetchPack (const boost::shared_ptr& if (!haveLedger) { WriteLog (lsINFO, Peer) << "Peer requests fetch pack for ledger we don't have: " << hash; - punishPeer (LT_RequestNoReply); + applyLoadCharge (LT_RequestNoReply); return; } if (!haveLedger->isClosed ()) { WriteLog (lsWARNING, Peer) << "Peer requests fetch pack from open ledger: " << hash; - punishPeer (LT_InvalidRequest); + applyLoadCharge (LT_InvalidRequest); return; } @@ -2279,7 +2281,7 @@ void PeerImp::doFetchPack (const boost::shared_ptr& if (!wantLedger) { WriteLog (lsINFO, Peer) << "Peer requests fetch pack for ledger whose predecessor we don't have: " << hash; - punishPeer (LT_RequestNoReply); + applyLoadCharge (LT_RequestNoReply); return; } @@ -2374,12 +2376,12 @@ Peer::pointer Peer::New (boost::asio::io_service& io_service, return Peer::pointer (new PeerImp (io_service, ctx, id, inbound)); } -void Peer::punishPeer (const boost::weak_ptr& wp, LoadType l) +void Peer::applyLoadCharge (const boost::weak_ptr& wp, LoadType l) { Peer::pointer p = wp.lock (); if (p) - p->punishPeer (l); + p->applyLoadCharge (l); } // vim:ts=4 diff --git a/src/cpp/ripple/ripple_Peer.h b/src/cpp/ripple/ripple_Peer.h index 7b863d61c5..4c3dcd3cbd 100644 --- a/src/cpp/ripple/ripple_Peer.h +++ b/src/cpp/ripple/ripple_Peer.h @@ -57,10 +57,10 @@ public: virtual void sendGetPeers () = 0; - virtual void punishPeer (LoadType) = 0; + virtual void applyLoadCharge (LoadType) = 0; // VFALCO NOTE what's with this odd parameter passing? Why the static member? - static void punishPeer (const boost::weak_ptr&, LoadType); + static void applyLoadCharge (const boost::weak_ptr&, LoadType); virtual Json::Value getJson () = 0;