Exemple #1
0
def enqueue_l1(transaction: dict) -> None:
    txn_type_string = transaction["header"]["txn_type"]
    invocation_attempt = not transaction["header"].get(
        "invoker"
    )  # This transaction is an invocation attempt if there is no invoker

    try:
        transaction_type = transaction_type_dao.get_registered_transaction_type(
            txn_type_string)
    except exceptions.NotFound:
        _log.error("Invalid transaction type")
        raise exceptions.InvalidTransactionType(
            f"Transaction of type {txn_type_string} does not exist")

    # Enqueue to transaction queue
    enqueue_generic(transaction, queue=INCOMING_TX_KEY, deadline=0)

    # Attempt contract invocation if necessary
    if transaction_type.contract_id and invocation_attempt:
        _log.info(
            "Checking if smart contract is associated with this txn_type")
        contract = smart_contract_dao.get_contract_by_id(
            transaction_type.contract_id
        )  # Explicitly checked for existence above
        contract_active = contract.status["state"] in ["active", "updating"]
        _log.info(f"Contract found: {contract}")

        if contract_active:
            transaction["payload"] = json.loads(
                transaction["payload"]
            )  # We must parse the stringied payload of the SC invocation before sending
            invocation_request = contract.export_as_invoke_request(transaction)
            enqueue_generic(invocation_request,
                            queue=CONTRACT_INVOKE_MQ_KEY,
                            deadline=0)
def update_contract_v1(contract_id: str, update: dict) -> dict:
    """Update an existing contract on the chain
    Args:
        contract_id: The contract_id of the contract
        update: The parsed body, supplied by user. This is used to create an update data model
    Returns:
        DTO of the contract at rest which has been updated
    """
    # Get existing model, and check state
    contract = smart_contract_dao.get_contract_by_id(contract_id)
    contract_update = smart_contract_model.new_update_contract(
        update, existing_contract=contract)
    if smart_contract_model.ContractState.is_updatable_state(
            contract.status["state"]):
        raise exceptions.BadStateError(
            f'State {contract.status["state"]} not valid to begin updates')

    # Create and validate update model
    contract_update.start_state = contract.status["state"]

    # Set state to updating
    contract.set_state(smart_contract_model.ContractState.UPDATING)
    contract.save()

    try:
        job_processor.begin_task(
            contract_update,
            task_type=smart_contract_model.ContractActions.UPDATE)
    except RuntimeError:
        contract.set_state(
            state=smart_contract_model.ContractState.ACTIVE,
            msg="Contract update failed: could not start update.")
        contract.save()
        raise
    return contract.export_as_at_rest()
Exemple #3
0
def enqueue_l1_pipeline(pipeline: "Pipeline", transaction: Dict[str, Any]) -> "Pipeline":
    txn_type_string = transaction["header"]["txn_type"]
    invocation_attempt = not transaction["header"].get("invoker")  # This transaction is an invocation attempt if there is no invoker

    try:
        transaction_type = transaction_type_dao.get_registered_transaction_type(txn_type_string)
    except exceptions.NotFound:
        _log.error("Invalid transaction type")
        raise exceptions.InvalidTransactionType(f"Transaction of type {txn_type_string} does not exist")

    pipeline.lpush(INCOMING_TX_KEY, json.dumps(transaction, separators=(",", ":")))
    pipeline.sadd(TEMPORARY_TX_KEY, transaction["header"]["txn_id"])

    # Attempt contract invocation if necessary
    if transaction_type.contract_id and invocation_attempt:
        _log.info("Checking if smart contract is associated with this txn_type")
        contract = smart_contract_dao.get_contract_by_id(transaction_type.contract_id)  # Explicitly checked for existence above
        contract_active = contract.status["state"] in ["active", "updating"]
        _log.info(f"Contract found: {contract}")

        if contract_active:
            transaction["payload"] = json.loads(transaction["payload"])  # We must parse the stringied payload of the SC invocation before sending
            invocation_request = contract.export_as_invoke_request(transaction)
            pipeline.lpush(CONTRACT_INVOKE_MQ_KEY, json.dumps(invocation_request, separators=(",", ":")))

    return pipeline
def delete_contract_v1(contract_id: str) -> None:
    """Delete a contract
    Args:
        contract_id (str): The contract_id of the contract
    Returns:
        smart contract at rest which was deleted
    """
    _log.info(f"Getting contract {contract_id} to delete")
    contract = smart_contract_dao.get_contract_by_id(contract_id)
    _log.info("Setting delete state..")
    contract.set_state(smart_contract_model.ContractState.DELETING)
    contract.save()

    try:
        job_processor.begin_task(contract, task_type=smart_contract_model.ContractActions.DELETE)
    except RuntimeError:
        _log.exception("Could not begin delete, rolling back state.")
        contract.set_state(state=smart_contract_model.ContractState.ACTIVE, msg="Contract delete failed: could not start deletion")
        contract.save()
        raise