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()
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