Exemplo n.º 1
0
    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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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)