-
Notifications
You must be signed in to change notification settings - Fork 95
/
Copy pathbloom_tests.cpp
535 lines (416 loc) · 83.7 KB
/
bloom_tests.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
// Copyright (c) 2012-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <bloom.h>
#include <clientversion.h>
#include <key.h>
#include <key_io.h>
#include <merkleblock.h>
#include <primitives/block.h>
#include <random.h>
#include <serialize.h>
#include <streams.h>
#include <uint256.h>
#include <util/system.h>
#include <util/strencodings.h>
#include <test/test_bitcoin.h>
#include <vector>
#include <boost/test/unit_test.hpp>
BOOST_FIXTURE_TEST_SUITE(bloom_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize)
{
CBloomFilter filter(3, 0.01, 0, BLOOM_UPDATE_ALL);
filter.insert(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8"));
BOOST_CHECK_MESSAGE( filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "Bloom filter doesn't contain just-inserted object!");
// One bit different in first byte
BOOST_CHECK_MESSAGE(!filter.contains(ParseHex("19108ad8ed9bb6274d3980bab5a85c048f0950c8")), "Bloom filter contains something it shouldn't!");
filter.insert(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee"));
BOOST_CHECK_MESSAGE(filter.contains(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee")), "Bloom filter doesn't contain just-inserted object (2)!");
filter.insert(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5"));
BOOST_CHECK_MESSAGE(filter.contains(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")), "Bloom filter doesn't contain just-inserted object (3)!");
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << filter;
std::vector<unsigned char> vch = ParseHex("03614e9b050000000000000001");
std::vector<char> expected(vch.size());
for (unsigned int i = 0; i < vch.size(); i++)
expected[i] = (char)vch[i];
BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end());
BOOST_CHECK_MESSAGE( filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "Bloom filter doesn't contain just-inserted object!");
filter.clear();
BOOST_CHECK_MESSAGE( !filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "Bloom filter should be empty!");
}
BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak)
{
// Same test as bloom_create_insert_serialize, but we add a nTweak of 100
CBloomFilter filter(3, 0.01, 2147483649UL, BLOOM_UPDATE_ALL);
filter.insert(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8"));
BOOST_CHECK_MESSAGE( filter.contains(ParseHex("99108ad8ed9bb6274d3980bab5a85c048f0950c8")), "Bloom filter doesn't contain just-inserted object!");
// One bit different in first byte
BOOST_CHECK_MESSAGE(!filter.contains(ParseHex("19108ad8ed9bb6274d3980bab5a85c048f0950c8")), "Bloom filter contains something it shouldn't!");
filter.insert(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee"));
BOOST_CHECK_MESSAGE(filter.contains(ParseHex("b5a2c786d9ef4658287ced5914b37a1b4aa32eee")), "Bloom filter doesn't contain just-inserted object (2)!");
filter.insert(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5"));
BOOST_CHECK_MESSAGE(filter.contains(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")), "Bloom filter doesn't contain just-inserted object (3)!");
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << filter;
std::vector<unsigned char> vch = ParseHex("03ce4299050000000100008001");
std::vector<char> expected(vch.size());
for (unsigned int i = 0; i < vch.size(); i++)
expected[i] = (char)vch[i];
BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end());
}
BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
{
std::string strSecret = std::string("Pr9a7x48SyiPsgVo1MkxqFo7BNtwoFqwRcRewbxzPSjsRd3g3NEW");
CKey key = DecodeSecret(strSecret);
CPubKey pubkey = key.GetPubKey();
std::vector<unsigned char> vchPubKey(pubkey.begin(), pubkey.end());
CBloomFilter filter(2, 0.001, 0, BLOOM_UPDATE_ALL);
filter.insert(vchPubKey);
uint160 hash = pubkey.GetID();
filter.insert(std::vector<unsigned char>(hash.begin(), hash.end()));
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << filter;
std::vector<unsigned char> vch = ParseHex("03d499c7080000000000000001");
std::vector<char> expected(vch.size());
for (unsigned int i = 0; i < vch.size(); i++)
expected[i] = (char)vch[i];
BOOST_CHECK_EQUAL_COLLECTIONS(stream.begin(), stream.end(), expected.begin(), expected.end());
}
BOOST_AUTO_TEST_CASE(bloom_match)
{
// Random real transaction (a41116ecfb466ca1df58c4f8c428d86c20e02ed859e27d40172de8ff810abbb9)
CDataStream stream(ParseHex("01000000012134fd572b79e2d3657862dde654a1ccb149887ee5d577600ee4d2986695d224010000006a473044022074bc105e27ab462ad7faf919f50be2d9aba66be4fbe5499ffcc75419d17c4e27022057389ea4bcc44855fd0c2049cfca5aeb8817ef26cc9c33a57fc741ef1183626c012102fdc596855e2fcdcdc23d798e00c555726aaece8e85e1178237564af3ae4eaafbffffffff02ae4ba97a6f0700001976a9141617f86512c72526c0cde953dc43bf5fd41ded2088ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac00000000"), SER_DISK, CLIENT_VERSION);
CTransaction tx(deserialize, stream);
// and one which spends it (ba8bab5303670ce9c9b658a13deae33933e1d7a1c84c0d7f541fbd3f83e11695)
CDataStream spendStream(ParseHex("0100000065394f77222898c652176aae67249ad50a3e085dc0cff74a5dfb3516283cef0ffe010000006a473044022014ed718e5810d46a9f0f9a2bc0d8d1c323cc6d94da3dd2a01385b5534acfcbd0022057dea4f58daffeea0e9730996451539f17b7f60ae1858226c3939f2606bd82b1012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffc176e8a175883be8d9ecbe9425562c457ea5efa2606a58c35b34b1ff7a6b9e26010000006b483045022100a760525c77d18d1a614e4ef8e7712d9035a58710fc44dd84f571c98fe2e8709202200fb2b448f0daf8d011789098965927e76ed71d734ad85c8965f9983739c04d84012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff0329da8b1814b7a861e85e2d31e47ce15fa25efd77523eef637817f7098e2f92010000006a47304402207adfa97c9b62b678b3ac0142f0fb6f79f30ebd288664a155bdf864acb6a0979702200bb529f1023d8a799aa4cd69077315a141373be29cdadefedc93942aac17f772012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff042c21d71ec8daace795f87066e86b9d012d7f2191589005f7957a59e5a8ac32000000006b483045022100f049e3971e0eb66119116e11f700f0ee07fb8b105373bd50c6fec2277f0886370220482de1a71a6d45413c2ef4e96c917b51f18eaece956e7985c17997a211a8b311012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffc9631ae7d6d233ee3ad81ec31db5361a11db3535e1f77c25aab51c0dcca3a050000000006a47304402207c33eaca903e25e117ed6e6bb683cce5aab8abdcfa215f292d41df586566b7c4022005ae7424295c2e62d06cff9a2849f2d56c777fb8cf1e62102264dd5c7769d835012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff6cd48a18f574aad46e533987756a4ff005fc1b6cfe24c329619e1b69beb8df9d000000006a47304402207ba096dbe88c2531f88eb93d1658416aacc77f127703f269f92df27746c7e71e022005ce0657bd747b93d52a94115cd52a2ce87bcd10d900de8fbf1e6114c3a1f764012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff94ba4f250b5686e22dd07fa65029fda54e9f720a2217c4290fd1c865f65ad029000000006a47304402205df4da238954a15145e4d5050c770e58b88f60cdfae0a014298ad2279967bec5022029bd4f73b584e28754257f0a4ff53242f5c690e760ea594539f111ff93bdea1a012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff48906c6378ebabd50d63dfb76e0643c207793590f7330cf495262d06b689bb5b000000006a47304402204979790287944bd41dbc8463ff56e0c2d1daaecf90f423a1cb6f27b8b5f22e720220403e7f0e6e2fe57a487fa338797f39f9084775c79c06443db43f742cfa3b56e4012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff2c739d32ecb29b54b68fb41c5b9435377402e21c2598752998f74c1dd8a1b242010000006b483045022100abb2dec59576bf50419514c8913d8f216bd962de27e5af398daded10b6922b1d02206ae58ff4df4db098741dbfd8ea7fd1cdcada7cb38c485a8d6c9f8e3f1f6970b5012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff72b7aee4f9d2edc38c2f1fe23b5ae876077dde15bfb94fdba9ed9fe234d08375000000006a47304402206243f384d8961cbdb816dbf381c765c26f0bdcd5978993067eace3dad42841110220708ae5bcc4d53ba4225e625f617c8b5c04bc236acab5ac8377d3055da67d71dc012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff2007cecc67df43fadb9f1ceb8615d173931356b65113e2031bd2db8081004df9010000006a473044022001780f9ec22ef1e6b04b0ec5d2cfcd749a40f680e82fe67d1939483fed54aaa302203df790455453ecf8352ca874f9dcb9ec67d77487cdda918fbcc4fdf3aa6b0737012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff899f95784869eee137194421aa126d1f8f637c089570979a540c8d4424cd412c000000006b483045022100ca860b135662dd8105cffb040dab689366b39e39b3c1d39721ab8027bca628e50220445ef34f1e025b72cdcfb492a6395ba9e60aa4ca4d4674920134ceed54787fc2012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff58a0433f9164656ebb70503676c82e5680539f0575bec7e50933c7a009f726d9010000006b48304502210094484316fb2eacabf09c66f53ce93c94547885e34b728cd3fd4bf4707335381a022048bb89ee1bb4446534ddf3e430297b9747301ef77e60a6469094c9fc90d4e548012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff3a3fae18852776fc87976126074d65f16c1016b1e112e3b8fd84e5d0022a168a010000006a47304402206c6a59a312881e4cc2ef08bac5ba3a9c077dae8e8dfdbb3fd4af1c39ef266224022051e29175f957c967ab0660b4723eca20e3fe0bdc3f808cc3441a57f692a84244012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff9b6bc4895c2d3528d6cd0a65bf592676ea13e9389f144d305503882f8b55afd5000000006b483045022100fae45e6865bac018eb767a235b53c26654e643f3162d7b917e6d13ffbaa218da02200e231dec61e525fb421a2644dd62dc1c730f7cfbc1aaeb98fbba4263fde6e878012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffb0ac4d520e15357bb9d3b3b90db8a5acd3f6ab6b0aa08a23cdca7a30eebb2b05000000006b483045022100cb5ecef0081d0313da5cf182c99e654a5d3a0ac349de524ed9c889367afc2083022005a9de9d1309eebee66bbe258674e7061c2cf42b8ef188377d2d275035fea592012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff254247b753134f79c8e78798ab6d5cbe896a842edd0105089435d71e47a6d5df010000006a47304402205722f8277f3504e7f3f443fd68fb1b0d42dff9fb2eeb1c9081b8064f013e486c02205498e445c22bf5bd74d3d0b3261072d7c1bfeadf859885f48df3d99f0e8fe7c3012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffb7fe76b43606b39a8f7ac8d59fb023f7e53e0f83949a7e82fa4b39737f362f36010000006a47304402204be1870300b4d3ff5378d7afc4155a95dc2427003af5818ad8223a74295659bf02207f216bb3e91a14bb116a4d44091a6701afb396ec29c6c1adc03cf271d8e2b14b012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff1dfaf45e1903521dded7040a2eb74ed6574c01a359c3df501b044d083dbd58ba000000006b4830450221008d7dbd30a9757d06085708ae382d12bc99e867f7e2462a663ee82f7a4f8f13e002202d296032b9dd0f0ad38cb5a07ed90ffb1c46b536aa0b64015ff3e00b62dc6e5e012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffbfe309aed5298e90341b4ddfe6ab0b769f2da957298fc48061dd6fcbe64484df010000006a47304402207addd6acc739b316e154c68b1ef7ff7f97358f7347e146fa0e6339f08298bbed022026ed13df914a73a6fe540b34c458966acf90883242ba501ab7de2798844eb7c9012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff69940d22b14cea9b2add02e39848f893296b3f5b1b95b5af0d5844e9dc9b840d010000006a473044022005b3dec5b73b977dba2194ffd017dd3c0d8a262ef32d64215dabdcaa626c126902200acdefef1846dae7c01dc1e8c88d400bcd25a23ebb6a997918320403f3128ccf012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffe580d08227f3039a7be478c9ab06f5db5a6c1dfd117a1dcf77e116868dd0150e000000006a47304402202727460fa20d3fee2a18dd99799de37ed5f762d6f1572ab4fe12e6e9d9b944230220307d2c9febbb1540b5d0e80e4a30f6e9f30cb13f9433e891c31fbe090e54ff2a012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff267e8b305992e075d13d95b0d57f9861bfed757b2a378f97d634e3520083fd36000000006a47304402205524a7a2f148993dbc5c1c7873d7e1f7275be837c18724d0f6cb66cca9d944d702207306b237087f87b036296164392a51f67002bae9f9a9596c8de07ce78f97e9a9012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff18de3ae1617129e94e81fae614cc6e650479e1d13d489fbf8cd7476f195038b9010000006b483045022100983b06ac0037e4b9d8211ece075542ecd6eb47dc5c5d3d92a22a540845784bfe022007d88458607bc78eb84da578c284d6c547e1ed624cd2c359519d32b3f6610791012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff780a0085b59683f63920a994c663da8a94dd9733870ac3d12c9e0d3db04ba19f010000006b483045022100e0328eafc375646d034f9486666dae68a2de966abc869f2f609a1bba6175a51502202572e87290e4dd023a37156551509d1d89e2886a11d5049b8bebf3a8bd0fb2f3012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff97f5b6e2e67e4a0189d098634897f7cbe53e24bf58427b096a432ff0828525f2010000006b483045022100fc7769fb7150216d97bf5b0f00c022f3157c59d548b0ab74d32d4fbfcb2a543102202340013796c3ece33764d0d344742ce0cf5a9a8b7aa02c35faeb158b2ba14a79012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff7f4a6d662884bded3170cb5f70312719ffd2167886652e71650937fd15d33abc000000006b48304502210092e098a3023366e3a99ded80fa3fabf02770546051e86e31097d738a9ef4753b0220700d37c674a5f853ae27ab6567de82130b3defb1205389ffff88032d1be89091012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff660e643e61e19aca41fff8859466e2c062036ca0a7e338024c72a38a331fdf5f000000006b4830450221008d9816310f0cc50ea1728b3c8e3e466d75bc3ea60fbafb8be00686d4a2939ff8022038b87d4dd5fc67f677eb12edfcd2d076a5e2b36d32b5a5aa1b91c7b4c3154471012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff103dee0caccbcb623da85585c8c4cd42ff67b631bd58f854b8e799d62d3cd251010000006b48304502210091489a52c6057b9ae6209ed5adb879c1ca7a6dbc0bdc3427d99253857fd1b0c20220574dac5f6ab7fdc8bcbb20d51f148768bbbf74f2e58fe71a92e4786deb05a11c012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff468457cbb4a1a7fb6aec8e31ba99422c06908490ef055af13771fd603c8e3347010000006a47304402203b56c4f7964a3073155be23d247df09725bbd3e44e607d4fac050114fee96fea02205291e22f06feda498b1c6753e681fad0eefa2ab2e00c6184fc84460ac81b7335012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff1871e7cc6d0f24c4af266ecbe5bb42db8f77e8c31002d1270ea6a4129c5318c9010000006a47304402207636178a8b0389b8b8b0be28cf84cd5dad0a79761f5e86b226f4dd54ee59f57202207f503ae6fdc805aa2160058acd97fbb0c895c6c5f4f9199c1abe2d8a22e689a7012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff2c596f8efe7feab95351a0a6510982854f1168221137936094331819611ac142000000006b483045022100d79c605dc7e994380d60cd41a32cf8b84b1ca7ba67258a227f1160716e3b9e3302205492103a87642e5bc7697c228dc26f2dbfd706c4701962963b4be029f54b01d2012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff9e02194b103dd9e927b87bfbebb4eafb2354c0387a388042396af5806597a87d010000006b48304502210098cc3eca8e6cb2be172932b9a14d645fbf530baa52a9834af2425120310997c102204da495246d55dcbeb8e06cc7bef2382de7846b49933a98e6768b6e8e006e6b33012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff6218a1e0e2b1ac3d14d338f9d5e9da78bcaf374ba903ea6f77e8c0c998ed2aef000000006b483045022100af16ba6919edf6b0b1e5d06915ef793fc5908e87d169c2fb47bcd68d8cb77264022003faea1e700cb20bcc3507d3915a052fe390c8a6417bc87f37ad4202e8230563012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffcb29c015d3756fbed443c25bb98fdc4e109a51a289ca9806149f1a0bbd83d9cb010000006a47304402207f8080a21c70fb319d5c9215798bfd31c9fbb5846a41fdba464ce8e108d2afaa02207b3bcd2ad178cb525365b82cf3c5a2c02400547dafa9e08c2930044a3f939486012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff772ebb57be90999e8757da2a3244336a8a87b6532c68b10824b8e63bed9b417c000000006a4730440220645a9628d787c46b942b79c43ae75e2d8902baa986ee71697bf7efda1a10b5c902202d705303b7b62fd5bf7cca27936ee6c4da881ab51c08a7e1c0427fe0c4232628012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff793fa80f398ef2860a24a4ecb66d844436b7935d53d381e376333ea89f443015010000006b483045022100913dc6328b8c03091761ac8a30dad4c69dc1b4cc0c58fc985ce705be861cf136022050318a8248929ee658719da49e21d718f34c7f149980dadbf843230023bbed8a012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff47a921ec8978084bbd9db3a4ad327fd516ac0a1c9ec8a94c07897ba7a7676df5000000006b4830450221009701dd3c120b403b894c4f4a0c0f67e15412d36ae22a30c5f8edec6ccad7815202203a9b07f655f2cd49e7cb56c61fe711c8fba06c1992a89d745542c01773fc4b33012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffc221647866781e58ec388f0e983988b951f44cf17fe1cbc6eaf32bbba7337f31010000006a47304402206aaac8f006684c8a1f646211c3955ed975663767ad23c9ead16f060c11c7c3ac022036791f51cdef33eafbf35a91b36e98c1e809c32fec710c2c4aeaa41518c79d89012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffde6928aa67169c6af8941926c021c4235253810ab1be34a3b781fb27d6f7751e000000006b483045022100f8c9ef90479bee68d0ff6e5035ff6632bb455aeea16bd909b3151e816296b9f902204f1c6aaa4970aecb19dd171675f54eebe70612672cdfe46768e4cdfa93469b62012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff544e333de21043c51a74ba0cc5945307a8a6559b68921bb4292a52d00c2c2b44000000006a4730440220301e729afea5892cd0b1ec30b483d6f15e70b823ed27668570a9d41c5a539174022024579353e313e088696f30c3dbbc6f3a894d3a214933ee9c7dee676081a8b5ca012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff41bd7f4d66506e9876bfad455b22b72070b1d21d26a2cd4c2e7a5696d5d56991000000006b4830450221008b5a2df0d8fa74f722ecc7002d94d819a2ab0aeb8d6725884ad8359cd302aa6c02203e08b275e7be7c46c17e1b5411545f07601d591d09541728a559165645ec15f8012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff67908cef1e654f5284ae08dce5014e0f9a78538bdac384ff0b1668f867dd8957010000006a473044022074ccb7c96c7c2fffc33dac6d27a88da040807656142f5785417a472f51ade90f0220026daacdc4d9d7aec7af02b70f8d6d7b0cad53d31ea2b31ab48bfae9d2058646012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffd6924aa11835985e45df248aa2a91d224324338544abd5f673bf194cc7c70c88010000006b4830450221008d705a9898ecc12683afe10fb3b687eba71cb71c833f33f875786a8e2320dc0e022004bad78090ad16a6173da44ffd44dbb86f942423cc3987c84f1c2bca50e66a1b012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff50d35494216cad85275a61c8fded61ab3c6e772e88284f39260e320cfb76a9fd010000006b483045022100bb2dbda4055fe20f7aafe369b8a3ae29beaa800e89215a759d6c5d10159b8b1b02200d436dea35df5ad798fd3a2220feb934dabdca6d721ff0784dff3a2d47d7d913012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffcaf5800170b4d0a670c047fbade0ca7093e05b352707f549cc356d2fa603d094010000006b48304502210088482a1d5bd05102ffbdc02681c14c2093693280f79a496aa879ffe37fe6840d02204d8e66ab685c621a5e44c36b29920f4d0d305c23dc4510cda2fdd390003d525e012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff4b20eeac32ff16941a125e002178e72db5d2187587a7f3e7bc205138e21f7da1010000006a47304402206c0d6a9094998b8743b80e5b7d3730692434e4d60f8b96aaa6708499feb4afe0022061b6cedee1d220b37ce4ba87f2a9964513d1909a9de9b7ad6c43c01a76ab933f012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffc47b2ca1fa944ab33227207640defd099296ea13edeb9647ec63df423ad8bc7b000000006a47304402201c603156e1822f3cc0ec1e28c5e7c2675f0e3535d77df643c69d3ad7b2b6c7f0022056be2cad442977b0803919d9d50ead183fe405655845c760824813745037466f012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffa2fe363cf4d14bbda2075685079d13bd6ab8c72b11789fddf2fbe7a4153d0b07000000006b483045022100e433e50453be295456d735d5743f29303ef5970bdda2d182ee1f7086c03cf8f40220716720a52be3c078441a9de039a4e1d4309357233b6b52e17ffa41b0327fee25012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff0117df3b88d1c20b6f39318dce73352fb3ab9fa72ad7ced92f8e548088ba53ba000000006b4830450221009614e74dd4566f63ffd59f404732a0d8f9ebc2b956f7afbf6fc985e37bb2df5d022056462763ffc95f6018881f39ed2b0fb2741b8588367d66001ace4e6f7097962a012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffca581c35f0fda6fb5bc3591f081016ebebfd22637d835b9f50ff8374d2878535000000006a4730440220075f8d40ca313299472e5777b53ff33f05c4ed04791e54ca457cc50c25ae749202205326276591497c85a9772bb6ad8b5958e8d56219a2ec2b6425ac448424bbd2d5012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffb9bb0a81ffe82d17407de259d82ee0206cd828c4f8c458dfa16c46fbec1611a4010000006b4830450221008e43ed7d1e799533c9080f7c6287f411f1b84a612d6af0dc0d47d7d4bfbd139402206229320025055e16b2d289c85b1b26ca66cb770090ffa10cf3f638b56eeffbee012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff3f810dabdf7dc97c5341ed8c696f806c60c25e8a308801c6c3d9339829cd5a0c000000006a473044022030aefa47a08b74a2bc45d8c637c4b78e97226f5e9761a5f10cb93ad88dec15a9022052959f2d4f65aa613e9ebee605b42923bb9c529a7f4f57eb30c203d0946cfc79012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dfffffffff8102fb19119c9f326c42bbf86da5257ae3afc04a6535f5d5377d36096afd42f010000006a4730440220587a3cf05891d5dcafa910f699f74df1afc65c2a0a5a19ca327efdc15cafb1ac02202512cb22231541bf5ace6575feb15584b123368c2bc5df61268af184d6e182e3012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff6974c18811a0091ae71213fb8e73bfe369995407b7fdbe9647f342afa4143456010000006a47304402202475f3e321ef75c085979187610b8f4ce61ddadd0210a44d36dae3d68d8cf88c02204471fe4545eaf48b063da0c557b0ff45e22dcdba24869ee19478e30a82358fc3012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff6f2564aec2e3afa0ea1043a32788c33a889bd02d55f483ac7512f911852e5469010000006a47304402201913e949b8d92d7cf406019f0d2e033ddfcc91c2908f090dc4e23d72681a85ed02206a11e63c8ea007d6e7abd8006c393c86a2ee5dc89e22d51310e8b246c9a6a42d012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff84519e2e84b28970790b9c8b3f53bda67f20334653a9a150898fe150cdcc8134000000006a473044022029fec8ed8d32f736b909f74dda66ac89f2dcba95135fefa71f36e35714deee0c02207d17a7d725a20010d03ee436ccf7231e6d4e9866a5875d2e9a443ca0e41b2b6d012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffed76a5ef7dd7ad90649bf18c319697282f9239124a5c0ec2baedc2729368f29e010000006b483045022100dfc360e50af3291c21e06e6d9ee854392bbad58e8dd4e51aa36cc19def545af70220690d1340ebce44d63b4807c2689f0f586c779c67c2cb739e4b7291a27193563b012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff88d914d59d9b3a9a667b91c0adad0f2a2cbe2ea2086002f5ca459d3726de80dd010000006a473044022000a3ab0f8db864a10d82ba9ed9bc53e963765a2d5ae7eae42527c0ad6a9d600f0220713a0e200eff854ddd2ccbdc0b64cd7f939910c55f6cd859bca9e9e3a68a3e10012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff57f3251a59d597425aa17b5a220590b695a27d13533f97c1aed70ff6b53876e4010000006b483045022100d0ba109e8ce0093b4205e7db25497bbba93ebe553febc49da783bd97eb0aa1a7022055e78172db45452fb519295108a17c2d63d5ff306f3c29eb5e3c9af1c6be12c1012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff09de6003ae5105c3ec83edeb796646c4b7e47a850f95bbb86698c5d4ebe4c154010000006b483045022100dd6755b6eebc369ef96b61106833ca0080144d27b71c40a27fe37d9c0fa355b302202ffcf18368418a18d82d21dbe9af820a3b8e969fa7976baa03db9cb440ae6962012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff2a6cb189ad60a34c106d57eef487d41de619c18b6d482dbcd594c8355c83e1cf010000006b483045022100c587ca8e1c3bcb7bb66ff3b2fb531450d349d6894e6c6e2a6ceb45eae2371a94022035774f2abcbaa445483e808d83d13059b3235593de252f3e6d8dcd8c26fc1760012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff99ce547a5672a0817e8a8830f682ef05b5c2f4a5c0c686d86224e9d3c1614e97000000006a47304402200c30834215900503bb16a134fed761b65fe411f648f1cddc0a16bc598d925db80220325fde5e1f893f682b306feb7d76db605199a5eeaa3e65e412935b17696b14fd012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff7171a23b0953b3fafc0280985b0d8fd14a80c0cc9de571fc43d78ae13878d98b010000006a47304402207692302398f93a771c758d4ed0a385b50a13ac631336aae1a7db98e3cc2e7ad6022036c444ea9f0693a77a7269a9693ec9f0a7ff7104b0f06e8c22513ab27a98abf5012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff07358aa451256a5d0ca5521e73f66f92c10611301d5bac844afd2bd8c8d224e4010000006b483045022100df025fd9bc123c3f10e03963970b60d697bf9f740ad1de125645cfa82e6b478002202061c562a03c2b68a17404d7872a4193007aadaf1b29f65c8d83e3df2b963920012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dfffffffffba58fe716cf6a6cbff216df0d679a43a95eb8bfb931dc3e37eef6051ae9bc47010000006a473044022039ad675f90492b67ac752f9f78f29eacdcf550f392cfe277b24c35709d75860b02205191648d6534d63a6f9c44fcc36aa9b0c47f51ac9acfaba77bc8a92973b47d4b012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff7d406455aa68a3c2532360b2ff9656f105492871f2f37b9c0865d9666bcf61bb000000006b483045022100f42ff210f168008aa2eb6c341fe4ebebc467e43c6e09bc0a19e25127563b31710220158c8a0b7f619b0564051f59aa8d43c6ac65a4efe762b8c4419f2b3e3d0afbbf012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff19eabd074e1fd6f8626a50009dc5ab5b5320d089768a4f3313eb5ed71241547b010000006b4830450221008cacfd2944596c4f6bf47533de37c4b7102b96087d3f0c77bb2aeaa992cc8faa0220203a13442f69543be6052cda644bd5456884255d9b992d7b5661674d55fc3412012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff4e074703fa84acc52fdab6f267ce56d5ee98d88e544367a63fd2124c6a093550010000006b483045022100d189b6616481774a42c06bff260d9185fe4d34e9e31970c856bbd4e1bebc187c02204ae70254a7a0830376ad37da384bb09c291e62816fcd2704a4ffa1b93415672b012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff053c10073ae38ab646e9e54c93c87c849979c867db4e44634c7b14836b1b83a3000000006b483045022100b21e440fd84211734a4da1d8331477eb4a036678327eb713e2fd63f3a064599302203f5fd892d9b784866bf496114fd25867cf2b136006dd0c3d361c9a3aa4749fdb012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff5fe43d35e7e2023664537ea344ab7a0ec36f87917c85010703593b6c16aeab0c000000006a47304402205842a56d44864dbddf8975758e90172263013e48b360798eba8b384ecaca609902207d8bdcbfc113a044a6f197b916c2d7c44f2db134ae91cf06a810d3706a35c34c012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff1f51e5baa2bde621406ce9681c07178e276ec102d975fd66f4e98fed08070cc8000000006b48304502210091ae0db4fc22ed9b0eca6c40fb69a5c34e569175a58f5b0482b173f224a1f402022029367099b1101c9e8a9db2e029fe3a95352d50445ab72f7f3ae54b6e70efeb9c012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffddc6c75cb0b236a2772d0d00a73114ce5e92d415d59651781a119098a582bf5d000000006a47304402202b64e2219bc5146891a3d1afd77089f80b0b622791a80db5ee61393a14bd831702203ca400946a7456149257220560aa996996ebe3d11f85565d05cdb2ec3237d0d5012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffceecfc58b983d7bfc107329eed23f4425b49362b23f086b654037999241038d5000000006a47304402202c27884b08774a44bb2a7f2c579ca6eeff25b901019508f8c3581ad85b53dbf202200d114291ab95cb0971995f2b7e0fd193ae42c7e2bbf1e9fda450af93a3494103012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffd1f192306b2bf309f6d339ccdbdff86933b94977898e94288c28a53c628778cc010000006b483045022100efc921986f328cb5bf2c366958078acee50cc661bffc832d9f39446d47fbb45a02204fea5414446639315f9e0b3b4dcefd38d5fcef4dcb7374561798af7fe1b0f3f5012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffd4d6da5ed6bb1372ec8a5dc5ddc35a5650c140363160ed511bfb427d514fa242010000006a473044022013e424200b4a5db5b288f4cb810c85c455b4c8ef8cf617bb35eea2bb1b46ca9e0220417e648b8c8fef9dfff25d77d6bffea3dd41337b7d05649d6f45ef09f811a58c012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff9afd09ac67c41dfc6787ac64e7adf36e07456beddd7f887895ae1b87bf6077f4010000006a47304402206233ddb7122ea57200322190aaa24e0d5af4ffef69502cc4360afb9503111f740220436a9e50d948542601d01b31207c71991e1851afd20627bd12f85c47d373ee02012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff01b4b22f57f4a893e700396ac7b880e7675fc79f4b22965ff08397ce9a4241f1010000006a47304402201b6d1b36ee9d6f32fbafa5a3b537683ace2dedbacf07af5986865b02a54169290220329b7a2a7661d9e91f974e9c841359dcff90f2466c57957d70268c5e32cb1a67012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffe54b78666a5acb6d534b09031ac25763627466ec7b2387f461af00cced556796000000006a4730440220137b61dcdde0242ec4a635970b1c41bac074e547406fa0abdaddf95034bb8e0102200dbf1bbdc8d7d8d6e7f23143c4a05b94e1a874eb572ea7070aa196c9a2301a5d012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff81e6ae1d073cc4a44ae59e0a921f00f487f93dd988a6e0b43ac0f39a86f8a120000000006a4730440220340856b24618c13991f04b003214355eca49b905f470ee394b0f4b140f8b0f510220426e63da5235f621e2a454431671b7db37188231df684451af200b30be87db06012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff6950b6744663f9472a3db3d8603f74dbbe9502c35b8b7b4574fbd60d4f6a62ba000000006a473044022015b9891eea5d77f60d4ef81153d75a5cedd0320d3c0eabf2d7a5760955fe96e80220507bfb0fb0d21eb8a884a4070cb1e0210b64012b6a6bf1dc5fbd252927f2d417012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffcff466fb6810ebd9091cc971efd680ae0348aa113d8d5d05198a8625f7ec3a97000000006b483045022100cf18cbf179817985e9ecc62edd6ccbeb39df56a5ef3d787c13dfaf96482ca1880220438fb4232fde25d095e0db8f8974f7d90b1ea702e086c89725d7f0d6df119d33012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff16398cc1461adff888f76f47197d5b8a5e6953b27330b9e4c3b367d199ab5f5d010000006a4730440220335647b5b7b04cac9219dde6bee891591299bb1bad8e651446c6efed29734b8b022035104d345d9f08ed3e6dba80da1e6f693c2eb329c46d69b1222f1b94e82153de012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffee4c652c1eec0edebff795e5d6b017f042fcbee1b6d9876f7c21cb48c27f285d010000006b483045022100be2872cf83f7dd33b3a05e5e96a281014fab91df4ec218ad48c26e5805c678fd02201ba6ecb5f37ddb5e2623084b6e6fc3be82587469ae29140f9352b94c56cb2548012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffdf81ae0bc5e998572d60556a8182fc62dc697814a9f11cfbe26029e2ebe4112f010000006a4730440220237d00ebfb405ee5b3b077d00f85c3368f245a08bd09fbc0fc3846cf5ab9fb6e02202e50677abce0f1cd299215986e706232647d7efab6583b75a5e56923a9fa40fb012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dfffffffff1d0d9d05d3916f946d0e5f44ce48856b25facf0151768ef03f8c4e03b74cf52000000006a47304402207bc37ebc79217f3991b76dfb6b73161f58a30bb9894d224fae8de46327a314b1022053a9f40ef5f35bb436900614d349671e1b5f76fdf8b65ba5d4a541a6cae977c1012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff4bc63849c0add2c920d147af9377a70b279df2e2e3089453b57cf38647960b92010000006a47304402204fa562e70354ef81d168cc87b28609c0ff51be667a9159199b3051735a186aad022072bfa942adddf488e32257d646fc1e726e206c380709d09ad183939118ab5966012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffec1922b1f2e3e103f3fc8024afa4f04cdb433577ff6759075d000aef4dc92b80000000006a47304402206bb933fa84aac2a641aef6bd11c744f41113bf5dfc2c33aa6ffa362645b09cc20220420ddf5c54263aac25a25245e19a0616c599a155f7be634385df42caa13dcdae012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffa3aada485086d976efcd6fb2fbea2cde75180ddc58f73d66fdc14579917cd4b8000000006b48304502210090bd95b391bb526d4fcdea6a3eddd6366b20182f969935185d798f454bef6b7b022056d07ab2f7ffa3a6f3e9f833d82ebc2bebb99fc152dbc8d555b2a1698132f54d012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff3dab0340f81c10605d31cacd51a376fb6047d9b7d3fef2186725cb56dbedae05000000006b48304502210081dac42646f7a47809915ca0d84f313d1407e210244db76fd3266ff46a082cdb02203580ebc75496af4afa2a085843ee1e8027f632a8f809d58dcc83c5faa0f47b45012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff1e178145e100f6c27f4e1265d79a142f5adde9871988cf08cbb3e6edc66cfa73010000006b483045022100cd5e89dca523471f0ad1ffa920f5f51be96debdb6da35df49d2813d3f2decc77022024cdc3038fece0fe58614ab2db287e6bdee8923a54b78235dd8cb8cb8487c99e012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff9250630549b8578e00afec707a6924607425f3569b8ae1b8bc8631cd443d5892010000006b483045022100f88a9825764230c9217d6cb744074cb353e267d1a749740628f753ff8d117cbb022019d71b3770b58d73a2f3e974609fafe562e8fb200457cc3d516a9f31cd79cadf012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff29233998da5119540ed22773430404b78880de5fa24f6567d6d9140a5421287b000000006a4730440220532f46bbfa3d5c777cb09819068fa8ede7b72478cc8a2be22439362702682aac0220346ed1e0d59dde8150c9e5be7ca107c9ae77633e43632c0f6556872e44160656012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff49226401cf7f5f3aa2252f99d15cc9305e5255094f03575ac48f5c4f25297d0c010000006b483045022100abdc09db7b6af8b58cea614f7c79a3692f31c51bb2627ef95048e8e39adf462d0220444be6c2edda2242f52f1ebb62f1b772a8116bc874bdc749b6b1baf3b0c9cff4012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff0213ecd0fe006cc5ee57f991b0efebb98d7ab425eb46bbdcab1dbdae551f6801000000006b4830450221008d13887f57e094b4b2e8051e3a1f44ec330d418797d1bdb7e24bacb7710c0ccd02207bacd00fd600be8e239707acb01308a070e2eb600dd9a1e94e6bbfc17d5a1a3d012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffbab5dee2a5f7a7a05d4ad8a3c8e89e7e25fa52d9bc66d1b3541909c5697fa0e5000000006a473044022024661f9651a3306f24cbd960523c8e64432e7997ffd23c4c5ecc18dedcfe6f9d022063f0b9490aac62eaf4b06d3771dc8443d02180d504bb34f4606a5edbd7eab0fd012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dfffffffff86b0992710db8a25946f236b3f997b284ae2f4876c997c9ac18f52a3e1e6ee7010000006b483045022100a41ed5c4d63dfcfd89b34a1308655c38261480df405af09219470c106e50f46602205ba3b8cc07331cf3723f3700b33c8ebd554765ebe163a35c0e3cee51e02f3fbf012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff37d0f5225bd39c1dbfe28947f0fa8abc0b6feaa2ebb6a4bbcf21d2ac0c8c578d010000006b483045022100b600f7b19cebb1a30056263b8d8bcf2b745432d8cfbc33c4fc2e560e7fc2ded002206cee46314a2a2f70152350ac7ca602c77edae4ab88ca6461d47caa4c61334967012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffe36b092162604581102090d426354f9dfedcc931b469fedf278c757c89615eb8010000006a47304402204761ca9757e2c3aa6d22ca69effb88826fdedab66d3964e5090bb9c99ee5500c022051a3903f39ce6b676b4de4a31fd38f4137e1164bc8b890be95d6da85766bee21012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffffb882e15c360c06e59aaa5fe22e9cac37020e9d1e898917c4426a696d8393669a000000006b483045022100b83e67e79fa495983d6eca90c452298047f75841552090ed2fa472318bff479002203fc08b33d548b1f899461a4fca84472329e7b2c06bf13a2933c259c673ba2d91012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff0e83bab0d868c724ece315ff9b431321c7b8e8ea086170051fcd464eda7d595a010000006a473044022061940299a4fcf4574c140f81f7127711d3675c50a6b72fbf66b45651e3a10a08022044b00e4e4f5cab9c36112697cb1235f7a0f8e488ec689c98dd159c9c0309fcb2012102c6baf6c152993841d239fcbaf7aec57d85259a4ff6bdbd1bf15fe7647988048dffffffff02ebbe973b000000001976a914f142bac9edabc77205ee61364b1a11c93d780b1488ac00e87648170000001976a91416f3d4d9eb5a420bfd73d3c9de4047af71c53fe688ac00000000"), SER_DISK, CLIENT_VERSION);
CTransaction spendingTx(deserialize, spendStream);
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
filter.insert(uint256S("0xa41116ecfb466ca1df58c4f8c428d86c20e02ed859e27d40172de8ff810abbb9"));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match tx hash");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// byte-reversed tx hash
filter.insert(ParseHex("b9bb0a81ffe82d17407de259d82ee0206cd828c4f8c458dfa16c46fbec1611a4"));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match manually serialized tx hash");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
filter.insert(ParseHex("3044022074bc105e27ab462ad7faf919f50be2d9aba66be4fbe5499ffcc75419d17c4e27022057389ea4bcc44855fd0c2049cfca5aeb8817ef26cc9c33a57fc741ef1183626c01"));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match input signature");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
filter.insert(ParseHex("02fdc596855e2fcdcdc23d798e00c555726aaece8e85e1178237564af3ae4eaafb"));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match input pub key");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
filter.insert(ParseHex("9c5781278b716c047ee60e5a3f29a98f55c5ef3f"));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match output address");
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(spendingTx), "Simple Bloom filter didn't add output");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
filter.insert(ParseHex("1617f86512c72526c0cde953dc43bf5fd41ded20"));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match output address");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
filter.insert(COutPoint(uint256S("0x24d2956698d2e40e6077d5e57e8849b1cca154e6dd627865d3e2792b57fd3421"), 1));
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match COutPoint");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
COutPoint prevOutPoint(uint256S("0x24d2956698d2e40e6077d5e57e8849b1cca154e6dd627865d3e2792b57fd3421"), 1);
{
std::vector<unsigned char> data(32 + sizeof(unsigned int));
memcpy(data.data(), prevOutPoint.hash.begin(), 32);
memcpy(data.data()+32, &prevOutPoint.n, sizeof(unsigned int));
filter.insert(data);
}
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match manually serialized COutPoint");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
filter.insert(uint256S("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436"));
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random tx hash");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
filter.insert(ParseHex("0000006d2965547608b9e15d9032a7b9d64fa431"));
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random address");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1));
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about");
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
filter.insert(COutPoint(uint256S("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about");
}
BOOST_AUTO_TEST_CASE(merkle_block_1)
{
CBlock block = getBlock13b8a();
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the last transaction
filter.insert(uint256S("0x35dec570275a395a8a297c726ac48ad2674b1683f7e1ad5b93cc96dfe7dab94b"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex());
BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 1U);
std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x35dec570275a395a8a297c726ac48ad2674b1683f7e1ad5b93cc96dfe7dab94b"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 8);
std::vector<uint256> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
for (unsigned int i = 0; i < vMatched.size(); i++)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
// Also match the 8th transaction
filter.insert(uint256S("0x50bd80d89cc7e00a33698deac6438d965f94e9d058d62874b0250f84e0d8ff9c"));
merkleBlock = CMerkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2);
BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x50bd80d89cc7e00a33698deac6438d965f94e9d058d62874b0250f84e0d8ff9c"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 7);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
for (unsigned int i = 0; i < vMatched.size(); i++)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
}
BOOST_AUTO_TEST_CASE(merkle_block_2)
{
// Random real mainnet block 1525 (00000026710729f8bf2e45d6ac9e9e02db4a4d4fc393b3c4ae48c330615ecae8)
// With 13 txes
CBlock block;
CDataStream stream(ParseHex("03000000e680e2a6e09b4d6398bcfb723b9039d73f68aa91ddfbbc2cab8f63f243000000c7b8b35c26d3b9a744cf13116bbc362fe1e7a4a3a5e7376ca639d26695244780c86c8b592d1c6a1d22f01600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0502f5050117ffffffff026d18c50400000000232102a82d913ffd876a0e971e4cee199901446c06a7a26d4d4e01855d501e24140cc6ac1b463101000000001976a9147d7a3cb519a73f67d17ec26f50ba575a407c822e88ac0000000001000000016f7ab10bdf75a6566da2796ffe6850b9ce407757c99deade9c0a98bbb759f08b010000006a47304402200aeee55cf0a2809b04b1f9a998de539c116a6df14517fc7b690fc289e1dc5b4602206fde2d825d1be7c2741d14411dce32c3019d0d7624f7fe74308a784e686f215b0121022557c56946dd35cd55756c9cab09e622c459c6cacf1edd76f72102442d73301effffffff0235c5f9db3a0700001976a914c96a267af2c97828ffde02e40f4f5e7a0597e72388ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac000000000100000001cb9bee0fab319c23f9181625c8fec7dab23bc5161d95101ad661ba0e1eb24c17000000006a47304402207258ebd0d623d8f35da3c56ce6585472405bfbe692294b6cab3a0da2962621c302205471863a93d963b4a0cee81fbe24c302e9706328bbcc76af362cb98e16acadfb012102b7fcd79bda73b43b251398c8badd510598e710f926bbf8c74160f95ecd82e429ffffffff0200ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888acc6f05ea03a0700001976a914545597003f4f0c31bad4c48b39949e2c953a950c88ac000000000100000001196ca11818a9d75ca3528a3b006f9749b6e5f5bf01bf46dc511204c1bcd8ffd8010000006a4730440220457a4481f566177b5bd7e78822ca22cd0d8ef9d6d80e776d53dbbf8f6560f97502206a563ab3eaad5e81659acc8a16bc4cdae7ba00da7e1c039a564abc41cebe53d40121028ef726134fb7b8a89bc5f8bb9bccde8f3e08d0fc077feb6e641228c8ba1de502ffffffff0200ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac571cc4643a0700001976a91437a21d7534ed7ed083491fb6917b51e77d184d1d88ac0000000001000000019eee83d604a7008f963ea0c08e5dc4cd53f45f1d3a1d7ab1b72670582d2a2cf4010000006b48304502210081efcf063092f6716f877a32ccec66a48ce05c62c04c3f21f55bedeba732fcd30220648219a29b62a7212f0a41d5cdd66897508030af81f983e8d2739399e951a446012102b3272d9bd74e3c352d160cf5358bd0f4949c9878fabf0ec68dc1bb5114d87072ffffffff02dc4729293a0700001976a91475b73d4f6bec883ab023c239132ff979971b04da88ac00ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac0000000001000000015e65430ff1bbfee84a7341c497ce58d992a4ca5debf32c93155080cc73d4a525000000006a47304402200a1cc352d2ac99000eac88d918ff0661a5cef345fce520c969d210d67943384a02200b1ce61152beeafe111b9741649080b67807d6874169d095cd46c714411e97cc012103c0af645b4adc08cc605333f2d7340e41c4038513f44441996aad175b54714472ffffffff0200ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac6d738eed390700001976a914f72c89043016387192c0b23e25999d32ba433eaf88ac000000000100000001e5f5b685114fbe3eaa6908b45e82fa406c8d2c36a66b062cf13801ed059dd4ac010000006b483045022100c0ec2cae6c5c7dd74bc1a058c4cf7341ddc3a174abd1da45abafaf3c74a6963502206406fee80e25e1e6233fe6aa0d41f297b34045469b949bf2aa0fdda6ef60c3b80121026d7d41aa7a413faa2e45ae35663c7099ede8d0248e4c11f77c741c3d58c2a0e0ffffffff0200ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888acf29ef3b1390700001976a91430d0b87194a3c0a87b28d5f2cc94915d9547c09988ac000000000100000001af59a0aab44bdf92734124b0f0e919adbb56c39de2bf57b0bd48e2cd36b6fad3010000006b4830450221009d1aac067c463265397898f4e1bcba2f45cd58e58abcef74b2a07152a69a852c022002a425220d2df70ca3d2d1f7f051f12724e6e042fc55f2c884e416bbb3a6c77f0121038bcddffce8325fd4e9bec1f029f2bea10d7a614ec2ef4ec35c1086152a51643dffffffff0200ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac77ca5876390700001976a914ed6cc8200a1e9149eb5f75a199c1f51e78c658c288ac000000000100000001f869d14c8f2877b5c24d872931b7d77098b737d9f1dd01cf24c4fa0fc5ea795b010000006b483045022100f85226844199106902012463b2eaa3f472de5623cd65fea7290923e88a3a841a0220377ad9607b9cee41768306dcce3a23b4cbd59964f2258dac0b4387293143406c01210244d99ecbec03fdfbbcf6a3cad26c9eb9ef00d70cd684bab1010aaff3871a3ee6ffffffff02fcf5bd3a390700001976a91489f03209447529521bb2da16d5d368e9b600aefc88ac00ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac000000000100000001d5cc4a318abb78cfd9edb886330121afadc93410a8553db029734297d6cd33ee000000006b483045022100b4e1a0346bc5fa84822376bb8870ad03f768d35e3dfc6224e90217b9843bed4b022029edf8cb89442702914aeeca95c025e0e5a7b2d2cbbd98792966f2e5cb612ef0012103544416963ed248c47064c33735a7f8059179428c838428d806843758cd434fcbffffffff02812123ff380700001976a9145162e0eba3e08b4779d75e33b148dd943281d6f888ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac0000000001000000014ea199d9749376bcc90cc715272dab149db470f899f22184c07932f006d70afc000000006a473044022048a3ad9d71e3b4c6b710662b686994bfccaa44978da1e5e1e9dcee17665560660220032747e6e170de8b3b8cbb39ecb7d9cfe3d9ba56a869f28a1aac0e5d2498034e0121039136901122d97dfaeccee71ddae7f2fd61ebcc8ad907f02b936ac3e65d146798ffffffff0200ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac124d88c3380700001976a91437d2914a64b7e142e6798a29ec0cae7bc06883f388ac000000000100000001374b15805ae985ac1c5be3a79b4ba326d39565786e260f49c236161030f1ac5a010000006a47304402207838658626306701bb2848917c74df3dff533751123075ba5510e3b29c7042e602202187a83b0a4db8d28d968a258159e570757edddd2de6be516dec5827d783c442012102c62ed70f45eb9f92850c6dacb9168e32b60660499da599fa9a46902d8454276cffffffff02a378ed87380700001976a9146f6abd23be328135d21773bf42db48a0b2c425d288ac00ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac0000000001000000017ba266ebd7a3af44a58d4ce4b4b0f0ef219f8cf1c5486aa35f654d35253c7c87000000006b483045022100b2be79ea7e6e43350fee5dbd772e9360462aca3a4870a42f8b991c26d53f380702206c0e31d224fe8737eaca25944616a95228b9ee62f11149ea1933de6171e465a101210252b419d7766a408e996a68318be35c0a9bd091dfb676116d54ddb2cee6ba8c46ffffffff0228a4524c380700001976a914664fec3147bf9d2468daf25f45a4aeb8995fd3ad88ac00ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
stream >> block;
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the first transaction
filter.insert(uint256S("0xbe73c995150a0a34f70e94a8e8b884bfa7cb561594633e7de58f4229285c0610"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xbe73c995150a0a34f70e94a8e8b884bfa7cb561594633e7de58f4229285c0610"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
std::vector<uint256> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
for (unsigned int i = 0; i < vMatched.size(); i++)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
// Match an output from the second transaction (the pubkey for address Bi3Lqfndi8obPZQ85PjyVb7AWRN2QEAbdP)
// This should match the fifth transaction because it spends the output matched
// It also matches the ninth transaction, which spends to the pubkey again
filter.insert(ParseHex("9c5781278b716c047ee60e5a3f29a98f55c5ef3f"));
merkleBlock = CMerkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 4);
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x174cb21e0eba61d61a10951d16c53bb2dac7fec8251618f9239c31ab0fee9bcb"));
BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0xacd49d05ed0138f12c066ba6362c8d6c40fa825eb40869aa3ebe4f1185b6f5e5"));
BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 5);
BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256S("0xfc0ad706f03279c08421f299f870b49d14ab2d2715c70cc9bc769374d999a14e"));
BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 9);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
for (unsigned int i = 0; i < vMatched.size(); i++)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
}
BOOST_AUTO_TEST_CASE(merkle_block_2_with_update_none)
{
// Random real mainnet block 1525 (00000026710729f8bf2e45d6ac9e9e02db4a4d4fc393b3c4ae48c330615ecae8)
// With 13 txes
CBlock block;
CDataStream stream(ParseHex("03000000e680e2a6e09b4d6398bcfb723b9039d73f68aa91ddfbbc2cab8f63f243000000c7b8b35c26d3b9a744cf13116bbc362fe1e7a4a3a5e7376ca639d26695244780c86c8b592d1c6a1d22f01600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0502f5050117ffffffff026d18c50400000000232102a82d913ffd876a0e971e4cee199901446c06a7a26d4d4e01855d501e24140cc6ac1b463101000000001976a9147d7a3cb519a73f67d17ec26f50ba575a407c822e88ac0000000001000000016f7ab10bdf75a6566da2796ffe6850b9ce407757c99deade9c0a98bbb759f08b010000006a47304402200aeee55cf0a2809b04b1f9a998de539c116a6df14517fc7b690fc289e1dc5b4602206fde2d825d1be7c2741d14411dce32c3019d0d7624f7fe74308a784e686f215b0121022557c56946dd35cd55756c9cab09e622c459c6cacf1edd76f72102442d73301effffffff0235c5f9db3a0700001976a914c96a267af2c97828ffde02e40f4f5e7a0597e72388ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac000000000100000001cb9bee0fab319c23f9181625c8fec7dab23bc5161d95101ad661ba0e1eb24c17000000006a47304402207258ebd0d623d8f35da3c56ce6585472405bfbe692294b6cab3a0da2962621c302205471863a93d963b4a0cee81fbe24c302e9706328bbcc76af362cb98e16acadfb012102b7fcd79bda73b43b251398c8badd510598e710f926bbf8c74160f95ecd82e429ffffffff0200ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888acc6f05ea03a0700001976a914545597003f4f0c31bad4c48b39949e2c953a950c88ac000000000100000001196ca11818a9d75ca3528a3b006f9749b6e5f5bf01bf46dc511204c1bcd8ffd8010000006a4730440220457a4481f566177b5bd7e78822ca22cd0d8ef9d6d80e776d53dbbf8f6560f97502206a563ab3eaad5e81659acc8a16bc4cdae7ba00da7e1c039a564abc41cebe53d40121028ef726134fb7b8a89bc5f8bb9bccde8f3e08d0fc077feb6e641228c8ba1de502ffffffff0200ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac571cc4643a0700001976a91437a21d7534ed7ed083491fb6917b51e77d184d1d88ac0000000001000000019eee83d604a7008f963ea0c08e5dc4cd53f45f1d3a1d7ab1b72670582d2a2cf4010000006b48304502210081efcf063092f6716f877a32ccec66a48ce05c62c04c3f21f55bedeba732fcd30220648219a29b62a7212f0a41d5cdd66897508030af81f983e8d2739399e951a446012102b3272d9bd74e3c352d160cf5358bd0f4949c9878fabf0ec68dc1bb5114d87072ffffffff02dc4729293a0700001976a91475b73d4f6bec883ab023c239132ff979971b04da88ac00ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac0000000001000000015e65430ff1bbfee84a7341c497ce58d992a4ca5debf32c93155080cc73d4a525000000006a47304402200a1cc352d2ac99000eac88d918ff0661a5cef345fce520c969d210d67943384a02200b1ce61152beeafe111b9741649080b67807d6874169d095cd46c714411e97cc012103c0af645b4adc08cc605333f2d7340e41c4038513f44441996aad175b54714472ffffffff0200ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac6d738eed390700001976a914f72c89043016387192c0b23e25999d32ba433eaf88ac000000000100000001e5f5b685114fbe3eaa6908b45e82fa406c8d2c36a66b062cf13801ed059dd4ac010000006b483045022100c0ec2cae6c5c7dd74bc1a058c4cf7341ddc3a174abd1da45abafaf3c74a6963502206406fee80e25e1e6233fe6aa0d41f297b34045469b949bf2aa0fdda6ef60c3b80121026d7d41aa7a413faa2e45ae35663c7099ede8d0248e4c11f77c741c3d58c2a0e0ffffffff0200ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888acf29ef3b1390700001976a91430d0b87194a3c0a87b28d5f2cc94915d9547c09988ac000000000100000001af59a0aab44bdf92734124b0f0e919adbb56c39de2bf57b0bd48e2cd36b6fad3010000006b4830450221009d1aac067c463265397898f4e1bcba2f45cd58e58abcef74b2a07152a69a852c022002a425220d2df70ca3d2d1f7f051f12724e6e042fc55f2c884e416bbb3a6c77f0121038bcddffce8325fd4e9bec1f029f2bea10d7a614ec2ef4ec35c1086152a51643dffffffff0200ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac77ca5876390700001976a914ed6cc8200a1e9149eb5f75a199c1f51e78c658c288ac000000000100000001f869d14c8f2877b5c24d872931b7d77098b737d9f1dd01cf24c4fa0fc5ea795b010000006b483045022100f85226844199106902012463b2eaa3f472de5623cd65fea7290923e88a3a841a0220377ad9607b9cee41768306dcce3a23b4cbd59964f2258dac0b4387293143406c01210244d99ecbec03fdfbbcf6a3cad26c9eb9ef00d70cd684bab1010aaff3871a3ee6ffffffff02fcf5bd3a390700001976a91489f03209447529521bb2da16d5d368e9b600aefc88ac00ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac000000000100000001d5cc4a318abb78cfd9edb886330121afadc93410a8553db029734297d6cd33ee000000006b483045022100b4e1a0346bc5fa84822376bb8870ad03f768d35e3dfc6224e90217b9843bed4b022029edf8cb89442702914aeeca95c025e0e5a7b2d2cbbd98792966f2e5cb612ef0012103544416963ed248c47064c33735a7f8059179428c838428d806843758cd434fcbffffffff02812123ff380700001976a9145162e0eba3e08b4779d75e33b148dd943281d6f888ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac0000000001000000014ea199d9749376bcc90cc715272dab149db470f899f22184c07932f006d70afc000000006a473044022048a3ad9d71e3b4c6b710662b686994bfccaa44978da1e5e1e9dcee17665560660220032747e6e170de8b3b8cbb39ecb7d9cfe3d9ba56a869f28a1aac0e5d2498034e0121039136901122d97dfaeccee71ddae7f2fd61ebcc8ad907f02b936ac3e65d146798ffffffff0200ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac124d88c3380700001976a91437d2914a64b7e142e6798a29ec0cae7bc06883f388ac000000000100000001374b15805ae985ac1c5be3a79b4ba326d39565786e260f49c236161030f1ac5a010000006a47304402207838658626306701bb2848917c74df3dff533751123075ba5510e3b29c7042e602202187a83b0a4db8d28d968a258159e570757edddd2de6be516dec5827d783c442012102c62ed70f45eb9f92850c6dacb9168e32b60660499da599fa9a46902d8454276cffffffff02a378ed87380700001976a9146f6abd23be328135d21773bf42db48a0b2c425d288ac00ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac0000000001000000017ba266ebd7a3af44a58d4ce4b4b0f0ef219f8cf1c5486aa35f654d35253c7c87000000006b483045022100b2be79ea7e6e43350fee5dbd772e9360462aca3a4870a42f8b991c26d53f380702206c0e31d224fe8737eaca25944616a95228b9ee62f11149ea1933de6171e465a101210252b419d7766a408e996a68318be35c0a9bd091dfb676116d54ddb2cee6ba8c46ffffffff0228a4524c380700001976a914664fec3147bf9d2468daf25f45a4aeb8995fd3ad88ac00ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
stream >> block;
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE);
// Match the first transaction
filter.insert(uint256S("0xbe73c995150a0a34f70e94a8e8b884bfa7cb561594633e7de58f4229285c0610"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0xbe73c995150a0a34f70e94a8e8b884bfa7cb561594633e7de58f4229285c0610"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
std::vector<uint256> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
for (unsigned int i = 0; i < vMatched.size(); i++)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
// Match an output from the third transaction (the pubkey hash for address BknoNAY4mErMmv1dZziv7ctLQSTRLARgav)
// This should not match the third transaction though it spends the output matched
// It will match the fourth transaction, which has another pay-to-pubkey output to the same address
filter.insert(ParseHex("ba7fc8f8ccaa75e078961c8888e98c89213d85a8"));
merkleBlock = CMerkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 4);
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0xd8ffd8bcc1041251dc46bf01bff5e5b649976f003b8a52a35cd7a91818a16c19"));
BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 2);
BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0xd3fab636cde248bdb057bfe29dc356bbad19e9f0b024417392df4bb4aaa059af"));
BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 6);
BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256S("0x5aacf130101636c2490f266e786595d326a34b9ba7e35b1cac85e95a80154b37"));
BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 10);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
for (unsigned int i = 0; i < vMatched.size(); i++)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
}
BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize)
{
// Random real mainnet block 1000 (0000009d90967e8b3128906b6566eccfc5b167ed27004f6a7d998fcfcfe08ee6)
// With one tx
CBlock block;
CDataStream stream(ParseHex("0300000035486cdf2b8f6621f6373d8c8287f5692a636fa0fcf7516185ef1ffc62000000c2a179fe12d4faed5cd853585aa9e0e1301f26bcb767eea4235140d38e960d79c2ec8a59d8af001e4ab60900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0502e8030109ffffffff0200b4c40400000000232102fc6a458929c9cef89de235970bca84d8353b84e70ee3fd791b8d3cc8e1d3c637ac002d3101000000001976a9147d7a3cb519a73f67d17ec26f50ba575a407c822e88ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
stream >> block;
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the only transaction
filter.insert(uint256S("0x790d968ed3405123a4ee67b7bc261f30e1e0a95a5853d85cedfad412fe79a1c2"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x790d968ed3405123a4ee67b7bc261f30e1e0a95a5853d85cedfad412fe79a1c2"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
std::vector<uint256> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
for (unsigned int i = 0; i < vMatched.size(); i++)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
CDataStream merkleStream(SER_NETWORK, PROTOCOL_VERSION);
merkleStream << merkleBlock;
std::vector<unsigned char> vch = ParseHex("0300000035486cdf2b8f6621f6373d8c8287f5692a636fa0fcf7516185ef1ffc62000000c2a179fe12d4faed5cd853585aa9e0e1301f26bcb767eea4235140d38e960d79c2ec8a59d8af001e4ab60900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001c2a179fe12d4faed5cd853585aa9e0e1301f26bcb767eea4235140d38e960d790101");
std::vector<char> expected(vch.size());
for (unsigned int i = 0; i < vch.size(); i++)
expected[i] = (char)vch[i];
BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), merkleStream.begin(), merkleStream.end());
}
BOOST_AUTO_TEST_CASE(merkle_block_4)
{
// Random real mainnet block 1295 (0000001d3bdcc0d1fab90cb9b821353da5582585d1feeee709d999ff21320512)
// With 13 txes
CBlock block;
CDataStream stream(ParseHex("03000000c762eb3b258c964658c738feea9f93db3ddefe5a1bf0f6bea19f0ccb15000000aa95233e089fc2faf0c66d370d32936a1f9a7ef28725c996c7552dc3f08334f6a7358b59aec8001e48d21400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05020f050101ffffffff021d13c504000000002321033e254567ac5469ccf602aa8439aa3690e30c9add8ecb6f3ce055867b7eb95062acc7443101000000001976a9147d7a3cb519a73f67d17ec26f50ba575a407c822e88ac000000000100000001229c462e3e4345ae5cd46937af63b1020de36e94d898ea3afef7b6be7b2ce20d010000006a473044022016bb149bf67b03439f1b9297fb6cf980e10f616512f5ae24a6b71ad252b3372c0220662487af3fb5f7fe11b78460683b700d2375f1838788a95c1644ad28456c28bd012102404ca28ac01a9f948a34491e02e433198e83a118fbafbaa9b52db75cb4083f7fffffffff02f11567c3b20900001976a914caebdec3adf8f99d5ce8213c7adaeed90167cfb488ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac0000000001000000013ce05b435e0b8f891cee3638b535b798887333fe8d091633e7d64289ab464d54000000006a473044022052948bfd09bfb4d4c36aa147e0fbb605b9c78f6348cd74347e10e9f62696ad8c022021e0f32acf0cad0af206db08e4c43b1a6bbbb9092b0fbac9265b41b159d249820121023aa9c8ae47ae6ee13ab96d2e84af785660dbc7e6e22c403b6a67b4fdd07585abffffffff020542cc87b20900001976a9143e77d120d3585c6b241494260cab1d3321f2067188ac00ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac000000000100000001af1a67c2419ca63366fe6be93735dc641bd75bd9382a80de90cd47f39f305169000000006a47304402203a7898655915fd51685446d4beb8bf3658c491d5c7edfadf7f35db85b428210c02203c920bf7eff603a853c2f6fb1e380fa04d90f8feb0a6c74102b729cbaaffd39a0121021593d23c6ee5c8e88863db753747efc4fd421822d008b367e5cd11abd54123e2ffffffff0200ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac196e314cb20900001976a9143e0ea691e152bfe4bc7cea92df243e96f5049e4b88ac0000000001000000012ae69d3dd0dbdb03d814b6ff53fed00709ca69114a29a9f5bd445b2a25fec691010000006b48304502210092a28a1822cf72358e1ed934c38e9b728bd24edda955292a38d3082c9ea0b8a9022048db9e0c50dba465eb3a48378a5907f6c49fdda60758992b6141a0e256f892520121026de2041f3dbfb44e0eb356efd57a6110037fa766a8f55f787c4cf911a21c3083ffffffff0200ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac2d9a9610b20900001976a91456eedbf725b2dd72263ba2a46a5313aace7657e288ac000000000100000001f24c019b133c8733223bbb807ea01c2643d561ee82cb704134c825f00a84435d010000006a47304402206273d060d73514cfe436c6873bc2c475071c016116f276a0f677b8d04d840b1f0220533b3aa53587344b301b30dd8e9e3436e7f2bf339e9ad57ae5ff7488f000f1ec0121023e3fb614a8479eb0faee9d4c2f650611dddf2654f61322fcd754e7fe1b1ef6bcffffffff024cc6fbd4b10900001976a91447219483be4d5f601af119f305308544b1d1cf3f88ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac000000000100000001c0246062f0f2f20d025ddbacea5704b302280802c0535257b1ecc28052c5e02e000000006a47304402201d37afd8b8d2babc92e9d7074a7752426511cb50a7a1699aca7409eb125ce22e0220591a24a6e532f1c5c32e5e1d88ec07eb729350f0a5d10d433fb19b243aeff23401210391b38899c04efc03346e45e1400f6a672c8b76c1602eca296de08597221f856dffffffff0200ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac60f26099b10900001976a914563ce273ad9a4bbaec3724f292d13480bf4129b788ac0000000001000000012249ac508d394500cd5475d196be5f21c344412d12dd599200b365a765b15af8010000006a473044022060506da0ee97fae10b852d95cede4afb14072d144a245e9225cfa783169593fc022000b6da4ef93bcfdcd483494a042ca3c778674313ad97c64f23777b2f49c67883012102ddb4dc9fddb08390b508575158ded2ed8e342d73f4907564e368190589d67410ffffffff0200ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac7f1ec65db10900001976a914dd403efa39dc27282c05ae926529a1c2c9c9f2d388ac000000000100000001f1b041e4ec1772fd03318b68160406e3136317d6cef18c89ea2a20dd778bcb29010000006b483045022100a326111229af7027d1d417d5dbafbde1540d5d1dc70bce4b023f2777b93dfdf4022027054bb9ba82d683d069917b2794b171bd2f1e702077af6e8e6a48e3aa200495012102c19a09577dca933fbc232934937de49563b77f2868a01d0a25f921c6a5b29d32ffffffff0200ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac934a2b22b10900001976a91461e09f468be3d08ed2b49bc6a4b8e92e84b73a1488ac000000000100000001acc5db040cac2e8292cdfe8b861f7095f377de8e8d8031bd1eba6e7d25685885010000006b48304502210095774ef147d77b4b1b091bf302b996d149d7183202c0000d6b7fae41e09e940402206bf2b3c7c15927a9dcffb176b17bbb23fa5747b95261232d551b6b11f42cc3a9012103e9c44c5388c128ee141310d48dbf51745f7fb2aeea018b215d713586ca40fb6bffffffff0200ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88aca77690e6b00900001976a9146918ade56abe1d0a0f2f33f888017e10f5e33e8688ac0000000001000000016792865f2f10effbe09a1f818302cdab2a663af17edb1e95eb40d4e358aa6d5c010000006b483045022100c731646b5d285f904b43f26f3f86040b21b5a9f25e9d44a60f3c040c640351c1022070aed5a5c94a89eee2c2cd4484c234c32af7993784b5c772f3c31b5261596ea30121027fb179647854b9e04f7e745d40ed412ae8397658dc223d675b411eea0eccaed8ffffffff02bba2f5aab00900001976a914339b310e1dd13fa157b174290a399b6f7db7625d88ac00ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac000000000100000001a5bf4d334702570d2851c4bdf4a4709a859302f0ec9c61e01037a8a0b524c7a5000000006a47304402200327fd035357206724ac771c0f4dad530e8140c9e00f56db21a1b209f0251033022029539b1f4f360a50d087f5adbef35356f27663f44113c8185dd966da23ddeb5a012103719ae1953097622df373f1eb631794d54d28cb81ab7d59bb9cb6da5efe2c9b5dffffffff02dace5a6fb00900001976a91440fff735001b22b50468d8edecc51d3753c6ae7688ac00ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac000000000100000001017b37201d4f24673f9c0e18b4163afe47c2bb13cd9a7d6aa1a6f9db4d24d3fb000000006a47304402204d0fc656b86d6197904ae448681b8afe0911c085ef041437aafd4ab9f1973f68022059f2cc7a599a4e08e23b3dd42756f663c9ce6abb237963de98875951cdfd3f250121037fb305455db3509910704a8f429ea4aeff2c46bf60a8d7fdc75f07b94278e833ffffffff0200ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88aceefabf33b00900001976a91460d8dab232c50a0ab568ad0b5540d9e736967a5588ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
stream >> block;
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
// Match the last transaction
filter.insert(uint256S("0x661580e3ef1bdd89e86c8a5afc440bd319e49da9d69f3123a9b12b8ad96ac7a3"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0];
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x661580e3ef1bdd89e86c8a5afc440bd319e49da9d69f3123a9b12b8ad96ac7a3"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 12);
std::vector<uint256> vMatched;
std::vector<unsigned int> vIndex;
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
for (unsigned int i = 0; i < vMatched.size(); i++)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
// Also match the 4th transaction
filter.insert(uint256S("0x91c6fe252a5b44bdf5a9294a1169ca0907d0fe53ffb614d803dbdbd03d9de62a"));
merkleBlock = CMerkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2);
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x91c6fe252a5b44bdf5a9294a1169ca0907d0fe53ffb614d803dbdbd03d9de62a"));
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 3);
BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched, vIndex) == block.hashMerkleRoot);
BOOST_CHECK(vMatched.size() == merkleBlock.vMatchedTxn.size());
for (unsigned int i = 0; i < vMatched.size(); i++)
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
}
BOOST_AUTO_TEST_CASE(merkle_block_4_test_p2pubkey_only)
{
// Random real mainnet block 1295 (0000001d3bdcc0d1fab90cb9b821353da5582585d1feeee709d999ff21320512)
// With 13 txes
CBlock block;
CDataStream stream(ParseHex("03000000c762eb3b258c964658c738feea9f93db3ddefe5a1bf0f6bea19f0ccb15000000aa95233e089fc2faf0c66d370d32936a1f9a7ef28725c996c7552dc3f08334f6a7358b59aec8001e48d21400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05020f050101ffffffff021d13c504000000002321033e254567ac5469ccf602aa8439aa3690e30c9add8ecb6f3ce055867b7eb95062acc7443101000000001976a9147d7a3cb519a73f67d17ec26f50ba575a407c822e88ac000000000100000001229c462e3e4345ae5cd46937af63b1020de36e94d898ea3afef7b6be7b2ce20d010000006a473044022016bb149bf67b03439f1b9297fb6cf980e10f616512f5ae24a6b71ad252b3372c0220662487af3fb5f7fe11b78460683b700d2375f1838788a95c1644ad28456c28bd012102404ca28ac01a9f948a34491e02e433198e83a118fbafbaa9b52db75cb4083f7fffffffff02f11567c3b20900001976a914caebdec3adf8f99d5ce8213c7adaeed90167cfb488ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac0000000001000000013ce05b435e0b8f891cee3638b535b798887333fe8d091633e7d64289ab464d54000000006a473044022052948bfd09bfb4d4c36aa147e0fbb605b9c78f6348cd74347e10e9f62696ad8c022021e0f32acf0cad0af206db08e4c43b1a6bbbb9092b0fbac9265b41b159d249820121023aa9c8ae47ae6ee13ab96d2e84af785660dbc7e6e22c403b6a67b4fdd07585abffffffff020542cc87b20900001976a9143e77d120d3585c6b241494260cab1d3321f2067188ac00ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac000000000100000001af1a67c2419ca63366fe6be93735dc641bd75bd9382a80de90cd47f39f305169000000006a47304402203a7898655915fd51685446d4beb8bf3658c491d5c7edfadf7f35db85b428210c02203c920bf7eff603a853c2f6fb1e380fa04d90f8feb0a6c74102b729cbaaffd39a0121021593d23c6ee5c8e88863db753747efc4fd421822d008b367e5cd11abd54123e2ffffffff0200ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac196e314cb20900001976a9143e0ea691e152bfe4bc7cea92df243e96f5049e4b88ac0000000001000000012ae69d3dd0dbdb03d814b6ff53fed00709ca69114a29a9f5bd445b2a25fec691010000006b48304502210092a28a1822cf72358e1ed934c38e9b728bd24edda955292a38d3082c9ea0b8a9022048db9e0c50dba465eb3a48378a5907f6c49fdda60758992b6141a0e256f892520121026de2041f3dbfb44e0eb356efd57a6110037fa766a8f55f787c4cf911a21c3083ffffffff0200ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac2d9a9610b20900001976a91456eedbf725b2dd72263ba2a46a5313aace7657e288ac000000000100000001f24c019b133c8733223bbb807ea01c2643d561ee82cb704134c825f00a84435d010000006a47304402206273d060d73514cfe436c6873bc2c475071c016116f276a0f677b8d04d840b1f0220533b3aa53587344b301b30dd8e9e3436e7f2bf339e9ad57ae5ff7488f000f1ec0121023e3fb614a8479eb0faee9d4c2f650611dddf2654f61322fcd754e7fe1b1ef6bcffffffff024cc6fbd4b10900001976a91447219483be4d5f601af119f305308544b1d1cf3f88ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac000000000100000001c0246062f0f2f20d025ddbacea5704b302280802c0535257b1ecc28052c5e02e000000006a47304402201d37afd8b8d2babc92e9d7074a7752426511cb50a7a1699aca7409eb125ce22e0220591a24a6e532f1c5c32e5e1d88ec07eb729350f0a5d10d433fb19b243aeff23401210391b38899c04efc03346e45e1400f6a672c8b76c1602eca296de08597221f856dffffffff0200ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac60f26099b10900001976a914563ce273ad9a4bbaec3724f292d13480bf4129b788ac0000000001000000012249ac508d394500cd5475d196be5f21c344412d12dd599200b365a765b15af8010000006a473044022060506da0ee97fae10b852d95cede4afb14072d144a245e9225cfa783169593fc022000b6da4ef93bcfdcd483494a042ca3c778674313ad97c64f23777b2f49c67883012102ddb4dc9fddb08390b508575158ded2ed8e342d73f4907564e368190589d67410ffffffff0200ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac7f1ec65db10900001976a914dd403efa39dc27282c05ae926529a1c2c9c9f2d388ac000000000100000001f1b041e4ec1772fd03318b68160406e3136317d6cef18c89ea2a20dd778bcb29010000006b483045022100a326111229af7027d1d417d5dbafbde1540d5d1dc70bce4b023f2777b93dfdf4022027054bb9ba82d683d069917b2794b171bd2f1e702077af6e8e6a48e3aa200495012102c19a09577dca933fbc232934937de49563b77f2868a01d0a25f921c6a5b29d32ffffffff0200ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac934a2b22b10900001976a91461e09f468be3d08ed2b49bc6a4b8e92e84b73a1488ac000000000100000001acc5db040cac2e8292cdfe8b861f7095f377de8e8d8031bd1eba6e7d25685885010000006b48304502210095774ef147d77b4b1b091bf302b996d149d7183202c0000d6b7fae41e09e940402206bf2b3c7c15927a9dcffb176b17bbb23fa5747b95261232d551b6b11f42cc3a9012103e9c44c5388c128ee141310d48dbf51745f7fb2aeea018b215d713586ca40fb6bffffffff0200ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88aca77690e6b00900001976a9146918ade56abe1d0a0f2f33f888017e10f5e33e8688ac0000000001000000016792865f2f10effbe09a1f818302cdab2a663af17edb1e95eb40d4e358aa6d5c010000006b483045022100c731646b5d285f904b43f26f3f86040b21b5a9f25e9d44a60f3c040c640351c1022070aed5a5c94a89eee2c2cd4484c234c32af7993784b5c772f3c31b5261596ea30121027fb179647854b9e04f7e745d40ed412ae8397658dc223d675b411eea0eccaed8ffffffff02bba2f5aab00900001976a914339b310e1dd13fa157b174290a399b6f7db7625d88ac00ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac000000000100000001a5bf4d334702570d2851c4bdf4a4709a859302f0ec9c61e01037a8a0b524c7a5000000006a47304402200327fd035357206724ac771c0f4dad530e8140c9e00f56db21a1b209f0251033022029539b1f4f360a50d087f5adbef35356f27663f44113c8185dd966da23ddeb5a012103719ae1953097622df373f1eb631794d54d28cb81ab7d59bb9cb6da5efe2c9b5dffffffff02dace5a6fb00900001976a91440fff735001b22b50468d8edecc51d3753c6ae7688ac00ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac000000000100000001017b37201d4f24673f9c0e18b4163afe47c2bb13cd9a7d6aa1a6f9db4d24d3fb000000006a47304402204d0fc656b86d6197904ae448681b8afe0911c085ef041437aafd4ab9f1973f68022059f2cc7a599a4e08e23b3dd42756f663c9ce6abb237963de98875951cdfd3f250121037fb305455db3509910704a8f429ea4aeff2c46bf60a8d7fdc75f07b94278e833ffffffff0200ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88aceefabf33b00900001976a91460d8dab232c50a0ab568ad0b5540d9e736967a5588ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
stream >> block;
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_P2PUBKEY_ONLY);
// Match the generation pubkey
filter.insert(ParseHex("033e254567ac5469ccf602aa8439aa3690e30c9add8ecb6f3ce055867b7eb95062"));
// ...and the output address of the 4th transaction
filter.insert(ParseHex("995f273daaa1494bbaacbe583f42d99729128290"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
// We should match the generation outpoint
BOOST_CHECK(filter.contains(COutPoint(uint256S("0x8927ef1549de23475101a3bfb012355a5cd82d2e515a7c80ba9c242ff78e64b8"), 0)));
// ... but not the 4th transaction's output (its not pay-2-pubkey)
BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x91c6fe252a5b44bdf5a9294a1169ca0907d0fe53ffb614d803dbdbd03d9de62a"), 0)));
}
BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none)
{
// Random real mainnet block 1295 (0000001d3bdcc0d1fab90cb9b821353da5582585d1feeee709d999ff21320512)
// With 7 txes
CBlock block;
CDataStream stream(ParseHex("03000000c762eb3b258c964658c738feea9f93db3ddefe5a1bf0f6bea19f0ccb15000000aa95233e089fc2faf0c66d370d32936a1f9a7ef28725c996c7552dc3f08334f6a7358b59aec8001e48d21400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05020f050101ffffffff021d13c504000000002321033e254567ac5469ccf602aa8439aa3690e30c9add8ecb6f3ce055867b7eb95062acc7443101000000001976a9147d7a3cb519a73f67d17ec26f50ba575a407c822e88ac000000000100000001229c462e3e4345ae5cd46937af63b1020de36e94d898ea3afef7b6be7b2ce20d010000006a473044022016bb149bf67b03439f1b9297fb6cf980e10f616512f5ae24a6b71ad252b3372c0220662487af3fb5f7fe11b78460683b700d2375f1838788a95c1644ad28456c28bd012102404ca28ac01a9f948a34491e02e433198e83a118fbafbaa9b52db75cb4083f7fffffffff02f11567c3b20900001976a914caebdec3adf8f99d5ce8213c7adaeed90167cfb488ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac0000000001000000013ce05b435e0b8f891cee3638b535b798887333fe8d091633e7d64289ab464d54000000006a473044022052948bfd09bfb4d4c36aa147e0fbb605b9c78f6348cd74347e10e9f62696ad8c022021e0f32acf0cad0af206db08e4c43b1a6bbbb9092b0fbac9265b41b159d249820121023aa9c8ae47ae6ee13ab96d2e84af785660dbc7e6e22c403b6a67b4fdd07585abffffffff020542cc87b20900001976a9143e77d120d3585c6b241494260cab1d3321f2067188ac00ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac000000000100000001af1a67c2419ca63366fe6be93735dc641bd75bd9382a80de90cd47f39f305169000000006a47304402203a7898655915fd51685446d4beb8bf3658c491d5c7edfadf7f35db85b428210c02203c920bf7eff603a853c2f6fb1e380fa04d90f8feb0a6c74102b729cbaaffd39a0121021593d23c6ee5c8e88863db753747efc4fd421822d008b367e5cd11abd54123e2ffffffff0200ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac196e314cb20900001976a9143e0ea691e152bfe4bc7cea92df243e96f5049e4b88ac0000000001000000012ae69d3dd0dbdb03d814b6ff53fed00709ca69114a29a9f5bd445b2a25fec691010000006b48304502210092a28a1822cf72358e1ed934c38e9b728bd24edda955292a38d3082c9ea0b8a9022048db9e0c50dba465eb3a48378a5907f6c49fdda60758992b6141a0e256f892520121026de2041f3dbfb44e0eb356efd57a6110037fa766a8f55f787c4cf911a21c3083ffffffff0200ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac2d9a9610b20900001976a91456eedbf725b2dd72263ba2a46a5313aace7657e288ac000000000100000001f24c019b133c8733223bbb807ea01c2643d561ee82cb704134c825f00a84435d010000006a47304402206273d060d73514cfe436c6873bc2c475071c016116f276a0f677b8d04d840b1f0220533b3aa53587344b301b30dd8e9e3436e7f2bf339e9ad57ae5ff7488f000f1ec0121023e3fb614a8479eb0faee9d4c2f650611dddf2654f61322fcd754e7fe1b1ef6bcffffffff024cc6fbd4b10900001976a91447219483be4d5f601af119f305308544b1d1cf3f88ac00ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88ac000000000100000001c0246062f0f2f20d025ddbacea5704b302280802c0535257b1ecc28052c5e02e000000006a47304402201d37afd8b8d2babc92e9d7074a7752426511cb50a7a1699aca7409eb125ce22e0220591a24a6e532f1c5c32e5e1d88ec07eb729350f0a5d10d433fb19b243aeff23401210391b38899c04efc03346e45e1400f6a672c8b76c1602eca296de08597221f856dffffffff0200ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac60f26099b10900001976a914563ce273ad9a4bbaec3724f292d13480bf4129b788ac0000000001000000012249ac508d394500cd5475d196be5f21c344412d12dd599200b365a765b15af8010000006a473044022060506da0ee97fae10b852d95cede4afb14072d144a245e9225cfa783169593fc022000b6da4ef93bcfdcd483494a042ca3c778674313ad97c64f23777b2f49c67883012102ddb4dc9fddb08390b508575158ded2ed8e342d73f4907564e368190589d67410ffffffff0200ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac7f1ec65db10900001976a914dd403efa39dc27282c05ae926529a1c2c9c9f2d388ac000000000100000001f1b041e4ec1772fd03318b68160406e3136317d6cef18c89ea2a20dd778bcb29010000006b483045022100a326111229af7027d1d417d5dbafbde1540d5d1dc70bce4b023f2777b93dfdf4022027054bb9ba82d683d069917b2794b171bd2f1e702077af6e8e6a48e3aa200495012102c19a09577dca933fbc232934937de49563b77f2868a01d0a25f921c6a5b29d32ffffffff0200ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88ac934a2b22b10900001976a91461e09f468be3d08ed2b49bc6a4b8e92e84b73a1488ac000000000100000001acc5db040cac2e8292cdfe8b861f7095f377de8e8d8031bd1eba6e7d25685885010000006b48304502210095774ef147d77b4b1b091bf302b996d149d7183202c0000d6b7fae41e09e940402206bf2b3c7c15927a9dcffb176b17bbb23fa5747b95261232d551b6b11f42cc3a9012103e9c44c5388c128ee141310d48dbf51745f7fb2aeea018b215d713586ca40fb6bffffffff0200ca9a3b000000001976a9149c5781278b716c047ee60e5a3f29a98f55c5ef3f88aca77690e6b00900001976a9146918ade56abe1d0a0f2f33f888017e10f5e33e8688ac0000000001000000016792865f2f10effbe09a1f818302cdab2a663af17edb1e95eb40d4e358aa6d5c010000006b483045022100c731646b5d285f904b43f26f3f86040b21b5a9f25e9d44a60f3c040c640351c1022070aed5a5c94a89eee2c2cd4484c234c32af7993784b5c772f3c31b5261596ea30121027fb179647854b9e04f7e745d40ed412ae8397658dc223d675b411eea0eccaed8ffffffff02bba2f5aab00900001976a914339b310e1dd13fa157b174290a399b6f7db7625d88ac00ca9a3b000000001976a914ba7fc8f8ccaa75e078961c8888e98c89213d85a888ac000000000100000001a5bf4d334702570d2851c4bdf4a4709a859302f0ec9c61e01037a8a0b524c7a5000000006a47304402200327fd035357206724ac771c0f4dad530e8140c9e00f56db21a1b209f0251033022029539b1f4f360a50d087f5adbef35356f27663f44113c8185dd966da23ddeb5a012103719ae1953097622df373f1eb631794d54d28cb81ab7d59bb9cb6da5efe2c9b5dffffffff02dace5a6fb00900001976a91440fff735001b22b50468d8edecc51d3753c6ae7688ac00ca9a3b000000001976a914995f273daaa1494bbaacbe583f42d9972912829088ac000000000100000001017b37201d4f24673f9c0e18b4163afe47c2bb13cd9a7d6aa1a6f9db4d24d3fb000000006a47304402204d0fc656b86d6197904ae448681b8afe0911c085ef041437aafd4ab9f1973f68022059f2cc7a599a4e08e23b3dd42756f663c9ce6abb237963de98875951cdfd3f250121037fb305455db3509910704a8f429ea4aeff2c46bf60a8d7fdc75f07b94278e833ffffffff0200ca9a3b000000001976a914ef5acbda3141f7f4cbb81775b1afa46d8dde6a6e88aceefabf33b00900001976a91460d8dab232c50a0ab568ad0b5540d9e736967a5588ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
stream >> block;
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_NONE);
// Match the generation pubkey
filter.insert(ParseHex("033e254567ac5469ccf602aa8439aa3690e30c9add8ecb6f3ce055867b7eb95062"));
// ...and the output address of the 4th transaction
filter.insert(ParseHex("995f273daaa1494bbaacbe583f42d99729128290"));
CMerkleBlock merkleBlock(block, filter);
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
// We shouldn't match any outpoints (UPDATE_NONE)
BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x8927ef1549de23475101a3bfb012355a5cd82d2e515a7c80ba9c242ff78e64b8"), 0)));
BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x91c6fe252a5b44bdf5a9294a1169ca0907d0fe53ffb614d803dbdbd03d9de62a"), 0)));
}
static std::vector<unsigned char> RandomData()
{
uint256 r = InsecureRand256();
return std::vector<unsigned char>(r.begin(), r.end());
}
BOOST_AUTO_TEST_CASE(rolling_bloom)
{
SeedInsecureRand(/* deterministic */ true);
g_mock_deterministic_tests = true;
// last-100-entry, 1% false positive:
CRollingBloomFilter rb1(100, 0.01);
// Overfill:
static const int DATASIZE=399;
std::vector<unsigned char> data[DATASIZE];
for (int i = 0; i < DATASIZE; i++) {
data[i] = RandomData();
rb1.insert(data[i]);
}
// Last 100 guaranteed to be remembered:
for (int i = 299; i < DATASIZE; i++) {
BOOST_CHECK(rb1.contains(data[i]));
}
// false positive rate is 1%, so we should get about 100 hits if
// testing 10,000 random keys. We get worst-case false positive
// behavior when the filter is as full as possible, which is
// when we've inserted one minus an integer multiple of nElement*2.
unsigned int nHits = 0;
for (int i = 0; i < 10000; i++) {
if (rb1.contains(RandomData()))
++nHits;
}
// Expect about 100 hits
BOOST_CHECK_EQUAL(nHits, 75);
BOOST_CHECK(rb1.contains(data[DATASIZE-1]));
rb1.reset();
BOOST_CHECK(!rb1.contains(data[DATASIZE-1]));
// Now roll through data, make sure last 100 entries
// are always remembered:
for (int i = 0; i < DATASIZE; i++) {
if (i >= 100)
BOOST_CHECK(rb1.contains(data[i-100]));
rb1.insert(data[i]);
BOOST_CHECK(rb1.contains(data[i]));
}
// Insert 999 more random entries:
for (int i = 0; i < 999; i++) {
std::vector<unsigned char> d = RandomData();
rb1.insert(d);
BOOST_CHECK(rb1.contains(d));
}
// Sanity check to make sure the filter isn't just filling up:
nHits = 0;
for (int i = 0; i < DATASIZE; i++) {
if (rb1.contains(data[i]))
++nHits;
}
// Expect about 5 false positives
BOOST_CHECK_EQUAL(nHits, 6);
// last-1000-entry, 0.01% false positive:
CRollingBloomFilter rb2(1000, 0.001);
for (int i = 0; i < DATASIZE; i++) {
rb2.insert(data[i]);
}
// ... room for all of them:
for (int i = 0; i < DATASIZE; i++) {
BOOST_CHECK(rb2.contains(data[i]));
}
g_mock_deterministic_tests = false;
}
BOOST_AUTO_TEST_SUITE_END()