def test_10_search_transaction(self): print("\n-----", sys._getframe().f_code.co_name, "-----") transactions[0], fmt_type = bbclib.deserialize(transaction_dat) print("find txid=", binascii.b2a_hex(transactions[0].transaction_id)) clients[1]['app'].search_transaction(transactions[0].transaction_id) dat = msg_processor[1].synchronize() assert dat[KeyType.status] == 0 assert KeyType.transaction_data in dat txobj, fmt_type = bbclib.deserialize(dat[KeyType.transaction_data]) assert txobj.transaction_id == transactions[0].transaction_id
def verify_file(file): fileinfo = get_id_from_mappings(os.path.basename(file), asset_group_id) if fileinfo is None: print( "Not exists in local mapping cache. So, asset_id is not known...") sys.exit(1) bbc_app_client = setup_bbc_client() ret = bbc_app_client.search_transaction_with_condition( asset_group_id=asset_group_id, asset_id=fileinfo["asset_id"]) assert ret response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: print("ERROR: ", response_data[KeyType.reason].decode()) sys.exit(0) transaction, fmt_type = bbclib.deserialize( response_data[KeyType.transactions][0]) digest = transaction.digest() ret = transaction.signatures[0].verify(digest) if not ret: print("Transaction data is invalid.") sys.exit(1) with open(file, "rb") as fin: data = fin.read() file_digest = hashlib.sha256(data).digest() if file_digest == transaction.relations[0].asset.asset_file_digest: print("%s is valid" % file) else: print("%s is invalid" % file) print("done verify %s" % os.path.basename(file)) print("Content of the transaction:::") print(transaction)
def remove(self, transaction_id, txobj=None, db_num=-1): """Delete all data regarding the specified transaction_id This method requires either transaction_id or txobj. Args: transaction_id (bytes): target transaction_id txobj (BBcTransaction): transaction object to remove db_num (int): index of DB if multiple DBs are used """ if transaction_id is None: return if txobj is None: txdata = self.exec_sql( sql="SELECT * FROM transaction_table WHERE transaction_id = %s" % self.db_adaptors[0].placeholder, args=(transaction_id, )) txobj, fmt_type = bbclib.deserialize(txdata[0][1]) elif txobj.transaction_id != transaction_id: return if db_num == -1 or db_num >= len(self.db_adaptors): for i in range(len(self.db_adaptors)): self._remove_transaction(txobj, i) else: self._remove_transaction(txobj, db_num)
def test_14_search_transactions_start_until(self): print("\n-----", sys._getframe().f_code.co_name, "-----") global start_from print("* search start_from=%d, until=%d" % (start_from, start_from + 3300)) clients[0]['app'].search_transaction_with_condition( asset_group_id=asset_group_id, count=30, start_from=start_from, until=start_from + 3300) dat = msg_processor[0].synchronize() assert dat[KeyType.status] == ESUCCESS assert KeyType.transactions in dat assert len(dat[KeyType.transactions]) == 6 for i in range(3): txobj, fmt_type = bbclib.deserialize(dat[KeyType.transactions][i]) print("[%i] txid: %s -> timestamp: %d" % (i, txobj.transaction_id.hex(), txobj.timestamp)) clients[0]['app'].count_transactions(asset_group_id=asset_group_id, start_from=start_from, until=start_from + 3300) dat = msg_processor[0].synchronize() assert dat[KeyType.status] == ESUCCESS count = dat[KeyType.count] assert count == 6
def _receive_transaction_data_from_others(self, dat): """Receive transaction data from other core_nodes and check its validity Args: dat (dict): received message """ #print("_receive_transaction_data_from_others:") if KeyType.transaction_data not in dat or KeyType.transaction_id not in dat or KeyType.nonce not in dat: return if dat[KeyType.nonce] not in self.requesting_list: return asset_files = dict() if KeyType.all_asset_files in dat: asset_files = dat[KeyType.all_asset_files] txobj, fmt_type = bbclib.deserialize(dat[KeyType.transaction_data]) if txobj.transaction_data is None: return txobj_is_valid, valid_assets, invalid_assets = bbclib.validate_transaction_object( txobj, asset_files) if txobj_is_valid: self.stats.update_stats_increment("transaction", "success_repair", 1) for idx in range(len(self.data_handler.db_adaptors)): self.data_handler.restore_transaction_data( db_num=idx, transaction_id=txobj.transaction_id, txobj=txobj) add_info = { "repaired_by": dat[KeyType.source_node_id].hex(), "repaired_at": int(time.time()) } self.requesting_list[dat[KeyType.nonce]].update(add_info) self._output_log(self.requesting_list[dat[KeyType.nonce]]) del self.requesting_list[dat[KeyType.nonce]]
def create_transaction_object_and_send_sign_req(idx, receiver_user_id, ref_txids=None, file_data=None): if ref_txids is None or ref_txids[0] is None: ref_txids = [] txobj = bbclib.make_transaction(relation_num=1, witness=True) bbclib.add_relation_asset(txobj, relation_idx=0, asset_group_id=asset_group_id, user_id=receiver_user_id, asset_body="transferred", asset_file=file_data) txobj.witness.add_witness(user_ids[idx]) txobj.witness.add_witness(receiver_user_id) for i, ref_txid in enumerate(ref_txids): clients[idx].search_transaction(ref_txid) response_data = clients[idx].callback.synchronize() if response_data[KeyType.status] < ESUCCESS: print("ERROR: ", response_data[KeyType.reason].decode()) sys.exit(0) prev_tx, fmt_type = bbclib.deserialize(response_data[KeyType.transaction_data]) bbclib.add_relation_pointer(txobj, 0, ref_transaction_id=prev_tx.digest()) sig_mine = txobj.sign(private_key=keypairs[idx].private_key, public_key=keypairs[idx].public_key) txobj.witness.add_signature_object(user_id=user_ids[idx], signature=sig_mine) asset_id = txobj.relations[0].asset.asset_id asset_files = {asset_id: file_data} ret = clients[idx].gather_signatures(txobj, destinations=[receiver_user_id], asset_files=asset_files) assert ret return txobj
def get_file(file): fileinfo = get_id_from_mappings(os.path.basename(file), asset_group_id) if fileinfo is None: print( "Not exists in local mapping cache. So, asset_id is not known...") sys.exit(1) bbc_app_client = setup_bbc_client() ret = bbc_app_client.search_transaction_with_condition( asset_group_id=asset_group_id, asset_id=fileinfo["asset_id"]) assert ret response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: print("ERROR: ", response_data[KeyType.reason].decode()) sys.exit(0) get_transaction, fmt_type = bbclib.deserialize( response_data[KeyType.transactions][0]) if KeyType.all_asset_files in response_data: asset_file_dict = response_data[KeyType.all_asset_files] asset_id = get_transaction.relations[0].asset.asset_id data = asset_file_dict[asset_id] else: data = get_transaction.relations[0].asset.asset_body out_file_name = file if os.path.exists(out_file_name): current_datetime = datetime.datetime.now() time_str = current_datetime.strftime('_%Y%m%d%H%M%S') out_file_name += time_str with open(out_file_name, "wb") as outfile: outfile.write(data) print("done get %s" % out_file_name)
def proc_cmd_sign_request(self, dat): self.logger.debug( "[%i] Recv SIGN_REQUEST from %s" % (self.idx, binascii.b2a_hex(dat[KeyType.source_user_id]))) txobj, fmt_type = bbclib.deserialize(dat[KeyType.transaction_data]) signature = txobj.sign(keypair=clients[self.idx]['keypair']) clients[self.idx]['app'].sendback_signature( dat[KeyType.source_user_id], txobj.transaction_id, signature)
def test_19_search_asset(self): print("\n-----", sys._getframe().f_code.co_name, "-----") clients[0]['app'].search_transaction_with_condition(asset_group_id=asset_group_id, asset_id=transactions[0].events[1].asset.asset_id) dat = msg_processor[0].synchronize() assert KeyType.transactions in dat txobj, fmt_type = bbclib.deserialize(dat[KeyType.transactions][0]) assert txobj.transaction_id == transactions[0].transaction_id
def __get_transaction(self, tx_id): """Gets the transaction object of the specified ID.""" ret = self.__app.search_transaction(tx_id) res = self.__app.callback.sync_by_queryid(ret) if res[KeyType.status] < ESUCCESS: raise RuntimeError(res[KeyType.reason].decode()) tx, fmt = bbclib.deserialize(res[KeyType.transaction_data]) return tx
def store_proc(asset_body, asset_file, asset_group_id, domain_id, key_pair, user_id, txid=None): bbc_app_client = setup_bbc_client(domain_id, user_id) store_transaction = bbclib.make_transaction(relation_num=1, witness=True) bbclib.add_relation_asset(store_transaction, relation_idx=0, asset_group_id=asset_group_id, user_id=user_id, asset_body=asset_body, asset_file=asset_file) store_transaction.witness.add_witness(user_id) if txid: bbc_app_client.search_transaction(txid) response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: return None, None, "ERROR: %s" % response_data[ KeyType.reason].decode() prev_tx, fmt_type = bbclib.deserialize( response_data[KeyType.transaction_data]) keypair = bbclib.KeyPair(privkey=key_pair.private_key, pubkey=key_pair.public_key) if not keypair.verify(prev_tx.transaction_id, prev_tx.signatures[0].signature): return None, None, "ERROR: Signature or keypair is invalid." bbclib.add_relation_pointer(transaction=store_transaction, relation_idx=0, ref_transaction_id=prev_tx.transaction_id) sig = store_transaction.sign(private_key=key_pair.private_key, public_key=key_pair.public_key) store_transaction.get_sig_index(user_id) store_transaction.add_signature_object(user_id=user_id, signature=sig) store_transaction.digest() print(store_transaction) ret = bbc_app_client.insert_transaction(store_transaction) assert ret response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: return None, None, "ERROR: %s" % response_data[KeyType.reason].decode() transaction_id = response_data[KeyType.transaction_id] asset_ids = store_transaction.relations[0].asset.asset_id return asset_ids, transaction_id, None
def test_21_search_transaction_by_userid(self): print("\n-----", sys._getframe().f_code.co_name, "-----") clients[0]['app'].search_transaction_with_condition( asset_group_id=asset_group_id, user_id=clients[0]['user_id']) dat = wait_check_result_msg_type( msg_processor[0], bbclib.MsgType.RESPONSE_SEARCH_WITH_CONDITIONS) assert dat[KeyType.status] == ESUCCESS assert KeyType.transactions in dat txobj, fmt_type = bbclib.deserialize(dat[KeyType.transactions][0]) print(txobj)
def proc_cmd_sign_request(self, dat): self.logger.info("[%d] Recv SIGN_REQUEST from %s" % (self.idx, binascii.b2a_hex(dat[KeyType.source_user_id]))) if KeyType.transactions not in dat: self.logger.warn("message needs to include referred transactions") return txobj, fmt_type = bbclib.deserialize(dat[KeyType.transaction_data]) objs = dict() for txid, txdata in dat[KeyType.transactions].items(): txo, fmt_type = bbclib.deserialize(txdata) objs[txid] = txo for i, reference in enumerate(txobj.references): event = objs[reference.transaction_id].events[reference.event_index_in_ref] if clients[self.idx]['user_id'] in event.mandatory_approvers: signature = txobj.sign(keypair=clients[self.idx]['keypair']) clients[self.idx]['app'].sendback_signature(dat[KeyType.source_user_id], txobj.transaction_id, i, signature) return
def proc_resp_search_asset(self, dat): if KeyType.transaction_data in dat: self.logger.debug("OK: Asset [%s] is found." % binascii.b2a_hex(dat[KeyType.asset_id])) tx_obj, fmt_type = bbclib.deserialize(dat[KeyType.transaction_data]) for evt in tx_obj.events: if evt.asset.asset_body_size > 0: self.logger.debug(" [%s] asset_body --> %s" % (binascii.b2a_hex(evt.asset.asset_id[:4]), evt.asset.asset_body)) else: self.logger.debug("NG.....") dat = None self.queue.put(dat)
def search_transaction(domain_id, txid): """ Search transaction with the given transaction_id :param domain_id: :param txid: :return: """ bbc_app_client = setup_bbc_client(domain_id, user_id) bbc_app_client.search_transaction(transaction_id=txid) response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: print("ERROR: ", response_data[KeyType.reason].decode()) return None obj, fmt_type = bbclib.deserialize(response_data[KeyType.transaction_data]) return obj
def test_17_search_transaction(self): print("\n-----", sys._getframe().f_code.co_name, "-----") print("find txid=", binascii.b2a_hex(transactions[0].transaction_id)) clients[0]['app'].search_transaction(transactions[0].transaction_id) dat = msg_processor[0].synchronize() assert dat[KeyType.status] == 0 assert KeyType.compromised_transaction_data not in dat assert KeyType.transaction_data in dat print(bbclib.deserialize(dat[KeyType.transaction_data])) print("find txid=", binascii.b2a_hex(transactions[1].transaction_id)) clients[1]['app'].search_transaction(transactions[1].transaction_id) dat = msg_processor[1].synchronize() assert dat[KeyType.status] == 0 assert KeyType.compromised_transaction_data not in dat assert KeyType.transaction_data in dat
def verify_file(): if request.method == 'GET': asset_id_str = request.args.get('asset_id_str') asset_id = bbclib.convert_idstring_to_bytes(asset_id_str) asset_group_id_str = request.args.get('asset_group_id_str') asset_group_id = bbclib.convert_idstring_to_bytes(asset_group_id_str) user_id_str = request.args.get('user_id_str') user_id = bbclib.convert_idstring_to_bytes(user_id_str) bbc_app_client = setup_bbc_client(domain_id, user_id) ret = bbc_app_client.search_transaction_with_condition( asset_group_id=asset_group_id, asset_id=asset_id, user_id=user_id) assert ret response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: return jsonify(message="ERROR: %s" % response_data[KeyType.reason].decode('utf-8')), 404 transactions = [ bbclib.deserialize(data) for data in response_data[KeyType.transactions] ] transaction, fmt = transactions[0] digest = transaction.digest() if not transaction.signatures[0].verify(digest): return jsonify( message="ERROR: Transaction digest is invalid."), 404 if get_asset_file(transaction, response_data) is not None: data = get_asset_file(transaction, response_data) else: data = get_asset_body(transaction) file_digest = hashlib.sha256(data).digest() if file_digest == transaction.relations[0].asset.asset_file_digest: return jsonify(), 200 else: return jsonify(message="ERROR: Asset file digest is invalid."), 404
def test_06_search_transaction_direction_backward(self): print("\n-----", sys._getframe().f_code.co_name, "-----") clients[0]['app'].traverse_transactions( transactions2[4].transaction_id, direction=1, hop_count=3) dat = clients[0]['app'].callback.synchronize() assert dat[KeyType.status] == 0 assert KeyType.transaction_tree in dat assert len(dat[KeyType.transaction_tree]) == 3 asset_bodies = list() for i, txtree in enumerate(dat[KeyType.transaction_tree]): for txdat in txtree: txobj, fmt_type = bbclib.deserialize(txdat) asset_body = txobj.events[0].asset.asset_body print("[%d] asset=%s" % (i, asset_body)) asset_bodies.append(asset_body) assert b'transaction2_4' in asset_bodies assert b'transaction2_3' in asset_bodies assert b'transaction2_2' in asset_bodies
def test_11_verify_file(self): print("\n-----", sys._getframe().f_code.co_name, "-----") # -- verify by user_1 clients[1].search_transaction_with_condition(asset_group_id=asset_group_id, asset_id=asset_id) response_data = clients[1].callback.synchronize() assert response_data[KeyType.status] == ESUCCESS txobj, fmt_type = bbclib.deserialize(response_data[KeyType.transactions][0]) digest = txobj.digest() ret = txobj.signatures[0].verify(digest) assert ret file_digest = hashlib.sha256(large_data).digest() if file_digest == txobj.relations[0].asset.asset_file_digest: print("oooo valid") else: print("xxxx invalid") print(txobj)
def store_proc(file, txid=None): with open(file, "rb") as fin: data = fin.read() bbc_app_client = setup_bbc_client() store_transaction = bbclib.make_transaction(relation_num=1, witness=True) user_info = "Owner is %s" % user_name bbclib.add_relation_asset(store_transaction, relation_idx=0, asset_group_id=asset_group_id, user_id=user_id, asset_body=user_info, asset_file=data) store_transaction.witness.add_witness(user_id) if txid: bbc_app_client.search_transaction(txid) response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: print("ERROR: ", response_data[KeyType.reason].decode()) sys.exit(0) prev_tx, fmt_type = bbclib.deserialize( response_data[KeyType.transaction_data]) bbclib.add_relation_pointer(transaction=store_transaction, relation_idx=0, ref_transaction_id=prev_tx.transaction_id) sig = store_transaction.sign(private_key=key_pair.private_key, public_key=key_pair.public_key) store_transaction.get_sig_index(user_id) store_transaction.add_signature_object(user_id=user_id, signature=sig) store_transaction.digest() print(store_transaction) ret = bbc_app_client.insert_transaction(store_transaction) assert ret response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: print("ERROR: ", response_data[KeyType.reason].decode()) sys.exit(0) store_id_mappings(os.path.basename(file), asset_group_id, transaction_id=response_data[KeyType.transaction_id], asset_ids=store_transaction.relations[0].asset.asset_id)
def search_all_transactions_of_user(domain_id, user_id): """ Search all transactions with the specified user's asset and return the list of the transactions :param domain_id: :param user_id: :return: """ bbc_app_client = setup_bbc_client(domain_id, user_id) bbc_app_client.search_transaction_with_condition(asset_group_id=asset_group_id, user_id=user_id, direction=0, count=30) # direction=0 means that the result is sorted in descending order in terms of timestamp (direction=1 means ascending) response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: print("ERROR: ", response_data[KeyType.reason].decode()) return None txlist = list() for txdat in response_data[KeyType.transactions]: obj, fmt_type = bbclib.deserialize(txdat) txlist.append(obj) return txlist
def test_07_search_transaction_direction_forward(self): print("\n-----", sys._getframe().f_code.co_name, "-----") clients[0]['app'].traverse_transactions( transactions2[4].transaction_id, direction=0, hop_count=10) dat = clients[0]['app'].callback.synchronize() assert dat[KeyType.status] == 0 assert KeyType.transaction_tree in dat assert KeyType.all_included in dat and not dat[KeyType.all_included] print( "*Expected sequences: 4-5-6-7-8, 4-5-9-10-11-12-13-14 (total txobj count=11)" ) assert len( dat[KeyType.transaction_tree]) == 8 # "4-5-9-10-11-12-13-14" asset_bodies = list() for i, txtree in enumerate(dat[KeyType.transaction_tree]): for txdat in txtree: txobj, fmt_type = bbclib.deserialize(txdat) asset_body = txobj.events[0].asset.asset_body print("[%d] asset=%s" % (i, asset_body)) asset_bodies.append(asset_body)
def test_22_search_transaction_direction_forward(self): print("\n-----", sys._getframe().f_code.co_name, "-----") global start_from, transactions1 print("* search start_from=%d, until=%d" % (start_from, start_from + 2750)) clients[0]['app'].traverse_transactions( transactions1[1].transaction_id, asset_group_id=asset_group_id, start_from=start_from, until=start_from + 2750, direction=0, hop_count=10) dat = clients[0]['app'].callback.synchronize() assert dat[KeyType.status] == 0 assert KeyType.transaction_tree in dat assert len(dat[KeyType.transaction_tree]) == 5 for i, txtree in enumerate(dat[KeyType.transaction_tree]): for txdat in txtree: txobj, fmt_type = bbclib.deserialize(txdat) print("[%i] txid: %s -> timestamp: %d" % (i, txobj.transaction_id.hex(), txobj.timestamp))
def send_signreq(receiver_name, receiver_user_id, ref_txids=None, file_data=None, bbc_app_client=None): transaction = bbclib.make_transaction(relation_num=1, witness=True) user_info_msg = "Ownership is transfered from %s to %s" % (user_name, receiver_name) bbclib.add_relation_asset(transaction, relation_idx=0, asset_group_id=asset_group_id, user_id=receiver_user_id, asset_body=user_info_msg, asset_file=file_data) transaction.witness.add_witness(user_id) transaction.witness.add_witness(receiver_user_id) for i, ref_txid in enumerate(ref_txids): bbc_app_client.search_transaction(ref_txid) response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: print("ERROR: ", response_data[KeyType.reason].decode()) sys.exit(0) prev_tx, fmt_type = bbclib.deserialize( response_data[KeyType.transaction_data]) bbclib.add_relation_pointer(transaction, 0, ref_transaction_id=prev_tx.digest()) asset_id = transaction.relations[0].asset.asset_id asset_files = {asset_id: file_data} ret = bbc_app_client.gather_signatures(transaction, destinations=[receiver_user_id], asset_files=asset_files) if not ret: print("Failed to send sign request") sys.exit(0) return transaction
def __update_local_database(self, user_id): """Updates the local database upon synchronization with the current.""" ret = self.__app.search_transaction_with_condition( asset_group_id=self.namespace_id, user_id=user_id) res = self.__app.callback.sync_by_queryid( ret, 2) # FIXME: slow when not found if res is None or res[KeyType.status] < ESUCCESS: raise ValueError('not found') tx, fmt = bbclib.deserialize(res[KeyType.transactions][0]) tx_last = tx tx_directives = [] while True: ret = self.__db.exec_sql_fetchone( self.domain_id, NAME_OF_DB, ('select * from id_pubkey_table where ' 'tx_id_added=? or tx_id_removed=?'), tx.transaction_id, tx.transaction_id) if ret is not None: break directives = [] event = self.__get_event(tx, user_id) ptr = 0 while True: ptr, directive = Directive.from_serialized_data( ptr, event.asset.asset_body) if directive is None: break directives.append(directive) tx_directives.append((tx.transaction_id, directives)) tx = self.__get_referred_transaction(tx) if tx is None: break for (tx_id, directives) in reversed(tx_directives): for directive in directives: self.__apply(tx_id, user_id, directive) return tx_last
def pick_valid_transaction_info(received_data=None, bbc_app_client=None): transaction, fmt_type = bbclib.deserialize( received_data[KeyType.transaction_data]) asset_files = received_data[KeyType.all_asset_files] asset_id = transaction.relations[0].asset.asset_id if asset_id not in asset_files: print("**** No valid file is received...") print(received_data) bbc_app_client.sendback_denial_of_sign( received_data[KeyType.source_user_id], transaction.transaction_id, "No valid file is received.") sys.exit(1) file_to_obtain = asset_files[asset_id] file_digest = hashlib.sha256(file_to_obtain).digest() print("--------------------------") print( "File digest written in the transaction data: ", binascii.b2a_hex( transaction.relations[0].asset.asset_file_digest).decode()) print("File digest calculated from the received file:", binascii.b2a_hex(file_digest).decode()) print("--------------------------") return transaction, received_data[KeyType.source_user_id]
def store_file(): if request.method == 'GET': asset_id_str = request.args.get('asset_id_str') asset_id = bbclib.convert_idstring_to_bytes(asset_id_str) asset_group_id_str = request.args.get('asset_group_id_str') asset_group_id = bbclib.convert_idstring_to_bytes(asset_group_id_str) user_id_str = request.args.get('user_id_str') user_id = bbclib.convert_idstring_to_bytes(user_id_str) bbc_app_client = setup_bbc_client(domain_id, user_id) ret = bbc_app_client.search_transaction_with_condition( asset_group_id=asset_group_id, asset_id=asset_id, user_id=user_id) assert ret response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: return jsonify(message="ERROR: %s" % response_data[KeyType.reason].decode('utf-8')), 404 transactions = [ bbclib.deserialize(data) for data in response_data[KeyType.transactions] ] get_transaction, fmt_type = transactions[0] if KeyType.all_asset_files in response_data: asset_file_dict = response_data[KeyType.all_asset_files] asset_id = get_transaction.relations[0].asset.asset_id data = asset_file_dict[asset_id] else: data = get_transaction.relations[0].asset.asset_body return jsonify({ 'file': binascii.b2a_hex(data).decode('utf-8'), 'message': None, 'status': 'success' }) elif request.method == 'POST': asset_body = request.json.get('asset_body') asset_file = request.json.get('asset_file') asset_file_bytes = binascii.a2b_hex(asset_file) asset_group_id_str = request.json.get('asset_group_id_str') asset_group_id = bbclib.convert_idstring_to_bytes(asset_group_id_str) private_key_str = request.json.get('private_key_str') private_key = bbclib.convert_idstring_to_bytes(private_key_str) public_key_str = request.json.get('public_key_str') public_key = bbclib.convert_idstring_to_bytes(public_key_str) keypair = bbclib.KeyPair(privkey=private_key, pubkey=public_key) tx_id_str = request.json.get('tx_id_str') if tx_id_str is not None: tx_id = bbclib.convert_idstring_to_bytes(tx_id_str) else: tx_id = None user_id_str = request.json.get('user_id_str') user_id = bbclib.convert_idstring_to_bytes(user_id_str) asset_ids, transaction_id, message = \ store_proc(asset_body, asset_file_bytes, asset_group_id, domain_id, keypair, user_id, txid=tx_id) if message is not None: return jsonify(message=message), 404 if asset_ids is None: return jsonify(message="ERROR: asset_id is not found"), 404 if transaction_id is None: return jsonify(message="ERROR: transaction_id is not found"), 404 return jsonify(asset_ids_str=bbclib.convert_id_to_string(asset_ids), transaction_id_str=bbclib.convert_id_to_string( transaction_id)), 200
def get_transactions(): if request.method == 'GET': asset_id_str = request.args.get('asset_id_str') if asset_id_str is not None: asset_id = bbclib.convert_idstring_to_bytes(asset_id_str) else: asset_id = None asset_group_id_str = request.args.get('asset_group_id_str') if asset_group_id_str is not None: asset_group_id = bbclib.convert_idstring_to_bytes( asset_group_id_str) else: asset_group_id = None count = request.args.get('count') if count is None: count = 0 direction = request.args.get('direction') if direction is None: direction = 0 start_from = request.args.get('start_from') if start_from is None: start_from = None until = request.args.get('until') if until is None: until = None user_id_search_str = request.args.get('user_id_search_str') if user_id_search_str is not None: user_id_search = bbclib.convert_idstring_to_bytes( user_id_search_str) else: user_id_search = None user_id_str = request.args.get('user_id_str') user_id = bbclib.convert_idstring_to_bytes(user_id_str) bbc_app_client = setup_bbc_client(domain_id, user_id) ret = bbc_app_client.search_transaction_with_condition( asset_group_id=asset_group_id, asset_id=asset_id, user_id=user_id) assert ret response_data = bbc_app_client.callback.synchronize() if response_data[KeyType.status] < ESUCCESS: return jsonify(message="ERROR: %s" % response_data[KeyType.reason].decode('utf-8')), 404 transactions = [ bbclib.deserialize(data) for data in response_data[KeyType.transactions] ] dics = [] for tx_tuple in transactions: tx, fmt_type = tx_tuple dics.append({ 'transaction_id': bbclib.convert_id_to_string(tx.transaction_id), 'asset_group_id': bbclib.convert_id_to_string(tx.relations[0].asset_group_id), 'asset_id': bbclib.convert_id_to_string(tx.relations[0].asset.asset_id), 'user_id': bbclib.convert_id_to_string(tx.relations[0].asset.user_id), 'timestamp': datetime.fromtimestamp(tx.timestamp / 1000) }) return jsonify(transactions=dics), 200
def search_transaction(self, transaction_id=None, asset_group_id=None, asset_id=None, user_id=None, direction=0, count=1, db_num=0): """Search transaction data When Multiple conditions are given, they are considered as AND condition. Args: transaction_id (bytes): target transaction_id asset_group_id (bytes): asset_group_id that target transactions should have asset_id (bytes): asset_id that target transactions should have user_id (bytes): user_id that target transactions should have direction (int): 0: descend, 1: ascend count (int): The maximum number of transactions to retrieve db_num (int): index of DB if multiple DBs are used Returns: dict: mapping from transaction_id to serialized transaction data dict: dictionary of {asset_id: content} for the transaction """ if transaction_id is not None: txinfo = self.exec_sql( db_num=db_num, sql="SELECT * FROM transaction_table WHERE transaction_id = %s" % self.db_adaptors[0].placeholder, args=(transaction_id, )) if len(txinfo) == 0: return None, None else: dire = "DESC" if direction == 1: dire = "ASC" sql = "SELECT * from asset_info_table WHERE " conditions = list() if asset_group_id is not None: conditions.append("asset_group_id = %s " % self.db_adaptors[0].placeholder) if asset_id is not None: conditions.append("asset_id = %s " % self.db_adaptors[0].placeholder) if user_id is not None: conditions.append("user_id = %s " % self.db_adaptors[0].placeholder) sql += "AND ".join(conditions) + "ORDER BY id %s" % dire if count > 0: sql += " limit %d" % count sql += ";" args = list( filter(lambda a: a is not None, (asset_group_id, asset_id, user_id))) ret = self.exec_sql(db_num=db_num, sql=sql, args=args) txinfo = list() for record in ret: tx = self.exec_sql( db_num=db_num, sql= "SELECT * FROM transaction_table WHERE transaction_id = %s" % self.db_adaptors[0].placeholder, args=(record[1], )) if tx is not None and len(tx) == 1: txinfo.append(tx[0]) result_txobj = dict() result_asset_files = dict() for txid, txdata in txinfo: txobj, fmt_type = bbclib.deserialize(txdata) result_txobj[txid] = txobj for asset_group_id, asset_id, user_id, fileflag, filedigest in self.get_asset_info( txobj): if fileflag: result_asset_files[asset_id] = self.get_in_storage( asset_group_id, asset_id) return result_txobj, result_asset_files