From 423635d2ef6d5d15a2e0ec74c7749ae412bcd4d5 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 May 2013 18:25:47 -0700 Subject: [PATCH 1/7] Faster publishing of order book changes to book listeners --- src/cpp/ripple/NetworkOPs.h | 2 ++ src/cpp/ripple/OrderBookDB.cpp | 17 ++++++++++------- src/cpp/ripple/WSConnection.h | 7 +++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/cpp/ripple/NetworkOPs.h b/src/cpp/ripple/NetworkOPs.h index 24a212c82e..c18f8b55c1 100644 --- a/src/cpp/ripple/NetworkOPs.h +++ b/src/cpp/ripple/NetworkOPs.h @@ -52,6 +52,8 @@ public: virtual ~InfoSub(); virtual void send(const Json::Value& jvObj, bool broadcast) = 0; + virtual void send(const Json::Value& jvObj, const std::string& sObj, bool broadcast) + { send(jvObj, broadcast); } uint64 getSeq() { diff --git a/src/cpp/ripple/OrderBookDB.cpp b/src/cpp/ripple/OrderBookDB.cpp index 0a7be27834..94d659d3e8 100644 --- a/src/cpp/ripple/OrderBookDB.cpp +++ b/src/cpp/ripple/OrderBookDB.cpp @@ -167,13 +167,13 @@ void OrderBookDB::processTxn(Ledger::ref ledger, const ALTransaction& alTx, Json const STObject* data = dynamic_cast(node.peekAtPField(*field)); if (data) { - STAmount takerGets = data->getFieldAmount(sfTakerGets); - uint160 currencyGets = takerGets.getCurrency(); - uint160 issuerGets = takerGets.getIssuer(); + const STAmount& takerGets = data->getFieldAmount(sfTakerGets); + const uint160& currencyGets = takerGets.getCurrency(); + const uint160& issuerGets = takerGets.getIssuer(); - STAmount takerPays = data->getFieldAmount(sfTakerPays); - uint160 currencyPays = takerPays.getCurrency(); - uint160 issuerPays = takerPays.getIssuer(); + const STAmount& takerPays = data->getFieldAmount(sfTakerPays); + const uint160& currencyPays = takerPays.getCurrency(); + const uint160& issuerPays = takerPays.getIssuer(); // determine the OrderBook BookListeners::pointer book = @@ -206,6 +206,9 @@ void BookListeners::removeSubscriber(uint64 seq) void BookListeners::publish(Json::Value& jvObj) { + Json::FastWriter jfwWriter; + std::string sObj = jfwWriter.write(jvObj); + boost::recursive_mutex::scoped_lock sl(mLock); NetworkOPs::subMapType::const_iterator it = mListeners.begin(); while (it != mListeners.end()) @@ -213,7 +216,7 @@ void BookListeners::publish(Json::Value& jvObj) InfoSub::pointer p = it->second.lock(); if (p) { - p->send(jvObj, true); + p->send(jvObj, sObj, true); ++it; } else diff --git a/src/cpp/ripple/WSConnection.h b/src/cpp/ripple/WSConnection.h index f27ea00b26..baa8e3ab89 100644 --- a/src/cpp/ripple/WSConnection.h +++ b/src/cpp/ripple/WSConnection.h @@ -95,6 +95,13 @@ public: mHandler->send(ptr, jvObj, broadcast); } + void send(const Json::Value& jvObj, const std::string& sObj, bool broadcast) + { + connection_ptr ptr = mConnection.lock(); + if (ptr) + mHandler->send(ptr, sObj, broadcast); + } + // Utilities Json::Value invokeCommand(Json::Value& jvRequest) { From 29d86eba554247f34fa55f23900691dacfecfdb2 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 May 2013 18:36:14 -0700 Subject: [PATCH 2/7] Cache for immutable LES's. --- src/cpp/ripple/LedgerEntrySet.cpp | 8 ++++---- src/cpp/ripple/LedgerEntrySet.h | 8 ++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/cpp/ripple/LedgerEntrySet.cpp b/src/cpp/ripple/LedgerEntrySet.cpp index beb34a19d3..0931b82fca 100644 --- a/src/cpp/ripple/LedgerEntrySet.cpp +++ b/src/cpp/ripple/LedgerEntrySet.cpp @@ -94,7 +94,7 @@ SLE::pointer LedgerEntrySet::entryCache(LedgerEntryType letType, const uint256& if (!sleEntry) { assert(action != taaDELETE); - sleEntry = mLedger->getSLE(index); + sleEntry = mImmutable ? mLedger->getSLEi(index) : mLedger->getSLE(index); if (sleEntry) entryCache(sleEntry); } @@ -138,7 +138,7 @@ void LedgerEntrySet::entryCache(SLE::ref sle) void LedgerEntrySet::entryCreate(SLE::ref sle) { - assert(mLedger); + assert(mLedger && !mImmutable); assert(sle->isMutable()); std::map::iterator it = mEntries.find(sle->getIndex()); if (it == mEntries.end()) @@ -175,7 +175,7 @@ void LedgerEntrySet::entryCreate(SLE::ref sle) void LedgerEntrySet::entryModify(SLE::ref sle) { - assert(sle->isMutable()); + assert(sle->isMutable() && !mImmutable); assert(mLedger); std::map::iterator it = mEntries.find(sle->getIndex()); if (it == mEntries.end()) @@ -209,7 +209,7 @@ void LedgerEntrySet::entryModify(SLE::ref sle) void LedgerEntrySet::entryDelete(SLE::ref sle) { - assert(sle->isMutable()); + assert(sle->isMutable() && !mImmutable); assert(mLedger); std::map::iterator it = mEntries.find(sle->getIndex()); if (it == mEntries.end()) diff --git a/src/cpp/ripple/LedgerEntrySet.h b/src/cpp/ripple/LedgerEntrySet.h index 47962cdb19..8a4267b8b9 100644 --- a/src/cpp/ripple/LedgerEntrySet.h +++ b/src/cpp/ripple/LedgerEntrySet.h @@ -56,6 +56,7 @@ protected: TransactionMetaSet mSet; TransactionEngineParams mParams; int mSeq; + bool mImmutable; LedgerEntrySet(Ledger::ref ledger, const std::map &e, const TransactionMetaSet& s, int m) : mLedger(ledger), mEntries(e), mSet(s), mParams(tapNONE), mSeq(m) { ; } @@ -72,11 +73,14 @@ protected: public: - LedgerEntrySet(Ledger::ref ledger, TransactionEngineParams tep) : mLedger(ledger), mParams(tep), mSeq(0) { ; } + LedgerEntrySet(Ledger::ref ledger, TransactionEngineParams tep, bool immutable = false) : + mLedger(ledger), mParams(tep), mSeq(0), mImmutable(immutable) { ; } - LedgerEntrySet() : mParams(tapNONE), mSeq(0) { ; } + LedgerEntrySet() : mParams(tapNONE), mSeq(0), mImmutable(false) { ; } // set functions + void setImmutable() { mImmutable = true; } + bool isImmutable() const { return mImmutable; } LedgerEntrySet duplicate() const; // Make a duplicate of this set void setTo(const LedgerEntrySet&); // Set this set to have the same contents as another void swapWith(LedgerEntrySet&); // Swap the contents of two sets From 696ffe4b8710592f18af54ad014432387d554f60 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 May 2013 18:36:26 -0700 Subject: [PATCH 3/7] Use the immutable LES. --- src/cpp/ripple/NetworkOPs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 0a500b2f50..3ec5d8a93b 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1854,7 +1854,7 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays cLog(lsTRACE) << boost::str(boost::format("getBookPage: uBookEnd=%s") % uBookEnd); cLog(lsTRACE) << boost::str(boost::format("getBookPage: uTipIndex=%s") % uTipIndex); - LedgerEntrySet lesActive(lpLedger, tapNONE); + LedgerEntrySet lesActive(lpLedger, tapNONE, true); bool bDone = false; bool bDirectAdvance = true; From 417143a25e2568d24236a8365f74b6428e2ae154 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 May 2013 18:38:07 -0700 Subject: [PATCH 4/7] Okay to put immutable SLE in immutable LES. --- src/cpp/ripple/LedgerEntrySet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ripple/LedgerEntrySet.cpp b/src/cpp/ripple/LedgerEntrySet.cpp index 0931b82fca..7795a4f821 100644 --- a/src/cpp/ripple/LedgerEntrySet.cpp +++ b/src/cpp/ripple/LedgerEntrySet.cpp @@ -115,7 +115,7 @@ LedgerEntryAction LedgerEntrySet::hasEntry(const uint256& index) const void LedgerEntrySet::entryCache(SLE::ref sle) { assert(mLedger); - assert(sle->isMutable()); + assert(sle->isMutable() || !mImmutable); std::map::iterator it = mEntries.find(sle->getIndex()); if (it == mEntries.end()) { From 9be7b9cc3f182a1cf226029d9e6e6ca9d2510671 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 May 2013 18:38:36 -0700 Subject: [PATCH 5/7] doBookOffers optimizations. --- src/cpp/ripple/RPCHandler.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index d44d780716..aa185cfedc 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1202,12 +1202,15 @@ Json::Value RPCHandler::doBookOffers(Json::Value jvRequest, int& cost, ScopedLoc if (!lpLedger) return jvResult; + if (lpLedger->isImmutable()) + MasterLockHolder.unlock(); + if (!jvRequest.isMember("taker_pays") || !jvRequest.isMember("taker_gets") || !jvRequest["taker_pays"].isObject() || !jvRequest["taker_gets"].isObject()) return rpcError(rpcINVALID_PARAMS); - uint160 uTakerPaysCurrencyID; - uint160 uTakerPaysIssuerID; - Json::Value jvTakerPays = jvRequest["taker_pays"]; + uint160 uTakerPaysCurrencyID; + uint160 uTakerPaysIssuerID; + const Json::Value& jvTakerPays = jvRequest["taker_pays"]; // Parse mandatory currency. if (!jvTakerPays.isMember("currency") @@ -1230,9 +1233,9 @@ Json::Value RPCHandler::doBookOffers(Json::Value jvRequest, int& cost, ScopedLoc return rpcError(rpcSRC_ISR_MALFORMED); } - uint160 uTakerGetsCurrencyID; - uint160 uTakerGetsIssuerID; - Json::Value jvTakerGets = jvRequest["taker_gets"]; + uint160 uTakerGetsCurrencyID; + uint160 uTakerGetsIssuerID; + const Json::Value& jvTakerGets = jvRequest["taker_gets"]; // Parse mandatory currency. if (!jvTakerGets.isMember("currency") From 05b9004966cd10e62dbf8a47650c7ed38e2c163e Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 May 2013 18:41:21 -0700 Subject: [PATCH 6/7] Missed a constructor. --- src/cpp/ripple/LedgerEntrySet.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpp/ripple/LedgerEntrySet.h b/src/cpp/ripple/LedgerEntrySet.h index 8a4267b8b9..179f9a9c9e 100644 --- a/src/cpp/ripple/LedgerEntrySet.h +++ b/src/cpp/ripple/LedgerEntrySet.h @@ -59,7 +59,8 @@ protected: bool mImmutable; LedgerEntrySet(Ledger::ref ledger, const std::map &e, - const TransactionMetaSet& s, int m) : mLedger(ledger), mEntries(e), mSet(s), mParams(tapNONE), mSeq(m) { ; } + const TransactionMetaSet& s, int m) : + mLedger(ledger), mEntries(e), mSet(s), mParams(tapNONE), mSeq(m), mImmutable(false) { ; } SLE::pointer getForMod(const uint256& node, Ledger::ref ledger, boost::unordered_map& newMods); From c4345768e78ab3e25554705f3f2f08feff97b072 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 14 May 2013 18:44:27 -0700 Subject: [PATCH 7/7] Fix an assert. --- src/cpp/ripple/LedgerEntrySet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ripple/LedgerEntrySet.cpp b/src/cpp/ripple/LedgerEntrySet.cpp index 7795a4f821..66d9cc5e2a 100644 --- a/src/cpp/ripple/LedgerEntrySet.cpp +++ b/src/cpp/ripple/LedgerEntrySet.cpp @@ -115,7 +115,7 @@ LedgerEntryAction LedgerEntrySet::hasEntry(const uint256& index) const void LedgerEntrySet::entryCache(SLE::ref sle) { assert(mLedger); - assert(sle->isMutable() || !mImmutable); + assert(sle->isMutable() || mImmutable); // Don't put an immutable SLE in a mutable LES std::map::iterator it = mEntries.find(sle->getIndex()); if (it == mEntries.end()) {