示例#1
0
    def GetLatestData(self, request: qrl_pb2.GetLatestDataReq,
                      context) -> qrl_pb2.GetLatestDataResp:
        logger.debug("[PublicAPI] GetLatestData")
        response = qrl_pb2.GetLatestDataResp()

        all_requested = request.filter == qrl_pb2.GetLatestDataReq.ALL
        quantity = min(request.quantity, self.MAX_REQUEST_QUANTITY)

        if all_requested or request.filter == qrl_pb2.GetLatestDataReq.BLOCKHEADERS:
            result = []
            for blk in self.qrlnode.get_latest_blocks(offset=request.offset,
                                                      count=quantity):
                transaction_count = qrl_pb2.TransactionCount()
                for tx in blk.transactions:
                    transaction_count.count[tx.type] += 1
                for tx in blk.vote:
                    transaction_count.count[tx.type] += 1
                for tx in blk.duplicate_transactions:
                    transaction_count.count[tx.type] += 1

                voted_weight = 0
                total_stake_weight = 0
                if blk.block_number > 0:
                    voted_weight, total_stake_weight = self.qrlnode.get_vote_metadata(
                        blk.block_number)

                result.append(
                    qrl_pb2.BlockHeaderExtended(
                        header=blk.blockheader.pbdata,
                        transaction_count=transaction_count,
                        voted_weight=voted_weight,
                        total_stake_weight=total_stake_weight))
            response.blockheaders.extend(result)

        if all_requested or request.filter == qrl_pb2.GetLatestDataReq.TRANSACTIONS:
            result = []
            for tx in self.qrlnode.get_latest_transactions(
                    offset=request.offset, count=quantity):
                # FIXME: Improve this once we have a proper database schema
                block_index = self.qrlnode.get_blockidx_from_txhash(tx.txhash)
                block = self.qrlnode.get_block_from_index(block_index)
                txextended = qrl_pb2.TransactionExtended(
                    header=block.blockheader.pbdata, tx=tx.pbdata)
                result.append(txextended)

            response.transactions.extend(result)

        if all_requested or request.filter == qrl_pb2.GetLatestDataReq.TRANSACTIONS_UNCONFIRMED:
            result = []
            for tx in self.qrlnode.get_latest_transactions_unconfirmed(
                    offset=request.offset, count=quantity):
                block_index = self.qrlnode.get_blockidx_from_txhash(tx.txhash)
                block = self.qrlnode.get_block_from_index(block_index)
                txextended = qrl_pb2.TransactionExtended(
                    header=block.blockheader.pbdata, tx=tx.pbdata)
                result.append(txextended)
            response.transactions_unconfirmed.extend(result)

        return response
示例#2
0
    def GetObject(self, request: qrl_pb2.GetObjectReq,
                  context) -> qrl_pb2.GetObjectResp:
        logger.debug("[PublicAPI] GetObject")
        answer = qrl_pb2.GetObjectResp()
        answer.found = False

        # FIXME: We need a unified way to access and validate data.
        query = bytes(
            request.query
        )  # query will be as a string, if Q is detected convert, etc.

        if AddressState.address_is_valid(query):
            if self.qrlnode.get_address_is_used(query):
                address_state = self.qrlnode.get_address_state(query)
                if address_state is not None:
                    answer.found = True
                    answer.address_state.CopyFrom(address_state.pbdata)
                    return answer

        transaction, block_number = self.qrlnode.get_transaction(query)
        if transaction is not None:
            answer.found = True
            blockheader = None
            if block_number is not None:
                block = self.qrlnode.get_block_from_index(block_number)
                blockheader = block.blockheader.pbdata

            txextended = qrl_pb2.TransactionExtended(
                header=blockheader,
                tx=transaction.pbdata,
                addr_from=transaction.addr_from,
                size=transaction.size)
            answer.transaction.CopyFrom(txextended)
            return answer

        # NOTE: This is temporary, indexes are accepted for blocks
        try:
            block = self.qrlnode.get_block_from_hash(query)
            if block is None:
                query_str = query.decode()
                query_index = int(query_str)
                block = self.qrlnode.get_block_from_index(query_index)

            answer.found = True
            block_extended = qrl_pb2.BlockExtended()
            block_extended.header.CopyFrom(block.blockheader.pbdata)
            block_extended.size = block.size
            for transaction in block.transactions:
                tx = Transaction.from_pbdata(transaction)
                extended_tx = qrl_pb2.TransactionExtended(
                    tx=transaction, addr_from=tx.addr_from, size=tx.size)
                block_extended.extended_transactions.extend([extended_tx])
            answer.block_extended.CopyFrom(block_extended)
            return answer
        except Exception:
            pass

        return answer
