From 434f3284465daffaad124ac17b16798a3f152062 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Sat, 2 Apr 2016 23:31:26 -0600 Subject: [PATCH] Integrate new incremental merkle tree implementation into consensus. --- src/coins.cpp | 22 ++++---- src/coins.h | 12 ++-- src/main.cpp | 15 +---- src/test/coins_tests.cpp | 117 ++++++++++----------------------------- src/txdb.cpp | 22 +++----- src/txdb.h | 2 +- src/txmempool.cpp | 2 +- src/wallet/wallet.cpp | 2 +- src/zcbenchmarks.cpp | 2 + 9 files changed, 60 insertions(+), 136 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 7ccfc28d..d177b8ee 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -40,7 +40,7 @@ bool CCoins::Spend(uint32_t nPos) Cleanup(); return true; } -bool CCoinsView::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const { return false; } +bool CCoinsView::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return false; } bool CCoinsView::GetSerial(const uint256 &serial) const { return false; } bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } @@ -56,7 +56,7 @@ bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { } -bool CCoinsViewBacked::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const { return base->GetAnchorAt(rt, tree); } +bool CCoinsViewBacked::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { return base->GetAnchorAt(rt, tree); } bool CCoinsViewBacked::GetSerial(const uint256 &serial) const { return base->GetSerial(serial); } bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); } bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); } @@ -102,11 +102,11 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const } -bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const { +bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { CAnchorsMap::const_iterator it = cacheAnchors.find(rt); if (it != cacheAnchors.end()) { if (it->second.entered) { - tree.setTo(it->second.tree); + tree = it->second.tree; return true; } else { return false; @@ -119,7 +119,7 @@ bool CCoinsViewCache::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMer CAnchorsMap::iterator ret = cacheAnchors.insert(std::make_pair(rt, CAnchorsCacheEntry())).first; ret->second.entered = true; - ret->second.tree.setTo(tree); + ret->second.tree = tree; return true; } @@ -140,10 +140,8 @@ bool CCoinsViewCache::GetSerial(const uint256 &serial) const { return tmp; } -void CCoinsViewCache::PushAnchor(const libzerocash::IncrementalMerkleTree &tree) { - std::vector newrt_v(32); - tree.getRootValue(newrt_v); - uint256 newrt(newrt_v); +void CCoinsViewCache::PushAnchor(const ZCIncrementalMerkleTree &tree) { + uint256 newrt = tree.root(); auto currentRoot = GetBestAnchor(); @@ -156,7 +154,7 @@ void CCoinsViewCache::PushAnchor(const libzerocash::IncrementalMerkleTree &tree) CAnchorsMap::iterator ret = cacheAnchors.insert(std::make_pair(newrt, CAnchorsCacheEntry())).first; ret->second.entered = true; - ret->second.tree.setTo(tree); + ret->second.tree = tree; ret->second.flags = CAnchorsCacheEntry::DIRTY; hashAnchor = newrt; @@ -302,7 +300,7 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, CAnchorsCacheEntry& entry = cacheAnchors[child_it->first]; entry.entered = true; - entry.tree.setTo(child_it->second.tree); + entry.tree = child_it->second.tree; entry.flags = CAnchorsCacheEntry::DIRTY; // TODO: cache usage @@ -399,7 +397,7 @@ bool CCoinsViewCache::HavePourRequirements(const CTransaction& tx) const } } - libzerocash::IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree tree; if (!GetAnchorAt(pour.anchor, tree)) { // If we do not have the anchor for the pour, // it is invalid. diff --git a/src/coins.h b/src/coins.h index 53f04717..4e547d52 100644 --- a/src/coins.h +++ b/src/coins.h @@ -300,14 +300,14 @@ struct CCoinsCacheEntry struct CAnchorsCacheEntry { bool entered; // This will be false if the anchor is removed from the cache - libzerocash::IncrementalMerkleTree tree; // The tree itself + ZCIncrementalMerkleTree tree; // The tree itself unsigned char flags; enum Flags { DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view. }; - CAnchorsCacheEntry() : entered(false), flags(0), tree(INCREMENTAL_MERKLE_TREE_DEPTH) {} + CAnchorsCacheEntry() : entered(false), flags(0) {} }; struct CSerialsCacheEntry @@ -345,7 +345,7 @@ class CCoinsView { public: //! Retrieve the tree at a particular anchored root in the chain - virtual bool GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const; + virtual bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; //! Determine whether a serial is spent or not virtual bool GetSerial(const uint256 &serial) const; @@ -387,7 +387,7 @@ protected: public: CCoinsViewBacked(CCoinsView *viewIn); - bool GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const; + bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; bool GetSerial(const uint256 &serial) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; @@ -451,7 +451,7 @@ public: ~CCoinsViewCache(); // Standard CCoinsView methods - bool GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const; + bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; bool GetSerial(const uint256 &serial) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; @@ -467,7 +467,7 @@ public: // Adds the tree to mapAnchors and sets the current commitment // root to this root. - void PushAnchor(const libzerocash::IncrementalMerkleTree &tree); + void PushAnchor(const ZCIncrementalMerkleTree &tree); // Removes the current commitment root from mapAnchors and sets // the new current root. diff --git a/src/main.cpp b/src/main.cpp index fe096928..4860513b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2013,7 +2013,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Construct the incremental merkle tree at the current // block position, auto old_tree_root = view.GetBestAnchor(); - libzerocash::IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree tree; // This should never fail: we should always be able to get the root // that is on the tip of our chain assert(view.GetAnchorAt(old_tree_root, tree)); @@ -2021,11 +2021,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin { // Consistency check: the root of the tree we're given should // match what we asked for. - std::vector newrt_v(32); - tree.getRootValue(newrt_v); - uint256 anchor_received = uint256(newrt_v); - - assert(anchor_received == old_tree_root); + assert(tree.root() == old_tree_root); } for (unsigned int i = 0; i < block.vtx.size(); i++) @@ -2078,11 +2074,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin BOOST_FOREACH(const uint256 &bucket_commitment, pour.commitments) { // Insert the bucket commitments into our temporary tree. - std::vector index; - std::vector commitment_value(bucket_commitment.begin(), bucket_commitment.end()); - std::vector commitment_bv(ZC_CM_SIZE * 8); - libzerocash::convertBytesVectorToVector(commitment_value, commitment_bv); - tree.insertElement(commitment_bv, index); + tree.append(bucket_commitment); } } @@ -2090,7 +2082,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); } - tree.prune(); // prune it, so we don't cache intermediate states we don't need view.PushAnchor(tree); blockundo.old_tree_root = old_tree_root; diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index d03863cc..a599843f 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -11,7 +11,7 @@ #include #include -#include "zerocash/IncrementalMerkleTree.h" +#include "zcash/IncrementalMerkleTree.hpp" namespace { @@ -20,22 +20,22 @@ class CCoinsViewTest : public CCoinsView uint256 hashBestBlock_; uint256 hashBestAnchor_; std::map map_; - std::map mapAnchors_; + std::map mapAnchors_; std::map mapSerials_; public: - bool GetAnchorAt(const uint256& rt, libzerocash::IncrementalMerkleTree &tree) const { + bool GetAnchorAt(const uint256& rt, ZCIncrementalMerkleTree &tree) const { if (rt.IsNull()) { - IncrementalMerkleTree new_tree(INCREMENTAL_MERKLE_TREE_DEPTH); - tree.setTo(new_tree); + ZCIncrementalMerkleTree new_tree; + tree = new_tree; return true; } - std::map::const_iterator it = mapAnchors_.find(rt); + std::map::const_iterator it = mapAnchors_.find(rt); if (it == mapAnchors_.end()) { return false; } else { - tree.setTo(it->second); + tree = it->second; return true; } } @@ -93,10 +93,10 @@ public: } for (CAnchorsMap::iterator it = mapAnchors.begin(); it != mapAnchors.end(); ) { if (it->second.entered) { - std::map::iterator ret = - mapAnchors_.insert(std::make_pair(it->first, IncrementalMerkleTree(INCREMENTAL_MERKLE_TREE_DEPTH))).first; + std::map::iterator ret = + mapAnchors_.insert(std::make_pair(it->first, ZCIncrementalMerkleTree())).first; - ret->second.setTo(it->second.tree); + ret->second = it->second.tree; } else { mapAnchors_.erase(it->first); } @@ -164,16 +164,12 @@ BOOST_AUTO_TEST_CASE(serials_test) BOOST_CHECK(!cache3.GetSerial(myserial)); } -void appendRandomCommitment(IncrementalMerkleTree &tree) +void appendRandomCommitment(ZCIncrementalMerkleTree &tree) { Address addr = Address::CreateNewRandomAddress(); Coin coin(addr.getPublicAddress(), 100); - std::vector commitment(ZC_CM_SIZE * 8); - convertBytesVectorToVector(coin.getCoinCommitment().getCommitmentValue(), commitment); - - std::vector index; - tree.insertElement(commitment, index); + tree.append(uint256(coin.getCoinCommitment().getCommitmentValue())); } BOOST_AUTO_TEST_CASE(anchors_flush_test) @@ -182,15 +178,11 @@ BOOST_AUTO_TEST_CASE(anchors_flush_test) uint256 newrt; { CCoinsViewCacheTest cache(&base); - IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree tree; BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree)); appendRandomCommitment(tree); - { - std::vector newrt_v(32); - tree.getRootValue(newrt_v); - newrt = uint256(newrt_v); - } + newrt = tree.root(); cache.PushAnchor(tree); cache.Flush(); @@ -198,18 +190,13 @@ BOOST_AUTO_TEST_CASE(anchors_flush_test) { CCoinsViewCacheTest cache(&base); - IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree tree; 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); - } + uint256 check_rt = tree.root(); BOOST_CHECK(check_rt == newrt); } @@ -226,7 +213,7 @@ BOOST_AUTO_TEST_CASE(anchors_test) BOOST_CHECK(cache.GetBestAnchor() == uint256()); { - IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree tree; BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), tree)); appendRandomCommitment(tree); @@ -236,96 +223,50 @@ BOOST_AUTO_TEST_CASE(anchors_test) appendRandomCommitment(tree); appendRandomCommitment(tree); appendRandomCommitment(tree); - tree.prune(); - IncrementalMerkleTree save_tree_for_later(INCREMENTAL_MERKLE_TREE_DEPTH); - save_tree_for_later.setTo(tree); + ZCIncrementalMerkleTree save_tree_for_later; + save_tree_for_later = tree; - uint256 newrt; + uint256 newrt = tree.root(); uint256 newrt2; - { - std::vector newrt_v(32); - tree.getRootValue(newrt_v); - - newrt = uint256(newrt_v); - } cache.PushAnchor(tree); BOOST_CHECK(cache.GetBestAnchor() == newrt); { - IncrementalMerkleTree confirm_same(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree confirm_same; BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), confirm_same)); - uint256 confirm_rt; - { - std::vector newrt_v(32); - confirm_same.getRootValue(newrt_v); - - confirm_rt = uint256(newrt_v); - } - - BOOST_CHECK(confirm_rt == newrt); + BOOST_CHECK(confirm_same.root() == newrt); } appendRandomCommitment(tree); appendRandomCommitment(tree); - tree.prune(); - { - std::vector newrt_v(32); - tree.getRootValue(newrt_v); - - newrt2 = uint256(newrt_v); - } + newrt2 = tree.root(); cache.PushAnchor(tree); BOOST_CHECK(cache.GetBestAnchor() == newrt2); - IncrementalMerkleTree test_tree(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree test_tree; BOOST_CHECK(cache.GetAnchorAt(cache.GetBestAnchor(), test_tree)); - { - std::vector a(32); - std::vector b(32); - tree.getRootValue(a); - test_tree.getRootValue(b); - - BOOST_CHECK(a == b); - } + BOOST_CHECK(tree.root() == test_tree.root()); { - std::vector a(32); - std::vector b(32); - IncrementalMerkleTree test_tree2(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree test_tree2; cache.GetAnchorAt(newrt, test_tree2); - uint256 recovered_rt; - { - std::vector newrt_v(32); - test_tree2.getRootValue(newrt_v); - - recovered_rt = uint256(newrt_v); - } - - BOOST_CHECK(recovered_rt == newrt); + BOOST_CHECK(test_tree2.root() == newrt); } { cache.PopAnchor(newrt); - IncrementalMerkleTree obtain_tree(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree obtain_tree; assert(!cache.GetAnchorAt(newrt2, obtain_tree)); // should have been popped off assert(cache.GetAnchorAt(newrt, obtain_tree)); - uint256 recovered_rt; - { - std::vector newrt_v(32); - obtain_tree.getRootValue(newrt_v); - - recovered_rt = uint256(newrt_v); - } - - assert(recovered_rt == newrt); + assert(obtain_tree.root() == newrt); } } } diff --git a/src/txdb.cpp b/src/txdb.cpp index ca335fb7..5ad5eb1f 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -33,13 +33,13 @@ static const char DB_LAST_BLOCK = 'l'; void static BatchWriteAnchor(CLevelDBBatch &batch, const uint256 &croot, - const libzerocash::IncrementalMerkleTree &tree, + const ZCIncrementalMerkleTree &tree, const bool &entered) { if (!entered) batch.Erase(make_pair(DB_ANCHOR, croot)); else { - batch.Write(make_pair(DB_ANCHOR, croot), tree.serialize()); + batch.Write(make_pair(DB_ANCHOR, croot), tree); } } @@ -69,24 +69,16 @@ CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(Get } -bool CCoinsViewDB::GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const { +bool CCoinsViewDB::GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { if (rt.IsNull()) { - IncrementalMerkleTree new_tree(INCREMENTAL_MERKLE_TREE_DEPTH); - tree.setTo(new_tree); + ZCIncrementalMerkleTree new_tree; + tree = new_tree; return true; } - std::vector tree_serialized; + bool read = db.Read(make_pair(DB_ANCHOR, rt), tree); - bool read = db.Read(make_pair(DB_ANCHOR, rt), tree_serialized); - - if (!read) return read; - - auto tree_deserialized = IncrementalMerkleTreeCompact::deserialize(tree_serialized); - - tree.fromCompactRepresentation(tree_deserialized); - - return true; + return read; } bool CCoinsViewDB::GetSerial(const uint256 &serial) const { diff --git a/src/txdb.h b/src/txdb.h index bd401b80..0e20b0d9 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -36,7 +36,7 @@ protected: public: CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); - bool GetAnchorAt(const uint256 &rt, libzerocash::IncrementalMerkleTree &tree) const; + bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const; bool GetSerial(const uint256 &serial) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; bool HaveCoins(const uint256 &txid) const; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d9e410a7..0a202229 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -320,7 +320,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const } // TODO: chained pours - libzerocash::IncrementalMerkleTree tree(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree tree; assert(pcoins->GetAnchorAt(pour.anchor, tree)); } if (fDependsWait) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f8b550c0..7c48c025 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1096,7 +1096,7 @@ bool CWallet::WitnessBucketCommitment(uint256 &commitment, // Consistency check: we should be able to find the current tree // in our CCoins view. - libzerocash::IncrementalMerkleTree dummy_tree(INCREMENTAL_MERKLE_TREE_DEPTH); + ZCIncrementalMerkleTree dummy_tree; assert(pcoinsTip->GetAnchorAt(current_anchor, dummy_tree)); pindex = chainActive.Next(pindex); diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 6a6bf6ae..8fc04217 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -1,3 +1,5 @@ +#include "zerocash/IncrementalMerkleTree.h" + #include #include #include "zerocash/ZerocashParams.h"