diff --git a/Builds/VisualStudio2015/RippleD.vcxproj b/Builds/VisualStudio2015/RippleD.vcxproj index 3be23550a..a21d354c8 100644 --- a/Builds/VisualStudio2015/RippleD.vcxproj +++ b/Builds/VisualStudio2015/RippleD.vcxproj @@ -789,6 +789,8 @@ + + True True diff --git a/Builds/VisualStudio2015/RippleD.vcxproj.filters b/Builds/VisualStudio2015/RippleD.vcxproj.filters index b2eca3b59..d37cd0fca 100644 --- a/Builds/VisualStudio2015/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2015/RippleD.vcxproj.filters @@ -1311,6 +1311,9 @@ ripple\app\consensus + + ripple\app\ledger + ripple\app\ledger diff --git a/src/ripple/app/ledger/AbstractFetchPackContainer.h b/src/ripple/app/ledger/AbstractFetchPackContainer.h new file mode 100644 index 000000000..819b03e3c --- /dev/null +++ b/src/ripple/app/ledger/AbstractFetchPackContainer.h @@ -0,0 +1,48 @@ +//------------------------------------------------------------------------------ +/* + 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. +*/ +//============================================================================== + +#ifndef RIPPLE_APP_LEDGER_ABSTRACTFETCHPACKCONTAINER_H_INCLUDED +#define RIPPLE_APP_LEDGER_ABSTRACTFETCHPACKCONTAINER_H_INCLUDED + +#include +#include +#include + +namespace ripple { + +/** An interface facilitating retrieval of fetch packs without + an application or ledgermaster object. +*/ +class AbstractFetchPackContainer +{ +public: + virtual ~AbstractFetchPackContainer() = default; + + /** Retrieves partial ledger data of the coresponding hash from peers.` + + @param nodeHash The 256-bit hash of the data to fetch. + @return `boost::none` if the hash isn't cached, + otherwise, the hash associated data. + */ + virtual boost::optional getFetchPack(uint256 const& nodeHash) = 0; +}; + +} // ripple + +#endif diff --git a/src/ripple/app/ledger/AccountStateSF.cpp b/src/ripple/app/ledger/AccountStateSF.cpp index 3b3551b1e..33e3fc044 100644 --- a/src/ripple/app/ledger/AccountStateSF.cpp +++ b/src/ripple/app/ledger/AccountStateSF.cpp @@ -19,17 +19,12 @@ #include #include -#include -#include -#include -#include -#include -#include namespace ripple { -AccountStateSF::AccountStateSF(Application& app) - : app_ (app) +AccountStateSF::AccountStateSF(Family& f, AbstractFetchPackContainer& fp) + : f_(f) + , fp_(fp) { } @@ -38,17 +33,14 @@ void AccountStateSF::gotNode (bool fromFilter, Blob&& nodeData, SHAMapTreeNode::TNType) const { - // VFALCO SHAMapSync filters should be passed the SHAMap, the - // SHAMap should provide an accessor to get the injected Database, - // and this should use that Database instad of getNodeStore - app_.getNodeStore ().store ( - hotACCOUNT_NODE, std::move (nodeData), nodeHash.as_uint256()); + f_.db().store(hotACCOUNT_NODE, std::move(nodeData), + nodeHash.as_uint256()); } -bool AccountStateSF::haveNode (SHAMapHash const& nodeHash, - Blob& nodeData) const +boost::optional +AccountStateSF::getNode(SHAMapHash const& nodeHash) const { - return app_.getLedgerMaster ().getFetchPack (nodeHash.as_uint256(), nodeData); + return fp_.getFetchPack(nodeHash.as_uint256()); } } // ripple diff --git a/src/ripple/app/ledger/AccountStateSF.h b/src/ripple/app/ledger/AccountStateSF.h index 7d27925f2..dd28eb3d2 100644 --- a/src/ripple/app/ledger/AccountStateSF.h +++ b/src/ripple/app/ledger/AccountStateSF.h @@ -20,8 +20,9 @@ #ifndef RIPPLE_APP_LEDGER_ACCOUNTSTATESF_H_INCLUDED #define RIPPLE_APP_LEDGER_ACCOUNTSTATESF_H_INCLUDED -#include +#include #include +#include namespace ripple { @@ -31,11 +32,11 @@ class AccountStateSF : public SHAMapSyncFilter { private: - Application& app_; + Family& f_; + AbstractFetchPackContainer& fp_; public: - explicit - AccountStateSF (Application& app); + AccountStateSF(Family&, AbstractFetchPackContainer&); // Note that the nodeData is overwritten by this call void gotNode (bool fromFilter, @@ -43,8 +44,8 @@ public: Blob&& nodeData, SHAMapTreeNode::TNType) const override; - bool haveNode (SHAMapHash const& nodeHash, - Blob& nodeData) const override; + boost::optional + getNode(SHAMapHash const& nodeHash) const override; }; } // ripple diff --git a/src/ripple/app/ledger/ConsensusTransSetSF.cpp b/src/ripple/app/ledger/ConsensusTransSetSF.cpp index fe6b9bddf..96b7569ca 100644 --- a/src/ripple/app/ledger/ConsensusTransSetSF.cpp +++ b/src/ripple/app/ledger/ConsensusTransSetSF.cpp @@ -75,11 +75,12 @@ void ConsensusTransSetSF::gotNode ( } } -bool ConsensusTransSetSF::haveNode ( - SHAMapHash const& nodeHash, Blob& nodeData) const +boost::optional +ConsensusTransSetSF::getNode (SHAMapHash const& nodeHash) const { + Blob nodeData; if (m_nodeCache.retrieve (nodeHash, nodeData)) - return true; + return nodeData; auto txn = app_.getMasterTransaction().fetch(nodeHash.as_uint256(), false); @@ -93,10 +94,10 @@ bool ConsensusTransSetSF::haveNode ( txn->getSTransaction ()->add (s); assert(sha512Half(s.slice()) == nodeHash.as_uint256()); nodeData = s.peekData (); - return true; + return nodeData; } - return false; + return boost::none; } } // ripple diff --git a/src/ripple/app/ledger/ConsensusTransSetSF.h b/src/ripple/app/ledger/ConsensusTransSetSF.h index c37f6272a..666d3792c 100644 --- a/src/ripple/app/ledger/ConsensusTransSetSF.h +++ b/src/ripple/app/ledger/ConsensusTransSetSF.h @@ -44,8 +44,8 @@ public: Blob&& nodeData, SHAMapTreeNode::TNType) const override; - bool haveNode (SHAMapHash const& nodeHash, - Blob& nodeData) const override; + boost::optional + getNode (SHAMapHash const& nodeHash) const override; private: Application& app_; diff --git a/src/ripple/app/ledger/LedgerMaster.h b/src/ripple/app/ledger/LedgerMaster.h index 05e019acb..3faf3137b 100644 --- a/src/ripple/app/ledger/LedgerMaster.h +++ b/src/ripple/app/ledger/LedgerMaster.h @@ -21,6 +21,7 @@ #define RIPPLE_APP_LEDGER_LEDGERMASTER_H_INCLUDED #include +#include #include #include #include @@ -61,6 +62,7 @@ struct LedgerReplay // class LedgerMaster : public Stoppable + , public AbstractFetchPackContainer { public: explicit @@ -232,9 +234,8 @@ public: uint256 const& hash, std::shared_ptr& data); - bool getFetchPack ( - uint256 const& hash, - Blob& data); + boost::optional + getFetchPack (uint256 const& hash) override; void makeFetchPack ( std::weak_ptr const& wPeer, diff --git a/src/ripple/app/ledger/TransactionStateSF.cpp b/src/ripple/app/ledger/TransactionStateSF.cpp index c2baa57d4..7f1401d20 100644 --- a/src/ripple/app/ledger/TransactionStateSF.cpp +++ b/src/ripple/app/ledger/TransactionStateSF.cpp @@ -19,40 +19,31 @@ #include #include -#include -#include -#include -#include -#include -#include namespace ripple { -TransactionStateSF::TransactionStateSF(Application& app) - : app_ (app) +TransactionStateSF::TransactionStateSF(Family& f, + AbstractFetchPackContainer& fp) + : f_(f) + , fp_(fp) { } -// VFALCO This might be better as Blob&& void TransactionStateSF::gotNode (bool fromFilter, SHAMapHash const& nodeHash, Blob&& nodeData, SHAMapTreeNode::TNType type) const { - // VFALCO SHAMapSync filters should be passed the SHAMap, the - // SHAMap should provide an accessor to get the injected Database, - // and this should use that Database instad of getNodeStore assert(type != SHAMapTreeNode::tnTRANSACTION_NM); - app_.getNodeStore().store( - hotTRANSACTION_NODE, - std::move (nodeData), nodeHash.as_uint256()); + f_.db().store(hotTRANSACTION_NODE, + std::move (nodeData), nodeHash.as_uint256()); } -bool TransactionStateSF::haveNode (SHAMapHash const& nodeHash, - Blob& nodeData) const +boost::optional +TransactionStateSF::getNode(SHAMapHash const& nodeHash) const { - return app_.getLedgerMaster ().getFetchPack (nodeHash.as_uint256(), nodeData); + return fp_.getFetchPack(nodeHash.as_uint256()); } } // ripple diff --git a/src/ripple/app/ledger/TransactionStateSF.h b/src/ripple/app/ledger/TransactionStateSF.h index 9cbe19ffa..9d3474e06 100644 --- a/src/ripple/app/ledger/TransactionStateSF.h +++ b/src/ripple/app/ledger/TransactionStateSF.h @@ -20,8 +20,9 @@ #ifndef RIPPLE_APP_LEDGER_TRANSACTIONSTATESF_H_INCLUDED #define RIPPLE_APP_LEDGER_TRANSACTIONSTATESF_H_INCLUDED -#include +#include #include +#include #include namespace ripple { @@ -32,11 +33,12 @@ class TransactionStateSF : public SHAMapSyncFilter { private: - Application& app_; + Family& f_; + AbstractFetchPackContainer& fp_; public: explicit - TransactionStateSF(Application& app); + TransactionStateSF(Family&, AbstractFetchPackContainer&); // Note that the nodeData is overwritten by this call void gotNode (bool fromFilter, @@ -44,8 +46,8 @@ public: Blob&& nodeData, SHAMapTreeNode::TNType) const override; - bool haveNode (SHAMapHash const& nodeHash, - Blob& nodeData) const override; + boost::optional + getNode(SHAMapHash const& nodeHash) const override; }; } // ripple diff --git a/src/ripple/app/ledger/impl/InboundLedger.cpp b/src/ripple/app/ledger/impl/InboundLedger.cpp index 3819ef388..3e13a611a 100644 --- a/src/ripple/app/ledger/impl/InboundLedger.cpp +++ b/src/ripple/app/ledger/impl/InboundLedger.cpp @@ -246,20 +246,19 @@ bool InboundLedger::tryLocal () if (!node) { - Blob data; - - if (!app_.getLedgerMaster ().getFetchPack (mHash, data)) + auto data = app_.getLedgerMaster().getFetchPack(mHash); + if (! data) return false; JLOG (m_journal.trace()) << "Ledger header found in fetch pack"; mLedger = std::make_shared ( - deserializeHeader (makeSlice(data), true), + deserializeHeader (makeSlice(*data), true), app_.family()); app_.getNodeStore ().store ( - hotLEDGER, std::move (data), mHash); + hotLEDGER, std::move (*data), mHash); } else { @@ -290,7 +289,8 @@ bool InboundLedger::tryLocal () } else { - TransactionStateSF filter(app_); + TransactionStateSF filter(mLedger->txMap().family(), + app_.getLedgerMaster()); if (mLedger->txMap().fetchRoot ( SHAMapHash{mLedger->info().txHash}, &filter)) @@ -316,7 +316,8 @@ bool InboundLedger::tryLocal () return true; } - AccountStateSF filter(app_); + AccountStateSF filter(mLedger->stateMap().family(), + app_.getLedgerMaster()); if (mLedger->stateMap().fetchRoot ( SHAMapHash{mLedger->info().accountHash}, &filter)) @@ -607,7 +608,8 @@ void InboundLedger::trigger (std::shared_ptr const& peer, TriggerReason re } else { - AccountStateSF filter(app_); + AccountStateSF filter(mLedger->stateMap().family(), + app_.getLedgerMaster()); // Release the lock while we process the large state map sl.unlock(); @@ -680,7 +682,8 @@ void InboundLedger::trigger (std::shared_ptr const& peer, TriggerReason re } else { - TransactionStateSF filter(app_); + TransactionStateSF filter(mLedger->txMap().family(), + app_.getLedgerMaster()); auto nodes = mLedger->txMap().getMissingNodes ( missingNodesFind, &filter); @@ -849,21 +852,23 @@ bool InboundLedger::takeTxNode (const std::vector& nodeIDs, auto nodeIDit = nodeIDs.cbegin (); auto nodeDatait = data.begin (); - TransactionStateSF tFilter(app_); + TransactionStateSF filter(mLedger->txMap().family(), + app_.getLedgerMaster()); while (nodeIDit != nodeIDs.cend ()) { if (nodeIDit->isRoot ()) { san += mLedger->txMap().addRootNode ( - SHAMapHash{mLedger->info().txHash}, makeSlice(*nodeDatait), snfWIRE, &tFilter); + SHAMapHash{mLedger->info().txHash}, + makeSlice(*nodeDatait), snfWIRE, &filter); if (!san.isGood()) return false; } else { san += mLedger->txMap().addKnownNode ( - *nodeIDit, makeSlice(*nodeDatait), &tFilter); + *nodeIDit, makeSlice(*nodeDatait), &filter); if (!san.isGood()) return false; } @@ -919,14 +924,16 @@ bool InboundLedger::takeAsNode (const std::vector& nodeIDs, auto nodeIDit = nodeIDs.cbegin (); auto nodeDatait = data.begin (); - AccountStateSF tFilter(app_); + AccountStateSF filter(mLedger->stateMap().family(), + app_.getLedgerMaster()); while (nodeIDit != nodeIDs.cend ()) { if (nodeIDit->isRoot ()) { san += mLedger->stateMap().addRootNode ( - SHAMapHash{mLedger->info().accountHash}, makeSlice(*nodeDatait), snfWIRE, &tFilter); + SHAMapHash{mLedger->info().accountHash}, + makeSlice(*nodeDatait), snfWIRE, &filter); if (!san.isGood ()) { JLOG (m_journal.warn()) << @@ -937,7 +944,7 @@ bool InboundLedger::takeAsNode (const std::vector& nodeIDs, else { san += mLedger->stateMap().addKnownNode ( - *nodeIDit, makeSlice(*nodeDatait), &tFilter); + *nodeIDit, makeSlice(*nodeDatait), &filter); if (!san.isGood ()) { JLOG (m_journal.warn()) << @@ -981,9 +988,10 @@ bool InboundLedger::takeAsRootNode (Slice const& data, SHAMapAddNode& san) return false; } - AccountStateSF tFilter(app_); + AccountStateSF filter(mLedger->stateMap().family(), + app_.getLedgerMaster()); san += mLedger->stateMap().addRootNode ( - SHAMapHash{mLedger->info().accountHash}, data, snfWIRE, &tFilter); + SHAMapHash{mLedger->info().accountHash}, data, snfWIRE, &filter); return san.isGood(); } @@ -1004,9 +1012,10 @@ bool InboundLedger::takeTxRootNode (Slice const& data, SHAMapAddNode& san) return false; } - TransactionStateSF tFilter(app_); + TransactionStateSF filter(mLedger->txMap().family(), + app_.getLedgerMaster()); san += mLedger->txMap().addRootNode ( - SHAMapHash{mLedger->info().txHash}, data, snfWIRE, &tFilter); + SHAMapHash{mLedger->info().txHash}, data, snfWIRE, &filter); return san.isGood(); } @@ -1024,7 +1033,8 @@ InboundLedger::getNeededHashes () if (!mHaveState) { - AccountStateSF filter(app_); + AccountStateSF filter(mLedger->stateMap().family(), + app_.getLedgerMaster()); for (auto const& h : neededStateHashes (4, &filter)) { ret.push_back (std::make_pair ( @@ -1034,7 +1044,8 @@ InboundLedger::getNeededHashes () if (!mHaveTransactions) { - TransactionStateSF filter(app_); + TransactionStateSF filter(mLedger->txMap().family(), + app_.getLedgerMaster()); for (auto const& h : neededTxHashes (4, &filter)) { ret.push_back (std::make_pair ( diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp index a381d92be..827e9b074 100644 --- a/src/ripple/app/ledger/impl/LedgerMaster.cpp +++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp @@ -1779,17 +1779,18 @@ LedgerMaster::addFetchPack ( fetch_packs_.canonicalize (hash, data); } -bool +boost::optional LedgerMaster::getFetchPack ( - uint256 const& hash, - Blob& data) + uint256 const& hash) { - if (!fetch_packs_.retrieve (hash, data)) - return false; - - fetch_packs_.del (hash, false); - - return hash == sha512Half(makeSlice(data)); + Blob data; + if (fetch_packs_.retrieve(hash, data)) + { + fetch_packs_.del(hash, false); + if (hash == sha512Half(makeSlice(data))) + return data; + } + return boost::none; } void diff --git a/src/ripple/shamap/SHAMapSyncFilter.h b/src/ripple/shamap/SHAMapSyncFilter.h index 64e51c07f..786b3d457 100644 --- a/src/ripple/shamap/SHAMapSyncFilter.h +++ b/src/ripple/shamap/SHAMapSyncFilter.h @@ -40,8 +40,9 @@ public: Blob&& nodeData, SHAMapTreeNode::TNType type) const = 0; - virtual bool haveNode (SHAMapHash const& nodeHash, - Blob& nodeData) const = 0; + virtual + boost::optional + getNode(SHAMapHash const& nodeHash) const = 0; }; } diff --git a/src/ripple/shamap/impl/SHAMap.cpp b/src/ripple/shamap/impl/SHAMap.cpp index 0b1188459..5e8ba667e 100644 --- a/src/ripple/shamap/impl/SHAMap.cpp +++ b/src/ripple/shamap/impl/SHAMap.cpp @@ -306,15 +306,14 @@ SHAMap::checkFilter(SHAMapHash const& hash, SHAMapSyncFilter* filter) const { std::shared_ptr node; - Blob nodeData; - if (filter->haveNode (hash, nodeData)) + if (auto nodeData = filter->getNode (hash)) { node = SHAMapAbstractNode::make( - makeSlice(nodeData), 0, snfPREFIX, hash, true, f_.journal ()); + makeSlice(*nodeData), 0, snfPREFIX, hash, true, f_.journal ()); if (node) { filter->gotNode (true, hash, - std::move(nodeData), node->getType ()); + std::move(*nodeData), node->getType ()); if (backed_) canonicalize (hash, node); } diff --git a/src/test/shamap/FetchPack_test.cpp b/src/test/shamap/FetchPack_test.cpp index 47a2a38f4..76f0d3099 100644 --- a/src/test/shamap/FetchPack_test.cpp +++ b/src/test/shamap/FetchPack_test.cpp @@ -66,17 +66,16 @@ public: { } - bool haveNode (SHAMapHash const& nodeHash, - Blob& nodeData) const override + boost::optional + getNode (SHAMapHash const& nodeHash) const override { Map::iterator it = mMap.find (nodeHash); if (it == mMap.end ()) { JLOG(mJournal.fatal()) << "Test filter missing node"; - return false; + return boost::none; } - nodeData = it->second; - return true; + return it->second; } Map& mMap;