Esempio n. 1
0
 def _get_transaction_data_for_verification(self, domain_id,
                                            transaction_id):
     """Get transaction object and verify it"""
     txobjs, asts = self.networking.domains[domain_id][
         'data'].search_transaction(transaction_id=transaction_id)
     if transaction_id not in txobjs:
         return None
     txobj = txobjs[transaction_id]
     if txobj.WITH_WIRE:
         self.logger.info(
             "To use cross_reference the transaction object must not be in bson/msgpack format"
         )
         return None
     txobj_is_valid, valid_assets, invalid_assets = bbclib.validate_transaction_object(
         txobj, asts)
     if not txobj_is_valid:
         msg = {
             KeyType.command:
             repair_manager.RepairManager.REQUEST_REPAIR_TRANSACTION,
             KeyType.transaction_id: transaction_id,
         }
         self.networking.domains[domain_id]['repair'].put_message(msg)
         return None
     txobj.digest()
     cross_ref_dat = txobj.cross_ref.pack()
     sigdata = txobj.signatures[0].pack()
     return txobj.transaction_base_digest, cross_ref_dat, sigdata
Esempio n. 2
0
    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]]
Esempio n. 3
0
    def _send_asset_file(self, dat):
        """Send the asset file if having valid one

        Args:
            dat (dict): received message
        """
        #print("_send_asset_file::")
        asset_group_id = dat[KeyType.asset_group_id]
        asset_id = dat[KeyType.asset_id]
        asset_file = self.data_handler.get_in_storage(asset_group_id, asset_id)
        if asset_file is None:
            return
        result_txobj, result_asset_files = self.data_handler.search_transaction(
            asset_group_id=asset_group_id, asset_id=asset_id)
        txobj = next(iter(result_txobj.values()))
        txobj_is_valid, valid_assets, invalid_assets = bbclib.validate_transaction_object(
            txobj, result_asset_files)

        if (asset_group_id, asset_id) in valid_assets:
            dat[KeyType.command] = RepairManager.RESPONSE_ASSET_FILE
            dat[KeyType.asset_group_id] = asset_group_id
            dat[KeyType.asset_id] = asset_id
            dat[KeyType.asset_file] = asset_file
            dat[KeyType.destination_node_id] = dat[KeyType.source_node_id]
            self.network.send_message_in_network(None,
                                                 domain_id=self.domain_id,
                                                 msg=dat)
Esempio n. 4
0
 def test_03_transaction_len_custom(self):
     print("\n-----", sys._getframe().f_code.co_name, "-----")
     id_length = {
         "transaction_id": 24,
         "asset_group_id": 6,
         "user_id": 8,
         "asset_id": 16,
         "nonce": 9
     }
     make_transactions(id_len_conf=id_length)
     for i in range(0, 20):
         print("txdata_len: %d" % len(txdata[i]))
         digest = txdata_deserialized[i].digest()
         #print("transaction_id_len: %d" % len(txdata_deserialized[i].transaction_id))
         #print("asset_group_id_len: %d" % len(txdata_deserialized[i].relations[0].asset_group_id))
         #print("user_id_len: %d" % len(txdata_deserialized[i].relations[0].asset.user_id))
         #print("asset_id_len: %d" % len(txdata_deserialized[i].relations[0].asset.asset_id))
         assert len(txdata_deserialized[i].transaction_id
                    ) == id_length["transaction_id"]
         assert len(txdata_deserialized[i].relations[0].asset_group_id
                    ) == id_length["asset_group_id"]
         assert len(txdata_deserialized[i].relations[0].asset.user_id
                    ) == id_length["user_id"]
         assert len(txdata_deserialized[i].relations[0].asset.asset_id
                    ) == id_length["asset_id"]
         ret = txdata_deserialized[i].signatures[0].verify(
             digest, pubkey=keypair1.public_key)
         assert ret
         ret, _, _ = validate_transaction_object(txdata_deserialized[i])
         assert ret
     print(txdata_deserialized[19])
Esempio n. 5
0
    def _receive_asset_file_from_others(self, dat):
        """Receive asset file from other core_nodes and check its validity

        Args:
            dat (dict): received message
        """
        #print("_receive_asset_file_from_others:")
        if KeyType.nonce not in dat or dat[KeyType.nonce] not in self.requesting_list:
            return
        if KeyType.asset_group_id not in dat or KeyType.asset_id not in dat or KeyType.asset_file not in dat:
            return

        asset_group_id = dat[KeyType.asset_group_id]
        asset_id = dat[KeyType.asset_id]
        asset_file = dat[KeyType.asset_file]
        if asset_file is None:
            return
        asset_files = {asset_id: asset_file}
        result_txobj, result_asset_files = self.data_handler.search_transaction(asset_group_id=asset_group_id,
                                                                                asset_id=asset_id)
        txobj = next(iter(result_txobj.values()))

        txobj_is_valid, valid_assets, invalid_assets = bbclib.validate_transaction_object(txobj, asset_files)

        if (asset_group_id, asset_id) in valid_assets:

            self.data_handler.store_in_storage(asset_group_id, asset_id, asset_file, do_overwrite=True)
            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]]
