From 443eef3a9bcce4e4ba457340c3dbadbffefc470e Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 31 Jan 2012 20:07:55 -0800 Subject: [PATCH] Complete the SHAMapSync code. Next step is to finish the testing harness. --- SHAMap.h | 2 + SHAMapNodes.cpp | 10 +++++ SHAMapSync.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/SHAMap.h b/SHAMap.h index d5f8d9fad6..d78a0b28a3 100644 --- a/SHAMap.h +++ b/SHAMap.h @@ -56,7 +56,9 @@ public: bool operator<(const SHAMapNode&) const; bool operator>(const SHAMapNode&) const; bool operator==(const SHAMapNode&) const; + bool operator==(const uint256&) const; bool operator!=(const SHAMapNode&) const; + bool operator!=(const uint256&) const; bool operator<=(const SHAMapNode&) const; bool operator>=(const SHAMapNode&) const; diff --git a/SHAMapNodes.cpp b/SHAMapNodes.cpp index 9adf87e1f9..570538cad8 100644 --- a/SHAMapNodes.cpp +++ b/SHAMapNodes.cpp @@ -55,6 +55,16 @@ bool SHAMapNode::operator!=(const SHAMapNode &s) const return (s.mDepth!=mDepth) || (s.mNodeID!=mNodeID); } +bool SHAMapNode::operator==(const uint256 &s) const +{ + return s==mNodeID; +} + +bool SHAMapNode::operator!=(const uint256 &s) const +{ + return s!=mNodeID; +} + void SHAMapNode::ClassInit() { // set up the depth masks uint256 selector; diff --git a/SHAMapSync.cpp b/SHAMapSync.cpp index 750b4121cb..d11c78f9f3 100644 --- a/SHAMapSync.cpp +++ b/SHAMapSync.cpp @@ -105,15 +105,109 @@ bool SHAMap::getNodeFat(const SHAMapNode& wanted, std::vector& nodeI return ret; } -bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector& rawNode) +bool SHAMap::addRootNode(const uint256& hash, const std::vector& rootNode) { - // WRITEME + boost::recursive_mutex::scoped_lock sl(mLock); + + // we already have a root node + if(root->getNodeHash()!=0) + { +#ifdef DEBUG + std::cerr << "got root node, already have one" << std::endl; +#endif + assert(root->getNodeHash()==hash); + return true; + } + + SHAMapInnerNode::pointer node=SHAMapInnerNode::pointer(new SHAMapInnerNode(SHAMapNode(), rootNode, 0)); + if(!node) return false; + if(node->getNodeHash()!=hash) return false; + + root=node; + mInnerNodeByID[*node]=node; + if(mDirtyInnerNodes) (*mDirtyInnerNodes)[*node]=node; + return true; +} + +bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector& rawNode) +{ // return value: true=okay, false=error + assert(!node.isRoot()); + + boost::recursive_mutex::scoped_lock sl(mLock); + + if(node.isLeaf()) + { + if(checkCacheLeaf(node)) return true; + } + else + { + if(checkCacheNode(node)) return true; + } + + SHAMapInnerNode::pointer iNode=walkTo(node); + if(!iNode) + { // we should always have a root + assert(false); + return true; + } + + if(iNode->getDepth()==node.getDepth()) + { +#ifdef DEBUG + std::cerr << "got inner node, already had it (late)" << std::endl; +#endif + return true; + } + + if(iNode->getDepth()!=(node.getDepth()-1)) + { // Either this node is broken or we didn't request it +#ifdef DEBUG + std::cerr << "got inner node, unable to hook it" << std::endl; +#endif + return false; + } + + int branch=iNode->selectBranch(node.getNodeID()); + if(branch<0) + { + assert(false); + return false; + } + uint256 hash=iNode->getChildHash(branch); + if(!hash) return false; + + if(node.isLeaf()) + { // leaf node + SHAMapLeafNode::pointer leaf=SHAMapLeafNode::pointer(new SHAMapLeafNode(node, rawNode, mSeq)); + if( (leaf->getNodeHash()!=hash) || (node!=(*leaf)) ) + { +#ifdef DEBUG + std::cerr << "leaf fails consistency check" << std::endl; +#endif + return false; + } + mLeafByID[node]=leaf; + if(mDirtyLeafNodes) (*mDirtyLeafNodes)[node]=leaf; + return true; + } + + SHAMapInnerNode::pointer newNode=SHAMapInnerNode::pointer(new SHAMapInnerNode(node, rawNode, mSeq)); + if( (newNode->getNodeHash()!=hash) || (node!=newNode->getNodeID()) ) + { +#ifdef DEBUG + std::cerr << "inner node fails consistency check" << std::endl; +#endif + return false; + } + mInnerNodeByID[node]=newNode; + if(mDirtyInnerNodes) (*mDirtyInnerNodes)[node]=newNode; return true; } bool SHAMap::deepCompare(SHAMap& other) { // Intended for debug/test only std::stack stack; + boost::recursive_mutex::scoped_lock sl(mLock); SHAMapInnerNode::pointer node=root; while(node)