class TestDeleteTransactionType(unittest.TestCase): @patch( "dragonchain.webserver.lib.transaction_types.transaction_type_dao.get_registered_transaction_type", return_value=transaction_type_model.TransactionTypeModel( contract_id="my-id"), ) @patch("dragonchain.lib.dao.smart_contract_dao.contract_does_exist") def test_delete_if_txn_type_has_contract_id( self, dao_get_registered_txn_type_mock, mock_contract_does_exist): self.assertRaises(exceptions.ActionForbidden, transaction_types.delete_transaction_type_v1, "exists_but_contract") mock_contract_does_exist.assert_called_once() @patch( "dragonchain.webserver.lib.transaction_types.transaction_type_dao.remove_existing_transaction_type" ) @patch( "dragonchain.webserver.lib.transaction_types.transaction_type_dao.get_registered_transaction_type", return_value=transaction_type_model.TransactionTypeModel( txn_type="random", contract_id=""), ) def test_delete_txn_type_succeeds(self, mock_get_registered_type, dao_remove_txn_type_mock): transaction_types.delete_transaction_type_v1("random") mock_get_registered_type.assert_called_once_with("random")
def get_registered_transaction_types_or_default( transaction_types: List[str] ) -> Dict[str, transaction_type_model.TransactionTypeModel]: """Bulk get of registered transaction types Note: If a transaction type is not found, it is sent back as a TransactionTypeModel with default values Args: transaction_types: a list of transaction types to fetch models for Returns: dictionary with key being txn_type and value being of type TransactionTypeModel """ transaction_type_object: Dict[ str, transaction_type_model.TransactionTypeModel] = {} for txn_type in transaction_types: if txn_type not in transaction_type_object and not txn_type.startswith( "-SYSTEM"): try: transaction_type_object[ txn_type] = get_registered_transaction_type(txn_type) except exceptions.NotFound: # Use a 'default' TransactionTypeModel if we couldn't find an existing matching txn_type transaction_type_object[ txn_type] = transaction_type_model.TransactionTypeModel( txn_type=txn_type, custom_indexes=[], contract_id=False) return transaction_type_object
def _generate_transaction_indexes() -> None: # noqa: C901 # -- CREATE INDEXES FOR TRANSACTIONS -- client = _get_redisearch_index_client(Indexes.transaction.value) try: client.create_index([redisearch.TagField("block_id")]) # Used for reverse-lookup of transactions by id (with no txn_type) except redis.exceptions.ResponseError as e: if not str(e).startswith("Index already exists"): # We don't care if index already exists raise try: create_transaction_index(namespace.Namespaces.Contract.value, force=False) # Create the reserved txn type index except redis.exceptions.ResponseError as e: if not str(e).startswith("Index already exists"): # We don't care if index already exists raise txn_types_to_watch = {namespace.Namespaces.Contract.value: 1} # Will be use when going through all stored transactions txn_type_models = { namespace.Namespaces.Contract.value: transaction_type_model.TransactionTypeModel(namespace.Namespaces.Contract.value, active_since_block="1") } for txn_type in transaction_type_dao.list_registered_transaction_types(): txn_type_model = transaction_type_model.new_from_at_rest(txn_type) txn_type_models[txn_type_model.txn_type] = txn_type_model _log.info(f"Adding index for {txn_type_model.txn_type}") try: create_transaction_index(txn_type_model.txn_type, txn_type_model.custom_indexes, force=False) except redis.exceptions.ResponseError as e: if not str(e).startswith("Index already exists"): # We don't care if index already exists raise txn_types_to_watch[txn_type_model.txn_type] = int(txn_type_model.active_since_block) # -- LIST AND INDEX ACTUAL TRANSACTIONS FROM STORAGE _log.info("Listing all full transactions") transaction_blocks = storage.list_objects("TRANSACTION/") for txn_path in transaction_blocks: # do a check to see if this block's transactions were already marked as indexed if not client.redis.sismember(TXN_MIGRATION_KEY, txn_path): _log.info(f"Indexing transactions for {txn_path}") for txn in storage.get(txn_path).split(b"\n"): if txn: txn_model = transaction_model.new_from_at_rest_full(json.loads(txn)["txn"]) # Add general transaction index put_document(Indexes.transaction.value, f"txn-{txn_model.txn_id}", {"block_id": txn_model.block_id}, upsert=True) watch_block = txn_types_to_watch.get(txn_model.txn_type) # Extract custom indexes if necessary if watch_block and int(txn_model.block_id) >= watch_block: txn_model.extract_custom_indexes(txn_type_models[txn_model.txn_type]) put_document(txn_model.txn_type, txn_model.txn_id, txn_model.export_as_search_index(), upsert=True) client.redis.sadd(TXN_MIGRATION_KEY, txn_path) else: _log.info(f"Skipping already indexed transaction {txn_path}")
def _generate_transaction_indexes_from_scratch() -> None: client = _get_redisearch_index_client(Indexes.transaction.value) # TODO: replace after redisearch is fixed client.create_index([ TagField("block_id") ]) # Used for reverse-lookup of transactions by id (with no txn_type) force_create_transaction_index(namespace.Namespaces.Contract.value ) # Create the reserved txn type index txn_types_to_watch = { namespace.Namespaces.Contract.value: 1 } # Will be use when going through all stored transactions txn_type_models = { namespace.Namespaces.Contract.value: transaction_type_model.TransactionTypeModel( namespace.Namespaces.Contract.value, active_since_block="1") } for txn_type in transaction_type_dao.list_registered_transaction_types(): txn_type_model = transaction_type_model.new_from_at_rest(txn_type) txn_type_models[txn_type_model.txn_type] = txn_type_model _log.info(f"Adding index for {txn_type_model.txn_type}") force_create_transaction_index(txn_type_model.txn_type, txn_type_model.custom_indexes) txn_types_to_watch[txn_type_model.txn_type] = int( txn_type_model.active_since_block) _log.info("Listing all full transactions") transaction_blocks = storage.list_objects("TRANSACTION/") for txn_path in transaction_blocks: _log.info(f"Indexing transactions for {txn_path}") for txn in storage.get(txn_path).split(b"\n"): if txn: txn_model = transaction_model.new_from_at_rest_full( json.loads(txn)["txn"]) # Add general transaction index put_document(Indexes.transaction.value, f"txn-{txn_model.txn_id}", {"block_id": txn_model.block_id}, upsert=True) watch_block = txn_types_to_watch.get(txn_model.txn_type) # Extract custom indexes if necessary if watch_block and int(txn_model.block_id) >= watch_block: txn_model.extract_custom_indexes( txn_type_models[txn_model.txn_type]) put_document(txn_model.txn_type, txn_model.txn_id, txn_model.export_as_search_index(), upsert=True)