def query_file(file_id, query_type): result = do_query(file_id, query_type) if result.get("error") == boilerplate.ERROR_NO_QUERY_TYPE_SPECIFIED: raise JSONRPCDispatchException(code=boilerplate.ERROR_NO_QUERY_TYPE_SPECIFIED_CODE, message=result.get("error")) elif result.get("error") == boilerplate.ERROR_NO_SUCH_FILE: raise JSONRPCDispatchException(code=boilerplate.ERROR_NO_SUCH_FILE_CODE, message=result.get("error")) return result
def WorkerUpdate(self, **params): """ Function to update the worker details. Parameters: - param is the 'param' object in the a worker request as per TCF API 5.3.2 Worker Update JSON Payload """ worker_id = must_get_worker_id(params) # value retrieved is 'result' field as per Spec 5.3.8 Worker Retrieve # Response Payload value = self.kv_helper.get("workers", worker_id) if value is None: raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, "Worker Id not found in the database. Hence invalid parameter") json_dict = json.loads(value) worker_details = params["details"] for item in worker_details: json_dict["details"][item] = worker_details[item] value = json.dumps(json_dict) self.kv_helper.set("workers", worker_id, value) raise JSONRPCDispatchException( WorkerError.SUCCESS, "Successfully Updated")
def GetUniqueVerificationKey(self, **params): """ RPC method registered with the KME listener to generate an unique verification key before a WPE registration. Parameters : @param params - variable-length argument list Returns : @returns response - A jrpc response """ logger.info("in kme_enclave_manager.py GetUniqueVerificationKey") try: wo_request = get_request_json("GetUniqueVerificationKey", random.randint(0, 100000)) wo_request["params"] = params wo_response = self._execute_work_order(json.dumps(wo_request), "") wo_response_json = json.loads(wo_response) data = {"workOrderId": wo_request["params"]["workOrderId"]} if "result" in wo_response_json: return wo_response_json["result"] else: logger.error("Could not get UniqueVerificationKey - %s", wo_response_json) # For all negative cases, response should have an error field. # Hence constructing JSONRPC error response with # error code and message mapped to KME enclave response err_code = wo_response_json["error"]["code"] err_msg = wo_response_json["error"]["message"] raise JSONRPCDispatchException(err_code, err_msg, data) except Exception as e: raise JSONRPCDispatchException(WorkOrderStatus.FAILED, str(e), data)
def WorkerSetStatus(self, **params): """ Function to set the status of worker Parameters: - params is the 'params' object in a worker request json as per TCF API 5.3.3 Worker Set Status JSON Payload """ # status can be one of active, offline, decommissioned, or compromised worker_id = must_get_worker_id(params) value = self.kv_helper.get("workers", worker_id) if value: json_dict = json.loads(value) if not self.__validate_input_worker_status(params): raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, "Invalid parameter: worker status code") json_dict['status'] = params['status'] value = json.dumps(json_dict) self.kv_helper.set("workers", worker_id, value) raise JSONRPCDispatchException( WorkerError.SUCCESS, "Successfully Set Status") raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, "Worker Id not found in the database. Hence invalid parameter")
def GetUniqueVerificationKey(self, **params): """ """ try: wo_request = self._get_request_json("GetUniqueVerificationKey") wo_request["params"] = params wo_response = self._execute_work_order(json.dumps(wo_request), "") wo_response_json = json.loads(wo_response) data = { "workOrderId": wo_request["params"]["workOrderId"] } if "result" in wo_response_json: return wo_response_json["result"] else: logger.error("Could not get UniqueVerificationKey - %s", wo_response_json) # For all negative cases, response should have an error field. # Hence constructing JSONRPC error response with # error code and message mapped to KME enclave response err_code = wo_response_json["error"]["code"] err_msg = wo_response_json["error"]["message"] raise JSONRPCDispatchException(err_code, err_msg, data) except Exception as e: raise JSONRPCDispatchException( WorkOrderStatus.FAILED, str(e), data)
def WorkOrderSubmit(self, **params): """ Function to process work order request Parameters: - wo_id is work order id - input_json_str is a work order request json as per TCF API 6.1.1 Work Order Request Payload - response is the response object to be returned to client """ wo_id = params["workOrderId"] input_json_str = params["raw"] if ((self.workorder_count + 1) > self.max_workorder_count): # if max count reached clear a processed entry work_orders = self.kv_helper.lookup("wo-timestamps") for id in work_orders: # If work order is processed then remove from table if (self.kv_helper.get("wo-processed", id) is not None): self.kv_helper.remove("wo-processed", id) self.kv_helper.remove("wo-requests", id) self.kv_helper.remove("wo-responses", id) self.kv_helper.remove("wo-receipts", id) self.kv_helper.remove("wo-timestamps", id) self.workorder_list.remove(id) self.workorder_count -= 1 break # If no work order is processed then return busy if ((self.workorder_count + 1) > self.max_workorder_count): raise JSONRPCDispatchException( WorkOrderStatus.BUSY, "Work order handler is busy updating the result") if (self.kv_helper.get("wo-timestamps", wo_id) is None): # Create a new work order entry. Don't change the order of table updation. # The order is important for clean up if the TCS is restarted in middle epoch_time = str(time.time()) # Update the tables self.kv_helper.set("wo-timestamps", wo_id, epoch_time) self.kv_helper.set("wo-requests", wo_id, input_json_str) self.kv_helper.set("wo-scheduled", wo_id, input_json_str) # Add to the internal FIFO self.workorder_list.append(wo_id) self.workorder_count += 1 raise JSONRPCDispatchException( WorkOrderStatus.PENDING, "Work order is computing. Please query for WorkOrderGetResult \ to view the result") # Workorder id already exists raise JSONRPCDispatchException( WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE, "Work order id already exists in the database. \ Hence invalid parameter")
def WorkOrderReceiptUpdateRetrieve(self, **params): """ Function to retrieve the update to work order receipt Parameters: - params is variable-length argument list containing work order update retrieve request as defined in EEA spec 7.2.6 Returns: Jrpc response as defined in EEA spec 7.2.7 """ wo_id = params["workOrderId"] input_json_str = params["raw"] input_json = json.loads(input_json_str) input_params = input_json["params"] updater_id = None if "updaterId" in input_params and input_params["updaterId"]: updater_id = input_params["updaterId"] # update_index is index to fetch the particular update # starts from 1 update_index = input_params["updateIndex"] # Load list of updates to the receipt receipt_updates = self.kv_helper.get("wo-receipt-updates", wo_id) if receipt_updates: receipt_updates_json = json.loads(receipt_updates) total_updates = len(receipt_updates_json) if update_index <= 0: raise JSONRPCDispatchException( JRPCErrorCodes.INVALID_PARAMETER_FORMAT_OR_VALUE, "Update index should be positive non-zero number." " Hence invalid parameter") elif update_index > total_updates: if update_index == self.LAST_RECEIPT_INDEX: # set to the index of last update to receipt update_index = total_updates - 1 else: raise JSONRPCDispatchException( JRPCErrorCodes.INVALID_PARAMETER_FORMAT_OR_VALUE, "Update index is larger than total update count." " Hence invalid parameter") else: # If the index is less than total updates # then decrement by one since it is zero based array update_index = update_index - 1 update_to_receipt = receipt_updates_json[update_index] # If updater id is present then check whether it matches if updater_id: if update_to_receipt["updaterId"] != updater_id: raise JSONRPCDispatchException( JRPCErrorCodes.INVALID_PARAMETER_FORMAT_OR_VALUE, "Update index and updater id doesn't match" " Hence invalid parameter") update_to_receipt["updateCount"] = total_updates return update_to_receipt else: raise JSONRPCDispatchException( JRPCErrorCodes.INVALID_PARAMETER_FORMAT_OR_VALUE, "There is no updates available to this receipt" " Hence invalid parameter")
def WorkOrderGetResult(self, **params): """ Function to process work order get result. This API corresponds to Trusted Compute EEA API 6.1.4 Work Order Pull Request Payload Parameters: - params is variable-length arugment list containing work request as defined in EEA spec 6.1.4 Returns jrpc response as defined in EEA spec 6.1.2 """ if "workOrderId" in params: wo_id = params["workOrderId"] # Work order status payload should have # data field with work order id as defined in EEA spec section 6. data = {"workOrderId": wo_id} if not is_valid_hex_str(wo_id): logging.error("Invalid work order Id") raise JSONRPCDispatchException( JsonRpcErrorCode.INVALID_PARAMETER, "Invalid work order Id", data) # Work order is processed if it is in wo-response table value = self.kv_helper.get("wo-responses", wo_id) if value: response = json.loads(value) if 'result' in response: return response['result'] # response without a result should have an error err_code = response["error"]["code"] err_msg = response["error"]["message"] if err_code == EnclaveError.ENCLAVE_ERR_VALUE: err_code = \ WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE elif err_code == EnclaveError.ENCLAVE_ERR_UNKNOWN: err_code = WorkOrderStatus.UNKNOWN_ERROR elif err_code == EnclaveError.ENCLAVE_ERR_INVALID_WORKLOAD: err_code = WorkOrderStatus.INVALID_WORKLOAD else: err_code = WorkOrderStatus.FAILED raise JSONRPCDispatchException(err_code, err_msg, data) if (self.kv_helper.get("wo-timestamps", wo_id) is not None): # work order is yet to be processed raise JSONRPCDispatchException( WorkOrderStatus.PENDING, "Work order result is yet to be updated", data) # work order not in 'wo-timestamps' table raise JSONRPCDispatchException( WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE, "Work order Id not found in the database. " + "Hence invalid parameter", data) else: raise JSONRPCDispatchException( WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE, "Missing work order id")
def get_file(file_id): if file_id not in boilerplate.list_files(recursive=True): raise JSONRPCDispatchException(code=boilerplate.ERROR_NO_SUCH_FILE_CODE, message=boilerplate.ERROR_NO_SUCH_FILE) file_contents_base64 = None try: file_contents_base64 = b64encode(boilerplate.get_file(file_id)).decode("utf-8") except TypeError: raise JSONRPCDispatchException(code=boilerplate.ERROR_NO_FILE_PART_CODE, message=boilerplate.ERROR_NO_FILE_PART) return {"file_id": file_id, "file_contents_base64": file_contents_base64}
def __handle_exception(self, e: Exception) -> dict: if isinstance(e, proto.ProtoError): self._log.debug("Request proto error: {}".format(e)) raise JSONRPCDispatchException(e.code, str(e)) if isinstance(e, proto.SeEntryNotFound): self._log.debug("Request storage error: {}".format(e)) raise JSONRPCDispatchException(404, str(e)) self._log.error("Unhandled exception encountered, e={}".format(e)) raise JSONRPCDispatchException(500, "Internal Server Error")
def upload_file(file_name, file_contents_base64): if not file_name: raise JSONRPCDispatchException(code=boilerplate.ERROR_NO_SELECTED_FILE_CODE, message=boilerplate.ERROR_NO_SELECTED_FILE) if not file_contents_base64: raise JSONRPCDispatchException(code=boilerplate.ERROR_NO_FILE_PART_CODE, message=boilerplate.ERROR_NO_FILE_PART) if not boilerplate.allowed_file(file_name, allowed_extensions=ALLOWED_EXTENSIONS): raise JSONRPCDispatchException(code=boilerplate.ERROR_NOT_ALLOWED_CODE, message=boilerplate.ERROR_NOT_ALLOWED) try: file_contents = b64decode(file_contents_base64) file_size = len(file_contents) except TypeError: raise JSONRPCDispatchException(code=boilerplate.ERROR_NO_FILE_PART_CODE, message=boilerplate.ERROR_NO_FILE_PART) return boilerplate.save_file_simple(file_name, file_contents, file_size)
def must_get_worker_id(params): if 'workerId' not in params: raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, "Worker Id not found in the database. Hence invalid parameter") return str(params['workerId'])
def PreProcessWorkOrder(self, **params): """ RPC method registered with the KME listener to pre-process a work order request. Parameters : @param params - variable-length argument list Returns : @returns response - A jrpc response """ wo_request = get_request_json("PreProcessWorkOrder", random.randint(0, 100000)) wo_request["params"] = params wo_response = self._execute_work_order(json.dumps(wo_request), "") wo_response_json = json.loads(wo_response) if "result" in wo_response_json: return wo_response_json["result"] else: logger.error("Could not preprocess work order at KME") # For all negative cases, response should have an error field. # Hence constructing JSONRPC error response with # error code and message mapped to KME enclave response err_code = wo_response_json["error"]["code"] err_msg = wo_response_json["error"]["message"] data = { "workOrderId": wo_response_json["error"]["data"]["workOrderId"] } raise JSONRPCDispatchException(err_code, err_msg, data)
def WorkOrderReceiptRetrieve(self, **params): """ Function to retrieve the details of worker Parameters: - params is variable-length argument list containing work order receipt request request as defined in EEA spec 7.2.4 Returns jrpc response as defined in 7.2.5 """ wo_id = params["workOrderId"] value = self.kv_helper.get("wo-receipts", wo_id) if value: receipt = json.loads(value) receipt_updates = self.kv_helper.get("wo-receipt-updates", wo_id) if receipt_updates is None: receipt["params"]["receiptCurrentStatus"] = \ receipt["params"]["receiptCreateStatus"] else: receipt_updates_json = json.loads(receipt_updates) # Get the recent update to receipt last_receipt = receipt_updates_json[len(receipt_updates_json) - 1] receipt["params"]["receiptCurrentStatus"] = \ last_receipt["updateType"] return receipt["params"] else: raise JSONRPCDispatchException( JRPCErrorCodes.INVALID_PARAMETER_FORMAT_OR_VALUE, "Work order receipt for work order id {} not found in the " "database. Hence invalid parameter".format(wo_id))
def WorkerRetrieve(self, **params): """ Function to retrieve the details of worker Parameters: - param is the 'param' object in the a worker request as per TCF per TCF API 5.3.7 Worker Retrieve JSON Payload """ worker_id = must_get_worker_id(params) # value retrieved is 'result' field as per Spec 5.3.8 Worker Retrieve # Response Payload value = self.kv_helper.get("workers", worker_id) if value is None: raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, "Worker Id not found in the database. Hence invalid parameter") json_dict = json.loads(value) result = { "workerType": json_dict["workerType"], "organizationId": json_dict["organizationId"], "applicationTypeId": json_dict["applicationTypeId"], "details": json_dict["details"], "status": json_dict["status"], } return result
def process_files(file_ids): if not file_ids: raise JSONRPCDispatchException( code=boilerplate.ERROR_NO_FILE_PART_CODE, message=boilerplate.ERROR_NO_FILE_PART) if isinstance(file_ids, list): file_ids = ",".join(file_ids) return do_process(file_ids)
def _errback(self, failure, response): if isinstance(failure.value, JSONRPCDispatchException): e = failure.value else: e = JSONRPCDispatchException(code=4999, message=failure.getErrorMessage()) del response["result"] response["error"] = e.error._data # pylint: disable=protected-access self.sendJSONResponse(response)
def create_method(**kwargs): try: transaction_args, common_args, private_key_wif = split_params(**kwargs) return compose_transaction(db, name=tx, params=transaction_args, **common_args) except (TypeError, script.AddressError, exceptions.ComposeError, exceptions.TransactionError, exceptions.BalanceError) as error: # TypeError happens when unexpected keyword arguments are passed in error_msg = "Error composing {} transaction via API: {}".format(tx, str(error)) logging.warning(error_msg) raise JSONRPCDispatchException(code=JSON_RPC_ERROR_API_COMPOSE, message=error_msg)
def clustersearch(data: dict): ngram = data["q"] sim = data["sim"] freq = data["freq"] try: data = get_data(ngram=ngram, sim=sim, freq=freq) return json.dumps(data) except NotFoundError: raise JSONRPCDispatchException(code=404, message="Ngrams not found")
def WorkOrderReceiptCreate(self, **params): """ Function to process work order request Parameters: - params is variable-length arugment list containing work request as defined in EEA spec 7.2.2 Returns jrpc response as defined in 4.1 """ wo_id = params["workOrderId"] input_json_str = params["raw"] input_value = json.loads(input_json_str) wo_request = self.kv_helper.get("wo-requests", wo_id) if wo_request is None: raise JSONRPCDispatchException( JRPCErrorCodes.INVALID_PARAMETER_FORMAT_OR_VALUE, "Work order id does not exist, " "hence invalid request" ) else: wo_receipt = self.kv_helper.get("wo-receipts", wo_id) if wo_receipt is None: status, err_msg = \ self.__validate_work_order_receipt_create_req( input_value, wo_request) if status is True: self.kv_helper.set("wo-receipts", wo_id, input_json_str) raise JSONRPCDispatchException( JRPCErrorCodes.SUCCESS, "Receipt created successfully" ) else: raise JSONRPCDispatchException( JRPCErrorCodes.INVALID_PARAMETER_FORMAT_OR_VALUE, err_msg ) else: raise JSONRPCDispatchException( JRPCErrorCodes.INVALID_PARAMETER_FORMAT_OR_VALUE, "Work order receipt already exists. " + "Hence invalid parameter" )
def search(ngrams: list): cursor = connect(os.path.join(BASE_DIR, "wikidata.db")) try: data = DatabaseSearch(ngrams=ngrams, morph=morph, punct=punct, cursor=cursor) return json.dumps({"ngrams": data.ngrams, "csv_result": data.csv_format}) except NotFoundError: raise JSONRPCDispatchException(code=404, message="Ngrams not found")
def EncryptionKeySet(self, **params): """ Function to process set encryption key request. Parameters: - param is the 'param' object in the a worker request as per TCF API 6.1.11 Set Encryption Key Request Payload """ raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, "Operation is not supported. Hence invalid parameter")
def WorkerRetrieve(self, **params): """ Function to retrieve the details of worker Parameters: - param is the 'param' object in the a worker request as per Trusted Compute EEA API 5.3.7 Worker Retrieve JSON Payload """ input_json_str = params["raw"] input_value_json = json.loads(input_json_str) req_validator = WorkerRequestValidator() valid, err_msg = \ req_validator.worker_retrieve_validation( input_value_json["params"]) if not valid: raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, err_msg ) # value retrieved is 'result' field as per Spec 5.3.8 Worker Retrieve # Response Payload worker_id = str(params['workerId']) value = self.kv_helper.get("workers", worker_id) if value is None: raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, "Worker Id not found in the database. Hence invalid parameter") json_dict = json.loads(value) result = { "workerType": json_dict["workerType"], "organizationId": json_dict["organizationId"], "applicationTypeId": json_dict["applicationTypeId"], "details": json_dict["details"], "status": json_dict["status"], } return result
def WorkOrderGetResult(self, **params): """ Function to process work order get result This API corresponds to TCF API 6.1.4 Work Order Pull Request Payload Parameters: - wo_id is work order id - jrpc_id is JRPC id of response - response is the response object to be returned """ wo_id = params["workOrderId"] # Work order is processed if it is in wo-response table value = self.kv_helper.get("wo-responses", wo_id) if value: response = json.loads(value) if 'result' in response: return response['result'] # response without a result should have an error err_code = response["error"]["code"] err_msg = response["error"]["message"] if err_code == EnclaveError.ENCLAVE_ERR_VALUE: err_code = WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE elif err_code == EnclaveError.ENCLAVE_ERR_UNKNOWN: err_code = WorkOrderStatus.UNKNOWN_ERROR else: err_code = WorkOrderStatus.FAILED raise JSONRPCDispatchException(err_code, err_msg) if (self.kv_helper.get("wo-timestamps", wo_id) is not None): # work order is yet to be processed raise JSONRPCDispatchException( WorkOrderStatus.PENDING, "Work order result is yet to be updated") # work order not in 'wo-timestamps' table raise JSONRPCDispatchException( WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE, "Work order Id not found in the database. Hence invalid parameter")
def getblocktemplate(wallet_address): try: blob, difficulty = s.getblocktemplate(wallet_address) except Exception: raise JSONRPCDispatchException(code=-9, message="Core is busy") resp = { "blocktemplate_blob": blob, "difficulty": difficulty, "height": s.height, "status": "OK" } return resp
def call_method(self, func, *args, **kwargs): """ Calls the API method `func` with the given arguments. The arguments here are not yet deserialized according to the function type annotations. """ try: try: result = func(*args, **kwargs) log.info(f"Successfully called method {func.__name__}") return result except InstantError: raise except ArgumentError as e: e = e.__cause__ if isinstance(e, ValidationError): data = e.messages else: data = None raise InstantError( code=-32602, # Invalid params message=format_exception(e), data=data, http_code=400, ) except JSONRPCDispatchException as e: raise InstantError( code=e.error.code, message=e.error.message, data=e.error.data, ) except Exception: message = f"Unhandled error in method {func.__name__}" log.exception(message) raise InstantError( code=-32000, message=message, ) except InstantError as e: raise JSONRPCDispatchException( code=e.code, message=e.message, # Mash the http_code in here to be extracted later in handle_request # There's no easy way to get this info through the json-rpc # library up to the final response data=dict( __instant_http_code=e.http_code, data=e.data, ), )
def WorkerRegister(self, **params): """ Function to register a new worker to the enclave Parameters: - param is the 'param' object in the a worker request as per TCF 5.3.1 Worker Register JSON Payload. """ worker_id = must_get_worker_id(params) if(self.kv_helper.get("workers", worker_id) is not None): raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, "Worker Id already exists in the database." + " Hence invalid parameter") # Worker Initial Status is set to Active params["status"] = WorkerStatus.ACTIVE input_json_str = json.dumps(params) self.kv_helper.set("workers", worker_id, input_json_str) raise JSONRPCDispatchException( WorkerError.SUCCESS, "Successfully Registered")
def cancel(self, request_id): """Cancel pending request handler. Args: request_id (string | number): The id of the original request Note: Request will only be cancelled if it has not begun execution. """ log.debug('Cancel request %d', request_id) try: self._received_requests[request_id].set_exception( JSONRPCDispatchException(code=LSP_CANCEL_CODE, message="Request cancelled")) except KeyError: log.debug('Received cancel for finished/nonexistent request %d', request_id)
def WorkerLookUpNext(self, **params): """ Function to look the set of worker newly added Parameters: - param is the 'param' object in the a worker request as per TCF API 5.3.5 Worker Lookup Next JSON Payload """ input_json_str = params["raw"] input_value_json = json.loads(input_json_str) valid, err_msg = \ Validator.schema_validation( "WorkerLookUpNext", input_value_json["params"]) if not valid: raise JSONRPCDispatchException( WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, err_msg) return self.__lookup_basic(True, params)
def create_method(**kwargs): try: transaction_args, common_args, private_key_wif = split_params( **kwargs) return compose_transaction(db, name=tx, params=transaction_args, **common_args) except TypeError as e: raise APIError(str(e)) except (script.AddressError, exceptions.ComposeError, exceptions.TransactionError, exceptions.BalanceError) as error: error_msg = "Error composing {} transaction via API: {}".format( tx, str(error)) logging.warning(error_msg) raise JSONRPCDispatchException( code=JSON_RPC_ERROR_API_COMPOSE, message=error_msg)