Esempio n. 6
0
    def _repair_transaction_data(self, transaction_id):
        """Repair forged transaction_data or asset_file by getting legitimate one from other nodes

        Args:
            transaction_id (bytes): target transaction_id
        """
        #print("_repair_transaction_data:")
        self.stats.update_stats_increment("transaction", "repair_request", 1)
        forged_asset_files = set()
        if len(self.data_handler.db_adaptors) > 1:
            valid_txobj = None
            db_nums_with_invalid_data = list()
            for idx in range(1, len(self.data_handler.db_adaptors)):
                result_txobj, result_asset_files = self.data_handler.search_transaction(transaction_id=transaction_id, db_num=idx)
                txobj_is_valid, valid_assets, invalid_assets = bbclib.validate_transaction_object(result_txobj[0],
                                                                                                       result_asset_files)
                if txobj_is_valid and valid_txobj is None:
                    valid_txobj = result_txobj[0]
                if not txobj_is_valid:
                    db_nums_with_invalid_data.append(idx)
                if len(invalid_assets) > 0:
                    for ent in invalid_assets:
                        forged_asset_files.add(ent)
            if valid_txobj is None:
                self.stats.update_stats_increment("transaction", "fail_to_repair_in_local", 1)
                self.logger.fatal("Failed to repair transaction locally (transaction_id=%s in domain=%s)" %
                                  (transaction_id.hex(), self.domain_id.hex()))
            else:
                for i in db_nums_with_invalid_data:
                    self.data_handler.restore_transaction_data(db_num=i, transaction_id=transaction_id, txobj=valid_txobj)
                self.stats.update_stats_increment("transaction", "success_repair", 1)
            self._output_log({"transaction_id": transaction_id.hex(), "request_at": int(time.time()),
                             "repaired_by": "locally", "repaired_at": int(time.time())})

        if len(forged_asset_files) > 0:
            for asgid, ast in forged_asset_files:
                self._repair_asset_file(asset_group_id=asgid, asset_id=ast, need_check=False)

        if self.data_handler.replication_strategy == DataHandler.REPLICATION_EXT:
            return

        random_nonce = bbclib.get_random_value(4)
        while random_nonce in self.requesting_list:
            random_nonce = bbclib.get_random_value(4)
        self.requesting_list[random_nonce] = {
            "transaction_id": transaction_id.hex(),
            "request_at": int(time.time())
        }
        msg = {
            KeyType.domain_id: self.domain_id,
            KeyType.infra_msg_type: InfraMessageCategory.CATEGORY_DATA,
            KeyType.infra_command: DataHandler.REPAIR_TRANSACTION_DATA,
            KeyType.command: RepairManager.REQUEST_TO_SEND_TRANSACTION_DATA,
            KeyType.transaction_id: transaction_id,
            KeyType.nonce: random_nonce,
        }
        self.network.broadcast_message_in_network(domain_id=self.domain_id,
                                                  payload_type=PayloadType.Type_any, msg=msg)
        return
Esempio n. 7
0
 def _send_transaction_data(self, dat):
     """Send transaction data if having valid one"""
     #print("_send_transaction_data::")
     transaction_id = dat[KeyType.transaction_id]
     for idx in range(len(self.data_handler.db_adaptors)):
         result_txobj, result_asset_files = self.data_handler.search_transaction(transaction_id=transaction_id, db_num=idx)
         txobj_is_valid, valid_assets, invalid_assets = bbclib.validate_transaction_object(result_txobj[transaction_id])
         if txobj_is_valid:
             dat[KeyType.command] = RepairManager.RESPONSE_TRANSACTION_DATA
             dat[KeyType.transaction_data] = bbclib.serialize(result_txobj[transaction_id])
             dat[KeyType.destination_node_id] = dat[KeyType.source_node_id]
             self.network.send_message_in_network(None, domain_id=self.domain_id, msg=dat)
             return
Esempio n. 8
0
 def test_03_transaction_len_12(self):
     print("\n-----", sys._getframe().f_code.co_name, "-----")
     make_transactions(idlen=12)
     for i in range(0, 20):
         print("txdata_len: %d" % len(txdata[i]))
         digest = txdata_deserialized[i].digest()
         #print("transaction_id_len: %d" % len(txdata_deserialized[i].transaction_id))
         #print("asset_group_id_len: %d" % len(txdata_deserialized[i].relations[0].asset_group_id))
         #print("user_id_len: %d" % len(txdata_deserialized[i].relations[0].asset.user_id))
         #print("asset_id_len: %d" % len(txdata_deserialized[i].relations[0].asset.asset_id))
         assert len(txdata_deserialized[i].transaction_id) == 12
         assert len(
             txdata_deserialized[i].relations[0].asset_group_id) == 12
         assert len(txdata_deserialized[i].relations[0].asset.user_id) == 12
         assert len(
             txdata_deserialized[i].relations[0].asset.asset_id) == 12
         ret = txdata_deserialized[i].signatures[0].verify(digest)
         assert ret
         ret, _, _ = validate_transaction_object(txdata_deserialized[i])
         assert ret