def __init__(self, config): try: (self.kv_helper, _) = connector.open(config) except Exception as err: logger.error(f"failed to open db: {err}") sys.exit(-1) # Worker registry handler needs to be instantiated before Work order handler. Otherwise, LMDB operations don't operate on updated values. # TODO: Needs further investigation on what is causing the above behavior. self.worker_registry_handler = TCSWorkerRegistryHandler(self.kv_helper) self.workorder_handler = TCSWorkOrderHandler( self.kv_helper, config["Listener"]["max_work_order_count"]) self.workorder_receipt_handler = TCSWorkOrderReceiptHandler( self.kv_helper) self.worker_encryption_key_handler = WorkerEncryptionKeyHandler( self.kv_helper) self.dispatcher = Dispatcher() rpc_methods = [ self.worker_encryption_key_handler.EncryptionKeyGet, self.worker_encryption_key_handler.EncryptionKeySet, self.worker_registry_handler.WorkerLookUp, self.worker_registry_handler.WorkerLookUpNext, self.worker_registry_handler.WorkerRegister, self.worker_registry_handler.WorkerSetStatus, self.worker_registry_handler.WorkerRetrieve, self.worker_registry_handler.WorkerUpdate, self.workorder_handler.WorkOrderSubmit, self.workorder_handler.WorkOrderGetResult, ] for m in rpc_methods: self.dispatcher.add_method(m)
class ArachnadoRPC(object): """ Base class for all Arachnado RPC resources. Use it as a mixin for tornado.web.RequestHandler subclasses. It provides :meth:`handle_request` method which handles Jobs, Sites and Pages RPC requests. """ rpc_objects = tuple() def initialize(self, *args, **kwargs): jobs = Jobs(self, *args, **kwargs) sites = Sites(self, *args, **kwargs) pages = Pages(self, *args, **kwargs) self.rpc_objects = [jobs, sites, pages] self.dispatcher = Dispatcher() for obj in self.rpc_objects: self.dispatcher.add_object(obj) def handle_request(self, body): response = JSONRPCResponseManager.handle(body, self.dispatcher) if isinstance(response.result, Future): response.result.add_done_callback( partial(self.on_done, data=response.data)) else: self.send_data(response.data) def on_done(self, future, data): data['result'] = future.result() self.send_data(data) def send_data(self, data): raise NotImplementedError
def __init__(self, conn, *, name="RE QServer Comm"): self._conn = conn self._dispatcher = Dispatcher() # json-rpc dispatcher self._thread_running = False # Set True to exit the thread self._thread_name = name self._conn_polling_timeout = 0.1 # in sec.
def initialize(self, *args, **kwargs): jobs = Jobs(self, *args, **kwargs) sites = Sites(self, *args, **kwargs) pages = Pages(self, *args, **kwargs) self.rpc_objects = [jobs, sites, pages] self.dispatcher = Dispatcher() for obj in self.rpc_objects: self.dispatcher.add_object(obj)
def initialize(self, *args, **kwargs): self.stored_data = deque() self.storages = {} self.i_args = args self.i_kwargs = kwargs self.cp = kwargs.get("crawler_process", None) self.dispatcher = Dispatcher() self.dispatcher["cancel_subscription"] = self.cancel_subscription self.dispatcher["set_max_message_size"] = self.set_max_message_size
def test_init_from_dictionary(self): dummy = { 'one': lambda x: x, 'two': lambda x: x, } d = Dispatcher(dummy) self.assertIn("one", d) self.assertIn("two", d)
def __init__(self, rpc_socket, gpio_manager): self.rpc_socket = rpc_socket self.gpio_manager = gpio_manager self.dispatcher = Dispatcher() self.dispatcher.add_method(self.gpio_manager.add_input) self.dispatcher.add_method(self.gpio_manager.add_output) self.dispatcher.add_method(self.gpio_manager.pin_read) self.dispatcher.add_method(self.gpio_manager.pin_on) self.dispatcher.add_method(self.gpio_manager.pin_off) self.dispatcher.add_method(self.gpio_manager.enable_pub_when_activated) self.dispatcher.add_method(self.gpio_manager.disable_pub_when_activated) self.dispatcher.add_method(self.gpio_manager.enable_pub_when_deactivated) self.dispatcher.add_method(self.gpio_manager.disable_pub_when_deactivated)
def __init__(self, config): try: self.kv_helper = \ connector.open(config['KvStorage']['remote_storage_url']) except Exception as err: logger.error(f"failed to open db: {err}") sys.exit(-1) self.worker_registry_handler = TCSWorkerRegistryHandler(self.kv_helper) self.workorder_handler = TCSWorkOrderHandler( self.kv_helper, config["Listener"]["max_work_order_count"]) self.workorder_receipt_handler = TCSWorkOrderReceiptHandler( self.kv_helper) self.worker_encryption_key_handler = WorkerEncryptionKeyHandler( self.kv_helper) self.dispatcher = Dispatcher() rpc_methods = [ self.worker_encryption_key_handler.EncryptionKeyGet, self.worker_encryption_key_handler.EncryptionKeySet, self.worker_registry_handler.WorkerLookUp, self.worker_registry_handler.WorkerLookUpNext, self.worker_registry_handler.WorkerRegister, self.worker_registry_handler.WorkerSetStatus, self.worker_registry_handler.WorkerRetrieve, self.worker_registry_handler.WorkerUpdate, self.workorder_handler.WorkOrderSubmit, self.workorder_handler.WorkOrderGetResult, self.workorder_receipt_handler.WorkOrderReceiptCreate, self.workorder_receipt_handler.WorkOrderReceiptUpdate, self.workorder_receipt_handler.WorkOrderReceiptRetrieve, self.workorder_receipt_handler.WorkOrderReceiptUpdateRetrieve, self.workorder_receipt_handler.WorkOrderReceiptLookUp, self.workorder_receipt_handler.WorkOrderReceiptLookUpNext ] for m in rpc_methods: self.dispatcher.add_method(m)
def test_init_from_object_instance(self): class Dummy(): def one(self): pass def two(self): pass dummy = Dummy() d = Dispatcher(dummy) self.assertIn("one", d) self.assertIn("two", d) self.assertNotIn("__class__", d)
def __getitem__(self, key): """Override __getitem__ to support transparent translation. Translate function arguments, return value, and exceptions. """ old_value = Dispatcher.__getitem__(self, key) @wraps(old_value) def wrapped(*args, **kwargs): """Wrap a function in JSON formatting.""" try: return to_json(old_value(*from_json(args), **from_json(kwargs))) except Exception as exception: convert_exception(exception) raise return wrapped
class TCSListener(resource.Resource): """ TCSListener Class is comprised of HTTP interface which listens for the end user requests, Worker Registry Handler, Work Order Handler and Work Order Receipts Handler . """ # The isLeaf instance variable describes whether or not a resource will have children and only leaf resources get rendered. # TCSListener is the most derived class hence isLeaf is required. isLeaf = True # ----------------------------------------------------------------- def __init__(self, config): try: (self.kv_helper, _) = connector.open(config) except Exception as err: logger.error(f"failed to open db: {err}") sys.exit(-1) # Worker registry handler needs to be instantiated before Work order handler. Otherwise, LMDB operations don't operate on updated values. # TODO: Needs further investigation on what is causing the above behavior. self.worker_registry_handler = TCSWorkerRegistryHandler(self.kv_helper) self.workorder_handler = TCSWorkOrderHandler( self.kv_helper, config["Listener"]["max_work_order_count"]) self.workorder_receipt_handler = TCSWorkOrderReceiptHandler( self.kv_helper) self.worker_encryption_key_handler = WorkerEncryptionKeyHandler( self.kv_helper) self.dispatcher = Dispatcher() rpc_methods = [ self.worker_encryption_key_handler.EncryptionKeyGet, self.worker_encryption_key_handler.EncryptionKeySet, self.worker_registry_handler.WorkerLookUp, self.worker_registry_handler.WorkerLookUpNext, self.worker_registry_handler.WorkerRegister, self.worker_registry_handler.WorkerSetStatus, self.worker_registry_handler.WorkerRetrieve, self.worker_registry_handler.WorkerUpdate, self.workorder_handler.WorkOrderSubmit, self.workorder_handler.WorkOrderGetResult, ] for m in rpc_methods: self.dispatcher.add_method(m) def _process_request(self, input_json_str): response = {} response['error'] = {} response['error'][ 'code'] = WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE try: input_json = json.loads(input_json_str) except: response['error'][ 'message'] = 'Error: Improper Json. Unable to load' return response if ('jsonrpc' not in input_json or 'id' not in input_json or 'method' not in input_json or 'params' not in input_json): response['error'][ 'message'] = 'Error: Json does not have the required field' return response if not isinstance(input_json['id'], int): response['error'][ 'message'] = 'Error: Id should be of type integer' return response response['jsonrpc'] = input_json['jsonrpc'] response['id'] = input_json['id'] if not isinstance(input_json['method'], str): response['error'][ 'message'] = 'Error: Method has to be of type string' return response if ("WorkOrderReceipt" in input_json['method']): return self.workorder_receipt_handler.workorder_receipt_handler( input_json_str) logger.info("Received request: %s", input_json['method']) # save the full json for WorkOrderSubmit input_json["params"]["raw"] = input_json_str data = json.dumps(input_json).encode('utf-8') response = JSONRPCResponseManager.handle(data, self.dispatcher) return response.data def render_GET(self, request): # JRPC response with id 0 is returned because id parameter # will not be found in GET request response = utility.create_error_response( WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE, "0", "Only POST request is supported") logger.error( "GET request is not supported. Only POST request is supported") return response def render_POST(self, request): response = {} logger.info('Received a new request from the client') try: # process the message encoding encoding = request.getHeader('Content-Type') data = request.content.read() if encoding == 'application/json': try: input_json_str = data.decode('utf-8') input_json = json.loads(input_json_str) jrpc_id = input_json["id"] response = self._process_request(input_json_str) except AttributeError: logger.error("Error while loading input json") response = utility.create_error_response( WorkOrderStatus.UNKNOWN_ERROR, jrpc_id, "UNKNOWN_ERROR: Error while loading the input JSON file" ) return response else: # JRPC response with 0 as id is returned because id can't be fecthed # from a request with unknown encoding response = utility.create_error_response( WorkOrderStatus.UNKNOWN_ERROR, 0, "UNKNOWN_ERROR: unknown message encoding") return response except: logger.exception('exception while decoding http request %s', request.path) # JRPC response with 0 as id is returned because id can't be # fetched from improper request response = utility.create_error_response( WorkOrderStatus.UNKNOWN_ERROR, 0, "UNKNOWN_ERROR: unable to decode incoming request") return response # send back the results try: if encoding == 'application/json': response = json.dumps(response) logger.info('response[%s]: %s', encoding, response) request.setHeader('content-type', encoding) request.setResponseCode(http.OK) return response.encode('utf8') except: logger.exception('unknown exception while processing request %s', request.path) response = utility.create_error_response( WorkOrderStatus.UNKNOWN_ERROR, jrpc_id, "UNKNOWN_ERROR: unknown exception processing http \ request {0}".format(request.path)) return response
class PipeJsonRpcReceive: """ The class contains functions for receiving and processing JSON RPC messages received on communication pipe. Parameters ---------- conn: multiprocessing.Connection Reference to bidirectional end of a pipe (multiprocessing.Pipe) name: str Name of the receiving thread (it is better to assign meaningful unique names to threads. Examples -------- .. code-block:: python conn1, conn2 = multiprocessing.Pipe() pc = PipeJsonRPC(conn=conn1, name="RE QServer Receive") def func(): print("Testing") pc.add_handler(func, "some_method") pc.start() # Wait and process commands # The function 'func' is called when the message with method=="some_method" is received pc.stop() # Stop before exit to stop the thread. """ def __init__(self, conn, *, name="RE QServer Comm"): self._conn = conn self._dispatcher = Dispatcher() # json-rpc dispatcher self._thread_running = False # Set True to exit the thread self._thread_name = name self._conn_polling_timeout = 0.1 # in sec. def start(self): """ Start processing of the pipe messages """ self._start_conn_thread() def stop(self): """ Stop processing of the pipe messages (and exit the tread) """ self._thread_running = False def __del__(self): self.stop() def add_method(self, handler, name=None): """ Add method to json-rpc dispatcher. Parameters ---------- handler: callable Reference to a handler name: str, optional Name to register (default is the handler name) """ # Add method to json-rpc dispatcher self._dispatcher.add_method(handler, name) def _start_conn_thread(self): if not self._thread_running: # Clear the pipe from outdated unprocessed messages. while self._conn.poll(): self._conn.recv() self._thread_running = True self._thread_conn = threading.Thread( target=self._receive_conn_thread, name=self._thread_name, daemon=True) self._thread_conn.start() def _receive_conn_thread(self): while True: if self._conn.poll(self._conn_polling_timeout): try: msg = self._conn.recv() # Messages should be handled in the event loop self._conn_received(msg) except Exception as ex: logger.exception( "Exception occurred while waiting for RE Manager-> Watchdog message: %s", str(ex)) break if not self._thread_running: # Exit thread break def _conn_received(self, msg): # if logger.level < 11: # Print output only if logging level is DEBUG (10) or less # msg_json = json.loads(msg) # We don't want to print 'heartbeat' messages # if not isinstance(msg_json, dict) or (msg_json["method"] != "heartbeat"): # logger.debug("Command received RE Manager->Watchdog: %s", pprint.pformat(msg_json)) response = JSONRPCResponseManager.handle(msg, self._dispatcher) if response: response = response.json self._conn.send(response)
def __init__(self, rpc_methods): self.dispatcher = Dispatcher() for m in rpc_methods: self.dispatcher.add_method(m)
class BaseJRPCListener(resource.Resource): """ BaseJRPCListener Class is comprised of HTTP interface which listens for the end user requests using JRPC. """ # The isLeaf instance variable describes whether or not a resource will # have children and only leaf resources get rendered. # BaseListener is the supposed to be one but last class in the derivation # tree. So, isLeaf is set to False. isLeaf = False # ----------------------------------------------------------------- def __init__(self, rpc_methods): self.dispatcher = Dispatcher() for m in rpc_methods: self.dispatcher.add_method(m) def _process_request(self, input_json_str): """ Handles incoming requests or rather dispatches to appropriate rpc method Parameters : input_json_str - JSON formatted str of the request Returns : response - data field from the response received which is a dict """ response = {} response['error'] = {} response['error']['code'] = \ JRPCErrorCodes.INVALID_PARAMETER_FORMAT_OR_VALUE try: input_json = json.loads(input_json_str) logger.info("Received request: %s", input_json['method']) except Exception as err: logger.error("exception loading Json: %s", str(err)) response["error"]["message"] = "Improper Json request" return response # save the full json for WorkOrderSubmit input_json["params"]["raw"] = input_json_str data = json.dumps(input_json).encode('utf-8') response = JSONRPCResponseManager.handle(data, self.dispatcher) return response.data def render_GET(self, request): """ Handle a GET request to the listener. Not supported. So only error is expected to be returned as response. Parameters : request - Request coming in from a client Returns : response - A dict type response which always contains error """ # JRPC response with id 0 is returned because id parameter # will not be found in GET request response = jrpc_utility.create_error_response( JRPCErrorCodes.INVALID_PARAMETER_FORMAT_OR_VALUE, "0", "Only POST request is supported") logger.error( "GET request is not supported. Only POST request is supported") return response def render_POST(self, request): """ Handle a POST request to the listener. Decode and delegate to _process_request for handling. Parameters : request - Request coming in from a client Returns : response - A dict type response """ response = {} logger.info('Received a new request from the client') try: # process the message encoding encoding = request.getHeader('Content-Type') data = request.content.read() if encoding == 'application/json': try: input_json_str = data.decode('utf-8') input_json = json.loads(input_json_str) jrpc_id = input_json["id"] response = self._process_request(input_json_str) except AttributeError: logger.error("Error while loading input json") response = jrpc_utility.create_error_response( JRPCErrorCodes.UNKNOWN_ERROR, jrpc_id, "UNKNOWN_ERROR: Error while loading input JSON file") return response else: # JRPC response with 0 as id is returned because id can't be # fetched from a request with unknown encoding. response = jrpc_utility.create_error_response( JRPCErrorCodes.UNKNOWN_ERROR, 0, "UNKNOWN_ERROR: unknown message encoding") return response except Exception as err: logger.exception('exception while decoding http request %s: %s', request.path, str(err)) # JRPC response with 0 as id is returned because id can't be # fetched from improper request response = jrpc_utility.create_error_response( JRPCErrorCodes.UNKNOWN_ERROR, 0, "UNKNOWN_ERROR: unable to decode incoming request") return response # send back the results try: if encoding == 'application/json': response = json.dumps(response) logger.info('response[%s]: %s', encoding, response) request.setHeader('content-type', encoding) request.setResponseCode(http.OK) return response.encode('utf8') except Exception as err: logger.exception( 'unknown exception while processing request %s: %s', request.path, str(err)) response = jrpc_utility.create_error_response( JRPCErrorCodes.UNKNOWN_ERROR, jrpc_id, "UNKNOWN_ERROR: unknown exception processing http " + "request {0}: {1}".format(request.path, str(err))) return response def start(self, host_name, port): """ Start the listener instance on specified socket. Parameters : host_name - The hostname where this listener is reachable port - The port at which this listener needs to listen """ root = self site = server.Site(root) reactor.listenTCP(port, site, interface=host_name) logger.info('%s started on port %s', type(self).__name__, port) try: reactor.run() except reactor_error.ReactorNotRunning: logger.error('shutdown') except Exception as err: logger.error('shutdown: %s', str(err)) exit(0)
def __init__(self, conn): self._conn = conn self._dispatcher = Dispatcher() # json-rpc dispatcher self._stop_thread = False # Set True to exit the thread
def setUp(self): self.d = Dispatcher()
def dispatcher(self): # TODO: make decorator or something d = Dispatcher() d.add_method(self.request_player_state, name="request_state") d.add_method(self.player_change_state, name="state") d.add_method(self.register_player, name="register") d.add_method(self.register_controller, name="subscribe") d.add_method(self.player_command, name="command") return d
class GpioCoreServer: def __init__(self, rpc_socket, gpio_manager): self.rpc_socket = rpc_socket self.gpio_manager = gpio_manager self.dispatcher = Dispatcher() self.dispatcher.add_method(self.gpio_manager.add_input) self.dispatcher.add_method(self.gpio_manager.add_output) self.dispatcher.add_method(self.gpio_manager.pin_read) self.dispatcher.add_method(self.gpio_manager.pin_on) self.dispatcher.add_method(self.gpio_manager.pin_off) self.dispatcher.add_method(self.gpio_manager.enable_pub_when_activated) self.dispatcher.add_method(self.gpio_manager.disable_pub_when_activated) self.dispatcher.add_method(self.gpio_manager.enable_pub_when_deactivated) self.dispatcher.add_method(self.gpio_manager.disable_pub_when_deactivated) def run(self): try: while True: message = self.rpc_socket.recv_string() response = JSONRPCResponseManager.handle(message, self.dispatcher) self.rpc_socket.send_string(response.json) finally: self.gpio_manager.clean_up()
class TCSListener(resource.Resource): """ TCSListener Class is comprised of HTTP interface which listens for the end user requests, Worker Registry Handler, Work Order Handler and Work Order Receipts Handler . """ # The isLeaf instance variable describes whether or not a resource will # have children and only leaf resources get rendered. # TCSListener is the most derived class hence isLeaf is required. isLeaf = True # ----------------------------------------------------------------- def __init__(self, config): try: self.kv_helper = connector.open(config['KvStorage']['remote_url']) except Exception as err: logger.error(f"failed to open db: {err}") sys.exit(-1) self.worker_registry_handler = TCSWorkerRegistryHandler(self.kv_helper) self.workorder_handler = TCSWorkOrderHandler( self.kv_helper, config["Listener"]["max_work_order_count"]) self.workorder_receipt_handler = TCSWorkOrderReceiptHandler( self.kv_helper) self.worker_encryption_key_handler = WorkerEncryptionKeyHandler( self.kv_helper) self.dispatcher = Dispatcher() rpc_methods = [ self.worker_encryption_key_handler.EncryptionKeyGet, self.worker_encryption_key_handler.EncryptionKeySet, self.worker_registry_handler.WorkerLookUp, self.worker_registry_handler.WorkerLookUpNext, self.worker_registry_handler.WorkerRegister, self.worker_registry_handler.WorkerSetStatus, self.worker_registry_handler.WorkerRetrieve, self.worker_registry_handler.WorkerUpdate, self.workorder_handler.WorkOrderSubmit, self.workorder_handler.WorkOrderGetResult, self.workorder_receipt_handler.WorkOrderReceiptCreate, self.workorder_receipt_handler.WorkOrderReceiptUpdate, self.workorder_receipt_handler.WorkOrderReceiptRetrieve, self.workorder_receipt_handler.WorkOrderReceiptUpdateRetrieve, self.workorder_receipt_handler.WorkOrderReceiptLookUp, self.workorder_receipt_handler.WorkOrderReceiptLookUpNext ] for m in rpc_methods: self.dispatcher.add_method(m) def _process_request(self, input_json_str): response = {} response['error'] = {} response['error']['code'] = \ WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE try: input_json = json.loads(input_json_str) except Exception as err: logger.exception("exception loading Json: %s", str(err)) response = { "error": { "code": WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE, "message": "Error: Improper Json. Unable to load", }, } return response logger.info("Received request: %s", input_json['method']) # save the full json for WorkOrderSubmit input_json["params"]["raw"] = input_json_str data = json.dumps(input_json).encode('utf-8') response = JSONRPCResponseManager.handle(data, self.dispatcher) return response.data def render_GET(self, request): # JRPC response with id 0 is returned because id parameter # will not be found in GET request response = jrpc_utility.create_error_response( WorkOrderStatus.INVALID_PARAMETER_FORMAT_OR_VALUE, "0", "Only POST request is supported") logger.error( "GET request is not supported. Only POST request is supported") return response def render_POST(self, request): response = {} logger.info('Received a new request from the client') try: # process the message encoding encoding = request.getHeader('Content-Type') data = request.content.read() if encoding == 'application/json': try: input_json_str = data.decode('utf-8') input_json = json.loads(input_json_str) jrpc_id = input_json["id"] response = self._process_request(input_json_str) except AttributeError: logger.error("Error while loading input json") response = jrpc_utility.create_error_response( WorkOrderStatus.UNKNOWN_ERROR, jrpc_id, "UNKNOWN_ERROR: Error while loading input JSON file") return response else: # JRPC response with 0 as id is returned because id can't be # fetched from a request with unknown encoding. response = jrpc_utility.create_error_response( WorkOrderStatus.UNKNOWN_ERROR, 0, "UNKNOWN_ERROR: unknown message encoding") return response except Exception as err: logger.exception('exception while decoding http request %s: %s', request.path, str(err)) # JRPC response with 0 as id is returned because id can't be # fetched from improper request response = jrpc_utility.create_error_response( WorkOrderStatus.UNKNOWN_ERROR, 0, "UNKNOWN_ERROR: unable to decode incoming request") return response # send back the results try: if encoding == 'application/json': response = json.dumps(response) logger.info('response[%s]: %s', encoding, response) request.setHeader('content-type', encoding) request.setResponseCode(http.OK) return response.encode('utf8') except Exception as err: logger.exception( 'unknown exception while processing request %s: %s', request.path, str(err)) response = jrpc_utility.create_error_response( WorkOrderStatus.UNKNOWN_ERROR, jrpc_id, "UNKNOWN_ERROR: unknown exception processing http " + "request {0}: {1}".format(request.path, str(err))) return response
# coding:utf-8 from uuid import uuid4 from flask import Blueprint from jsonrpc.backend.flask import JSONRPCAPI from jsonrpc.dispatcher import Dispatcher class MyJsonRpcApi(JSONRPCAPI): def as_blueprint(self, name=None, url='/'): blueprint = Blueprint(name if name else str(uuid4()), __name__) blueprint.add_url_rule( url, view_func=self.jsonrpc, methods=['POST']) blueprint.add_url_rule( '/map', view_func=self.jsonrpc_map, methods=['GET']) return blueprint dispatcher = Dispatcher() api = MyJsonRpcApi(dispatcher) api_add = api.dispatcher.add_method api_class = api.dispatcher.add_class
def create_dispatcher(node: ecdkg.ECDKGNode, address: int = None): # TODO: make loop use uniform loop = asyncio.get_event_loop() dispatcher = Dispatcher() dispatcher['echo'] = lambda value: value def dispatcher_add_async_method(corofunc): @functools.wraps(corofunc) def wrapper(*args, **kwargs): return loop.create_task(corofunc(*args, **kwargs)) return dispatcher.add_method(wrapper) @dispatcher_add_async_method async def get_ecdkg_state(decryption_condition: str, phase: ecdkg.ECDKGPhase = ecdkg.ECDKGPhase.uninitialized): ecdkg_obj = node.get_protocol_instance_by_decryption_condition(decryption_condition) return ecdkg_obj.to_state_message() @dispatcher_add_async_method async def get_encryption_key(decryption_condition, notify_others=True): ecdkg_obj = node.get_protocol_instance_by_decryption_condition(decryption_condition) await ecdkg_obj.run_until_phase(ecdkg.ECDKGPhase.key_publication) return '{0[0]:064x}{0[1]:064x}'.format(ecdkg_obj.encryption_key) @dispatcher_add_async_method async def get_signed_decryption_key_part(decryption_condition): # TODO: Is running the get enc key even necessary now? await get_encryption_key(decryption_condition) await util.decryption_condition_satisfied(decryption_condition) ecdkg_obj = node.get_protocol_instance_by_decryption_condition(decryption_condition) return ecdkg_obj.get_signed_decryption_key_part() @dispatcher_add_async_method async def get_decryption_key(decryption_condition): ecdkg_obj = node.get_protocol_instance_by_decryption_condition(decryption_condition) await ecdkg_obj.run_until_phase(ecdkg.ECDKGPhase.complete) return '{:064x}'.format(ecdkg_obj.decryption_key) @dispatcher_add_async_method async def get_signed_verification_points(decryption_condition): logging.info('sending vpoints to {:040x}'.format(address)) ecdkg_obj = node.get_protocol_instance_by_decryption_condition(decryption_condition) await ecdkg_obj.run_until_phase(ecdkg.ECDKGPhase.key_distribution) return ecdkg_obj.get_signed_verification_points() @dispatcher_add_async_method async def get_signed_encryption_key_vector(decryption_condition): ecdkg_obj = node.get_protocol_instance_by_decryption_condition(decryption_condition) # await ecdkg_obj.run_until_phase(ecdkg.ECDKGPhase.key_generation) await ecdkg_obj.run_until_phase(ecdkg.ECDKGPhase.key_distribution) return ecdkg_obj.get_signed_encryption_key_vector() @dispatcher_add_async_method async def get_complaints(decryption_condition): ecdkg_obj = node.get_protocol_instance_by_decryption_condition(decryption_condition) # await ecdkg_obj.run_until_phase(ecdkg.ECDKGPhase.key_check) await ecdkg_obj.run_until_phase(ecdkg.ECDKGPhase.key_distribution) complaints = ecdkg_obj.get_complaints_by(node.address) logging.info('sending complaints: {}'.format(complaints)) return complaints if address is not None: @dispatcher_add_async_method async def get_signed_secret_shares(decryption_condition): logging.info('sending shares to {:040x}'.format(address)) ecdkg_obj = node.get_protocol_instance_by_decryption_condition(decryption_condition) await ecdkg_obj.run_until_phase(ecdkg.ECDKGPhase.key_distribution) return ecdkg_obj.get_signed_secret_shares(address) return dispatcher