Example #1
0
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.")
Example #2
0
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
Example #6
0
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.")
Example #8
0
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.")
Example #9
0
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")
Example #10
0
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
Example #11
0
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 "")
    }
Example #12
0
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")
Example #13
0
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")
Example #14
0
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
Example #15
0
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.")
Example #16
0
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}/")
    ]
Example #17
0
def not_found(e: Any) -> NoReturn:
    raise exceptions.NotFound("Route not found")
Example #18
0
 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)
Example #19
0
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.")