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 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 make_transactions(id_len_conf={}, idlen=None): global transactions if idlen is None: configure_id_length(id_len_conf) else: bbclib.configure_id_length_all(idlen) transactions[0] = bbclib.make_transaction(relation_num=1, witness=True) bbclib.add_relation_asset(transactions[0], relation_idx=0, asset_group_id=asset_group_id, user_id=user_id, asset_body=b'transaction_0') transactions[0].witness.add_witness(user_id) sig = transactions[0].sign(keypair=keypair1) transactions[0].witness.add_signature(user_id, sig) txdata[0] = bbclib.serialize(transactions[0]) for i in range(1, 20): k = i - 1 transactions[i] = bbclib.make_transaction(relation_num=1, witness=True) bbclib.add_relation_asset(transactions[i], 0, asset_group_id=asset_group_id, user_id=user_id, asset_body=b'transaction_%d' % i) bbclib.add_relation_pointer( transactions[i], 0, ref_transaction_id=transactions[k].transaction_id, ref_asset_id=transactions[k].relations[0].asset.asset_id) transactions[i].witness.add_witness(user_id) sig = transactions[i].sign(keypair=keypair1) transactions[i].witness.add_signature(user_id, sig) txdata[i] = bbclib.serialize(transactions[i]) bbclib.configure_id_length_all(32) for i in range(0, 20): txobj, fmt_type = bbclib.deserialize(txdata[i]) txdata_deserialized[i] = txobj print(txobj.digest().hex())
def search_transaction(self, transaction_id=None, asset_group_id=None, asset_id=None, user_id=None, start_from=None, until=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 start_from (int): the starting timestamp to search until (int): the end timestamp to search 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) if start_from is not None: conditions.append("timestamp >= %s " % self.db_adaptors[0].placeholder) if until is not None: conditions.append("timestamp <= %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, start_from, until))) 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
def test_02_verify(self): print("\n-----", sys._getframe().f_code.co_name, "-----") keypair1 = bbclib.KeyPair() keypair1.mk_keyobj_from_private_key_pem(pem1) keypair2 = bbclib.KeyPair() keypair2.mk_keyobj_from_private_key_pem(pem2) bbclib.configure_id_length_all(32) transactions = list() txids = list() for txdata in txdata_list: txobj, _ = bbclib.deserialize(txdata) transactions.append(txobj) txids.append(txobj.transaction_id) for idx in range(len(transactions)): txobj = transactions[idx] if idx % 20 == 0: assert len(txobj.transaction_id) == id_conf["transaction_id"] assert len(txobj.relations) == 1 assert len(txobj.events) == 1 assert txobj.transaction_id == txids[idx] assert txobj.relations[0].asset_group_id == asset_group_id1[:id_conf["asset_group_id"]] assert txobj.relations[0].asset.user_id == user_id1[:id_conf["user_id"]] assert txobj.relations[0].asset.asset_body == b'relation:asset_0-0' assert len(txobj.relations[0].asset.nonce) == id_conf["nonce"] assert txobj.events[0].asset_group_id == asset_group_id1[:id_conf["asset_group_id"]] assert txobj.events[0].mandatory_approvers[0] == user_id1[:id_conf["user_id"]] assert txobj.events[0].asset.user_id == user_id1[:id_conf["user_id"]] assert txobj.events[0].asset.asset_body == b'event:asset_0-0' assert len(txobj.events[0].asset.nonce) == id_conf["nonce"] assert len(txobj.witness.user_ids) == 1 assert len(txobj.witness.sig_indices) == 1 assert len(txobj.signatures) == 1 if idx < 20: assert txobj.signatures[0].verify(txobj.digest()) else: #print("no pubkey") pass else: assert len(txobj.transaction_id) == id_conf["transaction_id"] assert len(txobj.relations) == 4 assert len(txobj.relations[0].pointers) == 1 assert len(txobj.relations[1].pointers) == 2 assert len(txobj.events) == 1 assert len(txobj.references) == 1 assert txobj.relations[0].asset_group_id == asset_group_id1[:id_conf["asset_group_id"]] assert txobj.relations[0].asset.user_id == user_id1[:id_conf["user_id"]] assert txobj.relations[0].asset.asset_body == b'relation:asset_1-%d' % (idx % 20) assert len(txobj.relations[0].asset.nonce) == id_conf["nonce"] assert len(txobj.relations[0].pointers[0].transaction_id) == id_conf["transaction_id"] assert len(txobj.relations[0].pointers[0].asset_id) == id_conf["asset_id"] assert txobj.relations[0].pointers[0].transaction_id == transactions[idx-1].transaction_id assert txobj.relations[0].pointers[0].asset_id == transactions[idx-1].relations[0].asset.asset_id assert txobj.relations[1].asset_group_id == asset_group_id2[:id_conf["asset_group_id"]] assert txobj.relations[1].asset.user_id == user_id2[:id_conf["user_id"]] assert txobj.relations[1].asset.asset_body == b'relation:asset_2-%d' % (idx % 20) assert len(txobj.relations[1].asset.nonce) == id_conf["nonce"] assert len(txobj.relations[1].pointers[0].transaction_id) == id_conf["transaction_id"] assert len(txobj.relations[1].pointers[0].asset_id) == id_conf["asset_id"] assert txobj.relations[1].pointers[0].transaction_id == transactions[idx-1].transaction_id assert txobj.relations[1].pointers[0].asset_id == transactions[idx-1].relations[0].asset.asset_id assert len(txobj.relations[1].pointers[1].transaction_id) == id_conf["transaction_id"] assert len(txobj.relations[1].pointers[1].asset_id) == id_conf["asset_id"] assert txobj.relations[2].asset_group_id == asset_group_id1[:id_conf["asset_group_id"]] assert txobj.relations[2].asset_raw.asset_body == b'relation:asset_4-%d' % (idx % 20) assert len(txobj.relations[2].pointers[0].transaction_id) == id_conf["transaction_id"] assert len(txobj.relations[2].pointers[0].asset_id) == id_conf["asset_id"] assert len(txobj.relations[2].pointers[1].transaction_id) == id_conf["transaction_id"] assert txobj.relations[2].pointers[1].asset_id is None assert txobj.relations[3].asset_group_id == asset_group_id2[:id_conf["asset_group_id"]] assert len(txobj.relations[3].asset_hash.asset_ids) == 4 assert len(txobj.relations[3].pointers[0].transaction_id) == id_conf["transaction_id"] assert len(txobj.relations[3].pointers[0].asset_id) == id_conf["asset_id"] if idx < 20: assert txobj.relations[1].pointers[1].transaction_id == transactions[0].transaction_id assert txobj.relations[1].pointers[1].asset_id == transactions[0].relations[0].asset.asset_id assert txobj.relations[2].pointers[0].transaction_id == transactions[0].transaction_id assert txobj.relations[2].pointers[0].asset_id == transactions[0].relations[0].asset.asset_id assert txobj.relations[2].pointers[1].transaction_id == transactions[0].transaction_id assert txobj.relations[3].pointers[0].transaction_id == transactions[0].transaction_id assert txobj.relations[3].pointers[0].asset_id == transactions[0].relations[0].asset.asset_id else: assert txobj.relations[1].pointers[1].transaction_id == transactions[20].transaction_id assert txobj.relations[1].pointers[1].asset_id == transactions[20].relations[0].asset.asset_id assert txobj.relations[2].pointers[0].transaction_id == transactions[20].transaction_id assert txobj.relations[2].pointers[0].asset_id == transactions[20].relations[0].asset.asset_id assert txobj.relations[2].pointers[1].transaction_id == transactions[20].transaction_id assert txobj.relations[3].pointers[0].transaction_id == transactions[20].transaction_id assert txobj.relations[3].pointers[0].asset_id == transactions[20].relations[0].asset.asset_id assert txobj.events[0].asset_group_id == asset_group_id1[:id_conf["asset_group_id"]] assert txobj.events[0].mandatory_approvers[0] == user_id1[:id_conf["user_id"]] assert txobj.events[0].asset.user_id == user_id2[:id_conf["user_id"]] assert txobj.events[0].asset.asset_body == b'event:asset_3-%d' % (idx % 20) assert len(txobj.events[0].asset.nonce) == id_conf["nonce"] assert txobj.references[0].asset_group_id == asset_group_id1[:id_conf["asset_group_id"]] assert txobj.references[0].event_index_in_ref == 0 assert len(txobj.references[0].sig_indices) == 1 assert txobj.cross_ref.domain_id == domain_id if idx < 20: assert txobj.cross_ref.transaction_id == transactions[0].transaction_id else: assert txobj.cross_ref.transaction_id == transactions[20].transaction_id assert len(txobj.witness.user_ids) == 2 assert len(txobj.witness.sig_indices) == 2 assert len(txobj.signatures) == 2 if txobj.signatures[0].pubkey is None: pass else: assert txobj.signatures[0].verify(txobj.digest()) if txobj.signatures[1].pubkey is None: pass else: assert txobj.signatures[1].verify(txobj.digest())
assert len(txobj.witness.user_ids) == 2 assert len(txobj.witness.sig_indices) == 2 assert len(txobj.signatures) == 2 if txobj.signatures[0].pubkey is None: #print("no pubkey") pass else: assert txobj.signatures[0].verify(txobj.digest()) if txobj.signatures[1].pubkey is None: #print("no_pubkey") pass else: assert txobj.signatures[1].verify(txobj.digest()) if __name__ == '__main__': id_len_conf = common.read_idlen_config() db = common.DataHandler() ret = db.fetch_sql("SELECT * from txtbl") transactions = list() txids = list() for i, dat in enumerate(ret): if dat is None: continue txobj, fmt_type = bbclib.deserialize(dat[1]) transactions.append(txobj) txids.append(dat[0]) #print(transactions[1]) check_transaction(id_len_conf, transactions, txids) print("passed")