Exemple #1
0
async def probe(svr, proto_code, use_tor):
    conn = StratumClient()

    try:
        await conn.connect(svr,
                           proto_code,
                           use_tor=(svr.is_onion or use_tor),
                           short_term=True)
    except:
        failed.add(str(svr))
        return None

    peers, _ = conn.subscribe('server.peers.subscribe')

    peers = await peers
    print("%s gave %d peers" % (svr, len(peers)))

    connected.add(str(svr))

    # track them all.
    more = ks.add_peer_response(peers)

    if more:
        print("found %d more servers from %s: %s" %
              (len(more), svr, ', '.join(more)))

    conn.close()

    return str(svr)
Exemple #2
0
async def probe(svr, proto_code, use_tor):
    conn = StratumClient()

    try:
        await conn.connect(svr, proto_code, use_tor=(svr.is_onion or use_tor), short_term=True)
    except:
        failed.add(str(svr))
        return None

    peers, _ = conn.subscribe('server.peers.subscribe')

    peers = await peers
    print("%s gave %d peers" % (svr, len(peers)))

    connected.add(str(svr))

    # track them all.
    more = ks.add_peer_response(peers)

    if more:
        print("found %d more servers from %s: %s" % (len(more), svr, ', '.join(more)))
    

    conn.close()

    return str(svr)
Exemple #3
0
class Connection:
    """ Connection object. Connects to an Electrum server, and handles all
    Stratum protocol messages.
    """

    #  pylint: disable=E1111
    def __init__(self, loop: asyncio.AbstractEventLoop, server: str, port: int,
                 proto: str) -> None:
        """ Connection object constructor.

        :param loop: an asyncio event loop
        :param server: a string containing a hostname
        :param port: port number that the server listens on
        :returns: A new Connection object
        """
        logging.info("Connecting...")

        self.server_info = ServerInfo(server, hostname=server,
                                      ports=port)  # type: ServerInfo

        logging.info(str(self.server_info.get_port(proto)))

        self.client = StratumClient(loop)  # type: StratumClient
        self.connection = self.client.connect(
            self.server_info,
            proto_code=proto,
            use_tor=True,
            disable_cert_verify=(proto != "s"))  # type: asyncio.Future

        self.queue = None  # type: asyncio.Queue

    async def do_connect(self) -> None:
        """ Coroutine. Establishes a persistent connection to an Electrum server.
        Awaits the connection because AFAIK an init method can't be async.
        """
        await self.connection
        logging.info("Connected to server")

    async def listen_rpc(self, method: str, args: List) -> Any:
        """ Coroutine. Sends a normal RPC message to the server and awaits response.

        :param method: The Electrum API method to use
        :param args: Params associated with current method
        :returns: Future. Response from server for this method(args)
        """
        return await self.client.RPC(method, *args)

    def listen_subscribe(self, method: str, args: List) -> None:
        """ Sends a "subscribe" message to the server and adds to the queue.
        Throws away the immediate future containing the "history" hash.

        :param method: The Electrum API method to use
        :param args: Params associated with current method
        """
        t = self.client.subscribe(
            method, *args)  # type: Tuple[asyncio.Future, asyncio.Queue]
        future, queue = t

        self.queue = queue
        return future

    async def consume_queue(
            self, queue_func: Callable[[List[str]], Awaitable[None]]) -> None:
        """ Coroutine. Infinite loop that consumes the current subscription queue.
        :param queue_func: A function to call when new responses arrive
        """
        while True:
            result = await self.queue.get()  # type: List[str]
            await queue_func(result)