async def async_since(self, date=0): """ Async. Return the list of transactions we got since the given date :param date: :return: a list of posblock.PosMessage objects """ res = await self.async_fetchall(SQL_SINCE, (date, )) res = [posblock.PosMessage().from_list(tx) for tx in res] return res
def random_tx(sign=True, block_height=0): tx = posblock.PosMessage().from_values( recipient='BHbbLpbTAVKrJ1XDLMM48Qa6xJuCGofCuH', value=str(randint(0, 1000))) tx.block_height = block_height if sign: try: tx.sign() except Exception as e: print(e) return tx
async def async_all(self, block_height=0): """ Return all transactions in current mempool :return: list() of PosMessages instances """ res = await self.async_fetchall(SQL_SINCE, (int(time.time()) - NOT_OLDER_THAN_SECONDS,)) res = [posblock.PosMessage().from_list(tx) for tx in res] if block_height: # Set blockheight to be embedded in. for tx in res: tx.block_height = block_height return res
async def digest_tx(self, tx, poschain=None): """ Async. Check validity of the transaction and insert if mempool if ok. TODO: 2 steps when getting batch: first checks, then a single insert FR: We could also keep just the txids in a ram dict to filter out faster. (no need if ram mempool) :param tx: :param poschain: :return: """ if 'TX' == tx.__class__.__name__: # Protobuf, convert to object tx = posblock.PosMessage().from_proto(tx) # TODO: if list, convert also if self.verbose and 'txdigest' in config.LOG: self.app_log.info("Digesting {}".format(tx.to_json())) try: if await self.tx_exists(tx.txid): # TODO: useless since we have an index, we can raise or ignore commit if exists. return False if poschain: if await poschain.tx_exists(tx.txid): return False # Validity checks, will raise tx.check() # TODO: batch, so we can do a global commit? await self._insert_tx(tx) # TODO: also add the pubkey in index if present. # returns the native tx object return tx except Exception as e: self.app_log.error("mempool digest_tx: {}".format(e)) exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] self.app_log.error(exc_type, fname, exc_tb.tb_lineno) raise
async def action(self, action="hello", param=""): """ Action Handler :param action: :param param: :return: The command result """ try: if action not in ( "hello", "ping", "status", "tx", "address_txs", "mempool", "update", "txtest", "block", "round", "hypernodes", "blocksync", "headers", "heights", ): raise ValueError("Unknown action: {}".format(action)) tcp_client = TCPClient() # FR: if self.verbose, print time to connect, time to hello, time end to end. Use a finally: section if self.source_ip: stream = await tcp_client.connect(self.ip, self.port, source_ip=self.source_ip, timeout=self.timeout) else: stream = await tcp_client.connect(self.ip, self.port, timeout=self.timeout) # Clients identifies itself as port 00101. ports < 1000 won't be used as peers. await com_helpers.async_send_string(commands_pb2.Command.hello, self.hello_string, stream, self.ip) # Don't use too short a timeout, or long commands will timeout, too. msg = await com_helpers.async_receive(stream, self.ip, timeout=self.read_timeout) if self.verbose: print("Client got {}".format(msg.__str__().strip())) if msg.command == commands_pb2.Command.hello: # decompose posnet/address and check. if self.verbose: print("Client got Hello {} from {}".format( msg.string_value, self.ip)) if msg.command == commands_pb2.Command.ko: print("Client got Ko {}".format(msg.string_value)) return if "ping" == action: # TODO - useful for client? return if "hello" == action: print( json.dumps( poshelpers.hello_to_params(msg.string_value, as_dict=True))) return if "status" == action: start_time = time.time() await com_helpers.async_send_void(commands_pb2.Command.status, stream, self.ip) msg = await com_helpers.async_receive( stream, self.ip, timeout=self.read_timeout) if msg.command == commands_pb2.Command.status: end_time = time.time() status = json.loads(msg.string_value) status["client"] = { "version": self.client_version, "lib_version": __version__, "localtime": end_time, "rtt": end_time - start_time, } print(json.dumps(status)) return if "round" == action: await com_helpers.async_send_void( commands_pb2.Command.getround, stream, self.ip) msg = await com_helpers.async_receive( stream, self.ip, timeout=self.read_timeout) if msg.command == commands_pb2.Command.getround: status = json.loads(msg.string_value) print(json.dumps(status)) return if "hypernodes" == action: if param: await com_helpers.async_send_string( commands_pb2.Command.gethypernodes, str(param), stream, self.ip) else: await com_helpers.async_send_void( commands_pb2.Command.gethypernodes, stream, self.ip) msg = await com_helpers.async_receive( stream, self.ip, timeout=self.read_timeout) if msg.command == commands_pb2.Command.gethypernodes: status = json.loads(msg.string_value) print(json.dumps(status)) return if "heights" == action: await com_helpers.async_send_void( commands_pb2.Command.getheights, stream, self.ip) msg = await com_helpers.async_receive( stream, self.ip, timeout=self.read_timeout) if msg.command == commands_pb2.Command.getheights: status = json.loads(msg.string_value) print(json.dumps(status)) return if "tx" == action: await com_helpers.async_send_string(commands_pb2.Command.gettx, str(param), stream, self.ip) msg = await com_helpers.async_receive( stream, self.ip, timeout=self.read_timeout) if msg.command == commands_pb2.Command.gettx: if msg.tx_values: txs = [ posblock.PosMessage().from_proto(tx).to_list( as_hex=True) for tx in msg.tx_values ] print(json.dumps(txs)) return else: print("false") return if "address_txs" == action: await com_helpers.async_send_string( commands_pb2.Command.getaddtxs, str(param), stream, self.ip) msg = await com_helpers.async_receive( stream, self.ip, timeout=self.read_timeout) if msg.command == commands_pb2.Command.getaddtxs: txs = [ posblock.PosMessage().from_proto(tx).to_list( as_hex=True) for tx in msg.tx_values ] print(json.dumps(txs)) return if "mempool" == action: try: # mempool with an "1" int value means send full mempool, unfiltered await com_helpers.async_send_int32( commands_pb2.Command.mempool, 1, stream, self.ip) msg = await com_helpers.async_receive( stream, self.ip, timeout=self.read_timeout) if msg.command == commands_pb2.Command.mempool: txs = [ posblock.PosMessage().from_proto(tx).to_list( as_hex=True) for tx in msg.tx_values ] print(json.dumps(txs)) return except Exception as e: print(e) if "update" == action: try: print("Sending update ", param) await com_helpers.async_send_string( commands_pb2.Command.update, param, stream, self.ip) except Exception as e: print("update", e) if "txtest" == action: tx = posblock.PosMessage().from_values( recipient="BHbbLpbTAVKrJ1XDLMM48Qa6xJuCGofCuH", value="1") try: tx.sign() # tx.value = 5 # uncomment to trigger invalid signature print(tx.to_json()) await com_helpers.async_send_txs(commands_pb2.Command.tx, [tx], stream, self.ip) except Exception as e: print(e) if "block" == action: await com_helpers.async_send_int32( commands_pb2.Command.getblock, int(param), stream, self.ip) msg = await com_helpers.async_receive( stream, self.ip, timeout=self.read_timeout) if msg.command == commands_pb2.Command.getblock: if msg.block_value: block = posblock.PosBlock().from_proto( msg.block_value[0]) print(block.to_json()) else: print("false") return if "blocksync" == action: await com_helpers.async_send_int32( commands_pb2.Command.blocksync, int(param), stream, self.ip) msg = await com_helpers.async_receive( stream, self.ip, timeout=self.read_timeout) if msg.command == commands_pb2.Command.blocksync: if msg.block_value: blocks = [] for block in msg.block_value: blocks.append( posblock.PosBlock().from_proto(block).to_dict( as_hex=True)) print(json.dumps(blocks)) else: print("false") return if "headers" == action: await com_helpers.async_send_string( commands_pb2.Command.getheaders, str(param), stream, self.ip) msg = await com_helpers.async_receive( stream, self.ip, timeout=self.read_timeout) if msg.command == commands_pb2.Command.getheaders: if msg.block_value: blocks = [] for block in msg.block_value: blocks.append( posblock.PosBlock().from_proto(block).to_dict( as_hex=True)) print(json.dumps(blocks)) else: print("false") return msg = await com_helpers.async_receive(stream, self.ip, timeout=self.read_timeout) print("Client got {}".format(msg.__str__().strip())) except TimeoutError: print("'Timeout'") except StreamClosedError: print("'Closed'") except ValueError as e: print("Client:", e) except Exception as e: print("Client:", e) exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno)