Make a "getNeededHashes" function to get the hashes we need to fill in a ledger hole.

This commit is contained in:
JoelKatz
2013-01-04 15:21:02 -08:00
parent 8062c8c959
commit bb6b72fea4
2 changed files with 53 additions and 1 deletions

View File

@@ -413,6 +413,7 @@ public:
bool getNodeFat(const SHAMapNode& node, std::vector<SHAMapNode>& nodeIDs,
std::list<std::vector<unsigned char> >& rawNode, bool fatRoot, bool fatLeaves);
bool getRootNode(Serializer& s, SHANodeFormat format);
void getNeededHashes(std::vector<uint256>& hashes, int max);
SMAddNode addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
SHAMapSyncFilter* filter);
SMAddNode addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format,

View File

@@ -19,7 +19,7 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
boost::recursive_mutex::scoped_lock sl(mLock);
assert(root->isValid());
if (root->isFullBelow())
{
clearSynching();
@@ -91,6 +91,57 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
}
}
void SHAMap::getNeededHashes(std::vector<uint256>& ret, int max)
{
boost::recursive_mutex::scoped_lock sl(mLock);
assert(root->isValid());
if (root->isFullBelow() || !root->isInner())
{
clearSynching();
return;
}
std::stack<SHAMapTreeNode*> 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<SHAMapNode>& nodeIDs,
std::list<std::vector<unsigned char> >& rawNodes, bool fatRoot, bool fatLeaves)
{ // Gets a node and some of its children