示例#3
0
    def GetLatestData(self, request: qrl_pb2.GetLatestDataReq,
                      context) -> qrl_pb2.GetLatestDataResp:
        logger.debug("[PublicAPI] GetLatestData")
        response = qrl_pb2.GetLatestDataResp()

        all_requested = request.filter == qrl_pb2.GetLatestDataReq.ALL
        quantity = min(request.quantity, self.MAX_REQUEST_QUANTITY)

        if all_requested or request.filter == qrl_pb2.GetLatestDataReq.BLOCKHEADERS:
            result = []
            for blk in self.qrlnode.get_latest_blocks(offset=request.offset,
                                                      count=quantity):
                transaction_count = qrl_pb2.TransactionCount()
                for tx in blk.transactions:
                    transaction_count.count[CODEMAP[tx.WhichOneof(
                        'transactionType')]] += 1

                result.append(
                    qrl_pb2.BlockHeaderExtended(
                        header=blk.blockheader.pbdata,
                        transaction_count=transaction_count))
            response.blockheaders.extend(result)

        if all_requested or request.filter == qrl_pb2.GetLatestDataReq.TRANSACTIONS:
            result = []
            for tx in self.qrlnode.get_latest_transactions(
                    offset=request.offset, count=quantity):
                # FIXME: Improve this once we have a proper database schema
                block_index = self.qrlnode.get_blockidx_from_txhash(tx.txhash)
                block = self.qrlnode.get_block_from_index(block_index)
                header = None
                if block:
                    header = block.blockheader.pbdata
                txextended = qrl_pb2.TransactionExtended(
                    header=header,
                    tx=tx.pbdata,
                    addr_from=tx.addr_from,
                    size=tx.size)
                result.append(txextended)

            response.transactions.extend(result)

        if all_requested or request.filter == qrl_pb2.GetLatestDataReq.TRANSACTIONS_UNCONFIRMED:
            result = []
            for tx_info in self.qrlnode.get_latest_transactions_unconfirmed(
                    offset=request.offset, count=quantity):
                tx = tx_info.transaction
                txextended = qrl_pb2.TransactionExtended(
                    header=None,
                    tx=tx.pbdata,
                    addr_from=tx.addr_from,
                    size=tx.size,
                    timestamp_seconds=tx_info.timestamp)
                result.append(txextended)
            response.transactions_unconfirmed.extend(result)

        return response
示例#4
0
    def GetObject(self, request: qrl_pb2.GetObjectReq,
                  context) -> qrl_pb2.GetObjectResp:
        logger.debug("[PublicAPI] GetObject")
        answer = qrl_pb2.GetObjectResp()
        answer.found = False

        # FIXME: We need a unified way to access and validate data.
        query = bytes(
            request.query
        )  # query will be as a string, if Q is detected convert, etc.

        if self.qrlnode.address_is_valid(query):
            if self.qrlnode.get_address_is_used(query):
                address_state = self.qrlnode.get_address_state(query)
                if address_state is not None:
                    answer.found = True
                    answer.address_state.CopyFrom(address_state)
                    return answer

        transaction = self.qrlnode.get_transaction(query)
        if transaction is not None:
            answer.found = True
            block_index = self.qrlnode.get_blockidx_from_txhash(
                transaction.txhash)
            blockheader = None
            if block_index:
                block = self.qrlnode.get_block_from_index(block_index)
                blockheader = block.blockheader.pbdata

            txextended = qrl_pb2.TransactionExtended(header=blockheader,
                                                     tx=transaction.pbdata)
            answer.transaction.CopyFrom(txextended)
            return answer

        block = self.qrlnode.get_block_from_hash(query)
        if block is not None:
            answer.found = True
            answer.block.CopyFrom(block.pbdata)
            return answer

        block = self.qrlnode.get_block_from_hash(query)
        if block is not None:
            answer.found = True
            answer.block.CopyFrom(block.pbdata)
            return answer

        # NOTE: This is temporary, indexes are accepted for blocks
        try:
            query_str = query.decode()
            query_index = int(query_str)
            block = self.qrlnode.get_block_from_index(query_index)
            if block is not None:
                answer.found = True
                answer.block.CopyFrom(block.pbdata)
                return answer
        except Exception:
            pass

        return answer
示例#5
0
 def get_token_detailed_list(self):
     pbdata = self.db_state.get_token_list()
     token_list = TokenList.from_json(pbdata)
     token_detailed_list = qrl_pb2.TokenDetailedList()
     for token_txhash in token_list.token_txhash:
         token_txn, _ = self.db_state.get_tx_metadata(token_txhash)
         transaction_extended = qrl_pb2.TransactionExtended(
             tx=token_txn.pbdata, addr_from=token_txhash.addr_from)
         token_detailed_list.extended_tokens.extend([transaction_extended])
     return token_detailed_list
示例#6
0
    def GetMessageTxn(self, request: qrl_pb2.TokenTxnReq, context) -> qrl_pb2.TransferCoinsResp:
        logger.debug("[PublicAPI] GetMessageTxn")
        tx = self.qrlnode.create_message_txn(message_hash=request.message,
                                             fee=request.fee,
                                             xmss_pk=request.xmss_pk,
                                             master_addr=request.master_addr)

        extended_transaction_unsigned = qrl_pb2.TransactionExtended(tx=tx.pbdata,
                                                                    addr_from=tx.addr_from,
                                                                    size=tx.size)
        return qrl_pb2.TransferCoinsResp(extended_transaction_unsigned=extended_transaction_unsigned)
示例#7
0
    def TransferCoins(self, request: qrl_pb2.TransferCoinsReq, context) -> qrl_pb2.TransferCoinsResp:
        logger.debug("[PublicAPI] TransferCoins")
        tx = self.qrlnode.create_send_tx(addrs_to=request.addresses_to,
                                         amounts=request.amounts,
                                         fee=request.fee,
                                         xmss_pk=request.xmss_pk,
                                         master_addr=request.master_addr)

        extended_transaction_unsigned = qrl_pb2.TransactionExtended(tx=tx.pbdata,
                                                                    addr_from=tx.addr_from,
                                                                    size=tx.size)
        return qrl_pb2.TransferCoinsResp(extended_transaction_unsigned=extended_transaction_unsigned)
示例#8
0
    def GetSlaveTxn(self, request: qrl_pb2.SlaveTxnReq, context) -> qrl_pb2.TransferCoinsResp:
        logger.debug("[PublicAPI] GetSlaveTxn")
        tx = self.qrlnode.create_slave_tx(slave_pks=request.slave_pks,
                                          access_types=request.access_types,
                                          fee=request.fee,
                                          xmss_pk=request.xmss_pk,
                                          master_addr=request.master_addr)

        extended_transaction_unsigned = qrl_pb2.TransactionExtended(tx=tx.pbdata,
                                                                    addr_from=tx.addr_from,
                                                                    size=tx.size)
        return qrl_pb2.TransferCoinsResp(extended_transaction_unsigned=extended_transaction_unsigned)
