From 5d6e1aa60f4837f0f8edae047942ecdf36d505f7 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 15 Dec 2016 15:50:26 +1300 Subject: [PATCH 1/2] Add total number of commitments to getblockchaininfo --- src/rpcblockchain.cpp | 5 +++++ src/zcash/IncrementalMerkleTree.cpp | 19 +++++++++++++++++++ src/zcash/IncrementalMerkleTree.hpp | 2 ++ 3 files changed, 26 insertions(+) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 4c92979b2..4e6d42a6b 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -533,6 +533,7 @@ Value getblockchaininfo(const Array& params, bool fHelp) " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" + " \"commitments\": xxxxxx, (numeric) the current number of note commitments in the commitment tree\n" " \"softforks\": [ (array) status of softforks in progress\n" " {\n" " \"id\": \"xxxx\", (string) name of softfork\n" @@ -564,6 +565,10 @@ Value getblockchaininfo(const Array& params, bool fHelp) obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); + ZCIncrementalMerkleTree tree; + pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), tree); + obj.push_back(Pair("commitments", tree.size())); + const Consensus::Params& consensusParams = Params().GetConsensus(); CBlockIndex* tip = chainActive.Tip(); Array softforks; diff --git a/src/zcash/IncrementalMerkleTree.cpp b/src/zcash/IncrementalMerkleTree.cpp index cf2d00af7..d59e707fa 100644 --- a/src/zcash/IncrementalMerkleTree.cpp +++ b/src/zcash/IncrementalMerkleTree.cpp @@ -81,6 +81,25 @@ Hash IncrementalMerkleTree::last() const { } } +template +size_t IncrementalMerkleTree::size() const { + size_t ret = 0; + if (left) { + ret++; + } + if (right) { + ret++; + } + // Treat occupation of parents array as a binary number + // (right-shifted by 1) + for (size_t i = 0; i < parents.size(); i++) { + if (parents[i]) { + ret += (1 << (i+1)); + } + } + return ret; +} + template void IncrementalMerkleTree::append(Hash obj) { if (is_complete(Depth)) { diff --git a/src/zcash/IncrementalMerkleTree.hpp b/src/zcash/IncrementalMerkleTree.hpp index 6c50192c8..67b356318 100644 --- a/src/zcash/IncrementalMerkleTree.hpp +++ b/src/zcash/IncrementalMerkleTree.hpp @@ -75,6 +75,8 @@ public: parents.size() * 32; // parents } + size_t size() const; + void append(Hash obj); Hash root() const { return root(Depth, std::deque()); From fc538ec2ea3e426dcfa69a9426eddf359716b49b Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 16 Dec 2016 13:50:55 -0700 Subject: [PATCH 2/2] Add test for IncrementalMerkleTree::size(). --- src/gtest/test_merkletree.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gtest/test_merkletree.cpp b/src/gtest/test_merkletree.cpp index efe5587e5..cf1d8617a 100644 --- a/src/gtest/test_merkletree.cpp +++ b/src/gtest/test_merkletree.cpp @@ -79,6 +79,9 @@ void test_tree( // The tree doesn't have a 'last' element added since it's blank. ASSERT_THROW(tree.last(), std::runtime_error); + // The tree is empty. + ASSERT_TRUE(tree.size() == 0); + // We need to witness at every single point in the tree, so // that the consistency of the tree and the merkle paths can // be checked. @@ -93,6 +96,9 @@ void test_tree( // Now append a commitment to the tree tree.append(test_commitment); + // Size incremented by one. + ASSERT_TRUE(tree.size() == i+1); + // Last element added to the tree was `test_commitment` ASSERT_TRUE(tree.last() == test_commitment);