Example #1
0
 def testNumberOfSetBitsNeverDecreases(self):
     n = 10
     bf = BloomFilter(n, n)
     prev_cnt = 0
     for i in range(n):
         bf.insert(str(i))
         cnt = bf.count(True)
         self.assertTrue(cnt >= prev_cnt)
         prev_cnt = cnt
Example #2
0
 def testFalseNegativeNeverHappens(self):
     n = 10
     inserted = []
     bf = BloomFilter(n, n)
     for i in range(n):
         bf.insert(str(i))
         inserted.append(i)
         for j in inserted:
             self.assertTrue(bf.query(j))
Example #3
0
 def testFalseNegativeNeverHappens(self):
     n = 10
     inserted = []
     bf = BloomFilter(n, n)
     for i in range(n):
         bf.insert(str(i))
         inserted.append(i)
         for j in inserted:
             self.assertTrue(bf.query(j))
Example #4
0
 def testNumberOfSetBitsNeverDecreases(self):
     n = 10
     bf = BloomFilter(n, n)
     prev_cnt = 0
     for i in range(n):
         bf.insert(str(i))
         cnt = bf.count(True)
         self.assertTrue(cnt >= prev_cnt)
         prev_cnt = cnt
def get_dictionary_bloom(file_name):
    """
    Get a dictionary as a Bloom filer data-structure from a text file.

    :param str file_name: name of the file storing the dictionary
    :return BloomFilter: dictionary
    """
    bloom = BloomFilter()
    with open(file_name) as f:
        for line in f:
            bloom.insert(line.strip())
    return bloom
Example #6
0
 def testInputIsFalsePositiveUntilInserted(self):
     n = 100
     bf = BloomFilter(n / 2, n)
     fp = [False] * n
     inserted = [False] * n
     fp_cnt = 0
     for i in range(n):
         bf.insert(str(i))
         inserted[i] = True
         for j in range(n):
             if inserted[j]:
                 continue
             # It was false positive before, it must continue
             # to be (since it was not inserted).
             if fp[j]:
                 self.assertTrue(bf.query(j))
             # Update false positives list
             elif bf.query(j):
                 fp[j] = True
                 fp_cnt += 1
     # We're inserting more elements than the size of the array, so
     # there must be false positives.
     self.assertTrue(fp_cnt > 0)
Example #7
0
 def testInputIsFalsePositiveUntilInserted(self):
     n = 100
     bf = BloomFilter(n/2, n)
     fp = [False]*n
     inserted = [False]*n
     fp_cnt = 0
     for i in range(n):
         bf.insert(str(i))
         inserted[i] = True
         for j in range(n):
             if inserted[j]:
                 continue
             # It was false positive before, it must continue
             # to be (since it was not inserted).
             if fp[j]:
                 self.assertTrue(bf.query(j))
             # Update false positives list
             elif bf.query(j):
                 fp[j] = True
                 fp_cnt += 1
     # We're inserting more elements than the size of the array, so
     # there must be false positives.
     self.assertTrue(fp_cnt > 0)
Example #8
0
def bloom_filter_run(n, m, k=None):
    keys = range(n)
    # Random sampling without replacement
    random.shuffle(keys)
    probs = []
    filter = BloomFilter(m, n, k)
    inserted = [False] * (n)

    for cnt, entry in enumerate(keys):
        filter.insert(str(entry))

        inserted[entry] = True
        false_positives, total = 0, 0
        # Compute false positives
        for probe in range(n):
            if not inserted[probe]:
                exists = filter.query(probe)
                if exists:
                    false_positives += 1
                total += 1
        if total != 0:
            prob = false_positives * 1.0 / total
            probs.append(prob)
    return probs
def bloom_filter_run(n, m, k=None):
    keys = range(n)
    # Random sampling without replacement
    random.shuffle(keys)
    probs = []
    filter = BloomFilter(m, n, k)
    inserted = [False] * (n)

    for cnt, entry in enumerate(keys):
        filter.insert(str(entry))

        inserted[entry] = True
        false_positives, total = 0, 0
        # Compute false positives
        for probe in range(n):
            if not inserted[probe]:
                exists = filter.query(probe)
                if exists:
                    false_positives += 1
                total += 1
        if total != 0:
            prob = false_positives * 1.0 / total
            probs.append(prob)
    return probs