示例#9
0
    def GetTransferTokenTxn(self, request: qrl_pb2.TransferTokenTxnReq, context) -> qrl_pb2.TransferCoinsResp:
        logger.debug("[PublicAPI] GetTransferTokenTxn")
        bin_token_txhash = bytes(hstr2bin(request.token_txhash.decode()))
        tx = self.qrlnode.create_transfer_token_txn(addrs_to=request.addresses_to,
                                                    token_txhash=bin_token_txhash,
                                                    amounts=request.amounts,
                                                    fee=request.fee,
                                                    xmss_pk=request.xmss_pk,
                                                    master_addr=request.master_addr)

        extended_transaction_unsigned = qrl_pb2.TransactionExtended(tx=tx.pbdata,
                                                                    addr_from=tx.addr_from,
                                                                    size=tx.size)
        return qrl_pb2.TransferCoinsResp(extended_transaction_unsigned=extended_transaction_unsigned)
示例#10
0
    def GetLatticePublicKeyTxn(self, request: qrl_pb2.LatticePublicKeyTxnReq,
                               context) -> qrl_pb2.TransferCoinsResp:
        logger.debug("[PublicAPI] GetLatticePublicKeyTxn")
        tx = self.qrlnode.create_lattice_public_key_txn(
            kyber_pk=request.kyber_pk,
            dilithium_pk=request.dilithium_pk,
            fee=request.fee,
            xmss_pk=request.xmss_pk,
            master_addr=request.master_addr)

        extended_transaction_unsigned = qrl_pb2.TransactionExtended(
            tx=tx.pbdata, addr_from=tx.addr_from, size=tx.size)
        return qrl_pb2.TransferCoinsResp(
            extended_transaction_unsigned=extended_transaction_unsigned)
示例#11
0
    def GetLatticeTxn(self, request: qrl_pb2.LatticeTxnReq,
                      context) -> qrl_pb2.TransferCoinsResp:
        logger.debug("[PublicAPI] GetLatticeTxn")
        tx = self.qrlnode.create_lattice_tx(pk1=request.pk1,
                                            pk2=request.pk2,
                                            pk3=request.pk3,
                                            fee=request.fee,
                                            xmss_pk=request.xmss_pk,
                                            master_addr=request.master_addr)

        extended_transaction_unsigned = qrl_pb2.TransactionExtended(
            tx=tx.pbdata, addr_from=tx.addr_from, size=tx.size)
        return qrl_pb2.TransferCoinsResp(
            extended_transaction_unsigned=extended_transaction_unsigned)
示例#12
0
    def GetMultiSigVoteTxn(self, request: qrl_pb2.MultiSigVoteTxnReq,
                           context) -> qrl_pb2.TransferCoinsResp:
        logger.debug("[PublicAPI] GetMultiSigSpendTxnReq")
        tx = self.qrlnode.create_multi_sig_vote_txn(
            shared_key=request.shared_key,
            unvote=request.unvote,
            fee=request.fee,
            xmss_pk=request.xmss_pk,
            master_addr=request.master_addr)

        extended_transaction_unsigned = qrl_pb2.TransactionExtended(
            tx=tx.pbdata, addr_from=tx.addr_from, size=tx.size)
        return qrl_pb2.TransferCoinsResp(
            extended_transaction_unsigned=extended_transaction_unsigned)
示例#13
0
    def GetMultiSigCreateTxn(self, request: qrl_pb2.MultiSigCreateTxnReq,
                             context) -> qrl_pb2.TransferCoinsResp:
        logger.debug("[PublicAPI] GetMultiSigCreateTxnReq")
        tx = self.qrlnode.create_multi_sig_txn(signatories=request.signatories,
                                               weights=request.weights,
                                               threshold=request.threshold,
                                               fee=request.fee,
                                               xmss_pk=request.xmss_pk,
                                               master_addr=request.master_addr)

        extended_transaction_unsigned = qrl_pb2.TransactionExtended(
            tx=tx.pbdata, addr_from=tx.addr_from, size=tx.size)
        return qrl_pb2.TransferCoinsResp(
            extended_transaction_unsigned=extended_transaction_unsigned)
