PIVX Core  5.6.99
P2P Digital Currency
merkletree_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016-2020 The ZCash developers
2 // Copyright (c) 2020 The PIVX Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "test/test_pivx.h"
7 
13 
14 #include <iostream>
15 #include <stdexcept>
16 
17 #include "utilstrencodings.h"
18 #include "version.h"
19 #include "serialize.h"
20 #include "streams.h"
21 
23 #include "sapling/sapling_util.h"
24 
25 #include "json_test_vectors.h"
26 
27 #include <boost/test/unit_test.hpp>
28 
29 
30 BOOST_FIXTURE_TEST_SUITE(sapling_merkletree_tests, BasicTestingSetup)
31 
32 template<typename A, typename B, typename C>
33 void expect_ser_test_vector(B& b, const C& c, const A& tree) {
34  expect_test_vector<B, C>(b, c);
35 }
36 
37 template<typename Tree, typename Witness>
38 void test_tree(
39  UniValue commitment_tests,
40  UniValue root_tests,
41  UniValue ser_tests,
42  UniValue witness_ser_tests,
43  UniValue path_tests
44 )
45 {
46  size_t witness_ser_i = 0;
47  size_t path_i = 0;
48 
49  Tree tree;
50 
51  // The root of the tree at this point is expected to be the root of the
52  // empty tree.
53  BOOST_CHECK(tree.root() == Tree::empty_root());
54 
55  // The tree doesn't have a 'last' element added since it's blank.
56  BOOST_CHECK_THROW(tree.last(), std::runtime_error);
57 
58  // The tree is empty.
59  BOOST_CHECK(tree.size() == 0);
60 
61  // We need to witness at every single point in the tree, so
62  // that the consistency of the tree and the merkle paths can
63  // be checked.
64  std::vector<Witness> witnesses;
65 
66  for (size_t i = 0; i < 16; i++) {
67  uint256 test_commitment = uint256S(commitment_tests[i].get_str());
68 
69  // Witness here
70  witnesses.push_back(tree.witness());
71 
72  // Now append a commitment to the tree
73  tree.append(test_commitment);
74 
75  // Size incremented by one.
76  BOOST_CHECK(tree.size() == i+1);
77 
78  // Last element added to the tree was `test_commitment`
79  BOOST_CHECK(tree.last() == test_commitment);
80 
81  // Check tree root consistency
82  expect_test_vector(root_tests[i], tree.root());
83 
84  // Check serialization of tree
85  expect_ser_test_vector(ser_tests[i], tree, tree);
86 
87  bool first = true; // The first witness can never form a path
88  for (Witness& wit : witnesses) {
89  // Append the same commitment to all the witnesses
90  wit.append(test_commitment);
91 
92  if (first) {
93  BOOST_CHECK_THROW(wit.path(), std::runtime_error);
94  BOOST_CHECK_THROW(wit.element(), std::runtime_error);
95  } else {
96  auto path = wit.path();
97  expect_test_vector(path_tests[path_i++], path);
98  }
99 
100  // Check witness serialization
101  expect_ser_test_vector(witness_ser_tests[witness_ser_i++], wit, tree);
102 
103  BOOST_CHECK(wit.root() == tree.root());
104 
105  first = false;
106  }
107  }
108 
109  {
110  // Tree should be full now
111  BOOST_CHECK_THROW(tree.append(uint256()), std::runtime_error);
112 
113  for (Witness& wit : witnesses) {
114  BOOST_CHECK_THROW(wit.append(uint256()), std::runtime_error);
115  }
116  }
117 }
118 
119 #define MAKE_STRING(x) std::string((x), (x)+sizeof(x))
120 
121 BOOST_AUTO_TEST_CASE(SaplingVectors) {
122  UniValue root_tests = read_json(MAKE_STRING(json_tests::merkle_roots_sapling));
123  UniValue ser_tests = read_json(MAKE_STRING(json_tests::merkle_serialization_sapling));
124  UniValue witness_ser_tests = read_json(MAKE_STRING(json_tests::merkle_witness_serialization_sapling));
125  UniValue path_tests = read_json(MAKE_STRING(json_tests::merkle_path_sapling));
126  UniValue commitment_tests = read_json(MAKE_STRING(json_tests::merkle_commitments_sapling));
127 
128  test_tree<SaplingTestingMerkleTree, SaplingTestingWitness>(
129  commitment_tests,
130  root_tests,
131  ser_tests,
132  witness_ser_tests,
133  path_tests
134  );
135 }
136 
137 BOOST_AUTO_TEST_CASE(emptyroots) {
139  std::array<libzcash::SHA256Compress, 65> computed;
140 
141  computed.at(0) = libzcash::SHA256Compress::uncommitted();
142  BOOST_CHECK(emptyroots.empty_root(0) == computed.at(0));
143  for (size_t d = 1; d <= 64; d++) {
144  computed.at(d) = libzcash::SHA256Compress::combine(computed.at(d-1), computed.at(d-1), d-1);
145  BOOST_CHECK(emptyroots.empty_root(d) == computed.at(d));
146  }
147 
148  // Double check that we're testing (at least) all the empty roots we'll use.
150 }
151 
152 BOOST_AUTO_TEST_CASE(EmptyrootsSapling) {
154  std::array<libzcash::PedersenHash, 63> computed;
155 
156  computed.at(0) = libzcash::PedersenHash::uncommitted();
157  BOOST_CHECK(emptyroots.empty_root(0) == computed.at(0));
158  for (size_t d = 1; d <= 62; d++) {
159  computed.at(d) = libzcash::PedersenHash::combine(computed.at(d-1), computed.at(d-1), d-1);
160  BOOST_CHECK(emptyroots.empty_root(d) == computed.at(d));
161  }
162 
163  // Double check that we're testing (at least) all the empty roots we'll use.
165 }
166 
167 BOOST_AUTO_TEST_CASE(EmptyrootSapling) {
168  // This literal is the depth-32 empty tree root with the bytes reversed to
169  // account for the fact that uint256S() loads a big-endian representation of
170  // an integer which converted to little-endian internally.
171  uint256 expected = uint256S("3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb");
172 
174 }
175 
Hash empty_root(size_t depth) const
static PedersenHash combine(const PedersenHash &a, const PedersenHash &b, size_t depth)
static PedersenHash uncommitted()
static SHA256Compress uncommitted()
static SHA256Compress combine(const SHA256Compress &a, const SHA256Compress &b, size_t depth)
256-bit opaque blob.
Definition: uint256.h:138
BOOST_AUTO_TEST_SUITE_END()
void expect_test_vector(T &v, const U &expected)
void expect_ser_test_vector(B &b, const C &c, const A &tree)
#define MAKE_STRING(x)
BOOST_AUTO_TEST_CASE(SaplingVectors)
void test_tree(UniValue commitment_tests, UniValue root_tests, UniValue ser_tests, UniValue witness_ser_tests, UniValue path_tests)
UniValue read_json(const std::string &jsondata)
Definition: invalid.cpp:16
#define BOOST_CHECK_THROW(stmt, excMatch)
Definition: object.cpp:19
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
#define BOOST_CHECK(expr)
Definition: object.cpp:17
#define INCREMENTAL_MERKLE_TREE_DEPTH
Definition: sapling.h:13
Basic testing setup.
Definition: test_pivx.h:51
uint256 uint256S(const char *str)
Definition: uint256.h:157
#define B
Definition: util_tests.cpp:688