def get_contract_id_by_txn_type(txn_type: str) -> str: results = redisearch.search( index=redisearch.Indexes.smartcontract.value, query_str=f"@sc_name:{{{redisearch.get_escaped_redisearch_string(txn_type)}}}", only_id=True ).docs if results: return results[0].id raise exceptions.NotFound(f"Smart contract {txn_type} could not be found.")
def get_api_key_v1(key_id: str) -> Dict[str, Any]: """Returns the api key information (without the actual key itself) for a key id Args: key_id: ID of api key to get hide_key: remove the api key from the returned key Returns: API key ID and registration timestamp (if any) """ if key_id.startswith("INTERCHAIN"): raise exceptions.NotFound("Cannot get interchain api keys") return _api_key_model_to_user_dto( api_key_dao.get_api_key(key_id, interchain=False))
def get_serial_contracts() -> list: """Searches for serial contracts""" results = elasticsearch.search( folder=FOLDER, query={"query": { "match_phrase": { "execution_order": "serial" } }})["results"] if results: return results raise exceptions.NotFound("No serial smart contracts found.")
def make_matchmaking_request( http_verb: str, path: str, json_content: dict = None, retry: bool = True, authenticated: bool = True ) -> requests.Response: """Make an authenticated request to matchmaking and return the response Args: http_verb: GET, POST, etc path: path of the request json_content: OPTIONAL if the request needs a post body, include it as a dictionary retry: boolean whether or not to recursively retry on recoverable errors (i.e. no auth, missing registration) Note: This should not be provided manually, and is only for recursive calls within the function it authenticated: boolean whether or not this matchmaking endpoint is authenticated Returns: Requests response object Raises: exceptions.MatchmakingError when unexpected matchmaking error occurs exceptions.InsufficientFunds when matchmaking responds with payment required exceptions.NotFound when matchmaking responds with a 404 """ if json_content is None: json_content = {} http_verb = http_verb.upper() _log.info(f"[MATCHMAKING] Performing {http_verb} request to {path} with data: {json_content}") headers, data = None, None if authenticated: headers, data = authorization.generate_authenticated_request(http_verb, "matchmaking", path, json_content) else: data = json.dumps(json_content, separators=(",", ":")).encode("utf-8") if json_content else b"" headers = {"Content-Type": "application/json"} if json_content else {} response = requests.request(method=http_verb, url=f"{MATCHMAKING_ADDRESS}{path}", headers=headers, data=data, timeout=REQUEST_TIMEOUT) if response.status_code < 200 or response.status_code >= 300: if retry and response.status_code == 401 and authenticated: _log.warning("[MATCHMAKING] received 401 from matchmaking. Registering new key with matchmaking and trying again") authorization.register_new_key_with_matchmaking() return make_matchmaking_request(http_verb=http_verb, path=path, json_content=json_content, retry=False, authenticated=authenticated) elif retry and response.status_code == 403 and authenticated: _log.warning("[MATCHMAKING] received 403 from matchmaking. Registration is probably expired. Re-registering and trying again") register() return make_matchmaking_request(http_verb=http_verb, path=path, json_content=json_content, retry=False, authenticated=authenticated) elif response.status_code == 402: raise exceptions.InsufficientFunds("received insufficient funds (402) from matchmaking") elif response.status_code == 404: raise exceptions.NotFound("Not found (404) from matchmaking") raise exceptions.MatchmakingError( f"Received unexpected response code {response.status_code} from matchmaking with response:\n{response.text}" ) return response
def get_registration(dc_id: str) -> dict: """Retrieve matchmaking config for any registered chain Args: dc_id: chain id to get registration data for Returns: Dictionary of the identity json returned by matchmaking Raises: exceptions.NotFound if matchmaking sends back an empty response """ path = f"/registration/{dc_id}" response = make_matchmaking_request("GET", path, authenticated=False) registration = response.json() if not registration: raise exceptions.NotFound(f"Registration not found for {dc_id}") return registration
def delete_transaction_type_v1(transaction_type: str) -> None: """ Takes in a transaction type Checks if the transaction type is of smart contract Deletes type """ try: existing_type_structure = transaction_type_dao.get_registered_transaction_type(transaction_type) if existing_type_structure is None: raise exceptions.NotFound(transaction_type) if existing_type_structure.contract_id: raise exceptions.ActionForbidden("Cannot delete smart contract transaction type") transaction_type_dao.remove_existing_transaction_type(transaction_type) except exceptions.NotFound: pass
def get_contract_by_txn_type( txn_type: str) -> "smart_contract_model.SmartContractModel": """Searches for a contract by txn_type""" results = elasticsearch.search( folder=FOLDER, query={"query": { "match_phrase": { "txn_type": txn_type } }})["results"] if len(results) > 0: return smart_contract_model.new_contract_at_rest(results[0]) raise exceptions.NotFound(f"Smart contract {txn_type} could not be found.")
def get_transaction_v1(transaction_id: str, parse: bool) -> dict: """ get_transaction_by_id Searches for a transaction by a specific transaction ID """ results = _search_transaction( query={"query": { "match_phrase": { "txn_id": transaction_id } }}, should_parse=parse)["results"] if results: return results[0] raise exceptions.NotFound( f"Transaction {transaction_id} could not be found.")
def get_dc_secret(secret_name: str) -> Any: """Get the secret value for this Dragonchain's owned secrets Args: secret_name: The name of the secret to fetch Returns: Dragonchain secret by its key (usually a string, but not necessarily) """ try: with open(SECRET_LOCATION) as f: secrets_json = json.loads(f.read()) except Exception: raise RuntimeError("Error occurred loading DC secrets from file system") try: return secrets_json[secret_name] except Exception: raise exceptions.NotFound(f"Secret {secret_name} was not found")
def get_transaction_v1(transaction_id: str, parse: bool = True) -> Dict[str, Any]: """ get_transaction_by_id Searches for a transaction by a specific transaction ID """ doc = redisearch.get_document(redisearch.Indexes.transaction.value, f"txn-{transaction_id}") try: block_id = doc.block_id except AttributeError: raise exceptions.NotFound(f"Transaction {transaction_id} could not be found.") if block_id == "0": # Check for stubbed result return _get_transaction_stub(transaction_id) else: txn = storage.select_transaction(block_id, transaction_id) if parse: txn["payload"] = json.loads(txn["payload"]) return txn
def get_api_key_v1(key_id: str) -> Dict[str, Any]: """Returns the api key information (without the actual key itself) for a key id Args: key_id: ID of api key to get hide_key: remove the api key from the returned key Returns: API key ID and registration timestamp (if any) """ if key_id.startswith("SC_") or key_id.startswith( "WEB_") or key_id.startswith("INTERCHAIN"): raise exceptions.NotFound(f"api key with ID {key_id} not found") key = storage.get_json_from_object(f"KEYS/{key_id}") return { "id": str(key["id"]), "registration_time": int(key["registration_time"]), "nickname": str(key.get("nickname") or "") }
def get_interchain_client(blockchain: str, name: str) -> "model.InterchainModel": """Get a specific interchain client Args: blockchain: the blockchain of the desired client (i.e. bitcoin, ethereum, etc) name: the name (id) of the network to get (user defined on the creation of the interchain) Raises: exceptions.NotFound: When the requested client can't be found """ if blockchain == "bitcoin": return btc.new_from_at_rest( storage.get_json_from_object(f"{FOLDER}/bitcoin/{name}")) elif blockchain == "ethereum": return eth.new_from_at_rest( storage.get_json_from_object(f"{FOLDER}/ethereum/{name}")) else: raise exceptions.NotFound( f"Blockchain network {blockchain} is not supported")
def get_dc_secret(secret_name: str) -> Any: """Get the secret value for this Dragonchain's owned secrets Args: secret_name: The name of the environment variable holding the secret Returns: Dragonchain secret by its key (usually a string, but not necessarily) """ # Memo-ized for now until we need to support dynamic secrets global _secrets_json if _secrets_json is None: try: _secrets_json = json.loads(os.environ[SECRET_LOCATION]) except Exception: raise RuntimeError("Error occurred loading DC secrets from environment") try: return _secrets_json[secret_name] except Exception: raise exceptions.NotFound(f"Secret {secret_name} was not found")
def get_transaction_v1(transaction_id: str, parse: bool = True) -> Dict[str, Any]: """ get_transaction_by_id Searches for a transaction by a specific transaction ID """ if dc_redis.sismember_sync(queue.TEMPORARY_TX_KEY, transaction_id): return _get_transaction_stub(transaction_id) doc = redisearch.get_document(redisearch.Indexes.transaction.value, f"txn-{transaction_id}") try: block_id = doc.block_id except AttributeError: raise exceptions.NotFound( f"Transaction {transaction_id} could not be found.") txn = storage.select_transaction(block_id, transaction_id) if parse: txn["payload"] = json.loads(txn["payload"]) return txn
def get_block_by_id_v1(block_id: str, parse: bool) -> Dict[str, Any]: """Searches for a block by a specific block ID Args: block_id: The block id to get parse: whether or not to parse the result automatically """ results = elasticsearch.search( folder=block_dao.FOLDER, query={"query": { "match_phrase": { "block_id": block_id } }}, should_parse=parse)["results"] if len(results) > 0: return results[0] raise exceptions.NotFound(f"Block {block_id} could not be found.")
def list_interchain_clients(blockchain: str) -> List["model.InterchainModel"]: """Get all of the interchain clients for a specific blockchain type Args: blockchain: The blockchain of the desired clients to get Returns: List of instantiated interchain clients for the specified blockchain """ from_rest_function: Any = None if blockchain == "bitcoin": from_rest_function = btc.new_from_at_rest elif blockchain == "ethereum": from_rest_function = eth.new_from_at_rest else: raise exceptions.NotFound( f"Blockchain network {blockchain} is not supported") return [ from_rest_function(storage.get_json_from_object(x)) for x in storage.list_objects(f"{FOLDER}/{blockchain}/") ]
def not_found(e: Any) -> NoReturn: raise exceptions.NotFound("Route not found")
def test_webserver_error_handler_not_found(self, mock_http_response, mock_report_exception): exception = exceptions.NotFound() helpers.webserver_error_handler(exception) mock_report_exception.assert_not_called() mock_http_response.assert_called_once_with(404, ANY)
def get_by_txn_type_v1(txn_type: str) -> Dict[str, Any]: results = elasticsearch.search(folder=smart_contract_dao.FOLDER, query={"query": {"match_phrase": {"txn_type": txn_type}}})["results"] if results: return results[0] raise exceptions.NotFound(f"Smart contract {txn_type} could not be found.")