Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
Arthur Britto
2012-10-18 12:49:06 -07:00
3 changed files with 57 additions and 3 deletions

View File

@@ -814,6 +814,38 @@ SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& nodeID)
return node;
}
bool SHAMap::getPath(const uint256& index, std::vector< std::vector<unsigned char> >& nodes, SHANodeFormat format)
{
// Return the path of nodes to the specified index in the specified format
// Return value: true = node present, false = node not present
boost::recursive_mutex::scoped_lock sl(mLock);
SHAMapTreeNode* inNode = root.get();
while (!inNode->isLeaf())
{
Serializer s;
inNode->addRaw(s, format);
nodes.push_back(s.peekData());
int branch = inNode->selectBranch(index);
if (inNode->isEmptyBranch(branch)) // paths leads to empty branch
return false;
inNode = getNodePointer(inNode->getChildNodeID(branch), inNode->getChildHash(branch));
if (!inNode)
throw SHAMapMissingNode(mType, inNode->getChildNodeID(branch), inNode->getChildHash(branch), index);
}
if (inNode->getTag() != index) // path leads to different leaf
return false;
// path lead to the requested leaf
Serializer s;
inNode->addRaw(s, format);
nodes.push_back(s.peekData());
return true;
}
void SHAMap::dump(bool hash)
{
#if 0

View File

@@ -125,6 +125,7 @@ enum SHANodeFormat
{
snfPREFIX = 1, // Form that hashes to its official hash
snfWIRE = 2, // Compressed form used on the wire
snfHASH = 3, // just the hash
};
enum SHAMapType
@@ -404,6 +405,8 @@ public:
void walkMap(std::vector<SHAMapMissingNode>& missingNodes, int maxMissing);
bool getPath(const uint256& index, std::vector< std::vector<unsigned char> >& nodes, SHANodeFormat format);
bool deepCompare(SHAMap& other);
virtual void dump(bool withHashes = false);
};

View File

@@ -259,7 +259,7 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& id, const std::vector<unsigned
}
}
if (format == snfPREFIX)
else if (format == snfPREFIX)
{
if (rawNode.size() < 4)
{
@@ -316,6 +316,12 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& id, const std::vector<unsigned
}
}
else
{
assert(false);
throw std::runtime_error("Unknown format");
}
updateHash();
}
@@ -333,7 +339,16 @@ bool SHAMapTreeNode::updateHash()
break;
}
if(!empty)
{
nh = Serializer::getPrefixHash(sHP_InnerNode, reinterpret_cast<unsigned char *>(mHashes), sizeof(mHashes));
#ifdef DEBUG
Serializer s;
s.add32(sHP_InnerNode);
for(int i = 0; i < 16; ++i)
s.add256(mHashes[i]);
assert(nh == s.getSHA512Half());
#endif
}
}
else if (mType == tnTRANSACTION_NM)
{
@@ -366,11 +381,15 @@ bool SHAMapTreeNode::updateHash()
void SHAMapTreeNode::addRaw(Serializer& s, SHANodeFormat format)
{
assert((format == snfPREFIX) || (format == snfWIRE));
assert((format == snfPREFIX) || (format == snfWIRE) || (format == snfHASH));
if (mType == tnERROR)
throw std::runtime_error("invalid I node type");
if (mType == tnINNER)
if (format == snfHASH)
{
s.add256(getNodeHash());
}
else if (mType == tnINNER)
{
assert(!isEmpty());
if (format == snfPREFIX)