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
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
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
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
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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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