Exemplo n.º 1
0
def test_delete_trackers(db_manager):
    # Tests de deletion of trackers
    # Completed and outdated trackers are deleted using the same method. The only difference is the logging message
    height = 0

    for _ in range(ITERATIONS):
        trackers, tx_tracker_map = set_up_trackers(db_manager, MAX_ITEMS)
        selected_trackers = random.sample(list(trackers.keys()), k=ITEMS)

        # Delete the selected trackers {uuid:confirmation_count}
        completed_trackers = {tracker: 6 for tracker in selected_trackers}
        Cleaner.delete_trackers(completed_trackers, height, trackers,
                                tx_tracker_map, db_manager)

        # Check that the data is not in memory anymore
        all_trackers = list(flatten(tx_tracker_map.values()))
        assert not set(completed_trackers).issubset(trackers)
        assert not set(completed_trackers).issubset(all_trackers)

        # And neither is in the db
        db_trackers = db_manager.load_responder_trackers()
        assert not set(completed_trackers).issubset(db_trackers)

        # Check that the data has also been removed from the Watchers db (appointment and triggered flag)
        all_appointments = db_manager.load_watcher_appointments(
            include_triggered=True)
        all_flags = db_manager.load_all_triggered_flags()

        assert not set(completed_trackers).issubset(all_appointments)
        assert not set(completed_trackers).issubset(all_flags)
Exemplo n.º 2
0
def test_delete_trackers_db_match(db_manager):
    # Completed and expired trackers are deleted using the same method. The only difference is the logging message
    height = 0

    for _ in range(ITERATIONS):
        trackers, tx_tracker_map = set_up_trackers(db_manager, MAX_ITEMS)
        selected_trackers = random.sample(list(trackers.keys()), k=ITEMS)

        completed_trackers = {tracker: 6 for tracker in selected_trackers}

        Cleaner.delete_trackers(completed_trackers, height, trackers,
                                tx_tracker_map, db_manager)

        assert not set(completed_trackers).issubset(trackers.keys())
Exemplo n.º 3
0
def test_delete_trackers_no_db_match(db_manager):
    height = 0

    for _ in range(ITERATIONS):
        trackers, tx_tracker_map = set_up_trackers(db_manager, MAX_ITEMS)
        selected_trackers = random.sample(list(trackers.keys()), k=ITEMS)

        # Let's change some uuid's by creating new trackers that are not included in the db and share a penalty_txid
        # with another tracker that is stored in the db.
        for uuid in selected_trackers[:ITEMS // 2]:
            penalty_txid = trackers[uuid].get("penalty_txid")
            dispute_txid = get_random_value_hex(32)
            locator = dispute_txid[:LOCATOR_LEN_HEX]
            new_uuid = uuid4().hex

            trackers[new_uuid] = {
                "locator": locator,
                "penalty_txid": penalty_txid
            }
            tx_tracker_map[penalty_txid].append(new_uuid)
            selected_trackers.append(new_uuid)

        # Let's add some random data
        for i in range(ITEMS // 2):
            uuid = uuid4().hex
            penalty_txid = get_random_value_hex(32)
            dispute_txid = get_random_value_hex(32)
            locator = dispute_txid[:LOCATOR_LEN_HEX]

            trackers[uuid] = {"locator": locator, "penalty_txid": penalty_txid}
            tx_tracker_map[penalty_txid] = [uuid]
            selected_trackers.append(uuid)

        completed_trackers = {tracker: 6 for tracker in selected_trackers}

        # We should be able to delete the correct ones and not fail in the others
        Cleaner.delete_trackers(completed_trackers, height, trackers,
                                tx_tracker_map, db_manager)
        assert not set(completed_trackers).issubset(trackers.keys())
Exemplo n.º 4
0
    def do_watch(self):
        """
        Monitors the blockchain for reorgs and appointment ends.

        This is the main method of the :obj:`Responder` and triggers tracker cleaning, rebroadcasting, reorg managing,
        etc.
        """

        # Distinguish fresh bootstraps from bootstraps from db
        if self.last_known_block is None:
            self.last_known_block = self.block_processor.get_best_block_hash()
            self.db_manager.store_last_block_hash_responder(self.last_known_block)

        while True:
            block_hash = self.block_queue.get()
            block = self.block_processor.get_block(block_hash)
            logger.info("New block received", block_hash=block_hash, prev_block_hash=block.get("previousblockhash"))

            if len(self.trackers) > 0 and block is not None:
                txids = block.get("tx")

                completed_trackers = self.get_completed_trackers()
                expired_trackers = self.get_expired_trackers(block.get("height"))
                trackers_to_delete_gatekeeper = {
                    uuid: self.trackers[uuid].get("user_id") for uuid in completed_trackers + expired_trackers
                }

                if self.last_known_block == block.get("previousblockhash"):
                    self.check_confirmations(txids)
                    Cleaner.delete_trackers(
                        completed_trackers, block.get("height"), self.trackers, self.tx_tracker_map, self.db_manager
                    )
                    Cleaner.delete_trackers(
                        expired_trackers,
                        block.get("height"),
                        self.trackers,
                        self.tx_tracker_map,
                        self.db_manager,
                        expired=True,
                    )
                    Cleaner.delete_gatekeeper_appointments(self.gatekeeper, trackers_to_delete_gatekeeper)

                    self.rebroadcast(self.get_txs_to_rebroadcast())

                # NOTCOVERED
                else:
                    logger.warning(
                        "Reorg found",
                        local_prev_block_hash=self.last_known_block,
                        remote_prev_block_hash=block.get("previousblockhash"),
                    )

                    # ToDo: #24-properly-handle-reorgs
                    self.handle_reorgs(block_hash)

                # Clear the receipts issued in this block
                self.carrier.issued_receipts = {}

                if len(self.trackers) == 0:
                    logger.info("No more pending trackers")

            # Register the last processed block for the responder
            self.db_manager.store_last_block_hash_responder(block_hash)
            self.last_known_block = block.get("hash")
            self.block_queue.task_done()