async def __settle_bounty(self, bounty_guid, chain):
        """
        Callback registered in `__init__` to handle a settled bounty.

        Args:
            bounty_guid (str): GUID of the bounty being asserted on
            chain (str): Chain to operate on
        Returns:
            Response JSON parsed from polyswarmd containing emitted events
        """
        async with self.bounties_pending_locks[chain]:
            bounties_pending = self.bounties_pending.get(chain, set())
            if bounty_guid not in bounties_pending:
                logger.debug('Bounty %s already settled', bounty_guid)
                return []
            self.bounties_pending[chain] = bounties_pending - {bounty_guid}

        self.settles_posted += 1
        if self.testing > 0:
            if self.settles_posted > self.testing:
                logger.warning(
                    'Scheduled settle, but finished with testing mode')
                return []
            logger.info('Testing mode, %s settles remaining',
                        self.testing - self.settles_posted)

        ret = await self.client.bounties.settle_bounty(bounty_guid, chain)
        if 0 < self.testing <= self.settles_posted:
            logger.info('All testing bounties complete, exiting')
            asyncio_stop()
        return ret
Exemplo n.º 2
0
    async def __handle_settle_bounty(self, bounty_guid, chain):
        """
        Settle the given bounty on the given chain.

        Args:
            bounty_guid (str): The bounty which we are settling.
            chain (str): Which chain to operate on.
        Returns:
            Response JSON parsed from polyswarmd containing emitted events.
        """
        async with self.bounties_pending_locks[chain]:
            bounties_pending = self.bounties_pending.get(chain, set())
            if bounty_guid not in bounties_pending:
                logger.debug('Bounty %s already settled', bounty_guid)
                return []
            self.bounties_pending[chain] = bounties_pending - {bounty_guid}

        self.settles_posted += 1
        if self.testing > 0:
            if self.settles_posted > self.testing:
                logger.warning(
                    'Scheduled settle, but finished with testing mode')
                return []
            logger.info('Testing mode, %s settles remaining',
                        self.testing - self.settles_posted)

        ret = await self.client.bounties.settle_bounty(bounty_guid, chain)
        if 0 < self.testing <= self.settles_posted:
            logger.info('All testing bounties complete, exiting')
            asyncio_stop()
        return ret
Exemplo n.º 3
0
    def run(self, chains=None):
        """Run the main event loop

        Args:
            chains (set(str)): Set of chains to operate on. Defaults to {'home', 'side'}
        """
        if chains is None:
            chains = {'home', 'side'}

        configure_event_loop()

        while True:

            try:
                asyncio.get_event_loop().run_until_complete(
                    self.run_task(chains=chains))
            except asyncio.CancelledError:
                logger.info('Clean exit requested, exiting')

                asyncio_join()
                exit(0)
            except Exception:
                logger.exception('Unhandled exception at top level')
                asyncio_stop()
                asyncio_join()

                self.tries += 1
                wait = min(MAX_WAIT, self.tries * self.tries)

                logger.critical(
                    'Detected unhandled exception, sleeping for %s seconds then resetting task',
                    wait)
                time.sleep(wait)
                continue
Exemplo n.º 4
0
def mock_client(event_loop):
    asyncio.set_event_loop(event_loop)
    client = MockClient()
    client.start()
    yield client
    client.stop()
    asyncio_stop()
    asyncio_join()
Exemplo n.º 5
0
    async def watch_balance(self, block, chain):
        """
        Stores the latest block and then kicks off some balance checks.
        If the balance is outside the given range, it deposits, or withdraws as needed.
        """
        # Do nothing when talking to polyswarmd-fast
        if isinstance(self.client.bounties,
                      polyswarmclient.fast.bountiesclient.BountiesClient):
            return

        if chain == 'side':
            return

        # Keep block up to date, so we can use that value when figuring out what block the transaction may have gone in
        if chain == 'home':
            async with self.block_lock:
                if block > self.latest_block:
                    self.latest_block = block
                else:
                    return

        async with self.deposit_lock:
            side_balance = await self.client.balances.get_nct_balance(
                chain='side')
            if 0 < self.testing <= self.transfers:
                logger.info('Finished text runs')
                asyncio_stop()

            if self.last_relay is not None and (self.last_relay +
                                                self.confirmations) >= block:
                more_blocks = self.last_relay + self.confirmations - block
                logger.info('Waiting for %d more blocks', more_blocks)
                return
            elif self.last_relay is not None:
                logger.info('Checking NCT balance')
                # We can handle up to half refill_amount changes in either direction for any given block.
                # Greater than that, and the client will have to restart.
                if self.last_balance + (self.refill_amount /
                                        2) >= side_balance:
                    # Update balance, so each check against refill amount is from the latest changes
                    self.last_balance = side_balance
                    logger.error(
                        'Transfer does not appear to have completed. '
                        'Initial Balance: %s nct-wei. Current Balance: %s nct-wei.',
                        self.initial_balance, side_balance)
                    return
                else:
                    logger.info('Balance increased to %s nct-wei',
                                side_balance)
                    self.last_relay = None
                    self.last_balance = 0
                    self.initial_balance = 0

            if self.maximum is not None and self.withdraw_target is not None and side_balance > self.maximum:
                await self.try_withdrawal(side_balance)
            elif side_balance < self.minimum:
                await self.try_deposit(side_balance)
