Exemplo n.º 1
0
    def test_filter(self, filter_peer):
        # Set the bloomfilter using filterload
        filter_peer.send_and_ping(filter_peer.watch_filter_init)
        # If fRelay is not already True, sending filterload sets it to True
        assert self.nodes[0].getpeerinfo()[0]['relaytxes']
        filter_address = self.nodes[0].decodescript(
            filter_peer.watch_script_pubkey)['addresses'][0]

        self.log.info(
            'Check that we receive merkleblock and tx if the filter matches a tx in a block'
        )
        block_hash = self.nodes[0].generatetoaddress(1, filter_address)[0]
        txid = self.nodes[0].getblock(block_hash)['tx'][0]
        filter_peer.wait_for_merkleblock(block_hash)
        filter_peer.wait_for_tx(txid)

        self.log.info(
            'Check that we only receive a merkleblock if the filter does not match a tx in a block'
        )
        filter_peer.tx_received = False
        block_hash = self.nodes[0].generatetoaddress(
            1, self.nodes[0].getnewaddress())[0]
        filter_peer.wait_for_merkleblock(block_hash)
        assert not filter_peer.tx_received

        self.log.info(
            'Check that we not receive a tx if the filter does not match a mempool tx'
        )
        filter_peer.merkleblock_received = False
        filter_peer.tx_received = False
        self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 90)
        filter_peer.sync_with_ping()
        filter_peer.sync_with_ping()
        assert not filter_peer.merkleblock_received
        assert not filter_peer.tx_received

        self.log.info(
            'Check that we receive a tx if the filter matches a mempool tx')
        filter_peer.merkleblock_received = False
        txid = self.nodes[0].sendtoaddress(filter_address, 90)
        filter_peer.wait_for_tx(txid)
        assert not filter_peer.merkleblock_received

        self.log.info(
            'Check that after deleting filter all txs get relayed again')
        filter_peer.send_and_ping(msg_filterclear())
        for _ in range(5):
            txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(),
                                               7)
            filter_peer.wait_for_tx(txid)

        self.log.info(
            'Check that request for filtered blocks is ignored if no filter is set'
        )
        filter_peer.merkleblock_received = False
        filter_peer.tx_received = False
        with self.nodes[0].assert_debug_log(
                expected_msgs=['received getdata']):
            block_hash = self.nodes[0].generatetoaddress(
                1, self.nodes[0].getnewaddress())[0]
            filter_peer.wait_for_inv([CInv(MSG_BLOCK, int(block_hash, 16))])
            filter_peer.sync_with_ping()
            assert not filter_peer.merkleblock_received
            assert not filter_peer.tx_received

        self.log.info(
            'Check that sending "filteradd" if no filter is set is treated as misbehavior'
        )
        with self.nodes[0].assert_debug_log(['Misbehaving']):
            filter_peer.send_and_ping(msg_filteradd(data=b'letsmisbehave'))

        self.log.info(
            "Check that division-by-zero remote crash bug [CVE-2013-5700] is fixed"
        )
        filter_peer.send_and_ping(msg_filterload(data=b'', nHashFuncs=1))
        filter_peer.send_and_ping(
            msg_filteradd(data=b'letstrytocrashthisnode'))
        self.nodes[0].disconnect_p2ps()
Exemplo n.º 2
0
    def run_test(self):
        filter_node = self.nodes[0].add_p2p_connection(FilterNode())

        self.log.info('Check that too large filter is rejected')
        with self.nodes[0].assert_debug_log(['Misbehaving']):
            filter_node.send_and_ping(msg_filterload(data=b'\xaa', nHashFuncs=MAX_BLOOM_HASH_FUNCS+1))
        with self.nodes[0].assert_debug_log(['Misbehaving']):
            filter_node.send_and_ping(msg_filterload(data=b'\xbb'*(MAX_BLOOM_FILTER_SIZE+1)))

        self.log.info('Check that too large data element to add to the filter is rejected')
        with self.nodes[0].assert_debug_log(['Misbehaving']):
            filter_node.send_and_ping(msg_filteradd(data=b'\xcc'*(MAX_SCRIPT_ELEMENT_SIZE+1)))

        self.log.info('Add filtered P2P connection to the node')
        filter_node.send_and_ping(filter_node.watch_filter_init)
        filter_address = self.nodes[0].decodescript(filter_node.watch_script_pubkey)['addresses'][0]

        self.log.info('Check that we receive merkleblock and tx if the filter matches a tx in a block')
        block_hash = self.nodes[0].generatetoaddress(1, filter_address)[0]
        txid = self.nodes[0].getblock(block_hash)['tx'][0]
        filter_node.wait_for_merkleblock(block_hash)
        filter_node.wait_for_tx(txid)

        self.log.info('Check that we only receive a merkleblock if the filter does not match a tx in a block')
        filter_node.tx_received = False
        block_hash = self.nodes[0].generatetoaddress(1, self.nodes[0].getnewaddress())[0]
        filter_node.wait_for_merkleblock(block_hash)
        assert not filter_node.tx_received

        self.log.info('Check that we not receive a tx if the filter does not match a mempool tx')
        filter_node.merkleblock_received = False
        filter_node.tx_received = False
        self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 90)
        filter_node.sync_with_ping()
        filter_node.sync_with_ping()
        assert not filter_node.merkleblock_received
        assert not filter_node.tx_received

        self.log.info('Check that we receive a tx in reply to a mempool msg if the filter matches a mempool tx')
        filter_node.merkleblock_received = False
        txid = self.nodes[0].sendtoaddress(filter_address, 90)
        filter_node.wait_for_tx(txid)
        assert not filter_node.merkleblock_received

        self.log.info('Check that after deleting filter all txs get relayed again')
        filter_node.send_and_ping(msg_filterclear())
        for _ in range(5):
            txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 7)
            filter_node.wait_for_tx(txid)

        self.log.info('Check that request for filtered blocks is ignored if no filter is set')
        filter_node.merkleblock_received = False
        filter_node.tx_received = False
        with self.nodes[0].assert_debug_log(expected_msgs=['received getdata']):
            block_hash = self.nodes[0].generatetoaddress(1, self.nodes[0].getnewaddress())[0]
            filter_node.wait_for_inv([CInv(MSG_BLOCK, int(block_hash, 16))])
            filter_node.sync_with_ping()
            assert not filter_node.merkleblock_received
            assert not filter_node.tx_received

        self.log.info('Check that sending "filteradd" if no filter is set is treated as misbehavior')
        with self.nodes[0].assert_debug_log(['Misbehaving']):
            filter_node.send_and_ping(msg_filteradd(data=b'letsmisbehave'))

        self.log.info("Check that division-by-zero remote crash bug [CVE-2013-5700] is fixed")
        filter_node.send_and_ping(msg_filterload(data=b'', nHashFuncs=1))
        filter_node.send_and_ping(msg_filteradd(data=b'letstrytocrashthisnode'))