Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions bitcoin/bloom.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ def __init__(self, nElements, nFPRate, nTweak, nFlags):
"""
LN2SQUARED = 0.4804530139182014246671025263266649717305529515945455
LN2 = 0.6931471805599453094172321214581765680755001343602552
self.vData = bytearray(int(min(-1 / LN2SQUARED * nElements * math.log(nFPRate), self.MAX_BLOOM_FILTER_SIZE * 8) / 8))
self.nHashFuncs = int(min(len(self.vData) * 8 / nElements * LN2, self.MAX_HASH_FUNCS))
# Rounding must not produce a filter that matches every element.
self.vData = bytearray(max(1, int(min(-1 / LN2SQUARED * nElements * math.log(nFPRate), self.MAX_BLOOM_FILTER_SIZE * 8) / 8)))
self.nHashFuncs = max(1, int(min(len(self.vData) * 8 / nElements * LN2, self.MAX_HASH_FUNCS)))
self.nTweak = nTweak
self.nFlags = nFlags

Expand Down
14 changes: 14 additions & 0 deletions bitcoin/tests/test_bloom.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ def T(expected, seed, data):


class Test_CBloomFilter(unittest.TestCase):
def test_small_and_high_false_positive_rate_filters(self):
for elements in (1, 2, 10, 100):
for rate in (0.05, 0.1, 0.5, 0.9, 0.9999):
filter = CBloomFilter(elements, rate, 0, CBloomFilter.UPDATE_ALL)
# An empty filter must not match everything, even when its
# calculated storage size or hash count rounds down to zero.
self.assertFalse(filter.contains(b'not inserted'))
filter.insert(b'inserted')
self.assertTrue(filter.contains(b'inserted'))
self.assertTrue(filter.IsWithinSizeConstraints())
restored = CBloomFilter.deserialize(filter.serialize())
self.assertTrue(restored.contains(b'inserted'))
self.assertEqual(restored.serialize(), filter.serialize())

def test_create_insert_serialize(self):
filter = CBloomFilter(3, 0.01, 0, CBloomFilter.UPDATE_ALL)

Expand Down