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 = bbclib.BBcTransaction() txobj.deserialize(dat[KeyType.transaction_data]) objs = dict() for txid, txdata in dat[KeyType.transactions].items(): txo = bbclib.BBcTransaction() txo.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 test_10_search_transaction(self): print("\n-----", sys._getframe().f_code.co_name, "-----") transactions[0] = bbclib.BBcTransaction() transactions[0].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 = bbclib.BBcTransaction( deserialize=dat[KeyType.transaction_data]) assert txobj.transaction_id == transactions[0].transaction_id
def test_07_1_insert_transaction(self): print("\n-----", sys._getframe().f_code.co_name, "-----") global transaction transaction = bbclib.BBcTransaction() rtn = bbclib.BBcRelation() rtn.asset_group_id = asset_group_id rtn.asset = bbclib.BBcAsset() rtn.asset.add(user_id=user_id1, asset_body=b'bbbbbb') ptr = bbclib.BBcPointer() ptr.add(transaction_id=txid1) rtn.add(pointer=ptr) wit = bbclib.BBcWitness() transaction.add(relation=rtn, witness=wit) wit.add_witness(user_id1) sig = transaction.sign(key_type=CURVE_TYPE, private_key=keypair.private_key, public_key=keypair.public_key) transaction.add_signature(user_id=user_id1, signature=sig) transaction.digest() ret = cores[0].insert_transaction(domain_id, transaction.serialize()) assert ret[KeyType.transaction_id] == transaction.transaction_id ret = cores[0]._search_transaction_by_txid(domain_id, transaction.transaction_id) assert ret is not None print(ret) print("-- wait 2 seconds --")
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 = bbclib.BBcTransaction(deserialize=dat[KeyType.transactions][0]) assert txobj.transaction_id == transactions[0].transaction_id
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 = bbclib.BBcTransaction() txobj.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 search_transaction(self, transaction_id=None, asset_group_id=None, asset_id=None, user_id=None, direction=0, count=1): """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 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( sql="SELECT * FROM transaction_table WHERE transaction_id = %s" % self.db_adaptor.placeholder, args=(transaction_id,)) if len(txinfo) == 0: return 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_adaptor.placeholder) if asset_id is not None: conditions.append("asset_id = %s " % self.db_adaptor.placeholder) if user_id is not None: conditions.append("user_id = %s " % self.db_adaptor.placeholder) sql += "AND ".join(conditions) + "ORDER BY id %s" % dire if count > 0: if count > 20: count = 20 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(sql=sql, args=args) txinfo = list() for record in ret: tx = self.exec_sql( sql="SELECT * FROM transaction_table WHERE transaction_id = %s" % self.db_adaptor.placeholder, args=(record[1],)) if tx is not None and len(tx) == 1: txinfo.append(tx[0]) result_txobj = dict() for txid, txdata in txinfo: txobj = bbclib.BBcTransaction(deserialize=txdata) result_txobj[txid] = txobj return result_txobj
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 transaction_data = dat[KeyType.transactions][0] txobj = bbclib.BBcTransaction(deserialize=transaction_data) print(txobj)
def proc_resp_search_asset(self, dat): if KeyType.transaction_data in dat: self.logger.info("OK: Asset [%s] is found." % binascii.b2a_hex(dat[KeyType.asset_id])) tx_obj = bbclib.BBcTransaction( deserialize=dat[KeyType.transaction_data]) for evt in tx_obj.events: if evt.asset.asset_body_size > 0: self.logger.info( " [%s] asset_body --> %s" % (binascii.b2a_hex( evt.asset.asset_id[:4]), evt.asset.asset_body)) else: self.logger.info("NG.....") self.queue.put(dat)
def test_04_search_transaction_direction_backward(self): print("\n-----", sys._getframe().f_code.co_name, "-----") clients[0]['app'].traverse_transactions( transactions1[1].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]) == 2 asset_bodies = list() for i, txtree in enumerate(dat[KeyType.transaction_tree]): for txdat in txtree: txobj = bbclib.BBcTransaction(deserialize=txdat) asset_body = txobj.relations[0].asset.asset_body print("[%d] asset=%s" % (i, asset_body)) asset_bodies.append(asset_body) assert b'transaction1_1' in asset_bodies assert b'transaction1_0' in asset_bodies
def remove(self, transaction_id, txobj=None): """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 """ 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_adaptor.placeholder, args=(transaction_id,)) txobj = bbclib.BBcTransaction(deserialize=txdata[0][1]) elif txobj.transaction_id != transaction_id: return self._remove_transaction(txobj)
def test_07_search_transaction_direction_forward(self): print("\n-----", sys._getframe().f_code.co_name, "-----") clients[4]['app'].traverse_transactions( transactions2[4].transaction_id, direction=0, hop_count=10) dat = clients[4]['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 = bbclib.BBcTransaction(deserialize=txdat) asset_body = txobj.events[0].asset.asset_body print("[%d] asset=%s" % (i, asset_body)) asset_bodies.append(asset_body)
def test_01_setup(self): print("\n-----", sys._getframe().f_code.co_name, "-----") #prepare_db() global data_handler dummycore = DummyCore() conf = config["domains"][bbclib.convert_id_to_string(domain_id)] data_handler = DataHandler(networking=dummycore.networking, config=conf, workingdir="testdir", domain_id=domain_id) global transactions for i in range(10): txobj = bbclib.BBcTransaction() evt = bbclib.BBcEvent() ast = bbclib.BBcAsset() ast.add(user_id=user_id1, asset_body=b'aaaaaa') evt.add(asset_group_id=asset_group_id1, asset=ast) rtn = bbclib.BBcRelation() ast2 = bbclib.BBcAsset() ast2.add(user_id=user_id2, asset_body=b'cccccccccc%d' % i) rtn.add(asset_group_id=asset_group_id2, asset=ast2) ptr = bbclib.BBcPointer() ptr.add(transaction_id=txid1) rtn.add(pointer=ptr) if i > 0: ptr = bbclib.BBcPointer() ptr.add(transaction_id=transactions[-1].transaction_id) rtn.add(pointer=ptr) wit = bbclib.BBcWitness() txobj.add(event=evt, relation=rtn, witness=wit) wit.add_witness(user_id1) sig = txobj.sign(key_type=bbclib.KeyType.ECDSA_SECP256k1, private_key=keypair1.private_key, public_key=keypair1.public_key) txobj.add_signature(user_id=user_id1, signature=sig) txobj.digest() transactions.append(txobj)
def insert_transaction(domain_id_str=None): json_data = request.json try: domain_id = binascii.a2b_hex(domain_id_str) bbcapp.set_domain_id(domain_id) source_user_id = get_id_binary(json_data, 'source_user_id') bbcapp.set_user_id(source_user_id) bbcapp.register_to_core() except: return jsonify({'error': 'invalid request'}), 500 txobj = bbclib.BBcTransaction(format_type=bbclib.BBcFormat.FORMAT_BSON) txdat = base64.b64decode(json_data.get('transaction_bson')) txobj.deserialize_bson(txdat) qid = bbcapp.insert_transaction(txobj) retmsg = bbcapp.callback.sync_by_queryid(qid, timeout=5) if retmsg is None: return jsonify({'error': 'No response'}), 400 bbcapp.unregister_from_core() msg = { 'result': 'success', 'transaction_id': retmsg[KeyType.transaction_id].hex() } flog.debug(msg) return jsonify(msg), 200
async def insert_transaction(request): json_data = await request.json() try: domain_id_str = request.match_info['domain_id_str'] domain_id = binascii.a2b_hex(domain_id_str) bbcapp.set_domain_id(domain_id) source_user_id = get_id_binary(json_data, 'source_user_id') bbcapp.set_user_id(source_user_id) bbcapp.register_to_core() except: return json_response({'error': 'invalid request'}, 500) txobj = bbclib.BBcTransaction(format_type=bbclib.BBcFormat.FORMAT_BSON) txdat = base64.b64decode(json_data.get('transaction_bson')) txobj.deserialize_obj(txdat) retmsg = bbcapp.insert_transaction(txobj) if retmsg is None: return json_response({'error': 'No response'}, 400) bbcapp.unregister_from_core() msg = { 'result': 'success', 'transaction_id': retmsg[KeyType.transaction_id].hex() } flog.debug(msg) return json_response(msg, 200)
def get_encoded_bson_txobj(txdat): txobj = bbclib.BBcTransaction(deserialize=txdat, format_type=bbclib.BBcFormat.FORMAT_BSON) return base64.b64encode(txobj.serialize_bson(no_header=True)).decode()