From 0366fd87a12a0c981e43caa15625ab302e5760e0 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 May 2013 16:35:21 -0700 Subject: [PATCH 1/9] STAmount::setJson to allow amounts to be set in place. --- src/cpp/ripple/Amount.cpp | 11 ++++++++--- src/cpp/ripple/SerializedTypes.h | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/cpp/ripple/Amount.cpp b/src/cpp/ripple/Amount.cpp index c65067afb..9c1775c71 100644 --- a/src/cpp/ripple/Amount.cpp +++ b/src/cpp/ripple/Amount.cpp @@ -1223,9 +1223,9 @@ void STAmount::roundSelf() } } -Json::Value STAmount::getJson(int) const +void STAmount::setJson(Json::Value& elem) const { - Json::Value elem(Json::objectValue); + elem = Json::objectValue; if (!mIsNative) { @@ -1237,9 +1237,14 @@ Json::Value STAmount::getJson(int) const } else { - elem=getText(); + elem = getText(); } +} +Json::Value STAmount::getJson(int) const +{ + Json::Value elem; + setJson(elem); return elem; } diff --git a/src/cpp/ripple/SerializedTypes.h b/src/cpp/ripple/SerializedTypes.h index c599c2d73..7320fa917 100644 --- a/src/cpp/ripple/SerializedTypes.h +++ b/src/cpp/ripple/SerializedTypes.h @@ -473,6 +473,7 @@ public: static bool issuerFromString(uint160& uDstIssuer, const std::string& sIssuer); Json::Value getJson(int) const; + void setJson(Json::Value&) const; STAmount getRound() const; void roundSelf(); From 1ebcebd0673d4948d7f48334851f92eb3b9ec942 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 May 2013 16:35:36 -0700 Subject: [PATCH 2/9] Book offers improvements. --- src/cpp/ripple/NetworkOPs.cpp | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index b7208a606..f971bac21 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1841,8 +1841,9 @@ InfoSub::pointer NetworkOPs::addRpcSub(const std::string& strUrl, InfoSub::ref r // FIXME : support iLimit. void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPaysCurrencyID, const uint160& uTakerPaysIssuerID, const uint160& uTakerGetsCurrencyID, const uint160& uTakerGetsIssuerID, const uint160& uTakerID, const bool bProof, const unsigned int iLimit, const Json::Value& jvMarker, Json::Value& jvResult) { - boost::unordered_map umBalance; - Json::Value jvOffers = Json::Value(Json::arrayValue); + Json::Value& jvOffers = (jvResult["offers"] = Json::Value(Json::arrayValue)); + + std::map umBalance; const uint256 uBookBase = Ledger::getBookBase(uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID); const uint256 uBookEnd = Ledger::getQualityNext(uBookBase); uint256 uTipIndex = uBookBase; @@ -1896,8 +1897,8 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays { SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex); const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); - STAmount saTakerGets = sleOffer->getFieldAmount(sfTakerGets); - STAmount saTakerPays = sleOffer->getFieldAmount(sfTakerPays); + const STAmount& saTakerGets = sleOffer->getFieldAmount(sfTakerGets); + const STAmount& saTakerPays = sleOffer->getFieldAmount(sfTakerPays); STAmount saOwnerFunds; if (uTakerGetsIssuerID == uOfferOwnerID) @@ -1907,7 +1908,7 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays } else { - boost::unordered_map::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID); + std::map::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID); if (umBalanceEntry != umBalance.end()) { @@ -1964,30 +1965,26 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays // cLog(lsINFO) << boost::str(boost::format("getBookPage: saDirRate=%s") % saDirRate.getText()); // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate).getFullText()); // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays).getFullText()); - STAmount saTakerPaysFunded; - - saTakerGetsFunded = saOwnerFundsLimit; - saTakerPaysFunded = std::min(saTakerPays, STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays)); // Only provide, if not fully funded. - jvOffer["taker_gets_funded"] = saTakerGetsFunded.getJson(0); - jvOffer["taker_pays_funded"] = saTakerPaysFunded.getJson(0); + + saTakerGetsFunded = saOwnerFundsLimit; + + saTakerGetsFunded.setJson(jvOffer["taker_gets_funded"]); + std::min(saTakerPays, STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays)).setJson(jvOffer["taker_pays_funded"]); } - STAmount saOwnerPays = QUALITY_ONE == uOfferRate + STAmount saOwnerPays = (QUALITY_ONE == uOfferRate) ? saTakerGetsFunded : std::min(saOwnerFunds, STAmount::multiply(saTakerGetsFunded, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uOfferRate, -9))); - STAmount saOwnerBalance = saOwnerFunds-saOwnerPays; - - umBalance[uOfferOwnerID] = saOwnerBalance; + umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays; if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID) { // Only provide funded offers and offers of the taker. - jvOffer["quality"] = saDirRate.getText(); - - jvOffers.append(jvOffer); + Json::Value& jvOf = jvOffers.append(jvOffer); + jvOf["quality"] = saDirRate.getText(); } if (!lesActive.dirNext(uTipIndex, sleOfferDir, uBookEntry, uOfferIndex)) @@ -2001,7 +1998,6 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays } } - jvResult["offers"] = jvOffers; // jvResult["marker"] = Json::Value(Json::arrayValue); // jvResult["nodes"] = Json::Value(Json::arrayValue); } From c9fd800ea4524bffce5e56bc0ca0837b7c59332d Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 May 2013 17:00:18 -0700 Subject: [PATCH 3/9] More performance improvements. --- src/cpp/ripple/RPCHandler.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 4f46ba3cb..e93a9698e 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1151,7 +1151,8 @@ Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest, int& cost, Scoped if (as) { - Json::Value jsonLines(Json::arrayValue); + Json::Value& jsonLines = jvResult["offers"]; + jsonLines = Json::arrayValue; AccountItems offers(raAccount.getAccountID(), lpLedger, AccountItem::pointer(new Offer())); BOOST_FOREACH(AccountItem::ref item, offers.getItems()) @@ -1162,16 +1163,15 @@ Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest, int& cost, Scoped STAmount takerGets = offer->getTakerGets(); //RippleAddress account = offer->getAccount(); - Json::Value obj = Json::Value(Json::objectValue); + Json::Value& obj = jsonLines.append(obj); + obj = Json::Value(Json::objectValue); //obj["account"] = account.humanAccountID(); - obj["taker_pays"] = takerPays.getJson(0); - obj["taker_gets"] = takerGets.getJson(0); + takerPays.setJson(obj["taker_pays"]); + takerGets.setJson(obj["taker_gets"]); obj["seq"] = offer->getSeq(); - jsonLines.append(obj); } - jvResult["offers"] = jsonLines; } else { @@ -1967,15 +1967,14 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest, int& cost, for (std::vector::const_iterator it = txns.begin(), end = txns.end(); it != end; ++it) { - Json::Value jvObj(Json::objectValue); - uint32 uLedgerIndex = it->get<2>(); + Json::Value& jvObj = ret["transactions"].append(Json::objectValue); + uint32 uLedgerIndex = it->get<2>(); jvObj["tx_blob"] = it->get<0>(); jvObj["meta"] = it->get<1>(); jvObj["ledger_index"] = uLedgerIndex; jvObj["validated"] = bValidated && uValidatedMin <= uLedgerIndex && uValidatedMax >= uLedgerIndex; - ret["transactions"].append(jvObj); } } else @@ -1984,7 +1983,7 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest, int& cost, for (std::vector< std::pair >::iterator it = txns.begin(), end = txns.end(); it != end; ++it) { - Json::Value jvObj(Json::objectValue); + Json::Value& jvObj = ret["transactions"].append(Json::objectValue); if (it->first) jvObj["tx"] = it->first->getJson(1); @@ -1997,7 +1996,6 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest, int& cost, jvObj["validated"] = bValidated && uValidatedMin <= uLedgerIndex && uValidatedMax >= uLedgerIndex; } - ret["transactions"].append(jvObj); } } From bcf0fc0b3a53d1bcbf835e70afcfa9c59997bc0b Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 May 2013 18:28:54 -0700 Subject: [PATCH 4/9] Avoid construcing a RippleAddress just to throw it away. --- src/cpp/ripple/LedgerEntrySet.cpp | 2 +- src/cpp/ripple/NetworkOPs.cpp | 9 ++++++--- src/cpp/ripple/OfferCreateTransactor.cpp | 2 +- src/cpp/ripple/RippleCalc.cpp | 4 ++-- src/cpp/ripple/TransactionCheck.cpp | 3 +-- src/cpp/ripple/Transactor.cpp | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/cpp/ripple/LedgerEntrySet.cpp b/src/cpp/ripple/LedgerEntrySet.cpp index 9c51bcaa6..beb34a19d 100644 --- a/src/cpp/ripple/LedgerEntrySet.cpp +++ b/src/cpp/ripple/LedgerEntrySet.cpp @@ -985,7 +985,7 @@ TER LedgerEntrySet::offerDelete(SLE::ref sleOffer, const uint256& uOfferIndex, c TER LedgerEntrySet::offerDelete(const uint256& uOfferIndex) { SLE::pointer sleOffer = entryCache(ltOFFER, uOfferIndex); - const uint160 uOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); + const uint160 uOwnerID = sleOffer->getFieldAccount160(sfAccount); return offerDelete(sleOffer, uOfferIndex, uOwnerID); } diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index f971bac21..5d0e27268 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1864,11 +1864,13 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays unsigned int uBookEntry; STAmount saDirRate; -// unsigned int iLeft = iLimit; + unsigned int iLeft = iLimit; + if ((iLeft == 0) || (iLeft > 300)) + iLeft = 300; uint32 uTransferRate = lesActive.rippleTransferRate(uTakerGetsIssuerID); - while (!bDone) { + while (!bDone && (iLeft > 0)) { if (bDirectAdvance) { bDirectAdvance = false; @@ -1896,7 +1898,7 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays if (!bDone) { SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex); - const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); + const uint160 uOfferOwnerID = sleOffer->getFieldAccount160(sfAccount); const STAmount& saTakerGets = sleOffer->getFieldAmount(sfTakerGets); const STAmount& saTakerPays = sleOffer->getFieldAmount(sfTakerPays); STAmount saOwnerFunds; @@ -1985,6 +1987,7 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays // Only provide funded offers and offers of the taker. Json::Value& jvOf = jvOffers.append(jvOffer); jvOf["quality"] = saDirRate.getText(); + --iLeft; } if (!lesActive.dirNext(uTipIndex, sleOfferDir, uBookEntry, uOfferIndex)) diff --git a/src/cpp/ripple/OfferCreateTransactor.cpp b/src/cpp/ripple/OfferCreateTransactor.cpp index c7ce3e0ac..5abb874d4 100644 --- a/src/cpp/ripple/OfferCreateTransactor.cpp +++ b/src/cpp/ripple/OfferCreateTransactor.cpp @@ -212,7 +212,7 @@ TER OfferCreateTransactor::takeOffers( cLog(lsDEBUG) << "takeOffers: considering offer : " << sleOffer->getJson(0); - const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); + const uint160 uOfferOwnerID = sleOffer->getFieldAccount160(sfAccount); STAmount saOfferPays = sleOffer->getFieldAmount(sfTakerGets); STAmount saOfferGets = sleOffer->getFieldAmount(sfTakerPays); diff --git a/src/cpp/ripple/RippleCalc.cpp b/src/cpp/ripple/RippleCalc.cpp index 22da827e0..8741d1d58 100644 --- a/src/cpp/ripple/RippleCalc.cpp +++ b/src/cpp/ripple/RippleCalc.cpp @@ -978,7 +978,7 @@ TER RippleCalc::calcNodeAdvance( { // Got a new offer. sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex); - uOfrOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); + uOfrOwnerID = sleOffer->getFieldAccount160(sfAccount); saTakerPays = sleOffer->getFieldAmount(sfTakerPays); saTakerGets = sleOffer->getFieldAmount(sfTakerGets); @@ -3136,7 +3136,7 @@ void TransactionEngine::calcOfferBridgeNext( SLE::pointer sleOffer = entryCache(ltOFFER, uOfferIndex); - uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); + uint160 uOfferOwnerID = sleOffer->getFieldAccount160(sfAccount); STAmount saOfferPays = sleOffer->getFieldAmount(sfTakerGets); STAmount saOfferGets = sleOffer->getFieldAmount(sfTakerPays); diff --git a/src/cpp/ripple/TransactionCheck.cpp b/src/cpp/ripple/TransactionCheck.cpp index 2d4a0f8ea..0b4f5c1f5 100644 --- a/src/cpp/ripple/TransactionCheck.cpp +++ b/src/cpp/ripple/TransactionCheck.cpp @@ -9,12 +9,11 @@ SETUP_LOG(); bool TransactionEngine::checkInvariants(TER result, const SerializedTransaction& txn, TransactionEngineParams params) { #if 0 - const RippleAddress& srcAccount = txn.getFieldAccount(sfAccount); uint32 txnSeq = txn.getFieldU32(sfSequence); LedgerEntryAction leaAction; - uint256 srcActId = Ledger::getAccountRootIndex(srcAccount.getAccountID()); + uint256 srcActId = Ledger::getAccountRootIndex(txn.getFieldAccount(sfAccount)); SLE::pointer origSrcAct = mLedger->getSLE(srcActId); SLE::pointer newSrcAct = mNodes.getEntry(srcActId, leaAction); diff --git a/src/cpp/ripple/Transactor.cpp b/src/cpp/ripple/Transactor.cpp index b9068e504..82b8ab9bc 100644 --- a/src/cpp/ripple/Transactor.cpp +++ b/src/cpp/ripple/Transactor.cpp @@ -97,7 +97,7 @@ TER Transactor::checkSig() { // Consistency: Check signature // Verify the transaction's signing public key is the key authorized for signing. - if (mHasAuthKey && mSigningPubKey.getAccountID() == mTxnAccount->getFieldAccount(sfRegularKey).getAccountID()) + if (mHasAuthKey && mSigningPubKey.getAccountID() == mTxnAccount->getFieldAccount160(sfRegularKey)) { // Authorized to continue. nothing(); From e71849779e5fe17d633fc24d17494595fdc4b471 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 May 2013 18:34:46 -0700 Subject: [PATCH 5/9] Cleanup. --- src/cpp/ripple/NetworkOPs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 5d0e27268..5149a21c9 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1874,12 +1874,12 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays if (bDirectAdvance) { bDirectAdvance = false; - cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDirectAdvance")); + cLog(lsTRACE) << "getBookPage: bDirectAdvance"; sleOfferDir = lesActive.entryCache(ltDIR_NODE, lpLedger->getNextLedgerIndex(uTipIndex, uBookEnd)); if (!sleOfferDir) { - cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDone")); + cLog(lsTRACE) << "getBookPage: bDone"; bDone = true; } else From 1b619c72373a724b01504f3edb9821daf4a0bc37 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 13 May 2013 18:46:57 -0700 Subject: [PATCH 6/9] More performance improvements. --- src/cpp/ripple/RPCHandler.cpp | 36 +++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index e93a9698e..ba49aa01b 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1064,12 +1064,12 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL } AccountState::pointer as = mNetOps->getAccountState(lpLedger, raAccount); - MasterLockHolder.unlock(); + + if (lpLedger->isImmutable()) + MasterLockHolder.unlock(); if (as) { - Json::Value jsonLines(Json::arrayValue); - jvResult["account"] = raAccount.humanAccountID(); // XXX This is wrong, we do access the current ledger and do need to worry about changes. @@ -1077,6 +1077,7 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL AccountItems rippleLines(raAccount.getAccountID(), lpLedger, AccountItem::pointer(new RippleState())); + Json::Value& jsonLines = (jvResult["lines"] = Json::arrayValue); BOOST_FOREACH(AccountItem::ref item, rippleLines.getItems()) { RippleState* line=(RippleState*)item.get(); @@ -1087,7 +1088,7 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL STAmount saLimit = line->getLimit(); STAmount saLimitPeer = line->getLimitPeer(); - Json::Value jPeer = Json::Value(Json::objectValue); + Json::Value& jPeer = jsonLines.append(Json::objectValue); jPeer["account"] = RippleAddress::createHumanAccountID(line->getAccountIDPeer()); // Amount reported is positive if current account holds other account's IOUs. @@ -1098,11 +1099,8 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL jPeer["limit_peer"] = saLimitPeer.getText(); jPeer["quality_in"] = static_cast(line->getQualityIn()); jPeer["quality_out"] = static_cast(line->getQualityOut()); - - jsonLines.append(jPeer); } } - jvResult["lines"] = jsonLines; } else { @@ -1147,7 +1145,9 @@ Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest, int& cost, Scoped jvResult["account_index"] = iIndex; AccountState::pointer as = mNetOps->getAccountState(lpLedger, raAccount); - MasterLockHolder.unlock(); + + if (lpLedger->isImmutable()) + MasterLockHolder.unlock(); if (as) { @@ -1868,9 +1868,14 @@ Json::Value RPCHandler::doLedger(Json::Value jvRequest, int& cost, ScopedLock& M | (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0) | (bAccounts ? LEDGER_JSON_DUMP_STATE : 0); + if (bFull && !lpLedger->isImmutable()) + { // For full, it's cheaper to snapshot + lpLedger = boost::make_shared(*lpLedger, true); + } + Json::Value ret(Json::objectValue); - if (lpLedger->isClosed()) + if (lpLedger->isImmutable()) MasterLockHolder.unlock(); lpLedger->addJson(ret, iOptions); @@ -1957,7 +1962,7 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest, int& cost, Json::Value ret(Json::objectValue); ret["account"] = raAccount.humanAccountID(); - ret["transactions"] = Json::arrayValue; + Json::Value& jvTxns = (ret["transactions"] = Json::arrayValue); if (bBinary) { @@ -1967,7 +1972,7 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest, int& cost, for (std::vector::const_iterator it = txns.begin(), end = txns.end(); it != end; ++it) { - Json::Value& jvObj = ret["transactions"].append(Json::objectValue); + Json::Value& jvObj = jvTxns.append(Json::objectValue); uint32 uLedgerIndex = it->get<2>(); jvObj["tx_blob"] = it->get<0>(); @@ -1983,7 +1988,7 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest, int& cost, for (std::vector< std::pair >::iterator it = txns.begin(), end = txns.end(); it != end; ++it) { - Json::Value& jvObj = ret["transactions"].append(Json::objectValue); + Json::Value& jvObj = jvTxns.append(Json::objectValue); if (it->first) jvObj["tx"] = it->first->getJson(1); @@ -2172,6 +2177,8 @@ Json::Value RPCHandler::doLogRotate(Json::Value, int& cost, ScopedLock& MasterLo // } Json::Value RPCHandler::doWalletPropose(Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) { + MasterLockHolder.unlock(); + RippleAddress naSeed; RippleAddress naAccount; @@ -2670,7 +2677,8 @@ Json::Value RPCHandler::doLedgerEntry(Json::Value jvRequest, int& cost, ScopedLo if (!lpLedger) return jvResult; - if (lpLedger->isClosed()) + + if (lpLedger->isImmutable()) MasterLockHolder.unlock(); uint256 uNodeIndex; @@ -2838,7 +2846,7 @@ Json::Value RPCHandler::doLedgerEntry(Json::Value jvRequest, int& cost, ScopedLo jvResult["error"] = "unknownOption"; } - if (!!uNodeIndex) + if (uNodeIndex.isNonZero()) { SLE::pointer sleNode = mNetOps->getSLEi(lpLedger, uNodeIndex); From 957742f3b06c3ad351b603c8678e55ab997c78ba Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 May 2013 08:57:44 -0700 Subject: [PATCH 7/9] doLedger speedup. --- src/cpp/ripple/RPCHandler.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index ba49aa01b..01809a7dd 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1868,15 +1868,16 @@ Json::Value RPCHandler::doLedger(Json::Value jvRequest, int& cost, ScopedLock& M | (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0) | (bAccounts ? LEDGER_JSON_DUMP_STATE : 0); - if (bFull && !lpLedger->isImmutable()) - { // For full, it's cheaper to snapshot + if ((bFull || bAccounts) && !lpLedger->isImmutable()) + { // For full or accounts, it's cheaper to snapshot lpLedger = boost::make_shared(*lpLedger, true); + assert(lpLedger->isImmutable()); } - Json::Value ret(Json::objectValue); - if (lpLedger->isImmutable()) MasterLockHolder.unlock(); + + Json::Value ret(Json::objectValue); lpLedger->addJson(ret, iOptions); return ret; From baf2841873b50b8aa54f559b360c20e48c98f3ce Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 May 2013 09:30:00 -0700 Subject: [PATCH 8/9] Bugfix. --- src/cpp/ripple/RPCHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 01809a7dd..92b066f8f 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1870,7 +1870,7 @@ Json::Value RPCHandler::doLedger(Json::Value jvRequest, int& cost, ScopedLock& M if ((bFull || bAccounts) && !lpLedger->isImmutable()) { // For full or accounts, it's cheaper to snapshot - lpLedger = boost::make_shared(*lpLedger, true); + lpLedger = boost::make_shared(*lpLedger, false); assert(lpLedger->isImmutable()); } From 6a84a959792ccd76e0c2cbc88945c4cfea73e83c Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 May 2013 11:49:33 -0700 Subject: [PATCH 9/9] Accept ledgers more efficiently by avoiding allocate/allocate/copy/copy/free cycles. --- src/cpp/ripple/AcceptedLedger.cpp | 17 ++++++++--------- src/cpp/ripple/AcceptedLedger.h | 16 +++++++++------- src/cpp/ripple/Ledger.cpp | 8 ++++---- src/cpp/ripple/NetworkOPs.cpp | 4 ++-- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/cpp/ripple/AcceptedLedger.cpp b/src/cpp/ripple/AcceptedLedger.cpp index 6226c3ebc..2e2f69f08 100644 --- a/src/cpp/ripple/AcceptedLedger.cpp +++ b/src/cpp/ripple/AcceptedLedger.cpp @@ -49,12 +49,11 @@ void ALTransaction::buildJson() if (!mAffected.empty()) { - Json::Value affected(Json::arrayValue); + Json::Value& affected = (mJson["affected"] = Json::arrayValue); BOOST_FOREACH(const RippleAddress& ra, mAffected) { affected.append(ra.humanAccountID()); } - mJson["affected"] = affected; } } @@ -64,7 +63,7 @@ AcceptedLedger::AcceptedLedger(Ledger::ref ledger) : mLedger(ledger) for (SHAMapItem::pointer item = txSet.peekFirstItem(); !!item; item = txSet.peekNextItem(item->getTag())) { SerializerIterator sit(item->peekSerializer()); - insert(ALTransaction(ledger->getLedgerSeq(), sit)); + insert(boost::make_shared(ledger->getLedgerSeq(), sit)); } } @@ -78,16 +77,16 @@ AcceptedLedger::pointer AcceptedLedger::makeAcceptedLedger(Ledger::ref ledger) return ret; } -void AcceptedLedger::insert(const ALTransaction& at) +void AcceptedLedger::insert(ALTransaction::ref at) { - assert(mMap.find(at.getIndex()) == mMap.end()); - mMap.insert(std::make_pair(at.getIndex(), at)); + assert(mMap.find(at->getIndex()) == mMap.end()); + mMap.insert(std::make_pair(at->getIndex(), at)); } -const ALTransaction* AcceptedLedger::getTxn(int i) const +ALTransaction::pointer AcceptedLedger::getTxn(int i) const { map_t::const_iterator it = mMap.find(i); if (it == mMap.end()) - return NULL; - return &it->second; + return ALTransaction::pointer(); + return it->second; } diff --git a/src/cpp/ripple/AcceptedLedger.h b/src/cpp/ripple/AcceptedLedger.h index 04f917a78..f8de68739 100644 --- a/src/cpp/ripple/AcceptedLedger.h +++ b/src/cpp/ripple/AcceptedLedger.h @@ -19,6 +19,8 @@ protected: void buildJson(); public: + typedef boost::shared_ptr pointer; + typedef const pointer& ref; ALTransaction(uint32 ledgerSeq, SerializerIterator& sit); ALTransaction(SerializedTransaction::ref, TransactionMetaSet::ref); @@ -42,17 +44,17 @@ public: class AcceptedLedger { public: - typedef boost::shared_ptr pointer; - typedef const pointer& ret; - typedef std::map map_t; // Must be an ordered map! - typedef map_t::value_type value_type; - typedef map_t::const_iterator const_iterator; + typedef boost::shared_ptr pointer; + typedef const pointer& ret; + typedef std::map map_t; // Must be an ordered map! + typedef map_t::value_type value_type; + typedef map_t::const_iterator const_iterator; protected: Ledger::pointer mLedger; map_t mMap; - void insert(const ALTransaction&); + void insert(ALTransaction::ref); static TaggedCache ALCache; AcceptedLedger(Ledger::ref ledger); @@ -68,7 +70,7 @@ public: int getLedgerSeq() const { return mLedger->getLedgerSeq(); } int getTxnCount() const { return mMap.size(); } - const ALTransaction* getTxn(int) const; + ALTransaction::pointer getTxn(int) const; }; #endif diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 50c6f73da..d4ebb0bfe 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -471,12 +471,12 @@ void Ledger::saveAcceptedLedger(Job&, bool fromConsensus) BOOST_FOREACH(const AcceptedLedger::value_type& vt, aLedger->getMap()) { - uint256 txID = vt.second.getTransactionID(); + uint256 txID = vt.second->getTransactionID(); theApp->getMasterTransaction().inLedger(txID, mLedgerSeq); db->executeSQL(boost::str(deleteAcctTrans % txID.GetHex())); - const std::vector& accts = vt.second.getAffected(); + const std::vector& accts = vt.second->getAffected(); if (!accts.empty()) { std::string sql = "INSERT INTO AccountTransactions (TransID, Account, LedgerSeq, TxnSeq) VALUES "; @@ -496,7 +496,7 @@ void Ledger::saveAcceptedLedger(Job&, bool fromConsensus) sql += "',"; sql += boost::lexical_cast(getLedgerSeq()); sql += ","; - sql += boost::lexical_cast(vt.second.getTxnSeq()); + sql += boost::lexical_cast(vt.second->getTxnSeq()); sql += ")"; } sql += ";"; @@ -507,7 +507,7 @@ void Ledger::saveAcceptedLedger(Job&, bool fromConsensus) cLog(lsWARNING) << "Transaction in ledger " << mLedgerSeq << " affects no accounts"; db->executeSQL(SerializedTransaction::getMetaSQLInsertReplaceHeader() + - vt.second.getTxn()->getMetaSQL(getLedgerSeq(), vt.second.getEscMeta()) + ";"); + vt.second->getTxn()->getMetaSQL(getLedgerSeq(), vt.second->getEscMeta()) + ";"); } db->executeSQL("COMMIT TRANSACTION;"); } diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 5149a21c9..0a500b2f5 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1439,8 +1439,8 @@ void NetworkOPs::pubLedger(Ledger::ref accepted) { BOOST_FOREACH(const AcceptedLedger::value_type& vt, alpAccepted->getMap()) { - cLog(lsTRACE) << "pubAccepted: " << vt.second.getJson(); - pubValidatedTransaction(lpAccepted, vt.second); + cLog(lsTRACE) << "pubAccepted: " << vt.second->getJson(); + pubValidatedTransaction(lpAccepted, *vt.second); } } }