diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index c1ae7567b6..8eb6924edc 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -65,27 +65,15 @@ Ledger::Ledger (uint256 const& parentHash, updateHash(); loaded = true; - try - { - if (mTransHash.isNonZero()) - mTransactionMap->fetchRoot(mTransHash, NULL); - } - catch (...) + if (mTransHash.isNonZero() && !mTransactionMap->fetchRoot(mTransHash, NULL)) { loaded = false; - WriteLog (lsWARNING, Ledger) << "Don't have TX root for ledger"; } - try - { - if (mAccountHash.isNonZero()) - mAccountStateMap->fetchRoot(mAccountHash, NULL); - } - catch (...) + if (mAccountHash.isNonZero() && !mAccountStateMap->fetchRoot(mAccountHash, NULL)) { loaded = false; - WriteLog (lsWARNING, Ledger) << "Don't have AS root for ledger"; } diff --git a/src/cpp/ripple/ripple_LedgerAcquire.cpp b/src/cpp/ripple/ripple_LedgerAcquire.cpp index 54e2f6a96e..faf174fbfd 100644 --- a/src/cpp/ripple/ripple_LedgerAcquire.cpp +++ b/src/cpp/ripple/ripple_LedgerAcquire.cpp @@ -77,10 +77,9 @@ bool LedgerAcquire::tryLocal() } else { - try + TransactionStateSF filter(mLedger->getLedgerSeq()); + if (mLedger->peekTransactionMap()->fetchRoot(mLedger->getTransHash(), &filter)) { - TransactionStateSF filter(mLedger->getLedgerSeq()); - mLedger->peekTransactionMap()->fetchRoot(mLedger->getTransHash(), &filter); WriteLog (lsTRACE, LedgerAcquire) << "Got root txn map locally"; std::vector h = mLedger->getNeededTransactionHashes(1, &filter); if (h.empty()) @@ -89,9 +88,6 @@ bool LedgerAcquire::tryLocal() mHaveTransactions = true; } } - catch (SHAMapMissingNode&) - { - } } } @@ -104,10 +100,9 @@ bool LedgerAcquire::tryLocal() } else { - try + AccountStateSF filter(mLedger->getLedgerSeq()); + if (mLedger->peekAccountStateMap()->fetchRoot(mLedger->getAccountHash(), &filter)) { - AccountStateSF filter(mLedger->getLedgerSeq()); - mLedger->peekAccountStateMap()->fetchRoot(mLedger->getAccountHash(), &filter); WriteLog (lsTRACE, LedgerAcquire) << "Got root AS map locally"; std::vector h = mLedger->getNeededAccountStateHashes(1, &filter); if (h.empty()) @@ -116,9 +111,6 @@ bool LedgerAcquire::tryLocal() mHaveState = true; } } - catch (SHAMapMissingNode&) - { - } } } diff --git a/src/cpp/ripple/ripple_SHAMap.cpp b/src/cpp/ripple/ripple_SHAMap.cpp index 4131933219..1715668130 100644 --- a/src/cpp/ripple/ripple_SHAMap.cpp +++ b/src/cpp/ripple/ripple_SHAMap.cpp @@ -203,36 +203,46 @@ SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, uint256 const& has } SHAMapTreeNode* SHAMap::getNodePointer(const SHAMapNode& id, uint256 const& hash) +{ // fast, but you do not hold a reference + SHAMapTreeNode* ret = getNodePointerNT(id, hash); + if (!ret) + throw SHAMapMissingNode(mType, id, hash); + return ret; +} + +SHAMapTreeNode* SHAMap::getNodePointerNT(const SHAMapNode& id, uint256 const& hash) { // fast, but you do not hold a reference boost::unordered_map::iterator it = mTNByID.find(id); if (it != mTNByID.end()) return it->second.get(); - return fetchNodeExternal(id, hash).get(); + return fetchNodeExternalNT(id, hash).get(); } SHAMapTreeNode* SHAMap::getNodePointer(const SHAMapNode& id, uint256 const& hash, SHAMapSyncFilter* filter) { - try + SHAMapTreeNode* ret = getNodePointerNT(id, hash, filter); + if (!ret) + throw SHAMapMissingNode(mType, id, hash); + return ret; +} + +SHAMapTreeNode* SHAMap::getNodePointerNT(const SHAMapNode& id, uint256 const& hash, SHAMapSyncFilter* filter) +{ + SHAMapTreeNode* node = getNodePointerNT(id, hash); + if (!node && filter) { - return getNodePointer(id, hash); - } - catch (SHAMapMissingNode) - { - if (filter) + Blob nodeData; + if (filter->haveNode(id, hash, nodeData)) { - Blob nodeData; - if (filter->haveNode(id, hash, nodeData)) - { - SHAMapTreeNode::pointer node = boost::make_shared( - boost::cref(id), boost::cref(nodeData), mSeq - 1, snfPREFIX, boost::cref(hash), true); - mTNByID[id] = node; - filter->gotNode(true, id, hash, nodeData, node->getType()); - return node.get(); - } + SHAMapTreeNode::pointer node = boost::make_shared( + boost::cref(id), boost::cref(nodeData), mSeq - 1, snfPREFIX, boost::cref(hash), true); + mTNByID[id] = node; + filter->gotNode(true, id, hash, nodeData, node->getType()); + return node.get(); } - throw; } + return node; } @@ -692,8 +702,18 @@ void SHAMapItem::dump() SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, uint256 const& hash) { - if (!theApp->running()) + SHAMapTreeNode::pointer ret = fetchNodeExternalNT(id, hash); + if (!ret) throw SHAMapMissingNode(mType, id, hash); + return ret; +} + +SHAMapTreeNode::pointer SHAMap::fetchNodeExternalNT(const SHAMapNode& id, uint256 const& hash) +{ + SHAMapTreeNode::pointer ret; + + if (!theApp->running()) + return ret; HashedObject::pointer obj(theApp->getHashedObjectStore().retrieve(hash)); if (!obj) @@ -704,13 +724,12 @@ SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, uint256 theApp->getOPs().missingNodeInLedger(mLedgerSeq); mLedgerSeq = 0; } - throw SHAMapMissingNode(mType, id, hash); + return ret; } try { - SHAMapTreeNode::pointer ret = - boost::make_shared(id, obj->getData(), mSeq, snfPREFIX, hash, true); + ret = boost::make_shared(id, obj->getData(), mSeq, snfPREFIX, hash, true); if (id != *ret) { WriteLog (lsFATAL, SHAMap) << "id:" << id << ", got:" << *ret; @@ -733,14 +752,14 @@ SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, uint256 catch (...) { WriteLog (lsWARNING, SHAMap) << "fetchNodeExternal gets an invalid node: " << hash; - throw SHAMapMissingNode(mType, id, hash); + return SHAMapTreeNode::pointer(); } } -void SHAMap::fetchRoot(uint256 const& hash, SHAMapSyncFilter* filter) +bool SHAMap::fetchRoot(uint256 const& hash, SHAMapSyncFilter* filter) { if (hash == root->getNodeHash()) - return; + return true; if (ShouldLog (lsTRACE, SHAMap)) { if (mType == smtTRANSACTION) @@ -750,21 +769,19 @@ void SHAMap::fetchRoot(uint256 const& hash, SHAMapSyncFilter* filter) else WriteLog (lsTRACE, SHAMap) << "Fetch root SHAMap node " << hash; } - try - { - root = fetchNodeExternal(SHAMapNode(), hash); - } - catch (SHAMapMissingNode&) + root = fetchNodeExternalNT(SHAMapNode(), hash); + if (!root) { Blob nodeData; if (!filter || !filter->haveNode(SHAMapNode(), hash, nodeData)) - throw; + return false; root = boost::make_shared(SHAMapNode(), nodeData, mSeq - 1, snfPREFIX, hash, true); mTNByID[*root] = root; filter->gotNode(true, SHAMapNode(), hash, nodeData, root->getType()); } assert(root->getNodeHash() == hash); + return true; } int SHAMap::armDirty() diff --git a/src/cpp/ripple/ripple_SHAMap.h b/src/cpp/ripple/ripple_SHAMap.h index 0616f3261d..71dc6ece11 100644 --- a/src/cpp/ripple/ripple_SHAMap.h +++ b/src/cpp/ripple/ripple_SHAMap.h @@ -41,7 +41,7 @@ public: ScopedLock Lock() const { return ScopedLock(mLock); } bool hasNode(const SHAMapNode& id); - void fetchRoot(uint256 const& hash, SHAMapSyncFilter* filter); + bool fetchRoot(uint256 const& hash, SHAMapSyncFilter* filter); // normal hash access functions bool hasItem(uint256 const& id); @@ -104,7 +104,8 @@ public: uint32 getSeq() { return mSeq; } // overloads for backed maps - boost::shared_ptr fetchNodeExternal(const SHAMapNode& id, uint256 const& hash); + boost::shared_ptr fetchNodeExternal(const SHAMapNode& id, uint256 const& hash); // throws + boost::shared_ptr fetchNodeExternalNT(const SHAMapNode& id, uint256 const& hash); // no throw bool operator==(const SHAMap& s) { return getHash() == s.getHash(); } @@ -143,7 +144,9 @@ private: SHAMapTreeNode::pointer getNode(const SHAMapNode& id); SHAMapTreeNode::pointer getNode(const SHAMapNode& id, uint256 const& hash, bool modify); SHAMapTreeNode* getNodePointer(const SHAMapNode& id, uint256 const& hash); + SHAMapTreeNode* getNodePointerNT(const SHAMapNode& id, uint256 const& hash); SHAMapTreeNode* getNodePointer(const SHAMapNode& id, uint256 const& hash, SHAMapSyncFilter* filter); + SHAMapTreeNode* getNodePointerNT(const SHAMapNode& id, uint256 const& hash, SHAMapSyncFilter* filter); SHAMapTreeNode* firstBelow(SHAMapTreeNode*); SHAMapTreeNode* lastBelow(SHAMapTreeNode*); diff --git a/src/cpp/ripple/ripple_SHAMapSync.cpp b/src/cpp/ripple/ripple_SHAMapSync.cpp index 5468f796f1..67acce088c 100644 --- a/src/cpp/ripple/ripple_SHAMapSync.cpp +++ b/src/cpp/ripple/ripple_SHAMapSync.cpp @@ -43,17 +43,8 @@ void SHAMap::getMissingNodes(std::vector& nodeIDs, std::vectorgetChildNodeID(branch); - SHAMapTreeNode* d = NULL; - try - { - d = getNodePointer(childID, childHash, filter); - if (d->isInner() && !d->isFullBelow()) - { - have_all = false; - stack.push(d); - } - } - catch (SHAMapMissingNode&) + SHAMapTreeNode* d = getNodePointerNT(childID, childHash, filter); + if (!d) { // node is not in the map nodeIDs.push_back(childID); hashes.push_back(childHash); @@ -61,6 +52,11 @@ void SHAMap::getMissingNodes(std::vector& nodeIDs, std::vectorisInner() && !d->isFullBelow()) + { + have_all = false; + stack.push(d); + } } } } @@ -110,23 +106,19 @@ std::vector SHAMap::getNeededHashes(int max, SHAMapSyncFilter* filter) if (!fullBelowCache.isPresent(childHash)) { SHAMapNode childID = node->getChildNodeID(branch); - SHAMapTreeNode* d = NULL; - try + SHAMapTreeNode* d = getNodePointerNT(childID, childHash, filter); + if (!d) { - d = getNodePointer(childID, childHash, filter); - if (d->isInner() && !d->isFullBelow()) - { - have_all = false; - stack.push(d); - } - } - catch (SHAMapMissingNode&) - { // node is not in the map have_all = false; ret.push_back(childHash); if (--max <= 0) return ret; } + else if (d->isInner() && !d->isFullBelow()) + { + have_all = false; + stack.push(d); + } } } } @@ -270,8 +262,7 @@ SHAMapAddNode SHAMap::addRootNode(uint256 const& hash, Blob const& rootNode, SHA return SHAMapAddNode::useful(); } -SHAMapAddNode SHAMap::addKnownNode(const SHAMapNode& node, Blob const& rawNode, - SHAMapSyncFilter* filter) +SHAMapAddNode SHAMap::addKnownNode(const SHAMapNode& node, Blob const& rawNode, SHAMapSyncFilter* filter) { // return value: true=okay, false=error assert(!node.isRoot()); if (!isSynching()) @@ -303,7 +294,7 @@ SHAMapAddNode SHAMap::addKnownNode(const SHAMapNode& node, Blob const& rawNode, { iNode = getNodePointer(iNode->getChildNodeID(branch), iNode->getChildHash(branch), filter); } - catch (SHAMapMissingNode) + catch (SHAMapMissingNode&) { if (iNode->getDepth() != (node.getDepth() - 1)) { // Either this node is broken or we didn't request it (yet)