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}')
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])
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
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