示例#14
0
    def GetTokenTxn(self, request: qrl_pb2.TokenTxnReq, context) -> qrl_pb2.TransferCoinsResp:
        logger.debug("[PublicAPI] GetTokenTxn")
        tx = self.qrlnode.create_token_txn(symbol=request.symbol,
                                           name=request.name,
                                           owner=request.owner,
                                           decimals=request.decimals,
                                           initial_balances=request.initial_balances,
                                           fee=request.fee,
                                           xmss_pk=request.xmss_pk,
                                           master_addr=request.master_addr)

        extended_transaction_unsigned = qrl_pb2.TransactionExtended(tx=tx.pbdata,
                                                                    addr_from=tx.addr_from,
                                                                    size=tx.size)
        return qrl_pb2.TransferCoinsResp(extended_transaction_unsigned=extended_transaction_unsigned)
示例#15
0
    def GetMultiSigSpendTxn(self, request: qrl_pb2.MultiSigSpendTxnReq,
                            context) -> qrl_pb2.TransferCoinsResp:
        logger.debug("[PublicAPI] GetMultiSigSpendTxnReq")
        tx = self.qrlnode.create_multi_sig_spend_txn(
            multi_sig_address=request.multi_sig_address,
            addrs_to=request.addrs_to,
            amounts=request.amounts,
            expiry_block_number=request.expiry_block_number,
            fee=request.fee,
            xmss_pk=request.xmss_pk,
            master_addr=request.master_addr)

        extended_transaction_unsigned = qrl_pb2.TransactionExtended(
            tx=tx.pbdata, addr_from=tx.addr_from, size=tx.size)
        return qrl_pb2.TransferCoinsResp(
            extended_transaction_unsigned=extended_transaction_unsigned)
示例#16
0
    def GetObject(self, request: qrl_pb2.GetObjectReq,
                  context) -> qrl_pb2.GetObjectResp:
        logger.debug("[PublicAPI] GetObject")
        answer = qrl_pb2.GetObjectResp()
        answer.found = False

        # FIXME: We need a unified way to access and validate data.
        query = bytes(
            request.query
        )  # query will be as a string, if Q is detected convert, etc.

        try:
            if AddressState.address_is_valid(query):
                if self.qrlnode.get_address_is_used(query):
                    address_state = self.qrlnode.get_address_state(query)
                    if address_state is not None:
                        answer.found = True
                        answer.address_state.CopyFrom(address_state.pbdata)
                        return answer
        except ValueError:
            pass

        transaction_block_number = self.qrlnode.get_transaction(query)
        transaction = None
        blockheader = None
        if transaction_block_number:
            transaction, block_number = transaction_block_number
            answer.found = True
            block = self.qrlnode.get_block_from_index(block_number)
            blockheader = block.blockheader.pbdata
            timestamp = block.blockheader.timestamp
        else:
            transaction_timestamp = self.qrlnode.get_unconfirmed_transaction(
                query)
            if transaction_timestamp:
                transaction, timestamp = transaction_timestamp
                answer.found = True

        if transaction:
            txextended = qrl_pb2.TransactionExtended(
                header=blockheader,
                tx=transaction.pbdata,
                addr_from=transaction.addr_from,
                size=transaction.size,
                timestamp_seconds=timestamp)
            answer.transaction.CopyFrom(txextended)
            return answer

        # NOTE: This is temporary, indexes are accepted for blocks
        try:
            block = self.qrlnode.get_block_from_hash(query)
            # The condition after or is to avoid a bug, where a block is deserialized by BlockNumberMapping
            if block is None or (block.block_number == 0
                                 and block.prev_headerhash !=
                                 config.user.genesis_prev_headerhash):
                query_str = query.decode()
                query_index = int(query_str)
                block = self.qrlnode.get_block_from_index(query_index)
                if not block:
                    return answer

            answer.found = True
            block_extended = qrl_pb2.BlockExtended()
            block_extended.header.CopyFrom(block.blockheader.pbdata)
            block_extended.size = block.size
            for transaction in block.transactions:
                tx = Transaction.from_pbdata(transaction)
                extended_tx = qrl_pb2.TransactionExtended(
                    tx=transaction,
                    addr_from=tx.addr_from,
                    size=tx.size,
                    timestamp_seconds=block.blockheader.timestamp)
                block_extended.extended_transactions.extend([extended_tx])
            answer.block_extended.CopyFrom(block_extended)
            return answer
        except Exception:
            pass

        return answer