Exemplo n.º 1
0
async def main(host, port):
    async with aiorpcx.connect_rs(host, port) as session:
        # A good request with standard argument passing
        result = await session.send_request('echo', ["Howdy"])
        print(result)
        # A good request with named argument passing
        result = await session.send_request(
            'echo', {'message': "Hello with a named argument"})
        print(result)

        # aiorpcX transparently handles erroneous calls server-side, returning appropriate
        # errors.  This in turn causes an exception to be raised in the client.
        for bad_args in (
            ['echo'],
            ['echo', {}],
            ['foo'],
                # This causes an error running the server's buggy request handler.
                # aiorpcX catches the problem, returning an 'internal server error' to the
                # client, and continues serving
            ['sum', [2, 4, "b"]]):
            try:
                await session.send_request(*bad_args)
            except Exception as exc:
                print(repr(exc))

        # Batch requests
        async with session.send_batch() as batch:
            batch.add_request('echo', ["Me again"])
            batch.add_notification('ping')
            batch.add_request('sum', list(range(50)))

        for n, result in enumerate(batch.results, start=1):
            print(f'batch result #{n}: {result}')
Exemplo n.º 2
0
 async def get_bitcoin_balance(self, scripthash, num):
     async with timeout_after(30):
         async with connect_rs(self.electrumx_host, self.electrumx_port) as session:
             session.transport._framer.max_size = 0
             result = await session.send_request('query', {'items': [scripthash], 'limit': 1})
             logger.info("num: %s result: %s" % (num, result))
             if float(result[-1].strip('Balance:').strip('BTC')):
                 self.write_to_file([num])
Exemplo n.º 3
0
    async def _should_drop_peer(self, peer):
        peer.try_count += 1
        is_good = False
        for kind, port, family in peer.connection_tuples():
            peer.last_try = time.time()

            kwargs = {'family': family}
            if kind == 'SSL':
                kwargs['ssl'] = ssl.SSLContext(ssl.PROTOCOL_TLS)

            if self.env.force_proxy or peer.is_tor:
                if not self.proxy:
                    return
                kwargs['proxy'] = self.proxy
                kwargs['resolve'] = not peer.is_tor
            else:
                # Use our listening Host/IP for outgoing non-proxy
                # connections so our peers see the correct source.
                local_hosts = {
                    service.host
                    for service in self.env.services
                    if isinstance(service.host, (IPv4Address, IPv6Address))
                    and service.protocol != 'rpc'
                }
                if local_hosts:
                    kwargs['local_addr'] = (str(local_hosts.pop()), None)

            peer_text = f'[{peer}:{port} {kind}]'
            try:
                async with connect_rs(peer.host,
                                      port,
                                      session_factory=PeerSession,
                                      **kwargs) as session:
                    session.sent_request_timeout = 120 if peer.is_tor else 30
                    await self._verify_peer(session, peer)
                is_good = True
                break
            except BadPeerError as e:
                self.logger.error(f'{peer_text} marking bad: ({e})')
                peer.mark_bad()
                break
            except CodeMessageError as e:
                self.logger.error(f'{peer_text} RPC error: {e.message} '
                                  f'({e.code})')
            except (OSError, SOCKSError, ConnectionError, TaskTimeout) as e:
                self.logger.info(f'{peer_text} {e}')

        if is_good:
            now = time.time()
            elapsed = now - peer.last_try
            self.logger.info(f'{peer_text} verified in {elapsed:.1f}s')
            peer.try_count = 0
            peer.last_good = now
            peer.source = 'peer'
            # At most 2 matches if we're a host name, potentially
            # several if we're an IP address (several instances
            # can share a NAT).
            matches = peer.matches(self.peers)
            for match in matches:
                if match.ip_address:
                    if len(matches) > 1:
                        self.peers.remove(match)
                        # Force the peer's monitoring task to exit
                        match.retry_event.set()
                elif peer.host in match.features['hosts']:
                    match.update_features_from_peer(peer)
            # Trim this data structure
            self.recent_peer_adds = {
                k: v
                for k, v in self.recent_peer_adds.items()
                if v + PEER_ADD_PAUSE < now
            }
        else:
            # Forget the peer if long-term unreachable
            if peer.last_good and not peer.bad:
                try_limit = 10
            else:
                try_limit = 3
            if peer.try_count >= try_limit:
                desc = 'bad' if peer.bad else 'unreachable'
                self.logger.info(f'forgetting {desc} peer: {peer}')
                return True
        return False
Exemplo n.º 4
0
 async def _request_fee_estimate(numblocks):
     async with aiorpcx.connect_rs(Electrum.host, Electrum.port) as session:
         result = await session.send_request('blockchain.estimatefee', [numblocks])
         # convert from btc/kbyte
         sat_per_byte = int(result * (100_000_000/1000))
         Electrum.estimates[numblocks] = sat_per_byte