From bb6b72fea40fc56dab6fdcc73994ffe9e12aacc0 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 4 Jan 2013 15:21:02 -0800 Subject: [PATCH] Make a "getNeededHashes" function to get the hashes we need to fill in a ledger hole. --- src/cpp/ripple/SHAMap.h | 1 + src/cpp/ripple/SHAMapSync.cpp | 53 ++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/cpp/ripple/SHAMap.h b/src/cpp/ripple/SHAMap.h index e7d4565588..6071603f58 100644 --- a/src/cpp/ripple/SHAMap.h +++ b/src/cpp/ripple/SHAMap.h @@ -413,6 +413,7 @@ public: bool getNodeFat(const SHAMapNode& node, std::vector& nodeIDs, std::list >& rawNode, bool fatRoot, bool fatLeaves); bool getRootNode(Serializer& s, SHANodeFormat format); + void getNeededHashes(std::vector& hashes, int max); SMAddNode addRootNode(const uint256& hash, const std::vector& rootNode, SHANodeFormat format, SHAMapSyncFilter* filter); SMAddNode addRootNode(const std::vector& rootNode, SHANodeFormat format, diff --git a/src/cpp/ripple/SHAMapSync.cpp b/src/cpp/ripple/SHAMapSync.cpp index 344e2bdc1c..eb5e11b23c 100644 --- a/src/cpp/ripple/SHAMapSync.cpp +++ b/src/cpp/ripple/SHAMapSync.cpp @@ -19,7 +19,7 @@ void SHAMap::getMissingNodes(std::vector& nodeIDs, std::vectorisValid()); - + if (root->isFullBelow()) { clearSynching(); @@ -91,6 +91,57 @@ void SHAMap::getMissingNodes(std::vector& nodeIDs, std::vector& ret, int max) +{ + boost::recursive_mutex::scoped_lock sl(mLock); + + assert(root->isValid()); + + if (root->isFullBelow() || !root->isInner()) + { + clearSynching(); + return; + } + + std::stack stack; + stack.push(root.get()); + + while (!stack.empty()) + { + SHAMapTreeNode* node = stack.top(); + stack.pop(); + + int base = rand() % 256; + bool have_all = false; + for (int ii = 0; ii < 16; ++ii) + { // traverse in semi-random order + int branch = (base + ii) % 16; + if (!node->isEmptyBranch(branch)) + { + SHAMapNode childID = node->getChildNodeID(branch); + const uint256& childHash = node->getChildHash(branch); + SHAMapTreeNode* d; + try + { + d = getNodePointer(childID, childHash); + assert(d); + if (d->isInner() && !d->isFullBelow()) + stack.push(d); + } + catch (SHAMapMissingNode&) + { // node is not in the map + have_all = false; + ret.push_back(childHash); + if (--max <= 0) + return; + } + } + } + if (have_all) + node->setFullBelow(); + } +} + bool SHAMap::getNodeFat(const SHAMapNode& wanted, std::vector& nodeIDs, std::list >& rawNodes, bool fatRoot, bool fatLeaves) { // Gets a node and some of its children