Example #10
0
class BitcoinClient(object):
    def __init__(self,
                 addrs,
                 params=MAINNET,
                 user_agent="/pyBitcoin:0.1/",
                 max_connections=10):
        self.addrs = addrs
        self.params = params
        self.user_agent = user_agent
        self.max_connections = max_connections
        self.peers = []
        self.inventory = {}
        self.pending_txs = {}
        self.subscriptions = {}
        self.bloom_filter = BloomFilter(3, 0.01, random.getrandbits(32),
                                        BloomFilter.UPDATE_NONE)
        self.connect_to_peers()

    def connect_to_peers(self):
        if len(self.peers) < self.max_connections:
            shuffle(self.addrs)
            for i in range(self.max_connections - len(self.peers)):
                if len(self.addrs) > 0:
                    addr = self.addrs.pop(0)
                    peer = PeerFactory(self.params, self.user_agent,
                                       self.inventory, self.bloom_filter,
                                       self.on_peer_disconnected)
                    reactor.connectTCP(addr[0], addr[1], peer)
                    self.peers.append(peer)

    def on_peer_disconnected(self, peer):
        self.peers.remove(peer)
        self.connect_to_peers()

    def broadcast_tx(self, tx):
        """
        Send the tx to half our peers, wait for half of the remainder to announce the tx before
        calling back True.
        """
        def on_peer_anncounce(txid):
            self.pending_txs[txid][0] += 1
            if self.pending_txs[txid][0] >= self.pending_txs[txid][1] / 2:
                if self.pending_txs[txid][3].active():
                    self.pending_txs[txid][3].cancel()
                    self.pending_txs[txid][2].callback(True)

        d = defer.Deferred()
        self.inventory[bitcoin.txhash(tx)] = tx
        inv_packet = inv("TX", bitcoin.txhash(tx))
        self.bloom_filter.insert(bitcoin.bin_txhash(tx))
        self.pending_txs[bitcoin.txhash(tx)] = [
            0,
            len(self.peers) / 2, d,
            reactor.callLater(10, d.callback, False)
        ]
        for peer in self.peers[len(self.peers) / 2:]:
            peer.protocol.update_filter()
            peer.protocol.add_inv_callback(bitcoin.txhash(tx),
                                           on_peer_anncounce)
        for peer in self.peers[:len(self.peers) / 2]:
            peer.protocol.send_message(message(inv_packet, self.params))
        return d

    def subscribe_address(self, address, callback):
        """
        Listen for transactions on an address. Since we can't validate the transaction, we will only
        callback if a majority of our peers relay it. If less than a majority relay it, we will have
        to wait for block inclusion to callback.
        """
        def on_peer_announce(tx):
            txhash = bitcoin.txhash(bitcoin.serialize(tx["tx"]))
            if txhash in self.subscriptions[address][0] and self.subscriptions[
                    address][0][txhash][0] != "complete":
                self.subscriptions[address][0][txhash][0] += 1
                if self.subscriptions[address][0][txhash][
                        0] >= self.subscriptions[address][0][txhash][1]:
                    self.subscriptions[address][0][txhash][0] = "complete"
                    self.subscriptions[address][1](tx["tx"])
            elif txhash not in self.subscriptions[address][0]:
                self.subscriptions[address][0][txhash] = [
                    1, len(self.peers) / 2
                ]

        self.subscriptions[address] = [{}, callback]
        self.bloom_filter.insert(unhexlify(bitcoin.b58check_to_hex(address)))
        for peer in self.peers:
            peer.protocol.add_inv_callback(bitcoin.b58check_to_hex(address),
                                           on_peer_announce)
            peer.protocol.update_filter()
Example #11
0
class BitcoinClient(object):

    def __init__(self, addrs, params=MAINNET, user_agent="/pyBitcoin:0.1/", max_connections=10):
        self.addrs = addrs
        self.params = params
        self.user_agent = user_agent
        self.max_connections = max_connections
        self.peers = []
        self.inventory = {}
        self.pending_txs = {}
        self.subscriptions = {}
        self.bloom_filter = BloomFilter(3, 0.01, random.getrandbits(32), BloomFilter.UPDATE_NONE)
        self.connect_to_peers()

    def connect_to_peers(self):
        if len(self.peers) < self.max_connections:
            shuffle(self.addrs)
            for i in range(self.max_connections - len(self.peers)):
                if len(self.addrs) > 0:
                    addr = self.addrs.pop(0)
                    peer = PeerFactory(self.params, self.user_agent, self.inventory,
                                       self.bloom_filter, self.on_peer_disconnected)
                    reactor.connectTCP(addr[0], addr[1], peer)
                    self.peers.append(peer)

    def on_peer_disconnected(self, peer):
        self.peers.remove(peer)
        self.connect_to_peers()

    def broadcast_tx(self, tx):
        """
        Send the tx to half our peers, wait for half of the remainder to announce the tx before
        calling back True.
        """
        def on_peer_anncounce(txid):
            self.pending_txs[txid][0] += 1
            if self.pending_txs[txid][0] >= self.pending_txs[txid][1] / 2:
                if self.pending_txs[txid][3].active():
                    self.pending_txs[txid][3].cancel()
                    self.pending_txs[txid][2].callback(True)

        d = defer.Deferred()
        self.inventory[bitcoin.txhash(tx)] = tx
        inv_packet = inv("TX", bitcoin.txhash(tx))
        self.bloom_filter.insert(bitcoin.bin_txhash(tx))
        self.pending_txs[bitcoin.txhash(tx)] = [0, len(self.peers)/2, d, reactor.callLater(10, d.callback, False)]
        for peer in self.peers[len(self.peers)/2:]:
            peer.protocol.update_filter()
            peer.protocol.add_inv_callback(bitcoin.txhash(tx), on_peer_anncounce)
        for peer in self.peers[:len(self.peers)/2]:
            peer.protocol.send_message(message(inv_packet, self.params))
        return d

    def subscribe_address(self, address, callback):
        """
        Listen for transactions on an address. Since we can't validate the transaction, we will only
        callback if a majority of our peers relay it. If less than a majority relay it, we will have
        to wait for block inclusion to callback.
        """
        def on_peer_announce(tx):
            txhash = bitcoin.txhash(bitcoin.serialize(tx["tx"]))
            if txhash in self.subscriptions[address][0] and self.subscriptions[address][0][txhash][0] != "complete":
                self.subscriptions[address][0][txhash][0] += 1
                if self.subscriptions[address][0][txhash][0] >= self.subscriptions[address][0][txhash][1]:
                    self.subscriptions[address][0][txhash][0] = "complete"
                    self.subscriptions[address][1](tx["tx"])
            elif txhash not in self.subscriptions[address][0]:
                self.subscriptions[address][0][txhash] = [1, len(self.peers)/2]

        self.subscriptions[address] = [{}, callback]
        self.bloom_filter.insert(unhexlify(bitcoin.b58check_to_hex(address)))
        for peer in self.peers:
            peer.protocol.add_inv_callback(bitcoin.b58check_to_hex(address), on_peer_announce)
            peer.protocol.update_filter()