Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
compactproofs_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2022 The Bitcoin developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
6
8#include <streams.h>
9
10#include <test/util/setup_common.h>
11
12#include <boost/test/unit_test.hpp>
13
14#include <algorithm>
15
16namespace avalanche {
17namespace {
18 struct TestCompactProofs {
19 static std::vector<uint64_t> getShortProofIds(const CompactProofs &cp) {
20 return cp.shortproofids;
21 }
22
23 static std::vector<PrefilledProof>
24 getPrefilledProofs(const CompactProofs &cp) {
25 return cp.prefilledProofs;
26 }
27
28 static void addPrefilledProof(CompactProofs &cp, uint32_t index,
29 const ProofRef &proof) {
30 PrefilledProof pp{index, proof};
31 cp.prefilledProofs.push_back(std::move(pp));
32 }
33 };
34} // namespace
35} // namespace avalanche
36
37using namespace avalanche;
38
39// TestingSetup is required for buildRandomProof()
41
43 {
45 BOOST_CHECK_EQUAL(cpw.size(), 0);
46
49
52
53 BOOST_CHECK_EQUAL(cpr.size(), 0);
54 BOOST_CHECK_EQUAL(cpr.getKeys().first, cpw.getKeys().first);
55 BOOST_CHECK_EQUAL(cpr.getKeys().second, cpw.getKeys().second);
56 }
57
58 Chainstate &active_chainstate = Assert(m_node.chainman)->ActiveChainstate();
59
60 {
61 // Check index boundaries
63
64 TestCompactProofs::addPrefilledProof(
66 TestCompactProofs::addPrefilledProof(
67 cp, std::numeric_limits<uint32_t>::max(),
69
72
73 auto prefilledProofs = TestCompactProofs::getPrefilledProofs(cp);
74 BOOST_CHECK_EQUAL(prefilledProofs.size(), 2);
75
76 BOOST_CHECK_EQUAL(prefilledProofs[0].index, 0);
77 BOOST_CHECK_EQUAL(prefilledProofs[1].index,
78 std::numeric_limits<uint32_t>::max());
79 }
80
81 auto checkCompactProof = [&](size_t numofProof,
82 size_t numofPrefilledProof) {
84 for (size_t i = 0; i < numofProof; i++) {
85 BOOST_CHECK(proofs.insert(
87 }
88
91
93 for (size_t i = 0; i < numofPrefilledProof; i++) {
94 TestCompactProofs::addPrefilledProof(
97 }
98 auto prefilledProofs = TestCompactProofs::getPrefilledProofs(cpw);
99 BOOST_CHECK_EQUAL(prefilledProofs.size(), numofPrefilledProof);
100
103
106
108 BOOST_CHECK_EQUAL(cpr.getKeys().first, cpw.getKeys().first);
109 BOOST_CHECK_EQUAL(cpr.getKeys().second, cpw.getKeys().second);
110
112 const PrefilledProof &rhs) {
113 return lhs.index == rhs.index &&
114 lhs.proof->getId() == rhs.proof->getId() &&
115 lhs.proof->getSignature() == rhs.proof->getSignature();
116 };
117
118 auto prefilledProofsCpr = TestCompactProofs::getPrefilledProofs(cpr);
119 BOOST_CHECK(std::equal(prefilledProofsCpr.begin(),
120 prefilledProofsCpr.end(),
121 prefilledProofs.begin(), comparePrefilledProof));
122
123 auto shortIds = TestCompactProofs::getShortProofIds(cpr);
124 size_t index = 0;
125 proofs.forEachLeaf([&](auto pLeaf) {
126 const ProofId &proofid = pLeaf->getId();
127 BOOST_CHECK_EQUAL(cpr.getShortID(proofid), cpw.getShortID(proofid));
128 BOOST_CHECK_EQUAL(cpr.getShortID(proofid), shortIds[index]);
129 ++index;
130
131 return true;
132 });
133 };
134
135 // No proof at all
136 checkCompactProof(0, 0);
137
138 // No prefilled proofs
139 checkCompactProof(1000, 0);
140
141 // Only prefilled proofs
142 checkCompactProof(0, 1000);
143
144 // Mixed case
145 checkCompactProof(1000, 1000);
146}
147
149 Chainstate &active_chainstate = Assert(m_node.chainman)->ActiveChainstate();
150 {
152
153 TestCompactProofs::addPrefilledProof(
155 TestCompactProofs::addPrefilledProof(
157
159 BOOST_CHECK_EXCEPTION(ss << cp, std::ios_base::failure,
160 HasReason("differential value overflow"));
161 }
162
163 {
165
166 TestCompactProofs::addPrefilledProof(
168 TestCompactProofs::addPrefilledProof(
170
172 BOOST_CHECK_EXCEPTION(ss << cp, std::ios_base::failure,
173 HasReason("differential value overflow"));
174 }
175
176 {
178
179 TestCompactProofs::addPrefilledProof(
180 cp, std::numeric_limits<uint32_t>::max(),
182 TestCompactProofs::addPrefilledProof(
184
186 BOOST_CHECK_EXCEPTION(ss << cp, std::ios_base::failure,
187 HasReason("differential value overflow"));
188 }
189
190 {
192 // shortproofidk0, shortproofidk1
193 ss << uint64_t(0) << uint64_t(0);
194 // shortproofids.size()
196
198 BOOST_CHECK_EXCEPTION(ss >> cp, std::ios_base::failure,
199 HasReason("ReadCompactSize(): size too large"));
200 }
201
202 {
204 // shortproofidk0, shortproofidk1
205 ss << uint64_t(0) << uint64_t(0);
206 // shortproofids.size()
208 // prefilledProofs.size()
210
212 BOOST_CHECK_EXCEPTION(ss >> cp, std::ios_base::failure,
213 HasReason("ReadCompactSize(): size too large"));
214 }
215
216 {
218 // shortproofidk0, shortproofidk1
219 ss << uint64_t(0) << uint64_t(0);
220 // shortproofids.size()
222 // prefilledProofs.size()
224 // prefilledProofs[0].index
226 // prefilledProofs[0].proof
228
230 BOOST_CHECK_EXCEPTION(ss >> cp, std::ios_base::failure,
231 HasReason("ReadCompactSize(): size too large"));
232 }
233
234 // Compute the number of MAX_SIZE increment we need to cause an overflow
235 const uint64_t overflow =
236 uint64_t(std::numeric_limits<uint32_t>::max()) + 1;
237 // Due to differential encoding, a value of MAX_SIZE bumps the index by
238 // MAX_SIZE + 1
240 const uint64_t overflowIter = overflow / (MAX_SIZE + 1);
241
242 // Make sure the iteration fits in an uint32_t and is <= MAX_SIZE
243 BOOST_CHECK_LE(overflowIter, std::numeric_limits<uint32_t>::max());
246
247 {
249 // shortproofidk0, shortproofidk1
250 ss << uint64_t(0) << uint64_t(0);
251 // shortproofids.size()
253 // prefilledProofs.size()
255 for (uint32_t i = 0; i < overflowIter; i++) {
256 // prefilledProofs[i].index
258 // prefilledProofs[i].proof
260 }
261 // This is the prefilled proof causing the overflow
264
266 BOOST_CHECK_EXCEPTION(ss >> cp, std::ios_base::failure,
267 HasReason("differential value overflow"));
268 }
269
270 {
272 // shortproofidk0, shortproofidk1
273 ss << uint64_t(0) << uint64_t(0);
274 // shortproofids.size()
276 // shortproofids[0]
278 // prefilledProofs.size()
280 for (uint32_t i = 0; i < overflowIter; i++) {
281 // prefilledProofs[i].index
283 // prefilledProofs[i].proof
285 }
286 // This prefilled proof isn't enough to cause the overflow alone, but it
287 // overflows due to the extra shortid.
290
292 // ss >> cp;
293 BOOST_CHECK_EXCEPTION(ss >> cp, std::ios_base::failure,
294 HasReason("indexes overflowed 32 bits"));
295 }
296
297 {
299 // shortproofidk0, shortproofidk1
300 ss << uint64_t(0) << uint64_t(0);
301 // shortproofids.size()
303 // prefilledProofs.size()
305 // prefilledProofs[0].index
307 // prefilledProofs[0].proof
309 // prefilledProofs[1].index = 1 is differentially encoded, which means
310 // it has an absolute index of 2. This leaves no proof at index 1.
312 // prefilledProofs[1].proof
314
316 BOOST_CHECK_EXCEPTION(ss >> cp, std::ios_base::failure,
317 HasReason("non contiguous indexes"));
318 }
319}
320
#define Assert(val)
Identity function.
Definition check.h:84
Double ended buffer combining vector and stream-like interfaces.
Definition streams.h:177
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition validation.h:693
BOOST_AUTO_TEST_CASE(compactproofs_roundtrip)
ProofRef buildRandomProof(Chainstate &active_chainstate, uint32_t score, int height, const CKey &masterKey)
Definition util.cpp:20
constexpr uint32_t MIN_VALID_PROOF_SCORE
Definition util.h:17
NodeContext & m_node
#define BOOST_CHECK_EQUAL(v1, v2)
Definition object.cpp:18
#define BOOST_CHECK_NO_THROW(stmt)
Definition object.cpp:29
#define BOOST_CHECK(expr)
Definition object.cpp:17
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
Definition serialize.h:31
@ SER_DISK
Definition serialize.h:153
@ SER_NETWORK
Definition serialize.h:152
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
Definition serialize.h:1254
This is a radix tree storing values identified by a unique key.
Definition radix.h:40
static const int PROTOCOL_VERSION
network protocol versioning
Definition version.h:11