diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj index 97f42f0cd6..1954bdffe4 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj +++ b/Builds/VisualStudio2013/RippleD.vcxproj @@ -2034,6 +2034,9 @@ + + True + True @@ -3200,16 +3203,16 @@ - Document - protoc --cpp_out=..\..\build\proto --proto_path=%(RelativeDir) %(Identity) - ..\..\build\proto\ripple.pb.h;..\..\build\proto\ripple.pb.cc - protoc --cpp_out=..\..\build\proto --proto_path=%(RelativeDir) %(Identity) - false Document protoc --cpp_out=..\..\build\proto --proto_path=%(RelativeDir) %(Identity) ..\..\build\proto\ripple.pb.h;..\..\build\proto\ripple.pb.cc protoc --cpp_out=..\..\build\proto --proto_path=%(RelativeDir) %(Identity) false + Document + protoc --cpp_out=..\..\build\proto --proto_path=%(RelativeDir) %(Identity) + ..\..\build\proto\ripple.pb.h;..\..\build\proto\ripple.pb.cc + protoc --cpp_out=..\..\build\proto --proto_path=%(RelativeDir) %(Identity) + false @@ -3444,8 +3447,8 @@ - ..\..\src\hyperleveldb;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) ..\..\src\hyperleveldb;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) + ..\..\src\hyperleveldb;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) @@ -3454,8 +3457,8 @@ - ..\..\src\leveldb;..\..\src\leveldb\include;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) ..\..\src\leveldb;..\..\src\leveldb\include;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) + ..\..\src\leveldb;..\..\src\leveldb\include;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) @@ -3464,8 +3467,8 @@ - ..\..\src\leveldb\include;..\..\src\rocksdb\include;%(AdditionalIncludeDirectories) ..\..\src\leveldb\include;..\..\src\rocksdb\include;%(AdditionalIncludeDirectories) + ..\..\src\leveldb\include;..\..\src\rocksdb\include;%(AdditionalIncludeDirectories) @@ -3486,8 +3489,8 @@ - ..\..\src\rocksdb;..\..\src\rocksdb\include;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) ..\..\src\rocksdb;..\..\src\rocksdb\include;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) + ..\..\src\rocksdb;..\..\src\rocksdb\include;..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) @@ -3500,8 +3503,8 @@ - ..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) ..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) + ..\..\src\snappy\config;..\..\src\snappy\snappy;%(AdditionalIncludeDirectories) diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters index 27e9c62a0d..5a8b7f190d 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters @@ -3027,6 +3027,9 @@ ripple\module\app\ledger + + ripple\module\app\ledger + ripple\module\app\ledger diff --git a/src/ripple/module/app/book/impl/BookTip.cpp b/src/ripple/module/app/book/impl/BookTip.cpp index fe720f96e5..9b8281643d 100644 --- a/src/ripple/module/app/book/impl/BookTip.cpp +++ b/src/ripple/module/app/book/impl/BookTip.cpp @@ -25,9 +25,7 @@ namespace core { BookTip::BookTip (LedgerView& view, BookRef book) : m_view (view) , m_valid (false) - , m_book (Ledger::getBookBase ( - book.in.currency, book.in.account, - book.out.currency, book.out.account)) + , m_book (Ledger::getBookBase (book)) , m_end (Ledger::getQualityNext (m_book)) { } diff --git a/src/ripple/module/app/ledger/BookListeners.cpp b/src/ripple/module/app/ledger/BookListeners.cpp new file mode 100644 index 0000000000..1eb927cc53 --- /dev/null +++ b/src/ripple/module/app/ledger/BookListeners.cpp @@ -0,0 +1,56 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +namespace ripple { + +void BookListeners::addSubscriber (InfoSub::ref sub) +{ + ScopedLockType sl (mLock); + mListeners[sub->getSeq ()] = sub; +} + +void BookListeners::removeSubscriber (std::uint64_t seq) +{ + ScopedLockType sl (mLock); + mListeners.erase (seq); +} + +void BookListeners::publish (Json::Value const& jvObj) +{ + Json::FastWriter jfwWriter; + std::string sObj = jfwWriter.write (jvObj); + + ScopedLockType sl (mLock); + NetworkOPs::SubMapType::const_iterator it = mListeners.begin (); + + while (it != mListeners.end ()) + { + InfoSub::pointer p = it->second.lock (); + + if (p) + { + p->send (jvObj, sObj, true); + ++it; + } + else + it = mListeners.erase (it); + } +} + +} // ripple diff --git a/src/ripple/module/app/misc/OrderBook.cpp b/src/ripple/module/app/ledger/BookListeners.h similarity index 65% rename from src/ripple/module/app/misc/OrderBook.cpp rename to src/ripple/module/app/ledger/BookListeners.h index 222b62de20..847daa9261 100644 --- a/src/ripple/module/app/misc/OrderBook.cpp +++ b/src/ripple/module/app/ledger/BookListeners.h @@ -17,19 +17,31 @@ */ //============================================================================== +#ifndef RIPPLE_BOOKLISTENERS_H +#define RIPPLE_BOOKLISTENERS_H + namespace ripple { -OrderBook::OrderBook (uint256 const& index, - Currency const& currencyIn, - Currency const& currencyOut, - Account const& issuerIn, - Account const& issuerOut) - : mBookBase (index) - , mCurrencyIn (currencyIn) - , mCurrencyOut (currencyOut) - , mIssuerIn (issuerIn) - , mIssuerOut (issuerOut) +/** Listen to public/subscribe messages from a book. */ +class BookListeners { -} +public: + typedef std::shared_ptr pointer; + + BookListeners () {} + + void addSubscriber (InfoSub::ref sub); + void removeSubscriber (std::uint64_t sub); + void publish (Json::Value const& jvObj); + +private: + typedef RippleRecursiveMutex LockType; + typedef std::lock_guard ScopedLockType; + LockType mLock; + + ripple::unordered_map mListeners; +}; } // ripple + +#endif diff --git a/src/ripple/module/app/ledger/Ledger.cpp b/src/ripple/module/app/ledger/Ledger.cpp index 7a6c6c8a64..c30aea9937 100644 --- a/src/ripple/module/app/ledger/Ledger.cpp +++ b/src/ripple/module/app/ledger/Ledger.cpp @@ -242,16 +242,18 @@ Ledger::~Ledger () { if (mTransactionMap) { - logTimedDestroy (mTransactionMap, - beast::String ("mTransactionMap with ") + - beast::String::fromNumber (mTransactionMap->size ()) + " items"); + logTimedDestroy ( + mTransactionMap, + "mTransactionMap with " + + std::to_string(mTransactionMap->size ()) + " items"); } if (mAccountStateMap) { - logTimedDestroy (mAccountStateMap, - beast::String ("mAccountStateMap with ") + - beast::String::fromNumber (mAccountStateMap->size ()) + " items"); + logTimedDestroy ( + mAccountStateMap, + "mAccountStateMap with " + + std::to_string (mAccountStateMap->size ()) + " items"); } } @@ -614,17 +616,27 @@ uint256 Ledger::getHash () bool Ledger::saveValidatedLedger (bool current) { // TODO(tom): Fix this hard-coded SQL! - WriteLog (lsTRACE, Ledger) << "saveValidatedLedger " << (current ? "" : "fromAcquire ") << getLedgerSeq (); - static boost::format deleteLedger ("DELETE FROM Ledgers WHERE LedgerSeq = %u;"); - static boost::format deleteTrans1 ("DELETE FROM Transactions WHERE LedgerSeq = %u;"); - static boost::format deleteTrans2 ("DELETE FROM AccountTransactions WHERE LedgerSeq = %u;"); - static boost::format deleteAcctTrans ("DELETE FROM AccountTransactions WHERE TransID = '%s';"); - static boost::format transExists ("SELECT Status FROM Transactions WHERE TransID = '%s';"); - static boost::format - updateTx ("UPDATE Transactions SET LedgerSeq = %u, Status = '%c', TxnMeta = %s WHERE TransID = '%s';"); - static boost::format addLedger ("INSERT OR REPLACE INTO Ledgers " - "(LedgerHash,LedgerSeq,PrevHash,TotalCoins,ClosingTime,PrevClosingTime,CloseTimeRes,CloseFlags," - "AccountSetHash,TransSetHash) VALUES ('%s','%u','%s','%s','%u','%u','%d','%u','%s','%s');"); + WriteLog (lsTRACE, Ledger) + << "saveValidatedLedger " + << (current ? "" : "fromAcquire ") << getLedgerSeq (); + static boost::format deleteLedger ( + "DELETE FROM Ledgers WHERE LedgerSeq = %u;"); + static boost::format deleteTrans1 ( + "DELETE FROM Transactions WHERE LedgerSeq = %u;"); + static boost::format deleteTrans2 ( + "DELETE FROM AccountTransactions WHERE LedgerSeq = %u;"); + static boost::format deleteAcctTrans ( + "DELETE FROM AccountTransactions WHERE TransID = '%s';"); + static boost::format transExists ( + "SELECT Status FROM Transactions WHERE TransID = '%s';"); + static boost::format updateTx ( + "UPDATE Transactions SET LedgerSeq = %u, Status = '%c', TxnMeta = %s " + "WHERE TransID = '%s';"); + static boost::format addLedger ( + "INSERT OR REPLACE INTO Ledgers " + "(LedgerHash,LedgerSeq,PrevHash,TotalCoins,ClosingTime,PrevClosingTime," + "CloseTimeRes,CloseFlags,AccountSetHash,TransSetHash) VALUES " + "('%s','%u','%s','%s','%u','%u','%d','%u','%s','%s');"); if (!getAccountHash ().isNonZero ()) { @@ -738,10 +750,14 @@ bool Ledger::saveValidatedLedger (bool current) db->executeSQL (sql); } else - WriteLog (lsWARNING, Ledger) << "Transaction in ledger " << mLedgerSeq << " affects no accounts"; + WriteLog (lsWARNING, Ledger) + << "Transaction in ledger " << mLedgerSeq + << " affects no accounts"; - db->executeSQL (SerializedTransaction::getMetaSQLInsertReplaceHeader () + - vt.second->getTxn ()->getMetaSQL (getLedgerSeq (), vt.second->getEscMeta ()) + ";"); + db->executeSQL ( + SerializedTransaction::getMetaSQLInsertReplaceHeader () + + vt.second->getTxn ()->getMetaSQL ( + getLedgerSeq (), vt.second->getEscMeta ()) + ";"); } db->executeSQL ("COMMIT TRANSACTION;"); } @@ -749,7 +765,7 @@ bool Ledger::saveValidatedLedger (bool current) { DeprecatedScopedLock sl (getApp().getLedgerDB ()->getDBLock ()); - // TODO(tom): ARG! + // TODO(tom): ARG!! getApp().getLedgerDB ()->getDB ()->executeSQL (boost::str (addLedger % to_string (getHash ()) % mLedgerSeq % to_string (mParentHash) % beast::lexicalCastThrow (mTotCoins) % mCloseTime % @@ -1266,7 +1282,8 @@ LedgerStateParms Ledger::writeBack (LedgerStateParms parms, SLE::ref entry) { if ((parms & lepCREATE) == 0) { - WriteLog (lsERROR, Ledger) << "WriteBack non-existent node without create"; + WriteLog (lsERROR, Ledger) + << "WriteBack non-existent node without create"; return lepMISSING; } @@ -1343,9 +1360,9 @@ void Ledger::visitAccountItems ( if (!ownerDir || (ownerDir->getType () != ltDIR_NODE)) return; - for (auto const& uNode : ownerDir->getFieldV256 (sfIndexes).peekValue ()) + for (auto const& node : ownerDir->getFieldV256 (sfIndexes).peekValue ()) { - func (getSLEi (uNode)); + func (getSLEi (node)); } std::uint64_t uNodeNext = ownerDir->getFieldU64 (sfIndexNext); @@ -1386,49 +1403,6 @@ void Ledger::visitStateItems (std::function function) } } -/* -// VFALCO: A proof of concept for making an iterator instead of a visitor -class AccountItemIterator -{ -public: - explicit AccountItemIterator (Account const& accountID) - { - // Convert the account ID to the root hash - // - m_rootKey = Ledger::getOwnerDirIndex (accountID); - - // Start iterating from the root - // - m_currentKey = rootKey; - - } - - SerializedLedgerEntry::ref operator* () const - { - return m_currentEntry; - } - - SerializedLedgerEntry::ref end () const - { - return s_end; - } - - AccountItemIterator& operator++ (int) - { - } - -private: - static SerializedLedgerEntry s_end; - - uint256 m_rootKey; - uint256 m_currentKey; - - SerializedLedgerEntry::pointer m_currentEntry; -} -// typedef const std::shared_ptr& ref; -*/ - - uint256 Ledger::getFirstLedgerIndex () { SHAMapItem::pointer node = mAccountStateMap->peekFirstItem (); @@ -1703,9 +1677,9 @@ uint256 Ledger::getLedgerHash (std::uint32_t ledgerIndex) return uint256 (); } -std::vector< std::pair > Ledger::getLedgerHashes () +Ledger::LedgerHashes Ledger::getLedgerHashes () { - std::vector< std::pair > ret; + LedgerHashes ret; SLE::pointer hashIndex = getSLEi (getLedgerHashIndex ()); if (hashIndex) @@ -1733,74 +1707,23 @@ std::vector Ledger::getLedgerAmendments () return usAmendments; } -// XRP to XRP not allowed. -// Currencies must have appropriate issuer. -// Currencies or accounts must differ. -bool Ledger::isValidBook ( - Currency const& uTakerPaysCurrency, Account const& uTakerPaysIssuerID, - Currency const& uTakerGetsCurrency, Account const& uTakerGetsIssuerID) -{ - // TODO(tom): refactor to use == zero, better boolean logic. - if (uTakerPaysCurrency.isZero ()) - { - // XRP in - - if (uTakerPaysIssuerID.isNonZero ()) // XRP cannot have an issuer - return false; - - if (uTakerGetsCurrency.isZero ()) // XRP to XRP not allowed - return false; - - if (uTakerGetsIssuerID.isZero ()) // non-XRP must have issuer - return false; - - return true; - } - - // non-XRP in - if (uTakerPaysIssuerID.isZero ()) // non-XRP must have issuer - return false; - - if (uTakerGetsCurrency.isZero ()) // non-XRP to XRP - { - if (uTakerGetsIssuerID.isNonZero ()) // XRP cannot have issuer - return false; - } - else // non-XRP to non-XRP - { - // Input and output cannot be identical - if ((uTakerPaysCurrency == uTakerGetsCurrency) && - (uTakerGetsIssuerID == uTakerPaysIssuerID)) - return false; - } - - return true; -} - -uint256 Ledger::getBookBase ( - Currency const& uTakerPaysCurrency, Account const& uTakerPaysIssuerID, - Currency const& uTakerGetsCurrency, Account const& uTakerGetsIssuerID) +uint256 Ledger::getBookBase (Book const& book) { Serializer s (82); - s.add16 (spaceBookDir); // 2 - s.add160 (uTakerPaysCurrency); // 20 - s.add160 (uTakerGetsCurrency); // 20 - s.add160 (uTakerPaysIssuerID); // 20 - s.add160 (uTakerGetsIssuerID); // 20 + s.add16 (spaceBookDir); // 2 + s.add160 (book.in.currency); // 20 + s.add160 (book.out.currency); // 20 + s.add160 (book.in.account); // 20 + s.add160 (book.out.account); // 20 - uint256 uBaseIndex = getQualityIndex (s.getSHA512Half ()); // Return with quality 0. + // Return with quality 0. + uint256 uBaseIndex = getQualityIndex (s.getSHA512Half ()); WriteLog (lsTRACE, Ledger) - << "getBookBase" - << "(" << uTakerPaysCurrency - << "," << uTakerPaysIssuerID - << "," << uTakerGetsCurrency - << "," << uTakerGetsIssuerID - << ") = " << to_string (uBaseIndex); + << "getBookBase (" << book << ") = " << to_string (uBaseIndex); - assert (isValidBook (uTakerPaysCurrency, uTakerPaysIssuerID, - uTakerGetsCurrency, uTakerGetsIssuerID)); + assert (isConsistent (book)); return uBaseIndex; } @@ -1894,16 +1817,20 @@ bool Ledger::walkLedger () if (ShouldLog (lsINFO, Ledger) && !missingNodes1.empty ()) { - WriteLog (lsINFO, Ledger) << missingNodes1.size () << " missing account node(s)"; - WriteLog (lsINFO, Ledger) << "First: " << missingNodes1[0]; + WriteLog (lsINFO, Ledger) + << missingNodes1.size () << " missing account node(s)"; + WriteLog (lsINFO, Ledger) + << "First: " << missingNodes1[0]; } mTransactionMap->walkMap (missingNodes2, 32); if (ShouldLog (lsINFO, Ledger) && !missingNodes2.empty ()) { - WriteLog (lsINFO, Ledger) << missingNodes2.size () << " missing transaction node(s)"; - WriteLog (lsINFO, Ledger) << "First: " << missingNodes2[0]; + WriteLog (lsINFO, Ledger) + << missingNodes2.size () << " missing transaction node(s)"; + WriteLog (lsINFO, Ledger) + << "First: " << missingNodes2[0]; } return missingNodes1.empty () && missingNodes2.empty (); @@ -1996,7 +1923,8 @@ void Ledger::updateSkipList () } } -std::uint32_t Ledger::roundCloseTime (std::uint32_t closeTime, std::uint32_t closeResolution) +std::uint32_t Ledger::roundCloseTime ( + std::uint32_t closeTime, std::uint32_t closeResolution) { if (closeTime == 0) return 0; @@ -2022,7 +1950,8 @@ bool Ledger::pendSaveValidated (bool isSynchronous, bool isCurrent) StaticScopedLockType sl (sPendingSaveLock); if (!sPendingSaves.insert(getLedgerSeq()).second) { - WriteLog (lsDEBUG, Ledger) << "Pend save with seq in pending saves " << getLedgerSeq(); + WriteLog (lsDEBUG, Ledger) + << "Pend save with seq in pending saves " << getLedgerSeq(); return true; } } @@ -2072,8 +2001,8 @@ void Ledger::qualityDirDescriber ( if (isNew) { getApp().getOrderBookDB().addOrderBook( - uTakerPaysCurrency, uTakerGetsCurrency, - uTakerPaysIssuer, uTakerGetsIssuer); + {{uTakerPaysCurrency, uTakerPaysIssuer}, + {uTakerGetsCurrency, uTakerGetsIssuer}}); } } diff --git a/src/ripple/module/app/ledger/Ledger.h b/src/ripple/module/app/ledger/Ledger.h index d16def5542..f57f006676 100644 --- a/src/ripple/module/app/ledger/Ledger.h +++ b/src/ripple/module/app/ledger/Ledger.h @@ -342,7 +342,8 @@ public: std::uint32_t desiredLedgerIndex, std::uint32_t currentLedgerIndex); uint256 getLedgerHash (std::uint32_t ledgerIndex); - std::vector< std::pair > getLedgerHashes (); + typedef std::vector> LedgerHashes; + LedgerHashes getLedgerHashes (); static uint256 getLedgerAmendmentIndex (); static uint256 getLedgerFeeIndex (); @@ -398,13 +399,7 @@ public: // Order book dirs have a base so we can use next to step through them in // quality order. - static bool isValidBook ( - Currency const& uTakerPaysCurrency, Account const& uTakerPaysIssuerID, - Currency const& uTakerGetsCurrency, Account const& uTakerGetsIssuerID); - - static uint256 getBookBase ( - Currency const& uTakerPaysCurrency, Account const& uTakerPaysIssuerID, - Currency const& uTakerGetsCurrency, Account const& uTakerGetsIssuerID); + static uint256 getBookBase (Book const&); // // Offer functions diff --git a/src/ripple/module/app/ledger/OrderBookDB.cpp b/src/ripple/module/app/ledger/OrderBookDB.cpp index 79742101f6..703fbe8a6a 100644 --- a/src/ripple/module/app/ledger/OrderBookDB.cpp +++ b/src/ripple/module/app/ledger/OrderBookDB.cpp @@ -33,23 +33,25 @@ void OrderBookDB::invalidate () void OrderBookDB::setup (Ledger::ref ledger) { + auto seq = ledger->getLedgerSeq (); { ScopedLockType sl (mLock); // Do a full update every 256 ledgers if (mSeq != 0) { - if (ledger->getLedgerSeq () == mSeq) + if (seq == mSeq) return; - if ((ledger->getLedgerSeq () > mSeq) && ((ledger->getLedgerSeq () - mSeq) < 256)) + if ((seq > mSeq) && ((seq - mSeq) < 256)) return; - if ((ledger->getLedgerSeq () < mSeq) && ((mSeq - ledger->getLedgerSeq ()) < 16)) + if ((seq < mSeq) && ((mSeq - seq) < 16)) return; } - WriteLog (lsDEBUG, OrderBookDB) << "Advancing from " << mSeq << " to " << ledger->getLedgerSeq(); + WriteLog (lsDEBUG, OrderBookDB) + << "Advancing from " << mSeq << " to " << seq; - mSeq = ledger->getLedgerSeq (); + mSeq = seq; } if (getConfig().RUN_STANDALONE) @@ -61,34 +63,29 @@ void OrderBookDB::setup (Ledger::ref ledger) static void updateHelper (SLE::ref entry, ripple::unordered_set< uint256 >& seen, - ripple::unordered_map< Issue, std::vector >& destMap, - ripple::unordered_map< Issue, std::vector >& sourceMap, + OrderBookDB::IssueToOrderBook& destMap, + OrderBookDB::IssueToOrderBook& sourceMap, ripple::unordered_set< Issue >& XRPBooks, int& books) { - if ((entry->getType () == ltDIR_NODE) && (entry->isFieldPresent (sfExchangeRate)) && - (entry->getFieldH256 (sfRootIndex) == entry->getIndex())) + if (entry->getType () == ltDIR_NODE && + entry->isFieldPresent (sfExchangeRate) && + entry->getFieldH256 (sfRootIndex) == entry->getIndex()) { - Currency ci, co; - ci.copyFrom (entry->getFieldH160 (sfTakerPaysCurrency)); - co.copyFrom (entry->getFieldH160 (sfTakerGetsCurrency)); - - Account ii, io; - ii.copyFrom (entry->getFieldH160 (sfTakerPaysIssuer)); - io.copyFrom (entry->getFieldH160 (sfTakerGetsIssuer)); - - uint256 index = Ledger::getBookBase (ci, ii, co, io); + Book book; + book.in.currency.copyFrom (entry->getFieldH160 (sfTakerPaysCurrency)); + book.in.account.copyFrom (entry->getFieldH160 (sfTakerPaysIssuer)); + book.out.account.copyFrom (entry->getFieldH160 (sfTakerGetsIssuer)); + book.out.currency.copyFrom (entry->getFieldH160 (sfTakerGetsCurrency)); + uint256 index = Ledger::getBookBase (book); if (seen.insert (index).second) { - // VFALCO TODO Reduce the clunkiness of these parameter wrappers - OrderBook::pointer book = std::make_shared (std::cref (index), - std::cref (ci), std::cref (co), std::cref (ii), std::cref (io)); - - sourceMap[IssueRef (ci, ii)].push_back (book); - destMap[IssueRef (co, io)].push_back (book); - if (co.isZero()) - XRPBooks.insert(IssueRef (ci, ii)); + auto orderBook = std::make_shared (index, book); + sourceMap[book.in].push_back (orderBook); + destMap[book.out].push_back (orderBook); + if (isXRP(book.out)) + XRPBooks.insert(book.in); ++books; } } @@ -97,8 +94,8 @@ static void updateHelper (SLE::ref entry, void OrderBookDB::update (Ledger::pointer ledger) { ripple::unordered_set< uint256 > seen; - ripple::unordered_map< Issue, std::vector > destMap; - ripple::unordered_map< Issue, std::vector > sourceMap; + OrderBookDB::IssueToOrderBook destMap; + OrderBookDB::IssueToOrderBook sourceMap; ripple::unordered_set< Issue > XRPBooks; WriteLog (lsDEBUG, OrderBookDB) << "OrderBookDB::update>"; @@ -114,13 +111,15 @@ void OrderBookDB::update (Ledger::pointer ledger) } catch (const SHAMapMissingNode&) { - WriteLog (lsINFO, OrderBookDB) << "OrderBookDB::update encountered a missing node"; + WriteLog (lsINFO, OrderBookDB) + << "OrderBookDB::update encountered a missing node"; ScopedLockType sl (mLock); mSeq = 0; return; } - WriteLog (lsDEBUG, OrderBookDB) << "OrderBookDB::update< " << books << " books found"; + WriteLog (lsDEBUG, OrderBookDB) + << "OrderBookDB::update< " << books << " books found"; { ScopedLockType sl (mLock); @@ -131,63 +130,66 @@ void OrderBookDB::update (Ledger::pointer ledger) getApp().getLedgerMaster().newOrderBookDB(); } -void OrderBookDB::addOrderBook(Currency const& ci, Currency const& co, - Account const& ii, Account const& io) +void OrderBookDB::addOrderBook(Book const& book) { - bool toXRP = co.isZero(); + bool toXRP = isXRP (book.out); ScopedLockType sl (mLock); if (toXRP) - { // We don't want to search through all the to-XRP or from-XRP order books! - for (auto ob : mSourceMap[{ci, ii}]) + { + // We don't want to search through all the to-XRP or from-XRP order + // books! + for (auto ob: mSourceMap[book.in]) { - if (ob->getCurrencyOut().isZero ()) // also to XRP + if (isXRP (ob->getCurrencyOut ())) // also to XRP return; } } else { - for (auto ob : mDestMap[{co, io}]) + for (auto ob: mDestMap[book.out]) { - if ((ob->getCurrencyIn() == ci) && (ob->getIssuerIn() == ii)) + if (ob->getCurrencyIn() == book.in.currency && + ob->getIssuerIn() == book.in.account) + { return; + } } } + uint256 index = Ledger::getBookBase(book); + auto orderBook = std::make_shared (index, book); - uint256 index = Ledger::getBookBase(ci, ii, co, io); - auto book = std::make_shared (index, ci, co, ii, io); - - mSourceMap[{ci, ii}].push_back (book); - mDestMap[{co, io}].push_back (book); + mSourceMap[book.in].push_back (orderBook); + mDestMap[book.out].push_back (orderBook); if (toXRP) - mXRPBooks.insert({ci, ii}); + mXRPBooks.insert(book.in); } // return list of all orderbooks that want this issuerID and currencyID -void OrderBookDB::getBooksByTakerPays (Account const& issuerID, Currency const& currencyID, - std::vector& bookRet) +void OrderBookDB::getBooksByTakerPays ( + Issue const& issue, OrderBook::List& bookRet) { ScopedLockType sl (mLock); - auto it = mSourceMap.find ({currencyID, issuerID}); + auto it = mSourceMap.find (issue); if (it != mSourceMap.end ()) bookRet = it->second; else bookRet.clear (); } -bool OrderBookDB::isBookToXRP(Account const& issuerID, Currency const& currencyID) +bool OrderBookDB::isBookToXRP(Issue const& issue) { ScopedLockType sl (mLock); - return mXRPBooks.count({currencyID, issuerID}) > 0; + return mXRPBooks.count(issue) > 0; } // return list of all orderbooks that give this issuerID and currencyID -void OrderBookDB::getBooksByTakerGets (Account const& issuerID, Currency const& currencyID, - std::vector& bookRet) +void OrderBookDB::getBooksByTakerGets ( + Issue const& issue, OrderBook::List& bookRet) { ScopedLockType sl (mLock); - auto it = mDestMap.find ({currencyID, issuerID}); + auto it = mDestMap.find (issue); if (it != mDestMap.end ()) bookRet = it->second; @@ -195,49 +197,46 @@ void OrderBookDB::getBooksByTakerGets (Account const& issuerID, Currency const& bookRet.clear (); } -BookListeners::pointer OrderBookDB::makeBookListeners (Currency const& currencyPays, Currency const& currencyGets, - Account const& issuerPays, Account const& issuerGets) +BookListeners::pointer OrderBookDB::makeBookListeners (Book const& book) { ScopedLockType sl (mLock); - BookListeners::pointer ret = getBookListeners (currencyPays, currencyGets, issuerPays, issuerGets); + auto ret = getBookListeners (book); if (!ret) { ret = std::make_shared (); - mListeners [BookRef ({currencyPays, issuerPays}, - {currencyGets, issuerGets})] = ret; - assert (getBookListeners (currencyPays, currencyGets, issuerPays, issuerGets) == ret); + mListeners [book] = ret; + assert (getBookListeners (book) == ret); } return ret; } -BookListeners::pointer OrderBookDB::getBookListeners (Currency const& currencyPays, Currency const& currencyGets, - Account const& issuerPays, Account const& issuerGets) +BookListeners::pointer OrderBookDB::getBookListeners (Book const& book) { BookListeners::pointer ret; ScopedLockType sl (mLock); - auto it0 (mListeners.find (BookRef ( - {currencyPays, issuerPays}, {currencyGets, issuerGets}))); - + auto it0 = mListeners.find (book); if (it0 != mListeners.end ()) ret = it0->second; return ret; } -// Based on the meta, send the meta to the streams that are listening -// We need to determine which streams a given meta effects -void OrderBookDB::processTxn (Ledger::ref ledger, const AcceptedLedgerTx& alTx, Json::Value const& jvObj) +// Based on the meta, send the meta to the streams that are listening. +// We need to determine which streams a given meta effects. +void OrderBookDB::processTxn ( + Ledger::ref ledger, const AcceptedLedgerTx& alTx, Json::Value const& jvObj) { ScopedLockType sl (mLock); if (alTx.getResult () == tesSUCCESS) { - // check if this is an offer or an offer cancel or a payment that consumes an offer - //check to see what the meta looks like + // Check if this is an offer or an offer cancel or a payment that + // consumes an offer. + // Check to see what the meta looks like. for (auto& node : alTx.getMeta ()->getNodes ()) { try @@ -246,90 +245,40 @@ void OrderBookDB::processTxn (Ledger::ref ledger, const AcceptedLedgerTx& alTx, { SField* field = nullptr; - // We need a field that contains the TakerGets and TakerPays parameters + // We need a field that contains the TakerGets and TakerPays + // parameters. if (node.getFName () == sfModifiedNode) - { field = &sfPreviousFields; - } else if (node.getFName () == sfCreatedNode) - { field = &sfNewFields; - } else if (node.getFName () == sfDeletedNode) - { field = &sfFinalFields; - } if (field) { - const STObject* data = dynamic_cast (node.peekAtPField (*field)); + auto data = dynamic_cast ( + node.peekAtPField (*field)); if (data) { - const STAmount& takerGets = data->getFieldAmount (sfTakerGets); - Currency const& currencyGets = takerGets.getCurrency (); - Account const& issuerGets = takerGets.getIssuer (); - - const STAmount& takerPays = data->getFieldAmount (sfTakerPays); - Currency const& currencyPays = takerPays.getCurrency (); - Account const& issuerPays = takerPays.getIssuer (); - // determine the OrderBook - BookListeners::pointer book = - getBookListeners (currencyPays, currencyGets, issuerPays, issuerGets); + auto listeners = getBookListeners ( + {data->getFieldAmount (sfTakerGets).issue(), + data->getFieldAmount (sfTakerPays).issue()}); - if (book) - book->publish (jvObj); + if (listeners) + listeners->publish (jvObj); } } } } catch (...) { - WriteLog (lsINFO, OrderBookDB) << "Fields not found in OrderBookDB::processTxn"; + WriteLog (lsINFO, OrderBookDB) + << "Fields not found in OrderBookDB::processTxn"; } } } } -//------------------------------------------------------------------------------ - -BookListeners::BookListeners () -{ -} - -void BookListeners::addSubscriber (InfoSub::ref sub) -{ - ScopedLockType sl (mLock); - mListeners[sub->getSeq ()] = sub; -} - -void BookListeners::removeSubscriber (std::uint64_t seq) -{ - ScopedLockType sl (mLock); - mListeners.erase (seq); -} - -void BookListeners::publish (Json::Value const& jvObj) -{ - Json::FastWriter jfwWriter; - std::string sObj = jfwWriter.write (jvObj); - - ScopedLockType sl (mLock); - NetworkOPs::SubMapType::const_iterator it = mListeners.begin (); - - while (it != mListeners.end ()) - { - InfoSub::pointer p = it->second.lock (); - - if (p) - { - p->send (jvObj, sObj, true); - ++it; - } - else - it = mListeners.erase (it); - } -} - } // ripple diff --git a/src/ripple/module/app/ledger/OrderBookDB.h b/src/ripple/module/app/ledger/OrderBookDB.h index 66e58e9a85..06b059579b 100644 --- a/src/ripple/module/app/ledger/OrderBookDB.h +++ b/src/ripple/module/app/ledger/OrderBookDB.h @@ -20,32 +20,10 @@ #ifndef RIPPLE_ORDERBOOKDB_H_INCLUDED #define RIPPLE_ORDERBOOKDB_H_INCLUDED +#include + namespace ripple { -// VFALCO TODO Add Javadoc comment explaining what this class does -class BookListeners -{ -public: - typedef std::shared_ptr pointer; - - BookListeners (); - void addSubscriber (InfoSub::ref sub); - void removeSubscriber (std::uint64_t sub); - void publish (Json::Value const& jvObj); - -private: - typedef RippleRecursiveMutex LockType; - typedef std::lock_guard ScopedLockType; - LockType mLock; - - // VFALCO TODO Use a typedef for the uint64 - // Use a typedef for the container - ripple::unordered_map mListeners; -}; - -//------------------------------------------------------------------------------ - -// VFALCO TODO Add Javadoc comment explaining what this class does class OrderBookDB : public beast::Stoppable , public beast::LeakChecked @@ -57,36 +35,32 @@ public: void update (Ledger::pointer ledger); void invalidate (); - void addOrderBook( - Currency const& takerPaysCurrency, Currency const& takerGetsCurrency, - Account const& takerPaysIssuer, Account const& takerGetsIssuer); + void addOrderBook(Book const&); // return list of all orderbooks that want this issuerID and currencyID - void getBooksByTakerPays (Account const& issuerID, Currency const& currencyID, - std::vector& bookRet); - void getBooksByTakerGets (Account const& issuerID, Currency const& currencyID, - std::vector& bookRet); + void getBooksByTakerPays (Issue const&, OrderBook::List&); + void getBooksByTakerGets (Issue const&, OrderBook::List&); - bool isBookToXRP (Account const& issuerID, Currency const& currencyID); + bool isBookToXRP (Issue const&); - BookListeners::pointer getBookListeners (Currency const& currencyPays, Currency const& currencyGets, - Account const& issuerPays, Account const& issuerGets); - - BookListeners::pointer makeBookListeners (Currency const& currencyPays, Currency const& currencyGets, - Account const& issuerPays, Account const& issuerGets); + BookListeners::pointer getBookListeners (Book const&); + BookListeners::pointer makeBookListeners (Book const&); // see if this txn effects any orderbook - void processTxn (Ledger::ref ledger, const AcceptedLedgerTx& alTx, Json::Value const& jvObj); + void processTxn ( + Ledger::ref ledger, const AcceptedLedgerTx& alTx, + Json::Value const& jvObj); + + typedef ripple::unordered_map IssueToOrderBook; private: - typedef ripple::unordered_map > - AssetToOrderBook; + void rawAddBook(Book const&); // by ci/ii - AssetToOrderBook mSourceMap; + IssueToOrderBook mSourceMap; // by co/io - AssetToOrderBook mDestMap; + IssueToOrderBook mDestMap; // does an order book to XRP exist ripple::unordered_set mXRPBooks; @@ -101,7 +75,6 @@ private: BookToListenersMap mListeners; std::uint32_t mSeq; - }; } // ripple diff --git a/src/ripple/module/app/ledger/OrderBookIterator.cpp b/src/ripple/module/app/ledger/OrderBookIterator.cpp index 31bcd0f2b9..70c4d66648 100644 --- a/src/ripple/module/app/ledger/OrderBookIterator.cpp +++ b/src/ripple/module/app/ledger/OrderBookIterator.cpp @@ -24,7 +24,8 @@ BookDirIterator::BookDirIterator( Currency const& currencyIn, Account const& issuerIn, Currency const& currencyOut, Account const& issuerOut) { - mBase = Ledger::getBookBase(currencyIn, issuerIn, currencyOut, issuerOut); + mBase = Ledger::getBookBase({{currencyIn, issuerIn}, + {currencyOut, issuerOut}}); mEnd = Ledger::getQualityNext(mBase); mIndex = mBase; } diff --git a/src/ripple/module/app/misc/NetworkOPs.cpp b/src/ripple/module/app/misc/NetworkOPs.cpp index 2eda6917ff..99fca1b2a2 100644 --- a/src/ripple/module/app/misc/NetworkOPs.cpp +++ b/src/ripple/module/app/misc/NetworkOPs.cpp @@ -76,9 +76,14 @@ public: } // network information - std::uint32_t getNetworkTimeNC (); // Our best estimate of wall time in seconds from 1/1/2000 - std::uint32_t getCloseTimeNC (); // Our best estimate of current ledger close time - std::uint32_t getValidationTimeNC (); // Use *only* to timestamp our own validation + // Our best estimate of wall time in seconds from 1/1/2000 + std::uint32_t getNetworkTimeNC (); + + // Our best estimate of current ledger close time + std::uint32_t getCloseTimeNC (); + + // Use *only* to timestamp our own validation + std::uint32_t getValidationTimeNC (); void closeTimeOffset (int); boost::posix_time::ptime getNetworkTimePT (); std::uint32_t getLedgerID (uint256 const& hash); @@ -157,31 +162,46 @@ public: // // Transaction operations // - typedef std::function stCallback; // must complete immediately - void submitTransaction (Job&, SerializedTransaction::pointer, stCallback callback = stCallback ()); - Transaction::pointer submitTransactionSync (Transaction::ref tpTrans, bool bAdmin, bool bLocal, bool bFailHard, bool bSubmit); + + // must complete immediately + typedef std::function stCallback; + void submitTransaction ( + Job&, SerializedTransaction::pointer, + stCallback callback = stCallback ()); + + Transaction::pointer submitTransactionSync ( + Transaction::ref tpTrans, + bool bAdmin, bool bLocal, bool bFailHard, bool bSubmit); void runTransactionQueue (); - Transaction::pointer processTransactionCb (Transaction::pointer, bool bAdmin, bool bLocal, bool bFailHard, stCallback); - Transaction::pointer processTransaction (Transaction::pointer transaction, bool bAdmin, bool bLocal, bool bFailHard) + Transaction::pointer processTransactionCb ( + Transaction::pointer, + bool bAdmin, bool bLocal, bool bFailHard, stCallback); + Transaction::pointer processTransaction ( + Transaction::pointer transaction, + bool bAdmin, bool bLocal, bool bFailHard) { - return processTransactionCb (transaction, bAdmin, bLocal, bFailHard, stCallback ()); + return processTransactionCb ( + transaction, bAdmin, bLocal, bFailHard, stCallback ()); } - // VFALCO Workaround for MSVC std::function which doesn't swallow return types. + // VFALCO Workaround for MSVC std::function which doesn't swallow return + // types. // - void processTransactionCbVoid (Transaction::pointer p, bool bAdmin, bool bLocal, bool bFailHard, stCallback cb) + void processTransactionCbVoid ( + Transaction::pointer p, + bool bAdmin, bool bLocal, bool bFailHard, stCallback cb) { processTransactionCb (p, bAdmin, bLocal, bFailHard, cb); } Transaction::pointer findTransactionByID (uint256 const& transactionID); -#if 0 - int findTransactionsBySource (uint256 const& uLedger, std::list&, const RippleAddress& sourceAccount, - std::uint32_t minSeq, std::uint32_t maxSeq); -#endif - int findTransactionsByDestination (std::list&, const RippleAddress& destinationAccount, - std::uint32_t startLedgerSeq, std::uint32_t endLedgerSeq, int maxTransactions); + + int findTransactionsByDestination ( + std::list&, + const RippleAddress& destinationAccount, + std::uint32_t startLedgerSeq, std::uint32_t endLedgerSeq, + int maxTransactions); // // Account functions @@ -200,29 +220,19 @@ public: Ledger::ref lrLedger, uint256 const& uRootIndex, std::uint64_t& uNodePrevious, std::uint64_t& uNodeNext); -#if 0 - // - // Nickname functions - // - - NicknameState::pointer getNicknameState (uint256 const& uLedger, const std::string& strNickname); -#endif - // // Owner functions // - Json::Value getOwnerInfo (Ledger::pointer lpLedger, const RippleAddress& naAccount); + Json::Value getOwnerInfo ( + Ledger::pointer lpLedger, const RippleAddress& naAccount); // // Book functions // void getBookPage (Ledger::pointer lpLedger, - Currency const& uTakerPaysCurrencyID, - Account const& uTakerPaysIssuerID, - Currency const& uTakerGetsCurrencyID, - Account const& uTakerGetsIssuerID, + Book const&, Account const& uTakerID, const bool bProof, const unsigned int iLimit, @@ -230,18 +240,31 @@ public: Json::Value& jvResult); // ledger proposal/close functions - void processTrustedProposal (LedgerProposal::pointer proposal, std::shared_ptr set, - RippleAddress nodePublic, uint256 checkLedger, bool sigGood); - SHAMapAddNode gotTXData (const std::shared_ptr& peer, uint256 const& hash, - const std::list& nodeIDs, const std::list< Blob >& nodeData); - bool recvValidation (SerializedValidation::ref val, const std::string& source); + void processTrustedProposal ( + LedgerProposal::pointer proposal, + std::shared_ptr set, + RippleAddress nodePublic, uint256 checkLedger, bool sigGood); + + SHAMapAddNode gotTXData ( + const std::shared_ptr& peer, uint256 const& hash, + const std::list& nodeIDs, + const std::list< Blob >& nodeData); + + bool recvValidation ( + SerializedValidation::ref val, const std::string& source); void takePosition (int seq, SHAMap::ref position); SHAMap::pointer getTXMap (uint256 const& hash); - bool hasTXSet (const std::shared_ptr& peer, uint256 const& set, protocol::TxSetStatus status); + bool hasTXSet ( + const std::shared_ptr& peer, uint256 const& set, + protocol::TxSetStatus status); + void mapComplete (uint256 const& hash, SHAMap::ref map); bool stillNeedTXSet (uint256 const& hash); - void makeFetchPack (Job&, std::weak_ptr peer, std::shared_ptr request, - uint256 haveLedger, std::uint32_t uUptime); + void makeFetchPack ( + Job&, std::weak_ptr peer, + std::shared_ptr request, + uint256 haveLedger, std::uint32_t uUptime); + bool shouldFetchPack (std::uint32_t seq); void gotFetchPack (bool progress, std::uint32_t seq); void addFetchPack (uint256 const& hash, std::shared_ptr< Blob >& data); @@ -253,9 +276,14 @@ public: // VFALCO TODO Try to make all these private since they seem to be...private // - void switchLastClosedLedger (Ledger::pointer newLedger, bool duringConsensus); // Used for the "jump" case - bool checkLastClosedLedger (const Overlay::PeerSequence&, uint256& networkClosed); - int beginConsensus (uint256 const& networkClosed, Ledger::pointer closingLedger); + + // Used for the "jump" case + void switchLastClosedLedger ( + Ledger::pointer newLedger, bool duringConsensus); + bool checkLastClosedLedger ( + const Overlay::PeerSequence&, uint256& networkClosed); + int beginConsensus ( + uint256 const& networkClosed, Ledger::pointer closingLedger); void tryStartConsensus (); void endConsensus (bool correctLCL); void setStandAlone () @@ -329,7 +357,8 @@ public: { return mStoredProposals; } - void storeProposal (LedgerProposal::ref proposal, const RippleAddress& peerPublic); + void storeProposal ( + LedgerProposal::ref proposal, const RippleAddress& peerPublic); uint256 getConsensusLCL (); void reportFeeChange (); @@ -337,7 +366,8 @@ public: { m_localTX->sweep (newValidLedger); } - void addLocalTx (Ledger::ref openLedger, SerializedTransaction::ref txn) override + void addLocalTx ( + Ledger::ref openLedger, SerializedTransaction::ref txn) override { m_localTX->push_back (openLedger->getLedgerSeq(), txn); } @@ -347,50 +377,62 @@ public: } //Helper function to generate SQL query to get transactions - std::string transactionsSQL (std::string selection, const RippleAddress& account, - std::int32_t minLedger, std::int32_t maxLedger, - bool descending, std::uint32_t offset, int limit, - bool binary, bool count, bool bAdmin); - + std::string transactionsSQL ( + std::string selection, const RippleAddress& account, + std::int32_t minLedger, std::int32_t maxLedger, + bool descending, std::uint32_t offset, int limit, + bool binary, bool count, bool bAdmin); // client information retrieval functions std::vector< std::pair > - getAccountTxs (const RippleAddress& account, std::int32_t minLedger, std::int32_t maxLedger, - bool descending, std::uint32_t offset, int limit, bool bAdmin); + getAccountTxs ( + const RippleAddress& account, + std::int32_t minLedger, std::int32_t maxLedger, bool descending, + std::uint32_t offset, int limit, bool bAdmin); std::vector< std::pair > - getTxsAccount (const RippleAddress& account, std::int32_t minLedger, std::int32_t maxLedger, - bool forward, Json::Value& token, int limit, bool bAdmin); + getTxsAccount ( + const RippleAddress& account, std::int32_t minLedger, + std::int32_t maxLedger, bool forward, Json::Value& token, int limit, + bool bAdmin); - typedef std::tuple txnMetaLedgerType; + typedef std::tuple + txnMetaLedgerType; std::vector - getAccountTxsB (const RippleAddress& account, std::int32_t minLedger, - std::int32_t maxLedger, bool descending, std::uint32_t offset, - int limit, bool bAdmin); + getAccountTxsB ( + const RippleAddress& account, std::int32_t minLedger, + std::int32_t maxLedger, bool descending, std::uint32_t offset, + int limit, bool bAdmin); std::vector - getTxsAccountB (const RippleAddress& account, std::int32_t minLedger, - std::int32_t maxLedger, bool forward, Json::Value& token, int limit, bool bAdmin); + getTxsAccountB ( + const RippleAddress& account, std::int32_t minLedger, + std::int32_t maxLedger, bool forward, Json::Value& token, + int limit, bool bAdmin); - std::vector getLedgerAffectedAccounts (std::uint32_t ledgerSeq); + std::vector getLedgerAffectedAccounts ( + std::uint32_t ledgerSeq); // // Monitoring: publisher side // void pubLedger (Ledger::ref lpAccepted); - void pubProposedTransaction (Ledger::ref lpCurrent, SerializedTransaction::ref stTxn, TER terResult); + void pubProposedTransaction ( + Ledger::ref lpCurrent, SerializedTransaction::ref stTxn, TER terResult); //-------------------------------------------------------------------------- // // InfoSub::Source // - void subAccount (InfoSub::ref ispListener, - const ripple::unordered_set& vnaAccountIDs, - std::uint32_t uLedgerIndex, bool rt); - void unsubAccount (std::uint64_t uListener, - const ripple::unordered_set& vnaAccountIDs, - bool rt); + void subAccount ( + InfoSub::ref ispListener, + const ripple::unordered_set& vnaAccountIDs, + std::uint32_t uLedgerIndex, bool rt); + void unsubAccount ( + std::uint64_t uListener, + const ripple::unordered_set& vnaAccountIDs, + bool rt); bool subLedger (InfoSub::ref ispListener, Json::Value& jvResult); bool unsubLedger (std::uint64_t uListener); @@ -398,11 +440,8 @@ public: bool subServer (InfoSub::ref ispListener, Json::Value& jvResult); bool unsubServer (std::uint64_t uListener); - bool subBook (InfoSub::ref ispListener, Currency const& currencyPays, Currency const& currencyGets, - Account const& issuerPays, Account const& issuerGets); - bool unsubBook (std::uint64_t uListener, Currency const& currencyPays, - Currency const& currencyGets, - Account const& issuerPays, Account const& issuerGets); + bool subBook (InfoSub::ref ispListener, Book const&) override; + bool unsubBook (std::uint64_t uListener, Book const&) override; bool subTransactions (InfoSub::ref ispListener); bool unsubTransactions (std::uint64_t uListener); @@ -410,8 +449,8 @@ public: bool subRTTransactions (InfoSub::ref ispListener); bool unsubRTTransactions (std::uint64_t uListener); - InfoSub::pointer findRpcSub (const std::string& strUrl); - InfoSub::pointer addRpcSub (const std::string& strUrl, InfoSub::ref rspEntry); + InfoSub::pointer findRpcSub (const std::string& strUrl); + InfoSub::pointer addRpcSub (const std::string& strUrl, InfoSub::ref); //-------------------------------------------------------------------------- // @@ -445,7 +484,8 @@ private: void pubValidatedTransaction ( Ledger::ref alAccepted, const AcceptedLedgerTx& alTransaction); void pubAccountTransaction ( - Ledger::ref lpCurrent, const AcceptedLedgerTx& alTransaction, bool isAccepted); + Ledger::ref lpCurrent, const AcceptedLedgerTx& alTransaction, + bool isAccepted); void pubServer (); @@ -462,51 +502,57 @@ private: beast::Journal m_journal; std::unique_ptr m_localTX; - std::unique_ptr m_feeVote; LockType mLock; - OperatingMode mMode; - bool mNeedNetworkLedger; - bool mProposing, mValidating; - bool m_amendmentBlocked; - boost::posix_time::ptime mConnectTime; - beast::DeadlineTimer m_heartbeatTimer; - beast::DeadlineTimer m_clusterTimer; - std::shared_ptr mConsensus; - NetworkOPs::Proposals mStoredProposals; + OperatingMode mMode; - LedgerMaster& m_ledgerMaster; - InboundLedger::pointer mAcquiringLedger; + bool mNeedNetworkLedger; + bool mProposing; + bool mValidating; + bool m_amendmentBlocked; - int mCloseTimeOffset; + boost::posix_time::ptime mConnectTime; + + beast::DeadlineTimer m_heartbeatTimer; + beast::DeadlineTimer m_clusterTimer; + + std::shared_ptr mConsensus; + NetworkOPs::Proposals mStoredProposals; + + LedgerMaster& m_ledgerMaster; + InboundLedger::pointer mAcquiringLedger; + + int mCloseTimeOffset; // last ledger close - int mLastCloseProposers, mLastCloseConvergeTime; - uint256 mLastCloseHash; - std::uint32_t mLastCloseTime; - std::uint32_t mLastValidationTime; + int mLastCloseProposers; + int mLastCloseConvergeTime; + uint256 mLastCloseHash; + + std::uint32_t mLastCloseTime; + std::uint32_t mLastValidationTime; SerializedValidation::pointer mLastValidation; // Recent positions taken std::map > mRecentPositions; - SubInfoMapType mSubAccount; - SubInfoMapType mSubRTAccount; + SubInfoMapType mSubAccount; + SubInfoMapType mSubRTAccount; - subRpcMapType mRpcSubMap; + subRpcMapType mRpcSubMap; - SubMapType mSubLedger; // accepted ledgers - SubMapType mSubServer; // when server changes connectivity state - SubMapType mSubTransactions; // all accepted transactions - SubMapType mSubRTTransactions; // all proposed and accepted transactions + SubMapType mSubLedger; // accepted ledgers + SubMapType mSubServer; // when server changes connectivity state + SubMapType mSubTransactions; // all accepted transactions + SubMapType mSubRTTransactions; // all proposed and accepted transactions - TaggedCache< uint256, Blob> mFetchPack; - std::uint32_t mFetchSeq; + TaggedCache mFetchPack; + std::uint32_t mFetchSeq; - std::uint32_t mLastLoadBase; - std::uint32_t mLastLoadFactor; + std::uint32_t mLastLoadBase; + std::uint32_t mLastLoadFactor; }; //------------------------------------------------------------------------------ @@ -561,7 +607,8 @@ void NetworkOPsImp::processHeartbeatTimer () setMode (omDISCONNECTED); m_journal.warning << "Node count (" << numPeers << ") " - << "has fallen below quorum (" << getConfig ().NETWORK_QUORUM << ")."; + << "has fallen below quorum (" + << getConfig ().NETWORK_QUORUM << ")."; } setHeartbeatTimer (); @@ -575,15 +622,12 @@ void NetworkOPsImp::processHeartbeatTimer () m_journal.info << "Node count (" << numPeers << ") is sufficient."; } - // Check if the last validated ledger forces a change between these states + // Check if the last validated ledger forces a change between these + // states. if (mMode == omSYNCING) - { setMode (omSYNCING); - } else if (mMode == omCONNECTED) - { setMode (omCONNECTED); - } if (!mConsensus) tryStartConsensus (); @@ -598,29 +642,30 @@ void NetworkOPsImp::processHeartbeatTimer () void NetworkOPsImp::processClusterTimer () { bool synced = (m_ledgerMaster.getValidatedLedgerAge() <= 240); - ClusterNodeStatus us("", synced ? getApp().getFeeTrack().getLocalFee() : 0, getNetworkTimeNC()); - if (!getApp().getUNL().nodeUpdate(getApp().getLocalCredentials().getNodePublic(), us)) + ClusterNodeStatus us("", synced ? getApp().getFeeTrack().getLocalFee() : 0, + getNetworkTimeNC()); + auto& unl = getApp().getUNL(); + if (!unl.nodeUpdate(getApp().getLocalCredentials().getNodePublic(), us)) { m_journal.debug << "To soon to send cluster update"; return; } - std::map nodes = getApp().getUNL().getClusterStatus(); + auto nodes = unl.getClusterStatus(); protocol::TMCluster cluster; - for (std::map::iterator it = nodes.begin(), - end = nodes.end(); it != end; ++it) + for (auto& it: nodes) { protocol::TMClusterNode& node = *cluster.add_clusternodes(); - node.set_publickey(it->first.humanNodePublic()); - node.set_reporttime(it->second.getReportTime()); - node.set_nodeload(it->second.getLoadFee()); - if (!it->second.getName().empty()) - node.set_nodename(it->second.getName()); + node.set_publickey(it.first.humanNodePublic()); + node.set_reporttime(it.second.getReportTime()); + node.set_nodeload(it.second.getLoadFee()); + if (!it.second.getName().empty()) + node.set_nodename(it.second.getName()); } Resource::Gossip gossip = getApp().getResourceManager().exportConsumers(); - BOOST_FOREACH (Resource::Gossip::Item const& item, gossip.items) + for (auto& item: gossip.items) { protocol::TMLoadSource& node = *cluster.add_loadsources(); node.set_name (to_string (item.address)); @@ -665,7 +710,8 @@ boost::posix_time::ptime NetworkOPsImp::getNetworkTimePT () getApp().getSystemTimeOffset (offset); // VFALCO TODO Replace this with a beast call - return boost::posix_time::microsec_clock::universal_time () + boost::posix_time::seconds (offset); + return boost::posix_time::microsec_clock::universal_time () + + boost::posix_time::seconds (offset); } std::uint32_t NetworkOPsImp::getNetworkTimeNC () @@ -675,7 +721,8 @@ std::uint32_t NetworkOPsImp::getNetworkTimeNC () std::uint32_t NetworkOPsImp::getCloseTimeNC () { - return iToSeconds (getNetworkTimePT () + boost::posix_time::seconds (mCloseTimeOffset)); + return iToSeconds (getNetworkTimePT () + + boost::posix_time::seconds (mCloseTimeOffset)); } std::uint32_t NetworkOPsImp::getValidationTimeNC () @@ -761,7 +808,8 @@ void NetworkOPsImp::submitTransaction (Job&, SerializedTransaction::pointer iTra uint256 suppress = trans->getTransactionID (); int flags; - if (getApp().getHashRouter ().addSuppressionPeer (suppress, 0, flags) && ((flags & SF_RETRY) != 0)) + if (getApp().getHashRouter ().addSuppressionPeer (suppress, 0, flags) && + ((flags & SF_RETRY) != 0)) { m_journal.warning << "Redundant transactions submitted"; return; @@ -795,17 +843,20 @@ void NetworkOPsImp::submitTransaction (Job&, SerializedTransaction::pointer iTra getApp().getJobQueue().addJob (jtTRANSACTION, "submitTxn", std::bind (&NetworkOPsImp::processTransactionCbVoid, this, - std::make_shared (trans, false), false, false, false, callback)); + std::make_shared (trans, false), + false, false, false, callback)); } // Sterilize transaction through serialization. // This is fully synchronous and deprecated -Transaction::pointer NetworkOPsImp::submitTransactionSync (Transaction::ref tpTrans, bool bAdmin, bool bLocal, bool bFailHard, bool bSubmit) +Transaction::pointer NetworkOPsImp::submitTransactionSync ( + Transaction::ref tpTrans, + bool bAdmin, bool bLocal, bool bFailHard, bool bSubmit) { Serializer s; tpTrans->getSTransaction ()->add (s); - Transaction::pointer tpTransNew = Transaction::sharedTransaction (s.getData (), true); + auto tpTransNew = Transaction::sharedTransaction (s.getData (), true); if (!tpTransNew) { @@ -813,10 +864,11 @@ Transaction::pointer NetworkOPsImp::submitTransactionSync (Transaction::ref tpTr return tpTransNew; } - if (tpTransNew->getSTransaction ()->isEquivalent (*tpTrans->getSTransaction ())) + if (tpTransNew->getSTransaction ()->isEquivalent ( + *tpTrans->getSTransaction ())) { if (bSubmit) - (void) NetworkOPsImp::processTransaction (tpTransNew, bAdmin, bLocal, bFailHard); + processTransaction (tpTransNew, bAdmin, bLocal, bFailHard); } else { @@ -844,23 +896,24 @@ void NetworkOPsImp::runTransactionQueue () return; { - LoadEvent::autoptr ev = getApp().getJobQueue ().getLoadEventAP (jtTXN_PROC, "runTxnQ"); + auto ev = getApp().getJobQueue ().getLoadEventAP ( + jtTXN_PROC, "runTxnQ"); { Application::ScopedLockType lock (getApp().getMasterLock ()); - Transaction::pointer dbtx = getApp().getMasterTransaction ().fetch (txn->getID (), true); + auto dbtx = getApp().getMasterTransaction ().fetch ( + txn->getID (), true); assert (dbtx); bool didApply; - TER r = m_ledgerMaster.doTransaction (dbtx->getSTransaction (), - tapOPEN_LEDGER | tapNO_CHECK_SIGN, didApply); + TER r = m_ledgerMaster.doTransaction ( + dbtx->getSTransaction (), tapOPEN_LEDGER | tapNO_CHECK_SIGN, + didApply); dbtx->setResult (r); if (isTemMalformed (r)) // malformed, cache bad getApp().getHashRouter ().setFlag (txn->getID (), SF_BAD); - // else if (isTelLocal (r) || isTerRetry (r)) // can be retried - // getApp().getHashRouter ().setFlag (txn->getID (), SF_RETRY); if (isTerRetry (r)) @@ -879,7 +932,8 @@ void NetworkOPsImp::runTransactionQueue () } else if (r == tesSUCCESS) { - m_journal.info << "QTransaction is now included in open ledger"; + m_journal.info + << "QTransaction is now included in open ledger"; dbtx->setStatus (INCLUDED); getApp().getMasterTransaction ().canonicalize (&dbtx); } @@ -893,17 +947,22 @@ void NetworkOPsImp::runTransactionQueue () { std::set peers; - if (getApp().getHashRouter ().swapSet (txn->getID (), peers, SF_RELAYED)) + if (getApp().getHashRouter ().swapSet ( + txn->getID (), peers, SF_RELAYED)) { m_journal.debug << "relaying"; protocol::TMTransaction tx; Serializer s; dbtx->getSTransaction ()->add (s); - tx.set_rawtransaction (&s.getData ().front (), s.getLength ()); + tx.set_rawtransaction ( + &s.getData ().front (), s.getLength ()); tx.set_status (protocol::tsCURRENT); - tx.set_receivetimestamp (getNetworkTimeNC ()); // FIXME: This should be when we received it + tx.set_receivetimestamp (getNetworkTimeNC ()); + // FIXME: This should be when we received it + getApp ().overlay ().foreach (send_if_not ( - std::make_shared (tx, protocol::mtTRANSACTION), + std::make_shared ( + tx, protocol::mtTRANSACTION), peer_in_set(peers))); } else @@ -916,14 +975,17 @@ void NetworkOPsImp::runTransactionQueue () } if (getApp().getTxQueue ().stopProcessing (txn)) - getApp().getIOService ().post (std::bind (&NetworkOPsImp::runTransactionQueue, this)); + { + getApp().getIOService ().post (std::bind ( + &NetworkOPsImp::runTransactionQueue, this)); + } } Transaction::pointer NetworkOPsImp::processTransactionCb ( - Transaction::pointer trans, bool bAdmin, bool bLocal, bool bFailHard, stCallback callback) + Transaction::pointer trans, + bool bAdmin, bool bLocal, bool bFailHard, stCallback callback) { - LoadEvent::autoptr ev = getApp().getJobQueue ().getLoadEventAP (jtTXN_PROC, "ProcessTXN"); - + auto ev = getApp().getJobQueue ().getLoadEventAP (jtTXN_PROC, "ProcessTXN"); int newFlags = getApp().getHashRouter ().getFlags (trans->getID ()); if ((newFlags & SF_BAD) != 0) @@ -953,21 +1015,22 @@ Transaction::pointer NetworkOPsImp::processTransactionCb ( Application::ScopedLockType lock (getApp().getMasterLock ()); bool didApply; - TER r = m_ledgerMaster.doTransaction (trans->getSTransaction (), - bAdmin ? (tapOPEN_LEDGER | tapNO_CHECK_SIGN | tapADMIN) : (tapOPEN_LEDGER | tapNO_CHECK_SIGN), didApply); + TER r = m_ledgerMaster.doTransaction ( + trans->getSTransaction (), + bAdmin ? (tapOPEN_LEDGER | tapNO_CHECK_SIGN | tapADMIN) + : (tapOPEN_LEDGER | tapNO_CHECK_SIGN), didApply); trans->setResult (r); if (isTemMalformed (r)) // malformed, cache bad getApp().getHashRouter ().setFlag (trans->getID (), SF_BAD); - // else if (isTelLocal (r) || isTerRetry (r)) // can be retried - // getApp().getHashRouter ().setFlag (trans->getID (), SF_RETRY); #ifdef BEAST_DEBUG if (r != tesSUCCESS) { std::string token, human; if (transResultInfo (r, token, human)) - m_journal.info << "TransactionResult: " << token << ": " << human; + m_journal.info << "TransactionResult: " + << token << ": " << human; } #endif @@ -977,11 +1040,7 @@ Transaction::pointer NetworkOPsImp::processTransactionCb ( if (r == tefFAILURE) - { - // VFALCO TODO All callers use a try block so this should be changed to - // a return value. throw Fault (IO_ERROR); - } bool addLocal = bLocal; @@ -1019,20 +1078,25 @@ Transaction::pointer NetworkOPsImp::processTransactionCb ( } if (addLocal) - addLocalTx (m_ledgerMaster.getCurrentLedger (), trans->getSTransaction ()); + { + addLocalTx (m_ledgerMaster.getCurrentLedger (), + trans->getSTransaction ()); + } if (didApply || ((mMode != omFULL) && !bFailHard && bLocal)) { std::set peers; - if (getApp().getHashRouter ().swapSet (trans->getID (), peers, SF_RELAYED)) + if (getApp().getHashRouter ().swapSet ( + trans->getID (), peers, SF_RELAYED)) { protocol::TMTransaction tx; Serializer s; trans->getSTransaction ()->add (s); tx.set_rawtransaction (&s.getData ().front (), s.getLength ()); tx.set_status (protocol::tsCURRENT); - tx.set_receivetimestamp (getNetworkTimeNC ()); // FIXME: This should be when we received it + tx.set_receivetimestamp (getNetworkTimeNC ()); + // FIXME: This should be when we received it getApp ().overlay ().foreach (send_if_not ( std::make_shared (tx, protocol::mtTRANSACTION), peer_in_set(peers))); @@ -1043,14 +1107,16 @@ Transaction::pointer NetworkOPsImp::processTransactionCb ( return trans; } -Transaction::pointer NetworkOPsImp::findTransactionByID (uint256 const& transactionID) +Transaction::pointer NetworkOPsImp::findTransactionByID ( + uint256 const& transactionID) { return Transaction::load (transactionID); } -int NetworkOPsImp::findTransactionsByDestination (std::list& txns, - const RippleAddress& destinationAccount, std::uint32_t startLedgerSeq, - std::uint32_t endLedgerSeq, int maxTransactions) +int NetworkOPsImp::findTransactionsByDestination ( + std::list& txns, + const RippleAddress& destinationAccount, std::uint32_t startLedgerSeq, + std::uint32_t endLedgerSeq, int maxTransactions) { // WRITEME return 0; @@ -1091,17 +1157,24 @@ STVector256 NetworkOPsImp::getDirNodeInfo ( if (sleNode) { - m_journal.debug << "getDirNodeInfo: node index: " << to_string (uNodeIndex); + m_journal.debug + << "getDirNodeInfo: node index: " << to_string (uNodeIndex); - m_journal.trace << "getDirNodeInfo: first: " << strHex (sleNode->getFieldU64 (sfIndexPrevious)); - m_journal.trace << "getDirNodeInfo: last: " << strHex (sleNode->getFieldU64 (sfIndexNext)); + m_journal.trace + << "getDirNodeInfo: first: " + << strHex (sleNode->getFieldU64 (sfIndexPrevious)); + m_journal.trace + << "getDirNodeInfo: last: " + << strHex (sleNode->getFieldU64 (sfIndexNext)); - uNodePrevious = sleNode->getFieldU64 (sfIndexPrevious); - uNodeNext = sleNode->getFieldU64 (sfIndexNext); - svIndexes = sleNode->getFieldV256 (sfIndexes); + uNodePrevious = sleNode->getFieldU64 (sfIndexPrevious); + uNodeNext = sleNode->getFieldU64 (sfIndexNext); + svIndexes = sleNode->getFieldV256 (sfIndexes); - m_journal.trace << "getDirNodeInfo: first: " << strHex (uNodePrevious); - m_journal.trace << "getDirNodeInfo: last: " << strHex (uNodeNext); + m_journal.trace + << "getDirNodeInfo: first: " << strHex (uNodePrevious); + m_journal.trace + << "getDirNodeInfo: last: " << strHex (uNodeNext); } else { @@ -1114,28 +1187,16 @@ STVector256 NetworkOPsImp::getDirNodeInfo ( return svIndexes; } -#if 0 -// -// Nickname functions -// - -NicknameState::pointer NetworkOPsImp::getNicknameState (uint256 const& uLedger, const std::string& strNickname) -{ - return m_ledgerMaster.getLedgerByHash (uLedger)->getNicknameState (strNickname); -} -#endif - // // Owner functions // -Json::Value NetworkOPsImp::getOwnerInfo (Ledger::pointer lpLedger, const RippleAddress& naAccount) +Json::Value NetworkOPsImp::getOwnerInfo ( + Ledger::pointer lpLedger, const RippleAddress& naAccount) { Json::Value jvObjects (Json::objectValue); - - uint256 uRootIndex = lpLedger->getOwnerDirIndex (naAccount.getAccountID ()); - - SLE::pointer sleNode = lpLedger->getDirNode (uRootIndex); + auto uRootIndex = lpLedger->getOwnerDirIndex (naAccount.getAccountID ()); + auto sleNode = lpLedger->getDirNode (uRootIndex); if (sleNode) { @@ -1143,25 +1204,28 @@ Json::Value NetworkOPsImp::getOwnerInfo (Ledger::pointer lpLedger, const RippleA do { - STVector256 svIndexes = sleNode->getFieldV256 (sfIndexes); + STVector256 svIndexes = sleNode->getFieldV256 (sfIndexes); const std::vector& vuiIndexes = svIndexes.peekValue (); BOOST_FOREACH (uint256 const & uDirEntry, vuiIndexes) { - SLE::pointer sleCur = lpLedger->getSLEi (uDirEntry); + auto sleCur = lpLedger->getSLEi (uDirEntry); switch (sleCur->getType ()) { case ltOFFER: if (!jvObjects.isMember (jss::offers)) - jvObjects[jss::offers] = Json::Value (Json::arrayValue); + jvObjects[jss::offers] = Json::Value (Json::arrayValue); jvObjects[jss::offers].append (sleCur->getJson (0)); break; case ltRIPPLE_STATE: if (!jvObjects.isMember (jss::ripple_lines)) - jvObjects[jss::ripple_lines] = Json::Value (Json::arrayValue); + { + jvObjects[jss::ripple_lines] = + Json::Value (Json::arrayValue); + } jvObjects[jss::ripple_lines].append (sleCur->getJson (0)); break; @@ -1180,7 +1244,8 @@ Json::Value NetworkOPsImp::getOwnerInfo (Ledger::pointer lpLedger, const RippleA if (uNodeDir) { - sleNode = lpLedger->getDirNode (Ledger::getDirNodeIndex (uRootIndex, uNodeDir)); + sleNode = lpLedger->getDirNode ( + Ledger::getDirNodeIndex (uRootIndex, uNodeDir)); assert (sleNode); } } @@ -1236,21 +1301,23 @@ public: void NetworkOPsImp::tryStartConsensus () { uint256 networkClosed; - bool ledgerChange = checkLastClosedLedger (getApp().overlay ().getActivePeers (), networkClosed); + bool ledgerChange = checkLastClosedLedger ( + getApp().overlay ().getActivePeers (), networkClosed); if (networkClosed.isZero ()) return; // WRITEME: Unless we are in omFULL and in the process of doing a consensus, - // we must count how many nodes share our LCL, how many nodes disagree with our LCL, - // and how many validations our LCL has. We also want to check timing to make sure - // there shouldn't be a newer LCL. We need this information to do the next three - // tests. + // we must count how many nodes share our LCL, how many nodes disagree with + // our LCL, and how many validations our LCL has. We also want to check + // timing to make sure there shouldn't be a newer LCL. We need this + // information to do the next three tests. if (((mMode == omCONNECTED) || (mMode == omSYNCING)) && !ledgerChange) { - // count number of peers that agree with us and UNL nodes whose validations we have for LCL - // if the ledger is good enough, go to omTRACKING - TODO + // Count number of peers that agree with us and UNL nodes whose + // validations we have for LCL. If the ledger is good enough, go to + // omTRACKING - TODO if (!mNeedNetworkLedger) setMode (omTRACKING); } @@ -1260,20 +1327,24 @@ void NetworkOPsImp::tryStartConsensus () // check if the ledger is good enough to go to omFULL // Note: Do not go to omFULL if we don't have the previous ledger // check if the ledger is bad enough to go to omCONNECTED -- TODO - if (getApp().getOPs ().getNetworkTimeNC () < m_ledgerMaster.getCurrentLedger ()->getCloseTimeNC ()) + if (getApp().getOPs ().getNetworkTimeNC () < + m_ledgerMaster.getCurrentLedger ()->getCloseTimeNC ()) + { setMode (omFULL); + } } if ((!mConsensus) && (mMode != omDISCONNECTED)) beginConsensus (networkClosed, m_ledgerMaster.getCurrentLedger ()); } -bool NetworkOPsImp::checkLastClosedLedger (const Overlay::PeerSequence& peerList, uint256& networkClosed) +bool NetworkOPsImp::checkLastClosedLedger ( + const Overlay::PeerSequence& peerList, uint256& networkClosed) { - // Returns true if there's an *abnormal* ledger issue, normal changing in TRACKING mode should return false - // Do we have sufficient validations for our last closed ledger? Or do sufficient nodes - // agree? And do we have no better ledger available? - // If so, we are either tracking or full. + // Returns true if there's an *abnormal* ledger issue, normal changing in + // TRACKING mode should return false. Do we have sufficient validations for + // our last closed ledger? Or do sufficient nodes agree? And do we have no + // better ledger available? If so, we are either tracking or full. m_journal.trace << "NetworkOPsImp::checkLastClosedLedger"; @@ -1289,10 +1360,11 @@ bool NetworkOPsImp::checkLastClosedLedger (const Overlay::PeerSequence& peerList ripple::unordered_map ledgers; { - ripple::unordered_map current = - getApp().getValidations ().getCurrentValidations (closedLedger, prevClosedLedger); + auto current = getApp().getValidations ().getCurrentValidations ( + closedLedger, prevClosedLedger); + typedef std::map::value_type u256_cvc_pair; - BOOST_FOREACH (const u256_cvc_pair & it, current) + for (auto & it: current) { ValidationCount& vc = ledgers[it.first]; vc.trustedValidations += it.second.first; @@ -1314,7 +1386,7 @@ bool NetworkOPsImp::checkLastClosedLedger (const Overlay::PeerSequence& peerList ourVC.highNodeUsing = ourAddress; } - BOOST_FOREACH (Peer::ptr const& peer, peerList) + for (auto& peer: peerList) { uint256 peerLedger = peer->getClosedLedgerHash (); @@ -1341,7 +1413,8 @@ bool NetworkOPsImp::checkLastClosedLedger (const Overlay::PeerSequence& peerList ValidationCount bestVC = ledgers[closedLedger]; - // 3) Is there a network ledger we'd like to switch to? If so, do we have it? + // 3) Is there a network ledger we'd like to switch to? If so, do we have + // it? bool switchLedgers = false; for (auto const& it: ledgers) @@ -1382,7 +1455,8 @@ bool NetworkOPsImp::checkLastClosedLedger (const Overlay::PeerSequence& peerList if (mAcquiringLedger) { mAcquiringLedger->abort (); - getApp().getInboundLedgers ().dropLedger (mAcquiringLedger->getHash ()); + getApp().getInboundLedgers ().dropLedger ( + mAcquiringLedger->getHash ()); mAcquiringLedger.reset (); } @@ -1403,7 +1477,8 @@ bool NetworkOPsImp::checkLastClosedLedger (const Overlay::PeerSequence& peerList m_journal.info << "Acquiring consensus ledger " << closedLedger; if (!mAcquiringLedger || (mAcquiringLedger->getHash () != closedLedger)) - mAcquiringLedger = getApp().getInboundLedgers ().findCreate (closedLedger, 0, InboundLedger::fcCONSENSUS); + mAcquiringLedger = getApp().getInboundLedgers ().findCreate ( + closedLedger, 0, InboundLedger::fcCONSENSUS); if (!mAcquiringLedger || mAcquiringLedger->isFailed ()) { @@ -1419,25 +1494,25 @@ bool NetworkOPsImp::checkLastClosedLedger (const Overlay::PeerSequence& peerList consensus = mAcquiringLedger->getLedger (); } - // FIXME: If this rewinds the ledger sequence, or has the same sequence, we should update the status on - // any stored transactions in the invalidated ledgers. + // FIXME: If this rewinds the ledger sequence, or has the same sequence, we + // should update the status on any stored transactions in the invalidated + // ledgers. switchLastClosedLedger (consensus, false); return true; } -void NetworkOPsImp::switchLastClosedLedger (Ledger::pointer newLedger, bool duringConsensus) +void NetworkOPsImp::switchLastClosedLedger ( + Ledger::pointer newLedger, bool duringConsensus) { // set the newledger as our last closed ledger -- this is abnormal code - if (duringConsensus) - m_journal.error << "JUMPdc last closed ledger to " << newLedger->getHash (); - else - m_journal.error << "JUMP last closed ledger to " << newLedger->getHash (); + auto msg = duringConsensus ? "JUMPdc" : "JUMP"; + m_journal.error << msg << " last closed ledger to " << newLedger->getHash (); clearNeedNetworkLedger (); newLedger->setClosed (); - Ledger::pointer openLedger = std::make_shared (false, std::ref (*newLedger)); + auto openLedger = std::make_shared (false, std::ref (*newLedger)); m_ledgerMaster.switchLedgers (newLedger, openLedger); protocol::TMStatusChange s; @@ -1453,12 +1528,16 @@ void NetworkOPsImp::switchLastClosedLedger (Ledger::pointer newLedger, bool duri std::make_shared (s, protocol::mtSTATUS_CHANGE))); } -int NetworkOPsImp::beginConsensus (uint256 const& networkClosed, Ledger::pointer closingLedger) +int NetworkOPsImp::beginConsensus ( + uint256 const& networkClosed, Ledger::pointer closingLedger) { - m_journal.info << "Consensus time for ledger " << closingLedger->getLedgerSeq (); - m_journal.info << " LCL is " << closingLedger->getParentHash (); + m_journal.info + << "Consensus time for ledger " << closingLedger->getLedgerSeq (); + m_journal.info + << " LCL is " << closingLedger->getParentHash (); - Ledger::pointer prevLedger = m_ledgerMaster.getLedgerByHash (closingLedger->getParentHash ()); + auto prevLedger + = m_ledgerMaster.getLedgerByHash (closingLedger->getParentHash ()); if (!prevLedger) { @@ -1473,7 +1552,8 @@ int NetworkOPsImp::beginConsensus (uint256 const& networkClosed, Ledger::pointer } assert (prevLedger->getHash () == closingLedger->getParentHash ()); - assert (closingLedger->getParentHash () == m_ledgerMaster.getClosedLedger ()->getHash ()); + assert (closingLedger->getParentHash () == + m_ledgerMaster.getClosedLedger ()->getHash ()); // Create a consensus object to get consensus on this ledger assert (!mConsensus); @@ -1524,8 +1604,10 @@ uint256 NetworkOPsImp::getConsensusLCL () return mConsensus->getLCL (); } -void NetworkOPsImp::processTrustedProposal (LedgerProposal::pointer proposal, - std::shared_ptr set, RippleAddress nodePublic, uint256 checkLedger, bool sigGood) +void NetworkOPsImp::processTrustedProposal ( + LedgerProposal::pointer proposal, + std::shared_ptr set, RippleAddress nodePublic, + uint256 checkLedger, bool sigGood) { { Application::ScopedLockType lock (getApp().getMasterLock ()); @@ -1547,7 +1629,9 @@ void NetworkOPsImp::processTrustedProposal (LedgerProposal::pointer proposal, if (!set->has_previousledger () && (checkLedger != consensusLCL)) { - m_journal.warning << "Have to re-check proposal signature due to consensus view change"; + m_journal.warning + << "Have to re-check proposal signature due to " + << "consensus view change"; assert (proposal->hasSignature ()); proposal->setPrevLedger (consensusLCL); @@ -1558,7 +1642,8 @@ void NetworkOPsImp::processTrustedProposal (LedgerProposal::pointer proposal, if (sigGood && (consensusLCL == proposal->getPrevLedger ())) { relay = mConsensus->peerPosition (proposal); - m_journal.trace << "Proposal processing finished, relay=" << relay; + m_journal.trace + << "Proposal processing finished, relay=" << relay; } } @@ -1567,11 +1652,12 @@ void NetworkOPsImp::processTrustedProposal (LedgerProposal::pointer proposal, std::set peers; if (getApp().getHashRouter ().swapSet ( proposal->getSuppressionID (), peers, SF_RELAYED)) - { + { getApp ().overlay ().foreach (send_if_not ( - std::make_shared (*set, protocol::mtPROPOSE_LEDGER), + std::make_shared ( + *set, protocol::mtPROPOSE_LEDGER), peer_in_set(peers))); - } + } } else { @@ -1601,24 +1687,23 @@ void NetworkOPsImp::takePosition (int seq, SHAMap::ref position) if (mRecentPositions.size () > 4) { - std::map >::iterator it = mRecentPositions.begin (); - - while (it != mRecentPositions.end ()) + for (auto i = mRecentPositions.begin (); i != mRecentPositions.end ();) { - if (it->second.first < (seq - 2)) + if (i->second.first < (seq - 2)) { - mRecentPositions.erase (it); + mRecentPositions.erase (i); return; } - ++it; + ++i; } } } // Call with the master lock for now -SHAMapAddNode NetworkOPsImp::gotTXData (const std::shared_ptr& peer, uint256 const& hash, - const std::list& nodeIDs, const std::list< Blob >& nodeData) +SHAMapAddNode NetworkOPsImp::gotTXData ( + const std::shared_ptr& peer, uint256 const& hash, + const std::list& nodeIDs, const std::list< Blob >& nodeData) { if (!mConsensus) @@ -1630,7 +1715,9 @@ SHAMapAddNode NetworkOPsImp::gotTXData (const std::shared_ptr& peer, uint2 return mConsensus->peerGaveNodes (peer, hash, nodeIDs, nodeData); } -bool NetworkOPsImp::hasTXSet (const std::shared_ptr& peer, uint256 const& set, protocol::TxSetStatus status) +bool NetworkOPsImp::hasTXSet ( + const std::shared_ptr& peer, uint256 const& set, + protocol::TxSetStatus status) { if (mConsensus == nullptr) { @@ -1693,29 +1780,30 @@ void NetworkOPsImp::pubServer () jvObj [jss::type] = "serverStatus"; jvObj [jss::server_status] = strOperatingMode (); - jvObj [jss::load_base] = (mLastLoadBase = getApp().getFeeTrack ().getLoadBase ()); - jvObj [jss::load_factor] = (mLastLoadFactor = getApp().getFeeTrack ().getLoadFactor ()); + jvObj [jss::load_base] = + (mLastLoadBase = getApp().getFeeTrack ().getLoadBase ()); + jvObj [jss::load_factor] = + (mLastLoadFactor = getApp().getFeeTrack ().getLoadFactor ()); Json::FastWriter w; std::string sObj = w.write (jvObj); - NetworkOPsImp::SubMapType::const_iterator it = mSubServer.begin (); - while (it != mSubServer.end ()) + for (auto i = mSubServer.begin (); i != mSubServer.end (); ) { - InfoSub::pointer p = it->second.lock (); + InfoSub::pointer p = i->second.lock (); - // VFALCO TODO research the possibility of using thread queues and linearizing - // the deletion of subscribers with the sending of JSON data. + // VFALCO TODO research the possibility of using thread queues and + // linearizing the deletion of subscribers with the + // sending of JSON data. if (p) { p->send (jvObj, sObj, true); - - ++it; + ++i; } else { - it = mSubServer.erase (it); + i = mSubServer.erase (i); } } } @@ -1753,10 +1841,11 @@ void NetworkOPsImp::setMode (OperatingMode om) std::string -NetworkOPsImp::transactionsSQL (std::string selection, const RippleAddress& account, - std::int32_t minLedger, std::int32_t maxLedger, bool descending, - std::uint32_t offset, int limit, - bool binary, bool count, bool bAdmin) +NetworkOPsImp::transactionsSQL ( + std::string selection, const RippleAddress& account, + std::int32_t minLedger, std::int32_t maxLedger, bool descending, + std::uint32_t offset, int limit, + bool binary, bool count, bool bAdmin) { std::uint32_t NONBINARY_PAGE_LENGTH = 200; std::uint32_t BINARY_PAGE_LENGTH = 500; @@ -1768,8 +1857,9 @@ NetworkOPsImp::transactionsSQL (std::string selection, const RippleAddress& acco else if (limit < 0) numberOfResults = binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH; else if (!bAdmin) - numberOfResults = std::min (binary ? BINARY_PAGE_LENGTH - : NONBINARY_PAGE_LENGTH, static_cast (limit)); + numberOfResults = std::min ( + binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH, + static_cast (limit)); else numberOfResults = limit; @@ -1815,13 +1905,13 @@ NetworkOPsImp::transactionsSQL (std::string selection, const RippleAddress& acco return sql; } -std::vector< std::pair > -NetworkOPsImp::getAccountTxs (const RippleAddress& account, std::int32_t minLedger, - std::int32_t maxLedger, bool descending, std::uint32_t offset, - int limit, bool bAdmin) +NetworkOPs::AccountTxs NetworkOPsImp::getAccountTxs ( + const RippleAddress& account, + std::int32_t minLedger, std::int32_t maxLedger, bool descending, + std::uint32_t offset, int limit, bool bAdmin) { // can be called with no locks - std::vector< std::pair > ret; + AccountTxs ret; std::string sql = NetworkOPsImp::transactionsSQL ("AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta", account, minLedger, maxLedger, descending, offset, limit, false, false, bAdmin); @@ -1865,7 +1955,8 @@ NetworkOPsImp::getAccountTxs (const RippleAddress& account, std::int32_t minLedg } std::vector NetworkOPsImp::getAccountTxsB ( - const RippleAddress& account, std::int32_t minLedger, std::int32_t maxLedger, bool descending, + const RippleAddress& account, + std::int32_t minLedger, std::int32_t maxLedger, bool descending, std::uint32_t offset, int limit, bool bAdmin) { // can be called with no locks @@ -2679,32 +2770,25 @@ void NetworkOPsImp::unsubAccount (std::uint64_t uSeq, } } -bool NetworkOPsImp::subBook (InfoSub::ref isrListener, Currency const& currencyPays, Currency const& currencyGets, - Account const& issuerPays, Account const& issuerGets) +bool NetworkOPsImp::subBook (InfoSub::ref isrListener, Book const& book) { - BookListeners::pointer listeners = - getApp().getOrderBookDB ().makeBookListeners (currencyPays, currencyGets, issuerPays, issuerGets); - - assert (listeners); - if (listeners) + if (auto listeners = getApp().getOrderBookDB ().makeBookListeners (book)) listeners->addSubscriber (isrListener); - + else + assert (false); return true; } -bool NetworkOPsImp::unsubBook (std::uint64_t uSeq, - Currency const& currencyPays, Currency const& currencyGets, Account const& issuerPays, Account const& issuerGets) +bool NetworkOPsImp::unsubBook (std::uint64_t uSeq, Book const& book) { - BookListeners::pointer listeners = - getApp().getOrderBookDB ().getBookListeners (currencyPays, currencyGets, issuerPays, issuerGets); - - if (listeners) + if (auto listeners = getApp().getOrderBookDB ().getBookListeners (book)) listeners->removeSubscriber (uSeq); return true; } -void NetworkOPsImp::newLCL (int proposers, int convergeTime, uint256 const& ledgerHash) +void NetworkOPsImp::newLCL ( + int proposers, int convergeTime, uint256 const& ledgerHash) { assert (convergeTime); mLastCloseProposers = proposers; @@ -2848,16 +2932,14 @@ InfoSub::pointer NetworkOPsImp::addRpcSub (const std::string& strUrl, InfoSub::r } #ifndef USE_NEW_BOOK_PAGE + // NIKB FIXME this should be looked at. There's no reason why this shouldn't // work, but it demonstrated poor performance. // // FIXME : support iLimit. void NetworkOPsImp::getBookPage ( Ledger::pointer lpLedger, - Currency const& uTakerPaysCurrencyID, - Account const& uTakerPaysIssuerID, - Currency const& uTakerGetsCurrencyID, - Account const& uTakerGetsIssuerID, + Book const& book, Account const& uTakerID, bool const bProof, const unsigned int iLimit, @@ -2868,24 +2950,13 @@ void NetworkOPsImp::getBookPage ( (jvResult[jss::offers] = Json::Value (Json::arrayValue)); std::map umBalance; - const uint256 uBookBase = Ledger::getBookBase ( - uTakerPaysCurrencyID, uTakerPaysIssuerID, - uTakerGetsCurrencyID, uTakerGetsIssuerID); + const uint256 uBookBase = Ledger::getBookBase (book); const uint256 uBookEnd = Ledger::getQualityNext (uBookBase); uint256 uTipIndex = uBookBase; if (m_journal.trace) { - m_journal.trace << "getBookPage:" << - " uTakerPaysCurrencyID=" << - to_string (uTakerPaysCurrencyID) << - " uTakerPaysIssuerID=" << - to_string (uTakerPaysIssuerID); - m_journal.trace << "getBookPage:" << - " uTakerGetsCurrencyID=" << - to_string (uTakerGetsCurrencyID) << - " uTakerGetsIssuerID=" << - to_string (uTakerGetsIssuerID); + m_journal.trace << "getBookPage:" << book; m_journal.trace << "getBookPage: uBookBase=" << uBookBase; m_journal.trace << "getBookPage: uBookEnd=" << uBookEnd; m_journal.trace << "getBookPage: uTipIndex=" << uTipIndex; @@ -2906,7 +2977,7 @@ void NetworkOPsImp::getBookPage ( if ((iLeft == 0) || (iLeft > 300)) iLeft = 300; - std::uint32_t uTransferRate = lesActive.rippleTransferRate (uTakerGetsIssuerID); + std::uint32_t uTransferRate = lesActive.rippleTransferRate (book.out.account); while (!bDone && (--iLeft > 0)) { @@ -2916,7 +2987,8 @@ void NetworkOPsImp::getBookPage ( m_journal.trace << "getBookPage: bDirectAdvance"; - sleOfferDir = lesActive.entryCache (ltDIR_NODE, lpLedger->getNextLedgerIndex (uTipIndex, uBookEnd)); + sleOfferDir = lesActive.entryCache ( + ltDIR_NODE, lpLedger->getNextLedgerIndex (uTipIndex, uBookEnd)); if (!sleOfferDir) { @@ -2925,10 +2997,11 @@ void NetworkOPsImp::getBookPage ( } else { - uTipIndex = sleOfferDir->getIndex (); - saDirRate = STAmount::setRate (Ledger::getQuality (uTipIndex)); + uTipIndex = sleOfferDir->getIndex (); + saDirRate = STAmount::setRate (Ledger::getQuality (uTipIndex)); - lesActive.dirFirst (uTipIndex, sleOfferDir, uBookEntry, offerIndex); + lesActive.dirFirst ( + uTipIndex, sleOfferDir, uBookEntry, offerIndex); m_journal.trace << "getBookPage: uTipIndex=" << uTipIndex; m_journal.trace << "getBookPage: offerIndex=" << offerIndex; @@ -2949,9 +3022,10 @@ void NetworkOPsImp::getBookPage ( sleOffer->getFieldAmount (sfTakerPays); STAmount saOwnerFunds; - if (uTakerGetsIssuerID == uOfferOwnerID) + if (book.out.account == uOfferOwnerID) { - // If offer is selling issuer's own IOUs, it is fully funded. + // If an offer is selling issuer's own IOUs, it is fully + // funded. saOwnerFunds = saTakerGets; } else @@ -2962,19 +3036,15 @@ void NetworkOPsImp::getBookPage ( // Found in running balance table. saOwnerFunds = umBalanceEntry->second; - // m_journal.info << "getBookPage: saOwnerFunds=%s - // (cached)") % saOwnerFunds.getFullText()); } else { // Did not find balance in table. saOwnerFunds = lesActive.accountHolds ( - uOfferOwnerID, uTakerGetsCurrencyID, - uTakerGetsIssuerID); + uOfferOwnerID, book.out.currency, + book.out.account); - // m_journal.info << boost::format(getBookPage: - // saOwnerFunds=%s (new)") % saOwnerFunds.getFullText()); if (saOwnerFunds < zero) { // Treat negative funds as zero. @@ -2991,9 +3061,12 @@ void NetworkOPsImp::getBookPage ( std::uint32_t uOfferRate; - if (uTransferRate != QUALITY_ONE // Have a tranfer fee. - && uTakerID != uTakerGetsIssuerID // Not taking offers of own IOUs. - && uTakerGetsIssuerID != uOfferOwnerID) // Offer owner not issuing ownfunds + if (uTransferRate != QUALITY_ONE + // Have a tranfer fee. + && uTakerID != book.out.account + // Not taking offers of own IOUs. + && book.out.account != uOfferOwnerID) + // Offer owner not issuing ownfunds { // Need to charge a transfer fee to offer owner. uOfferRate = uTransferRate; @@ -3048,7 +3121,8 @@ void NetworkOPsImp::getBookPage ( m_journal.warning << "Missing offer"; } - if (!lesActive.dirNext (uTipIndex, sleOfferDir, uBookEntry, offerIndex)) + if (!lesActive.dirNext ( + uTipIndex, sleOfferDir, uBookEntry, offerIndex)) { bDirectAdvance = true; } @@ -3072,10 +3146,7 @@ void NetworkOPsImp::getBookPage ( // FIXME : support iLimit. void NetworkOPsImp::getBookPage ( Ledger::pointer lpLedger, - Currency const& uTakerPaysCurrencyID, - Account const& uTakerPaysIssuerID, - Currency const& uTakerGetsCurrencyID, - Account const& uTakerGetsIssuerID, + Book const& book, Account const& uTakerID, bool const bProof, const unsigned int iLimit, @@ -3087,16 +3158,14 @@ void NetworkOPsImp::getBookPage ( std::map umBalance; LedgerEntrySet lesActive (lpLedger, tapNONE, true); - OrderBookIterator obIterator ( - lesActive, uTakerPaysCurrencyID, uTakerPaysIssuerID, - uTakerGetsCurrencyID, uTakerGetsIssuerID); + OrderBookIterator obIterator (lesActive, book); unsigned int iLeft = iLimit; if ((iLeft == 0) || (iLeft > 300)) iLeft = 300; - auto uTransferRate = lesActive.rippleTransferRate (uTakerGetsIssuerID); + auto uTransferRate = lesActive.rippleTransferRate (book.out.account); while ((--iLeft > 0) && obIterator.nextOffer ()) { @@ -3110,7 +3179,7 @@ void NetworkOPsImp::getBookPage ( STAmount saDirRate = obIterator.getCurrentRate (); STAmount saOwnerFunds; - if (uTakerGetsIssuerID == uOfferOwnerID) + if (book.out.account == uOfferOwnerID) { // If offer is selling issuer's own IOUs, it is fully funded. saOwnerFunds = saTakerGets; @@ -3130,7 +3199,7 @@ void NetworkOPsImp::getBookPage ( // Did not find balance in table. saOwnerFunds = lesActive.accountHolds ( - uOfferOwnerID, uTakerGetsCurrencyID, uTakerGetsIssuerID); + uOfferOwnerID, book.out.currency, book.out.account); if (saOwnerFunds.isNegative ()) { @@ -3150,9 +3219,9 @@ void NetworkOPsImp::getBookPage ( if (uTransferRate != QUALITY_ONE // Have a tranfer fee. - && uTakerID != uTakerGetsIssuerID + && uTakerID != book.out.account // Not taking offers of own IOUs. - && uTakerGetsIssuerID != uOfferOwnerID) + && book.out.account != uOfferOwnerID) // Offer owner not issuing ownfunds { // Need to charge a transfer fee to offer owner. @@ -3212,8 +3281,9 @@ void NetworkOPsImp::getBookPage ( #endif -static void fpAppender (protocol::TMGetObjectByHash* reply, std::uint32_t ledgerSeq, - const uint256& hash, const Blob& blob) +static void fpAppender ( + protocol::TMGetObjectByHash* reply, std::uint32_t ledgerSeq, + const uint256& hash, const Blob& blob) { protocol::TMIndexedObject& newObj = * (reply->add_objects ()); newObj.set_ledgerseq (ledgerSeq); @@ -3221,9 +3291,10 @@ static void fpAppender (protocol::TMGetObjectByHash* reply, std::uint32_t ledger newObj.set_data (&blob[0], blob.size ()); } -void NetworkOPsImp::makeFetchPack (Job&, std::weak_ptr wPeer, - std::shared_ptr request, - uint256 haveLedgerHash, std::uint32_t uUptime) +void NetworkOPsImp::makeFetchPack ( + Job&, std::weak_ptr wPeer, + std::shared_ptr request, + uint256 haveLedgerHash, std::uint32_t uUptime) { if (UptimeTimer::getInstance ().getElapsedSeconds () > (uUptime + 1)) { @@ -3247,14 +3318,18 @@ void NetworkOPsImp::makeFetchPack (Job&, std::weak_ptr wPeer, if (!haveLedger) { - m_journal.info << "Peer requests fetch pack for ledger we don't have: " << haveLedger; + m_journal.info + << "Peer requests fetch pack for ledger we don't have: " + << haveLedger; peer->charge (Resource::feeRequestNoReply); return; } if (!haveLedger->isClosed ()) { - m_journal.warning << "Peer requests fetch pack from open ledger: " << haveLedger; + m_journal.warning + << "Peer requests fetch pack from open ledger: " + << haveLedger; peer->charge (Resource::feeInvalidRequest); return; } @@ -3271,15 +3346,14 @@ void NetworkOPsImp::makeFetchPack (Job&, std::weak_ptr wPeer, if (!wantLedger) { m_journal.info - << "Peer requests fetch pack for ledger whose predecessor we don't have: " - << haveLedger; + << "Peer requests fetch pack for ledger whose predecessor we " + << "don't have: " << haveLedger; peer->charge (Resource::feeRequestNoReply); return; } try { - protocol::TMGetObjectByHash reply; reply.set_query (false); @@ -3319,10 +3393,12 @@ void NetworkOPsImp::makeFetchPack (Job&, std::weak_ptr wPeer, haveLedger = std::move (wantLedger); wantLedger = getLedgerByHash (haveLedger->getParentHash ()); } - while (wantLedger && (UptimeTimer::getInstance ().getElapsedSeconds () <= (uUptime + 1))); + while (wantLedger && + UptimeTimer::getInstance ().getElapsedSeconds () <= uUptime + 1); - m_journal.info << "Built fetch pack with " << reply.objects ().size () << " nodes"; - Message::pointer msg = std::make_shared (reply, protocol::mtGET_OBJECTS); + m_journal.info + << "Built fetch pack with " << reply.objects ().size () << " nodes"; + auto msg = std::make_shared (reply, protocol::mtGET_OBJECTS); peer->send (msg); } catch (...) @@ -3336,7 +3412,8 @@ void NetworkOPsImp::sweepFetchPack () mFetchPack.sweep (); } -void NetworkOPsImp::addFetchPack (uint256 const& hash, std::shared_ptr< Blob >& data) +void NetworkOPsImp::addFetchPack ( + uint256 const& hash, std::shared_ptr< Blob >& data) { mFetchPack.canonicalize (hash, data); } @@ -3379,9 +3456,10 @@ void NetworkOPsImp::gotFetchPack (bool progress, std::uint32_t seq) // InboundLedgers::gotFetchPack being called more than once // which is expensive. A flag should track whether we've already dispatched - getApp().getJobQueue ().addJob (jtLEDGER_DATA, "gotFetchPack", - std::bind (&InboundLedgers::gotFetchPack, - &getApp().getInboundLedgers (), std::placeholders::_1)); + getApp().getJobQueue ().addJob ( + jtLEDGER_DATA, "gotFetchPack", + std::bind (&InboundLedgers::gotFetchPack, + &getApp().getInboundLedgers (), std::placeholders::_1)); } void NetworkOPsImp::missingNodeInLedger (std::uint32_t seq) @@ -3389,12 +3467,14 @@ void NetworkOPsImp::missingNodeInLedger (std::uint32_t seq) uint256 hash = getApp().getLedgerMaster ().getHashBySeq (seq); if (hash.isZero()) { - m_journal.warning << "Missing a node in ledger " << seq << " cannot fetch"; + m_journal.warning + << "Missing a node in ledger " << seq << " cannot fetch"; } else { m_journal.warning << "Missing a node in ledger " << seq << " fetching"; - getApp().getInboundLedgers ().findCreate (hash, seq, InboundLedger::fcGENERIC); + getApp().getInboundLedgers ().findCreate ( + hash, seq, InboundLedger::fcGENERIC); } } diff --git a/src/ripple/module/app/misc/NetworkOPs.h b/src/ripple/module/app/misc/NetworkOPs.h index 2e357579cb..e2357d0637 100644 --- a/src/ripple/module/app/misc/NetworkOPs.h +++ b/src/ripple/module/app/misc/NetworkOPs.h @@ -190,10 +190,7 @@ public: virtual void getBookPage ( Ledger::pointer lpLedger, - Currency const& uTakerPaysCurrencyID, - Account const& uTakerPaysIssuerID, - Currency const& uTakerGetsCurrencyID, - Account const& uTakerGetsIssuerID, + Book const& book, Account const& uTakerID, bool const bProof, const unsigned int iLimit, @@ -232,7 +229,8 @@ public: virtual bool shouldFetchPack (std::uint32_t seq) = 0; virtual void gotFetchPack (bool progress, std::uint32_t seq) = 0; - virtual void addFetchPack (uint256 const& hash, std::shared_ptr< Blob >& data) = 0; + virtual void addFetchPack ( + uint256 const& hash, std::shared_ptr< Blob >& data) = 0; virtual bool getFetchPack (uint256 const& hash, Blob& data) = 0; virtual int getFetchSize () = 0; virtual void sweepFetchPack () = 0; @@ -242,7 +240,8 @@ public: virtual void setStandAlone () = 0; virtual void setStateTimer () = 0; - virtual void newLCL (int proposers, int convergeTime, uint256 const& ledgerHash) = 0; + virtual void newLCL ( + int proposers, int convergeTime, uint256 const& ledgerHash) = 0; // VFALCO TODO rename to setNeedNetworkLedger virtual void needNetworkLedger () = 0; virtual void clearNeedNetworkLedger () = 0; @@ -287,18 +286,29 @@ public: bool count, bool bAdmin) = 0; // client information retrieval functions - typedef std::vector< std::pair > AccountTxs; - virtual AccountTxs getAccountTxs (const RippleAddress& account, - std::int32_t minLedger, std::int32_t maxLedger, bool descending, std::uint32_t offset, - int limit, bool bAdmin) = 0; + typedef std::vector< + std::pair > + AccountTxs; - typedef std::vector< std::pair > TxsAccount; - virtual TxsAccount getTxsAccount (const RippleAddress& account, - std::int32_t minLedger, std::int32_t maxLedger, bool forward, Json::Value& token, - int limit, bool bAdmin) = 0; + virtual AccountTxs getAccountTxs ( + const RippleAddress& account, + std::int32_t minLedger, std::int32_t maxLedger, bool descending, + std::uint32_t offset, int limit, bool bAdmin) = 0; + + typedef std::vector< + std::pair > + TxsAccount; + + virtual TxsAccount getTxsAccount ( + const RippleAddress& account, + std::int32_t minLedger, std::int32_t maxLedger, bool forward, + Json::Value& token, int limit, bool bAdmin) = 0; + + typedef std::tuple + txnMetaLedgerType; - typedef std::tuple txnMetaLedgerType; typedef std::vector MetaTxsList; + virtual MetaTxsList getAccountTxsB (const RippleAddress& account, std::int32_t minLedger, std::int32_t maxLedger, bool descending, std::uint32_t offset, int limit, bool bAdmin) = 0; @@ -307,7 +317,8 @@ public: std::int32_t minLedger, std::int32_t maxLedger, bool forward, Json::Value& token, int limit, bool bAdmin) = 0; - virtual std::vector getLedgerAffectedAccounts (std::uint32_t ledgerSeq) = 0; + virtual std::vector getLedgerAffectedAccounts ( + std::uint32_t ledgerSeq) = 0; //-------------------------------------------------------------------------- // diff --git a/src/ripple/module/app/misc/OrderBook.h b/src/ripple/module/app/misc/OrderBook.h index 062e4f54e4..9663999f7d 100644 --- a/src/ripple/module/app/misc/OrderBook.h +++ b/src/ripple/module/app/misc/OrderBook.h @@ -28,55 +28,53 @@ class OrderBook : beast::LeakChecked public: typedef std::shared_ptr pointer; typedef std::shared_ptr const& ref; + typedef std::vector List; public: /** Construct from a currency specification. @param index ??? - @param currencyIn The base currency. - @param currencyOut The destination currency. - @param issuerIn The base issuer. - @param issuerOut The destination issuer. + @param book in and out currency/issuer pairs. */ // VFALCO NOTE what is the meaning of the index parameter? - // VFALCO TODO Replace with Issue - OrderBook (uint256 const& index, - Currency const& currencyIn, - Currency const& currencyOut, - Account const& issuerIn, - Account const& issuerOut); + OrderBook (uint256 const& base, Book const& book) + : mBookBase(base), mBook(book) + { + } uint256 const& getBookBase () const { return mBookBase; } + Book const& book() const + { + return mBook; + } + Currency const& getCurrencyIn () const { - return mCurrencyIn; + return mBook.in.currency; } Currency const& getCurrencyOut () const { - return mCurrencyOut; + return mBook.out.currency; } Account const& getIssuerIn () const { - return mIssuerIn; + return mBook.in.account; } Account const& getIssuerOut () const { - return mIssuerOut; + return mBook.out.account; } private: uint256 const mBookBase; - Currency const mCurrencyIn; - Currency const mCurrencyOut; - Account const mIssuerIn; - Account const mIssuerOut; + Book const mBook; }; } // ripple diff --git a/src/ripple/module/app/paths/CalcNodeAdvance.cpp b/src/ripple/module/app/paths/CalcNodeAdvance.cpp index 284d78fbf3..2bc35b393f 100644 --- a/src/ripple/module/app/paths/CalcNodeAdvance.cpp +++ b/src/ripple/module/app/paths/CalcNodeAdvance.cpp @@ -71,10 +71,9 @@ TER nodeAdvance ( { // Need to initialize current node. - node.currentDirectory_.copyFrom(Ledger::getBookBase ( - previousNode.currency_, previousNode.issuer_, - node.currency_, - node.issuer_)); + node.currentDirectory_.copyFrom(Ledger::getBookBase ({ + {previousNode.currency_, previousNode.issuer_}, + {node.currency_, node.issuer_}})); node.nextDirectory_.copyFrom( Ledger::getQualityNext (node.currentDirectory_)); diff --git a/src/ripple/module/app/paths/Pathfinder.cpp b/src/ripple/module/app/paths/Pathfinder.cpp index 00071dddf6..785cc36bb4 100644 --- a/src/ripple/module/app/paths/Pathfinder.cpp +++ b/src/ripple/module/app/paths/Pathfinder.cpp @@ -787,7 +787,7 @@ void Pathfinder::addLink( { // add order books if (addFlags & afOB_XRP) { // to XRP only - if (!bOnXRP && getApp().getOrderBookDB().isBookToXRP(uEndIssuer, uEndCurrency)) + if (!bOnXRP && getApp().getOrderBookDB().isBookToXRP({uEndCurrency, uEndIssuer})) { STPathElement pathElement( STPathElement::typeCurrency, @@ -799,7 +799,7 @@ void Pathfinder::addLink( { bool bDestOnly = (addFlags & afOB_LAST) != 0; std::vector books; - getApp().getOrderBookDB().getBooksByTakerPays(uEndIssuer, uEndCurrency, books); + getApp().getOrderBookDB().getBooksByTakerPays({uEndCurrency, uEndIssuer}, books); WriteLog (lsTRACE, Pathfinder) << books.size() << " books found from this currency/issuer"; BOOST_FOREACH(OrderBook::ref book, books) { diff --git a/src/ripple/module/app/transactors/CreateOffer.cpp b/src/ripple/module/app/transactors/CreateOffer.cpp index d07e152eed..a68f5bedcf 100644 --- a/src/ripple/module/app/transactors/CreateOffer.cpp +++ b/src/ripple/module/app/transactors/CreateOffer.cpp @@ -442,8 +442,8 @@ CreateOffer::doApply () view.ownerCountAdjust (mTxnAccountID, 1, sleCreator); uint256 const uBookBase (Ledger::getBookBase ( - uPaysCurrency, uPaysIssuerID, - uGetsCurrency, uGetsIssuerID)); + {{uPaysCurrency, uPaysIssuerID}, + {uGetsCurrency, uGetsIssuerID}})); if (m_journal.debug) m_journal.debug << "adding to book: " << to_string (uBookBase) << diff --git a/src/ripple/module/net/rpc/InfoSub.cpp b/src/ripple/module/net/rpc/InfoSub.cpp index de2b4f3a71..76e1d79a8e 100644 --- a/src/ripple/module/net/rpc/InfoSub.cpp +++ b/src/ripple/module/net/rpc/InfoSub.cpp @@ -62,7 +62,8 @@ Resource::Consumer& InfoSub::getConsumer() return m_consumer; } -void InfoSub::send (const Json::Value& jvObj, const std::string& sObj, bool broadcast) +void InfoSub::send ( + const Json::Value& jvObj, const std::string& sObj, bool broadcast) { send (jvObj, broadcast); } @@ -76,7 +77,8 @@ void InfoSub::onSendEmpty () { } -void InfoSub::insertSubAccountInfo (RippleAddress addr, std::uint32_t uLedgerIndex) +void InfoSub::insertSubAccountInfo ( + RippleAddress addr, std::uint32_t uLedgerIndex) { ScopedLockType sl (mLock); diff --git a/src/ripple/module/net/rpc/InfoSub.h b/src/ripple/module/net/rpc/InfoSub.h index adf4b33923..2c1986aae2 100644 --- a/src/ripple/module/net/rpc/InfoSub.h +++ b/src/ripple/module/net/rpc/InfoSub.h @@ -63,30 +63,19 @@ public: bool rt) = 0; // VFALCO TODO Document the bool return value - virtual bool subLedger (ref ispListener, - Json::Value& jvResult) = 0; - + virtual bool subLedger (ref ispListener, Json::Value& jvResult) = 0; virtual bool unsubLedger (std::uint64_t uListener) = 0; - virtual bool subServer (ref ispListener, - Json::Value& jvResult) = 0; - + virtual bool subServer (ref ispListener, Json::Value& jvResult) = 0; virtual bool unsubServer (std::uint64_t uListener) = 0; - virtual bool subBook (ref ispListener, - Currency const& currencyPays, Currency const& currencyGets, - Account const& issuerPays, Account const& issuerGets) = 0; - - virtual bool unsubBook (std::uint64_t uListener, - Currency const& currencyPays, Currency const& currencyGets, - Account const& issuerPays, Account const& issuerGets) = 0; + virtual bool subBook (ref ispListener, Book const&) = 0; + virtual bool unsubBook (std::uint64_t uListener, Book const&) = 0; virtual bool subTransactions (ref ispListener) = 0; - virtual bool unsubTransactions (std::uint64_t uListener) = 0; virtual bool subRTTransactions (ref ispListener) = 0; - virtual bool unsubRTTransactions (std::uint64_t uListener) = 0; // VFALCO TODO Remove @@ -94,7 +83,6 @@ public: // "pushes" subscription data to a particular URL. // virtual pointer findRpcSub (const std::string& strUrl) = 0; - virtual pointer addRpcSub (const std::string& strUrl, ref rspEntry) = 0; }; @@ -108,7 +96,8 @@ public: virtual void send (const Json::Value & jvObj, bool broadcast) = 0; // VFALCO NOTE Why is this virtual? - virtual void send (const Json::Value & jvObj, const std::string & sObj, bool broadcast); + virtual void send ( + const Json::Value & jvObj, const std::string & sObj, bool broadcast); std::uint64_t getSeq (); diff --git a/src/ripple/module/rpc/handlers/BookOffers.cpp b/src/ripple/module/rpc/handlers/BookOffers.cpp index b96a2289d4..2727b6b9cc 100644 --- a/src/ripple/module/rpc/handlers/BookOffers.cpp +++ b/src/ripple/module/rpc/handlers/BookOffers.cpp @@ -161,9 +161,11 @@ Json::Value doBookOffers (RPC::Context& context) return RPC::make_error (rpcBAD_MARKET); } - if (context.params_.isMember ("limit") && ! context.params_ ["limit"].isIntegral()) - return RPC::expected_field_error ( - "limit", "integer"); + if (context.params_.isMember ("limit") && + !context.params_ ["limit"].isIntegral()) + { + return RPC::expected_field_error ("limit", "integer"); + } unsigned int const iLimit (context.params_.isMember ("limit") ? context.params_ ["limit"].asUInt () @@ -175,9 +177,10 @@ Json::Value doBookOffers (RPC::Context& context) ? context.params_["marker"] : Json::Value (Json::nullValue)); - context.netOps_.getBookPage (lpLedger, pay_currency, pay_issuer, - get_currency, get_issuer, raTakerID.getAccountID (), - bProof, iLimit, jvMarker, jvResult); + context.netOps_.getBookPage ( + lpLedger, + {{pay_currency, pay_issuer}, {get_currency, get_issuer}}, + raTakerID.getAccountID (), bProof, iLimit, jvMarker, jvResult); context.loadType_ = Resource::feeMediumBurdenRPC; diff --git a/src/ripple/module/rpc/handlers/Subscribe.cpp b/src/ripple/module/rpc/handlers/Subscribe.cpp index d0a957b610..c0245d802b 100644 --- a/src/ripple/module/rpc/handlers/Subscribe.cpp +++ b/src/ripple/module/rpc/handlers/Subscribe.cpp @@ -27,14 +27,16 @@ Json::Value doSubscribe (RPC::Context& context) InfoSub::pointer ispSub; Json::Value jvResult (Json::objectValue); - std::uint32_t uLedgerIndex = context.params_.isMember (jss::ledger_index) && context.params_[jss::ledger_index].isNumeric () - ? context.params_[jss::ledger_index].asUInt () - : 0; + std::uint32_t uLedgerIndex = context.params_.isMember (jss::ledger_index) + && context.params_[jss::ledger_index].isNumeric () + ? context.params_[jss::ledger_index].asUInt () + : 0; if (!context.infoSub_ && !context.params_.isMember ("url")) { // Must be a JSON-RPC call. - WriteLog (lsINFO, RPCHandler) << boost::str (boost::format ("doSubscribe: RPC subscribe requires a url")); + WriteLog (lsINFO, RPCHandler) + << "doSubscribe: RPC subscribe requires a url"; return rpcError (rpcINVALID_PARAMS); } @@ -45,8 +47,10 @@ Json::Value doSubscribe (RPC::Context& context) return rpcError (rpcNO_PERMISSION); std::string strUrl = context.params_["url"].asString (); - std::string strUsername = context.params_.isMember ("url_username") ? context.params_["url_username"].asString () : ""; - std::string strPassword = context.params_.isMember ("url_password") ? context.params_["url_password"].asString () : ""; + std::string strUsername = context.params_.isMember ("url_username") ? + context.params_["url_username"].asString () : ""; + std::string strPassword = context.params_.isMember ("url_password") ? + context.params_["url_password"].asString () : ""; // DEPRECATED if (context.params_.isMember ("username")) @@ -60,16 +64,19 @@ Json::Value doSubscribe (RPC::Context& context) if (!ispSub) { - WriteLog (lsDEBUG, RPCHandler) << boost::str (boost::format ("doSubscribe: building: %s") % strUrl); + WriteLog (lsDEBUG, RPCHandler) + << "doSubscribe: building: " << strUrl; RPCSub::pointer rspSub = RPCSub::New (getApp ().getOPs (), getApp ().getIOService (), getApp ().getJobQueue (), strUrl, strUsername, strPassword); - ispSub = context.netOps_.addRpcSub (strUrl, std::dynamic_pointer_cast (rspSub)); + ispSub = context.netOps_.addRpcSub ( + strUrl, std::dynamic_pointer_cast (rspSub)); } else { - WriteLog (lsTRACE, RPCHandler) << boost::str (boost::format ("doSubscribe: reusing: %s") % strUrl); + WriteLog (lsTRACE, RPCHandler) + << "doSubscribe: reusing: " << strUrl; if (context.params_.isMember ("username")) dynamic_cast (&*ispSub)->setUsername (strUsername); @@ -88,17 +95,18 @@ Json::Value doSubscribe (RPC::Context& context) } else if (!context.params_["streams"].isArray ()) { - WriteLog (lsINFO, RPCHandler) << boost::str (boost::format ("doSubscribe: streams requires an array.")); + WriteLog (lsINFO, RPCHandler) + << "doSubscribe: streams requires an array."; return rpcError (rpcINVALID_PARAMS); } else { - for (Json::Value::iterator it = context.params_["streams"].begin (); it != context.params_["streams"].end (); it++) + for (auto& it: context.params_["streams"]) { - if ((*it).isString ()) + if (it.isString ()) { - std::string streamName = (*it).asString (); + std::string streamName = it.asString (); if (streamName == "server") { @@ -129,9 +137,9 @@ Json::Value doSubscribe (RPC::Context& context) } } - std::string strAccountsProposed = context.params_.isMember ("accounts_proposed") - ? "accounts_proposed" - : "rt_accounts"; // DEPRECATED + std::string strAccountsProposed = + context.params_.isMember ("accounts_proposed") + ? "accounts_proposed" : "rt_accounts"; // DEPRECATED if (!context.params_.isMember (strAccountsProposed)) { @@ -142,16 +150,12 @@ Json::Value doSubscribe (RPC::Context& context) } else { - ripple::unordered_set usnaAccoundIds = RPC::parseAccountIds (context.params_[strAccountsProposed]); + auto ids = RPC::parseAccountIds (context.params_[strAccountsProposed]); - if (usnaAccoundIds.empty ()) - { - jvResult[jss::error] = "malformedAccount"; - } + if (ids.empty ()) + jvResult[jss::error] = "malformedAccount"; else - { - context.netOps_.subAccount (ispSub, usnaAccoundIds, uLedgerIndex, true); - } + context.netOps_.subAccount (ispSub, ids, uLedgerIndex, true); } if (!context.params_.isMember ("accounts")) @@ -163,17 +167,17 @@ Json::Value doSubscribe (RPC::Context& context) } else { - ripple::unordered_set usnaAccoundIds = RPC::parseAccountIds (context.params_["accounts"]); + auto ids = RPC::parseAccountIds (context.params_["accounts"]); - if (usnaAccoundIds.empty ()) + if (ids.empty ()) { jvResult[jss::error] = "malformedAccount"; } else { - context.netOps_.subAccount (ispSub, usnaAccoundIds, uLedgerIndex, false); - - WriteLog (lsDEBUG, RPCHandler) << boost::str (boost::format ("doSubscribe: accounts: %d") % usnaAccoundIds.size ()); + context.netOps_.subAccount (ispSub, ids, uLedgerIndex, false); + WriteLog (lsDEBUG, RPCHandler) + << "doSubscribe: accounts: " << ids.size (); } } @@ -187,34 +191,32 @@ Json::Value doSubscribe (RPC::Context& context) } else { - for (Json::Value::iterator it = context.params_["books"].begin (); it != context.params_["books"].end (); it++) + for (auto& j: context.params_["books"]) { - Json::Value& jvSubRequest = *it; - - if (!jvSubRequest.isObject () - || !jvSubRequest.isMember (jss::taker_pays) - || !jvSubRequest.isMember (jss::taker_gets) - || !jvSubRequest[jss::taker_pays].isObject () - || !jvSubRequest[jss::taker_gets].isObject ()) + if (!j.isObject () + || !j.isMember (jss::taker_pays) + || !j.isMember (jss::taker_gets) + || !j[jss::taker_pays].isObject () + || !j[jss::taker_gets].isObject ()) return rpcError (rpcINVALID_PARAMS); - // VFALCO TODO Use Issue here - Currency pay_currency; - Account pay_issuer; - Currency get_currency; - Account get_issuer; + Book book; + bool bBoth = + (j.isMember ("both") && j["both"].asBool ()) || + (j.isMember ("both_sides") && j["both_sides"].asBool ()); + bool bSnapshot = + (j.isMember ("snapshot") && j["snapshot"].asBool ()) || + (j.isMember ("state_now") && j["state_now"].asBool ()); + // TODO(tom): both_sides and state_now are apparently deprecated... + // where is this documented? - bool bBoth = (jvSubRequest.isMember ("both") && jvSubRequest["both"].asBool ()) - || (jvSubRequest.isMember ("both_sides") && jvSubRequest["both_sides"].asBool ()); // DEPRECATED - bool bSnapshot = (jvSubRequest.isMember ("snapshot") && jvSubRequest["snapshot"].asBool ()) - || (jvSubRequest.isMember ("state_now") && jvSubRequest["state_now"].asBool ()); // DEPRECATED - - Json::Value taker_pays = jvSubRequest[jss::taker_pays]; - Json::Value taker_gets = jvSubRequest[jss::taker_gets]; + Json::Value taker_pays = j[jss::taker_pays]; + Json::Value taker_gets = j[jss::taker_gets]; // Parse mandatory currency. if (!taker_pays.isMember (jss::currency) - || !to_currency (pay_currency, taker_pays[jss::currency].asString ())) + || !to_currency (book.in.currency, + taker_pays[jss::currency].asString ())) { WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency."; @@ -223,10 +225,11 @@ Json::Value doSubscribe (RPC::Context& context) // Parse optional issuer. else if (((taker_pays.isMember (jss::issuer)) && (!taker_pays[jss::issuer].isString () - || !to_issuer (pay_issuer, taker_pays[jss::issuer].asString ()))) + || !to_issuer (book.in.account, + taker_pays[jss::issuer].asString ()))) // Don't allow illegal issuers. - || (!pay_currency != !pay_issuer) - || noAccount() == pay_issuer) + || (!book.in.currency != !book.in.account) + || noAccount() == book.in.account) { WriteLog (lsINFO, RPCHandler) << "Bad taker_pays issuer."; @@ -235,7 +238,8 @@ Json::Value doSubscribe (RPC::Context& context) // Parse mandatory currency. if (!taker_gets.isMember (jss::currency) - || !to_currency (get_currency, taker_gets[jss::currency].asString ())) + || !to_currency (book.out.currency, + taker_gets[jss::currency].asString ())) { WriteLog (lsINFO, RPCHandler) << "Bad taker_pays currency."; @@ -244,18 +248,19 @@ Json::Value doSubscribe (RPC::Context& context) // Parse optional issuer. else if (((taker_gets.isMember (jss::issuer)) && (!taker_gets[jss::issuer].isString () - || !to_issuer (get_issuer, taker_gets[jss::issuer].asString ()))) + || !to_issuer (book.out.account, + taker_gets[jss::issuer].asString ()))) // Don't allow illegal issuers. - || (!get_currency != !get_issuer) - || noAccount() == get_issuer) + || (!book.out.currency != !book.out.account) + || noAccount() == book.out.account) { WriteLog (lsINFO, RPCHandler) << "Bad taker_gets issuer."; return rpcError (rpcDST_ISR_MALFORMED); } - if (pay_currency == get_currency - && pay_issuer == get_issuer) + if (book.in.currency == book.out.currency + && book.in.account == book.out.account) { WriteLog (lsINFO, RPCHandler) << "taker_gets same as taker_pays."; @@ -264,26 +269,21 @@ Json::Value doSubscribe (RPC::Context& context) RippleAddress raTakerID; - if (!jvSubRequest.isMember ("taker")) - { + if (!j.isMember ("taker")) raTakerID.setAccountID (noAccount()); - } - else if (!raTakerID.setAccountID (jvSubRequest["taker"].asString ())) - { + else if (!raTakerID.setAccountID (j["taker"].asString ())) return rpcError (rpcBAD_ISSUER); - } - if (!Ledger::isValidBook (pay_currency, pay_issuer, get_currency, get_issuer)) + if (!isConsistent (book)) { - WriteLog (lsWARNING, RPCHandler) << "Bad market: " << - pay_currency << ":" << pay_issuer << " -> " << - get_currency << ":" << get_issuer; + WriteLog (lsWARNING, RPCHandler) << "Bad market: " << book; return rpcError (rpcBAD_MARKET); } - context.netOps_.subBook (ispSub, pay_currency, get_currency, pay_issuer, get_issuer); + context.netOps_.subBook (ispSub, book); - if (bBoth) context.netOps_.subBook (ispSub, get_currency, pay_currency, get_issuer, pay_issuer); + if (bBoth) + context.netOps_.subBook (ispSub, book); if (bSnapshot) { @@ -294,27 +294,36 @@ Json::Value doSubscribe (RPC::Context& context) } context.loadType_ = Resource::feeMediumBurdenRPC; - Ledger::pointer lpLedger = getApp().getLedgerMaster ().getPublishedLedger (); + auto lpLedger = getApp().getLedgerMaster (). + getPublishedLedger (); if (lpLedger) { - const Json::Value jvMarker = Json::Value (Json::nullValue); + const Json::Value jvMarker = Json::Value (Json::nullValue); if (bBoth) { Json::Value jvBids (Json::objectValue); Json::Value jvAsks (Json::objectValue); - context.netOps_.getBookPage (lpLedger, pay_currency, pay_issuer, get_currency, get_issuer, raTakerID.getAccountID (), false, 0, jvMarker, jvBids); + context.netOps_.getBookPage ( + lpLedger, book, raTakerID.getAccountID (), false, 0, + jvMarker, jvBids); - if (jvBids.isMember (jss::offers)) jvResult[jss::bids] = jvBids[jss::offers]; + if (jvBids.isMember (jss::offers)) + jvResult[jss::bids] = jvBids[jss::offers]; - context.netOps_.getBookPage (lpLedger, get_currency, get_issuer, pay_currency, pay_issuer, raTakerID.getAccountID (), false, 0, jvMarker, jvAsks); + context.netOps_.getBookPage ( + lpLedger, book, raTakerID.getAccountID (), + false, 0, jvMarker, jvAsks); - if (jvAsks.isMember (jss::offers)) jvResult[jss::asks] = jvAsks[jss::offers]; + if (jvAsks.isMember (jss::offers)) + jvResult[jss::asks] = jvAsks[jss::offers]; } else { - context.netOps_.getBookPage (lpLedger, pay_currency, pay_issuer, get_currency, get_issuer, raTakerID.getAccountID (), false, 0, jvMarker, jvResult); + context.netOps_.getBookPage ( + lpLedger, book, raTakerID.getAccountID (), false, 0, + jvMarker, jvResult); } } } diff --git a/src/ripple/module/rpc/handlers/Unsubscribe.cpp b/src/ripple/module/rpc/handlers/Unsubscribe.cpp index 44fb1b5a6f..59cf8a4d1c 100644 --- a/src/ripple/module/rpc/handlers/Unsubscribe.cpp +++ b/src/ripple/module/rpc/handlers/Unsubscribe.cpp @@ -203,18 +203,11 @@ Json::Value doUnsubscribe (RPC::Context& context) return rpcError (rpcBAD_MARKET); } - context.netOps_.unsubBook ( - ispSub->getSeq (), - pay_currency, get_currency, - pay_issuer, get_issuer); + Book book{{pay_currency, pay_issuer}, {get_currency, get_issuer}}; + context.netOps_.unsubBook (ispSub->getSeq (), book); if (bBoth) - { - context.netOps_.unsubBook ( - ispSub->getSeq (), - get_currency, pay_currency, - get_issuer, pay_issuer); - } + context.netOps_.unsubBook (ispSub->getSeq (), book); } } diff --git a/src/ripple/types/api/Book.h b/src/ripple/types/api/Book.h index 554f1feaae..bf7a7f7f05 100644 --- a/src/ripple/types/api/Book.h +++ b/src/ripple/types/api/Book.h @@ -66,6 +66,13 @@ public: } }; +template +bool isConsistent(BookType const& book) +{ + return isConsistent(book.in) && isConsistent (book.out) + && book.in != book.out; +} + template std::string to_string (BookType const& book) { diff --git a/src/ripple/types/api/Issue.h b/src/ripple/types/api/Issue.h index caaf402851..a077c5fb77 100644 --- a/src/ripple/types/api/Issue.h +++ b/src/ripple/types/api/Issue.h @@ -83,6 +83,13 @@ bool isConsistent(IssueType const& ac) return isXRP (ac.currency) == isXRP (ac.account); } +template +bool isXRP(IssueType const& ac) +{ + // Assumes that isConsistent() is true. + return isXRP (ac.currency); +} + template std::string to_string (IssueType const& ac) { diff --git a/src/ripple/unity/app1.cpp b/src/ripple/unity/app1.cpp index c47aa76a26..27e29bcb84 100644 --- a/src/ripple/unity/app1.cpp +++ b/src/ripple/unity/app1.cpp @@ -32,7 +32,6 @@ #include #include -#include #include #include #include diff --git a/src/ripple/unity/app2.cpp b/src/ripple/unity/app2.cpp index 27906c57b5..4808470b6a 100644 --- a/src/ripple/unity/app2.cpp +++ b/src/ripple/unity/app2.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include