125
126
spendStream >> spendingTx;
127
128
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
128
filter.insert(uint256("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b"));
129
filter.insert(uint256S("0xb4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b"));
129
130
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match tx hash");
131
132
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
151
152
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match output address");
153
154
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
154
filter.insert(COutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
155
filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
155
156
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match COutPoint");
157
158
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
158
COutPoint prevOutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0);
159
COutPoint prevOutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0);
160
161
vector<unsigned char> data(32 + sizeof(unsigned int));
161
162
memcpy(&data[0], prevOutPoint.hash.begin(), 32);
165
166
BOOST_CHECK_MESSAGE(filter.IsRelevantAndUpdate(tx), "Simple Bloom filter didn't match manually serialized COutPoint");
167
168
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
168
filter.insert(uint256("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436"));
169
filter.insert(uint256S("00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436"));
169
170
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random tx hash");
171
172
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
173
174
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched random address");
175
176
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
176
filter.insert(COutPoint(uint256("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1));
177
filter.insert(COutPoint(uint256S("0x90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 1));
177
178
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about");
179
180
filter = CBloomFilter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
180
filter.insert(COutPoint(uint256("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
181
filter.insert(COutPoint(uint256S("0x000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"), 0));
181
182
BOOST_CHECK_MESSAGE(!filter.IsRelevantAndUpdate(tx), "Simple Bloom filter matched COutPoint for an output we didn't care about");
266
267
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
268
BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
269
BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
269
270
BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
271
BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"));
272
BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x6b0f8a73a56c04b519f1883e8aafda643ba61a30bd1439969df21bea5f4e27e2"));
272
273
BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 2);
274
BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
275
BOOST_CHECK(merkleBlock.vMatchedTxn[3].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
275
276
BOOST_CHECK(merkleBlock.vMatchedTxn[3].first == 3);
277
278
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
320
321
BOOST_CHECK(pair == merkleBlock.vMatchedTxn[0]);
322
BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
323
BOOST_CHECK(merkleBlock.vMatchedTxn[1].second == uint256S("0x28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f"));
323
324
BOOST_CHECK(merkleBlock.vMatchedTxn[1].first == 1);
325
BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
326
BOOST_CHECK(merkleBlock.vMatchedTxn[2].second == uint256S("0x3c1d7e82342158e4109df2e0b6348b6e84e403d8b4046d7007663ace63cddb23"));
326
327
BOOST_CHECK(merkleBlock.vMatchedTxn[2].first == 3);
328
329
BOOST_CHECK(merkleBlock.txn.ExtractMatches(vMatched) == block.hashMerkleRoot);
342
343
CBloomFilter filter(10, 0.000001, 0, BLOOM_UPDATE_ALL);
343
344
// Match the only transaction
344
filter.insert(uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
345
filter.insert(uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
346
347
CMerkleBlock merkleBlock(block, filter);
347
348
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
349
350
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 1);
351
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
352
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x63194f18be0af63f2c6bc9dc0f777cbefed3d9415c4af83f3ee3a3d669c00cb5"));
352
353
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 0);
354
355
vector<uint256> vMatched;
397
398
BOOST_CHECK(vMatched[i] == merkleBlock.vMatchedTxn[i].second);
399
400
// Also match the 4th transaction
400
filter.insert(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
401
filter.insert(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
401
402
merkleBlock = CMerkleBlock(block, filter);
402
403
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
404
405
BOOST_CHECK(merkleBlock.vMatchedTxn.size() == 2);
406
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
407
BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"));
407
408
BOOST_CHECK(merkleBlock.vMatchedTxn[0].first == 3);
409
410
BOOST_CHECK(merkleBlock.vMatchedTxn[1] == pair);
432
433
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
434
435
// We should match the generation outpoint
435
BOOST_CHECK(filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
436
BOOST_CHECK(filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
436
437
// ... but not the 4th transaction's output (its not pay-2-pubkey)
437
BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
438
BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
440
441
BOOST_AUTO_TEST_CASE(merkle_block_4_test_update_none)
455
456
BOOST_CHECK(merkleBlock.header.GetHash() == block.GetHash());
457
458
// We shouldn't match any outpoints (UPDATE_NONE)
458
BOOST_CHECK(!filter.contains(COutPoint(uint256("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
459
BOOST_CHECK(!filter.contains(COutPoint(uint256("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
459
BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"), 0)));
460
BOOST_CHECK(!filter.contains(COutPoint(uint256S("0x02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"), 0)));
463
static std::vector<unsigned char> RandomData()
465
uint256 r = GetRandHash();
466
return std::vector<unsigned char>(r.begin(), r.end());
469
BOOST_AUTO_TEST_CASE(rolling_bloom)
471
// last-100-entry, 1% false positive:
472
CRollingBloomFilter rb1(100, 0.01, 0);
475
static const int DATASIZE=399;
476
std::vector<unsigned char> data[DATASIZE];
477
for (int i = 0; i < DATASIZE; i++) {
478
data[i] = RandomData();
481
// Last 100 guaranteed to be remembered:
482
for (int i = 299; i < DATASIZE; i++) {
483
BOOST_CHECK(rb1.contains(data[i]));
486
// false positive rate is 1%, so we should get about 100 hits if
487
// testing 10,000 random keys. We get worst-case false positive
488
// behavior when the filter is as full as possible, which is
489
// when we've inserted one minus an integer multiple of nElement*2.
490
unsigned int nHits = 0;
491
for (int i = 0; i < 10000; i++) {
492
if (rb1.contains(RandomData()))
495
// Run test_bitcoin with --log_level=message to see BOOST_TEST_MESSAGEs:
496
BOOST_TEST_MESSAGE("RollingBloomFilter got " << nHits << " false positives (~100 expected)");
498
// Insanely unlikely to get a fp count outside this range:
499
BOOST_CHECK(nHits > 25);
500
BOOST_CHECK(nHits < 175);
502
BOOST_CHECK(rb1.contains(data[DATASIZE-1]));
504
BOOST_CHECK(!rb1.contains(data[DATASIZE-1]));
506
// Now roll through data, make sure last 100 entries
507
// are always remembered:
508
for (int i = 0; i < DATASIZE; i++) {
510
BOOST_CHECK(rb1.contains(data[i-100]));
514
// Insert 999 more random entries:
515
for (int i = 0; i < 999; i++) {
516
rb1.insert(RandomData());
518
// Sanity check to make sure the filter isn't just filling up:
520
for (int i = 0; i < DATASIZE; i++) {
521
if (rb1.contains(data[i]))
524
// Expect about 5 false positives, more than 100 means
525
// something is definitely broken.
526
BOOST_TEST_MESSAGE("RollingBloomFilter got " << nHits << " false positives (~5 expected)");
527
BOOST_CHECK(nHits < 100);
529
// last-1000-entry, 0.01% false positive:
530
CRollingBloomFilter rb2(1000, 0.001, 0);
531
for (int i = 0; i < DATASIZE; i++) {
534
// ... room for all of them:
535
for (int i = 0; i < DATASIZE; i++) {
536
BOOST_CHECK(rb2.contains(data[i]));
462
540
BOOST_AUTO_TEST_SUITE_END()