From cf471983703ece9e1665e2ff1f46c955e337db8f Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Thu, 14 Jan 2016 15:56:33 -0700 Subject: [PATCH] Fixed a couple incremental merkle tree bugs breaking consistency checks. --- src/coins.cpp | 7 +++---- src/test/coins_tests.cpp | 44 +++++++++++++++++++++++++++++++++++++++- src/wallet/wallet.cpp | 3 +-- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 02f31165c..7ccfc28d1 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -113,14 +113,13 @@ bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMer } } - CAnchorsCacheEntry entry; if (!base->GetAnchorAt(rt, tree)) { return false; } - entry.entered = true; - entry.tree.setTo(tree); - cacheAnchors.insert(std::make_pair(rt, entry)); + CAnchorsMap::iterator ret = cacheAnchors.insert(std::make_pair(rt, CAnchorsCacheEntry())).first; + ret->second.entered = true; + ret->second.tree.setTo(tree); return true; } diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 8f39971ee..0a5c7853a 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -93,7 +93,10 @@ public: } for (CAnchorsMap::iterator it = mapAnchors.begin(); it != mapAnchors.end(); ) { if (it->second.entered) { - mapAnchors_[it->first] = it->second.tree; + std::map::iterator ret = + mapAnchors_.insert(std::make_pair(it->first, IncrementalMerkleTree(INCREMENTAL_MERKLE_TREE_DEPTH))).first; + + ret->second.setTo(it->second.tree); } else { mapAnchors_.erase(it->first); } @@ -173,6 +176,45 @@ void appendRandomCommitment(IncrementalMerkleTree &tree) tree.insertElement(commitment, index); } +BOOST_AUTO_TEST_CASE(anchors_flush_test) +{ + CCoinsViewTest base; + uint256 newrt; + { + CCoinsViewCacheTest cache(&base); + IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH); + BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree)); + appendRandomCommitment(tree); + + { + std::vector newrt_v(32); + tree.getRootValue(newrt_v); + newrt = uint256(newrt_v); + } + + cache.PushAnchor(tree); + cache.Flush(); + } + + { + CCoinsViewCacheTest cache(&base); + IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH); + BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree)); + + // Get the cached entry. + BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree)); + + uint256 check_rt; + { + std::vector newrt_v(32); + tree.getRootValue(newrt_v); + check_rt = uint256(newrt_v); + } + + BOOST_CHECK(check_rt == newrt); + } +} + BOOST_AUTO_TEST_CASE(anchors_test) { // TODO: These tests should be more methodical. diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d9fb67047..f8b550c08 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1077,12 +1077,11 @@ bool CWallet::WitnessBucketCommitment(uint256 &commitment, std::vector index; std::vector commitment_value(bucket_commitment.begin(), bucket_commitment.end()); libzerocash::convertBytesVectorToVector(commitment_value, commitment_bv); - tree.insertElement(commitment_bv, index); + assert(tree.insertElement(commitment_bv, index)); if (bucket_commitment == commitment) { // We've found it! Now, we construct a witness. res = true; - tree.prune(); commitment_index = index; } }