Exemplo n.º 6
0
 def run(self):
     configure_event_loop()
     loop = asyncio.get_event_loop()
     try:
         self.start(loop)
         # This stops any leftover tasks after out main task finishes
         asyncio_stop()
     except asyncio.CancelledError:
         logger.info('Clean exit requested, exiting')
         asyncio_join()
     except Exception:
         logger.exception('Unhandled exception at top level')
         asyncio_stop()
         asyncio_join()
Exemplo n.º 7
0
    def run(self, chains=None):
        """Run the main event loop

        Args:
            chains (set(str)): Set of chains to operate on. Defaults to {'home', 'side'}
        """
        if chains is None:
            chains = {'home', 'side'}

        # noinspection PyBroadException
        try:
            asyncio.get_event_loop().run_until_complete(self.run_task(chains=chains))
        except asyncio.CancelledError:
            logger.info('Clean exit requested')
            utils.asyncio_join()
        except Exception:
            logger.exception('Unhandled exception at top level')
            utils.asyncio_stop()
            utils.asyncio_join()
    async def __do_handle_settle_bounty(self, bounty_guid, chain):
        """
        When a bounty is scheduled to be settled, actually settle the bounty to the given chain.

        Args:
            bounty_guid (str): GUID of the bounty to be submitted.
            chain (str): Name of the chain where the bounty is to be posted.
        Returns:
            Response JSON parsed from polyswarmd containing emitted events.
        """
        async with self.bounties_pending_locks[chain]:
            bounties_pending = self.bounties_pending.get(chain, set())
            if bounty_guid not in bounties_pending:
                logger.debug(f'Bounty {bounty_guid} already settled')
                return []
            self.bounties_pending[chain] = bounties_pending - {bounty_guid}

        last_settle = False
        async with self.settles_posted_locks[chain]:
            settles_posted = self.settles_posted.get(chain, 0)
            self.settles_posted[chain] = settles_posted + 1

            if self.testing > 0:
                if self.settles_posted[chain] > self.testing:
                    logger.warning(
                        'Scheduled settle, but finished with testing mode')
                    return []
                elif self.settles_posted[chain] == self.testing:
                    last_settle = True

            logger.info(
                f'Testing mode, {self.testing - self.settles_posted[chain]} settles remaining'
            )

        ret = await self.client.bounties.settle_bounty(bounty_guid, chain)
        if last_settle:
            logger.info("All testing bounties complete, exiting")
            asyncio_stop()

        return ret
Exemplo n.º 9
0
 def run(self):
     while not self.finished:
         configure_event_loop()
         loop = asyncio.get_event_loop()
         try:
             self.start(loop)
             # This stops any leftover tasks after out main task finishes
             asyncio_stop()
         except asyncio.CancelledError:
             logger.info('Clean exit requested, exiting')
             asyncio_join()
             exit(0)
         except Exception:
             logger.exception('Unhandled exception at top level')
             asyncio_stop()
             asyncio_join()
             self.tries += 1
             wait = min(MAX_WAIT, self.tries * self.tries)
             logger.critical(
                 f'Detected unhandled exception, sleeping for {wait} seconds then resetting task'
             )
             time.sleep(wait)
             continue
Exemplo n.º 10
0
    def run(self):
        while not self.finished:
            loop = asyncio.SelectorEventLoop()

            # Default event loop does not support pipes on Windows
            if sys.platform == 'win32':
                loop = asyncio.ProactorEventLoop()

            asyncio.set_event_loop(loop)

            # K8 uses SIGTERM on linux and SIGINT and windows
            exit_signal = signal.SIGINT if platform.system() == "Windows" else signal.SIGTERM
            try:
                loop.add_signal_handler(exit_signal, self.handle_signal)
            except NotImplementedError:
                # Disable graceful exit, but run anyway
                logger.exception(f'{platform.system()} does not support graceful shutdown')
            try:
                asyncio.get_event_loop().run_until_complete(self.setup())
                gather_task = asyncio.gather(*[self.run_task(i) for i in range(self.task_count)])
                asyncio.get_event_loop().run_until_complete(gather_task)
            except asyncio.CancelledError:
                logger.info('Clean exit requested, exiting')

                asyncio_join()
                exit(0)
            except Exception:
                logger.exception('Unhandled exception at top level')
                asyncio_stop()
                asyncio_join()

                self.tries += 1
                wait = min(MAX_WAIT, self.tries * self.tries)

                logger.critical(f'Detected unhandled exception, sleeping for {wait} seconds then resetting task')
                time.sleep(wait)
                continue
Exemplo n.º 11
0
    def stop(self):
        self.http_mock.stop()
        self.__ws_mock_manager.stop()

        asyncio_stop()