Example #1
0
 def handle(self, connection_id, message_content):
     request = validator_pb2.Message()
     request.ParseFromString(message_content)
     return dispatch.HandlerResult(
         dispatch.HandlerStatus.RETURN,
         message_out=validator_pb2.Message(
             correlation_id=request.correlation_id, ),
         message_type=validator_pb2.Message.DEFAULT)
Example #2
0
    def _determine_next(self, message_id, future):
        if future.result().status == HandlerStatus.DROP:
            del self._message_information[message_id]

        elif future.result().status == HandlerStatus.PASS:
            self._process(message_id)

        elif future.result().status == HandlerStatus.RETURN_AND_PASS:
            connection, connection_id, \
                original_message, _ = self._message_information[message_id]

            message = validator_pb2.Message(
                content=future.result().message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=future.result().message_type)
            try:
                self._send_message[connection](msg=message,
                                               connection_id=connection_id)
            except KeyError:
                LOGGER.info(
                    "Can't send message %s back to "
                    "%s because connection %s not in dispatcher",
                    get_enum_name(message.message_type), connection_id,
                    connection)
            self._process(message_id)

        elif future.result().status == HandlerStatus.RETURN:
            connection, connection_id,  \
                original_message, _ = self._message_information[message_id]

            del self._message_information[message_id]

            message = validator_pb2.Message(
                content=future.result().message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=future.result().message_type)
            try:
                self._send_message[connection](msg=message,
                                               connection_id=connection_id)
            except KeyError:
                LOGGER.info(
                    "Can't send message %s back to "
                    "%s because connection %s not in dispatcher",
                    get_enum_name(message.message_type), connection_id,
                    connection)
        with self._condition:
            if len(self._message_information) == 0:
                self._condition.notify()
Example #3
0
    def send(self, message_type, data, connection_id, callback=None):
        """
        Send a message of message_type
        :param connection_id: the identity for the connection to send to
        :param message_type: validator_pb2.Message.* enum value
        :param data: bytes serialized protobuf
        :return: future.Future
        """
        if connection_id not in self._connections:
            raise ValueError("Unknown connection id: %s", connection_id)
        connection_info = self._connections.get(connection_id)
        if connection_info.connection_type == \
                ConnectionType.ZMQ_IDENTITY:
            message = validator_pb2.Message(correlation_id=_generate_id(),
                                            content=data,
                                            message_type=message_type)

            fut = future.Future(
                message.correlation_id,
                message.content,
                has_callback=True if callback is not None else False)

            if callback is not None:
                fut.add_callback(callback)

            self._futures.put(fut)

            self._send_receive_thread.send_message(msg=message,
                                                   connection_id=connection_id)
            return fut
        else:
            return connection_info.connection.send(message_type,
                                                   data,
                                                   callback=callback)
Example #4
0
    def handle(self, message, responder):
        request = client_pb2.ClientBlockGetRequest()
        resp_proto = client_pb2.ClientBlockGetResponse
        status = resp_proto.OK

        try:
            request.ParseFromString(message.content)
            block = self._block_store[request.block_id].block.get_block()
        except DecodeError:
            LOGGER.info("Expected protobuf of class %s failed to "
                        "deserialize", request)
            status = resp_proto.ERROR
        except KeyError as e:
            status = client_pb2.ClientStateListResponse.NORESOURCE
            LOGGER.info(e)

        if status != resp_proto.OK:
            response = resp_proto(status=status)
        else:
            response = resp_proto(status=status, block=block)

        responder.send(validator_pb2.Message(
            sender=message.sender,
            message_type=validator_pb2.Message.CLIENT_BLOCK_LIST_RESPONSE,
            correlation_id=message.correlation_id,
            content=response.SerializeToString()))
Example #5
0
    def handle(self, message, responder):
        request = client_pb2.ClientStateListRequest()
        resp_proto = client_pb2.ClientStateListResponse
        status = resp_proto.OK

        try:
            request.ParseFromString(message.content)
            self._tree.set_merkle_root(request.merkle_root)
        except KeyError as e:
            status = resp_proto.NORESOURCE
            LOGGER.debug(e)
        except DecodeError:
            status = resp_proto.ERROR
            LOGGER.info("Expected protobuf of class %s failed to "
                        "deserialize", request)

        if status != resp_proto.OK:
            response = resp_proto(status=status)
        else:
            prefix = request.prefix
            leaves = self._tree.leaves(prefix)

            if len(leaves) == 0:
                status = resp_proto.NORESOURCE
                response = resp_proto(status=status)
            else:
                entries = [Entry(address=a, data=v) for a, v in leaves.items()]
                response = resp_proto(status=status, entries=entries)

        responder.send(validator_pb2.Message(
            sender=message.sender,
            message_type=validator_pb2.Message.CLIENT_STATE_LIST_RESPONSE,
            correlation_id=message.correlation_id,
            content=response.SerializeToString()))
Example #6
0
    def send(self, message_type, data, callback=None):
        """Sends a message of message_type

        Args:
            message_type (validator_pb2.Message): enum value
            data (bytes): serialized protobuf
            callback (function): a callback function to call when a
                response to this message is received

        Returns:
            future.Future
        """
        message = validator_pb2.Message(correlation_id=_generate_id(),
                                        content=data,
                                        message_type=message_type)

        fut = future.Future(
            message.correlation_id,
            message.content,
            has_callback=True if callback is not None else False)

        if callback is not None:
            fut.add_callback(callback)

        self._futures.put(fut)

        self._send_receive_thread.send_message(message)
        return fut
Example #7
0
    def _receive_message(self):
        """
        Internal coroutine for receiving messages
        """
        with self._condition:
            self._condition.wait_for(lambda: self._socket is not None)
        while True:
            if self._socket.getsockopt(zmq.TYPE) == zmq.ROUTER:
                identity, msg_bytes = yield from self._socket.recv_multipart()
            else:
                msg_bytes = yield from self._socket.recv()

            message = validator_pb2.Message()
            message.ParseFromString(msg_bytes)

            LOGGER.debug("receiving %s message",
                         get_enum_name(message.message_type))
            try:
                self._futures.set_result(
                    message.correlation_id,
                    future.FutureResult(message_type=message.message_type,
                                        content=message.content))
            except future.FutureCollectionKeyError:
                if self._socket.getsockopt(zmq.TYPE) == zmq.ROUTER:
                    self._dispatcher.dispatch(identity, message)
                else:
                    LOGGER.info(
                        "received a first message on the zmq dealer.")
            else:
                my_future = self._futures.get(message.correlation_id)
                LOGGER.debug("message round "
                             "trip: %s %s",
                             get_enum_name(message.message_type),
                             my_future.get_duration())
                self._futures.remove(message.correlation_id)
Example #8
0
    def test_signature_thread(self):
        try:
            self.verifier.start()
            blocks = self._create_blocks(1, 1)
            message = GossipMessage(content_type="Block",
                                    content=blocks[0].SerializeToString())
            content = message.SerializeToString()
            msg = validator_pb2.Message(
                message_type=validator_pb2.Message.GOSSIP_MESSAGE,
                correlation_id=self._generate_id(),
                content=content)

            with self._in_condition:
                self._in.put_nowait(msg)
                self._in_condition.notify_all()

            to = TimeOut(2)
            while self._out.qsize() == 0:
                if to.is_timed_out():
                    break

            self.assertEqual(self._out.qsize(), 1)

        finally:
            with self._in_condition:
                self.verifier.stop()
                self._in_condition.notify_all()
Example #9
0
    def _receive_message(self):
        """
        Internal coroutine for receiving messages from the
        zmq processor DEALER interface
        """
        with self._condition:
            self._condition.wait_for(lambda: self._proc_sock is not None)
        while True:
            msg_bytes = yield from self._proc_sock.recv()
            LOGGER.debug("Client received message: %s", msg_bytes)
            message = validator_pb2.Message()
            message.ParseFromString(msg_bytes)
            try:
                self._futures.set_result(
                    message.correlation_id,
                    future.FutureResult(message_type=message.message_type,
                                        content=message.content))
            except future.FutureCollectionKeyError:
                # if we are getting an initial message, not a response
                if message.message_type in self._handlers:
                    handler = self._handlers[message.message_type]
                else:
                    handler = self._handlers[validator_pb2.Message.DEFAULT]

                handler.handle(message, _Responder(self.send_message))
                self._recv_queue.put_nowait(message)
            else:
                my_future = self._futures.get(message.correlation_id)
                LOGGER.debug("Message round "
                             "trip: %s", my_future.get_duration())
Example #10
0
    def _receive_message(self):
        """
        Internal coroutine for receiving messages from the
        zmq processor ROUTER interface
        """
        with self._condition:
            self._condition.wait_for(lambda: self._proc_sock is not None)
        while True:
            ident, result = yield from self._proc_sock.recv_multipart()
            LOGGER.debug("Server received message "
                         "from %s: %s", ident, result)
            message = validator_pb2.Message()
            message.ParseFromString(result)
            message.sender = ident
            try:
                # if there is a future, then we are getting a response
                self._futures.set_result(
                    message.correlation_id,
                    future.FutureResult(content=message.content,
                                        message_type=message.message_type))
            except future.FutureCollectionKeyError:
                # if there isn't a future, we are getting an initial message
                if message.message_type in self._handlers:
                    handler = self._handlers[message.message_type]
                else:
                    handler = self._handlers[validator_pb2.Message.DEFAULT]

                handler.handle(message, _Responder(self.send_message))
Example #11
0
    def _receive_message(self):
        """
        Internal coroutine for receiving messages
        """
        zmq_identity = None
        while True:
            try:
                if self._socket.getsockopt(zmq.TYPE) == zmq.ROUTER:
                    zmq_identity, msg_bytes = \
                        yield from self._socket.recv_multipart()
                    self._received_from_identity(zmq_identity)
                else:
                    msg_bytes = yield from self._socket.recv()
                    self._last_message_time = time.time()

                message = validator_pb2.Message()
                message.ParseFromString(msg_bytes)
                LOGGER.debug("%s receiving %s message: %s bytes",
                             self._connection,
                             get_enum_name(message.message_type),
                             sys.getsizeof(msg_bytes))

                tag = get_enum_name(message.message_type)
                self._get_received_message_counter(tag).inc()

                if zmq_identity is not None:
                    connection_id = \
                        self._identity_to_connection_id(zmq_identity)
                else:
                    connection_id = \
                        self._identity_to_connection_id(
                            self._connection.encode())
                try:
                    self._futures.set_result(
                        message.correlation_id,
                        future.FutureResult(message_type=message.message_type,
                                            content=message.content,
                                            connection_id=connection_id))
                except future.FutureCollectionKeyError:
                    self._dispatcher.dispatch(self._connection, message,
                                              connection_id)
                else:
                    my_future = self._futures.get(message.correlation_id)

                    LOGGER.debug("message round "
                                 "trip: %s %s",
                                 get_enum_name(message.message_type),
                                 my_future.get_duration())
                    my_future.timer_stop()

                    self._futures.remove(message.correlation_id)
            except CancelledError:
                # The concurrent.futures.CancelledError is caught by asyncio
                # when the Task associated with the coroutine is cancelled.
                # The raise is required to stop this component.
                raise
            except Exception as e:  # pylint: disable=broad-except
                LOGGER.exception(
                    "Received a message on address %s that "
                    "caused an error: %s", self._address, e)
Example #12
0
 def handle(self, message, responder):
     error = False
     current_root = None
     try:
         client_pb2.ClientStateCurrentRequest().ParseFromString(
             message.content)
         current_root = self._current_root_func()
     except DecodeError:
         LOGGER.info(
             "Expected protobuf of class %s failed to "
             "deserialize.", client_pb2.ClientStateCurrentRequest())
         error = True
     if error:
         response = client_pb2.ClientStateCurrentResponse(
             status=client_pb2.ClientStateCurrentResponse.ERROR)
     else:
         response = client_pb2.ClientStateCurrentResponse(
             status=client_pb2.ClientStateCurrentResponse.OK,
             merkle_root=current_root)
     responder.send(
         validator_pb2.Message(sender=message.sender,
                               message_type=validator_pb2.Message.
                               CLIENT_STATE_CURRENT_RESPONSE,
                               correlation_id=message.correlation_id,
                               content=response.SerializeToString()))
Example #13
0
    def send(self, message_type, data, connection_id, callback=None):
        """
        Send a message of message_type
        :param connection_id: the identity for the connection to send to
        :param message_type: validator_pb2.Message.* enum value
        :param data: bytes serialized protobuf
        :return: future.Future
        """
        if connection_id not in self._connections:
            raise ValueError("Unknown connection id: %s", connection_id)
        connection_info = self._connections.get(connection_id)
        if connection_info.connection_type == \
                ConnectionType.ZMQ_IDENTITY:
            message = validator_pb2.Message(correlation_id=_generate_id(),
                                            content=data,
                                            message_type=message_type)

            timer_tag = get_enum_name(message.message_type)
            timer_ctx = self._get_send_response_timer(timer_tag).time()
            fut = future.Future(message.correlation_id,
                                message.content,
                                callback,
                                timer_ctx=timer_ctx)

            self._futures.put(fut)

            self._send_receive_thread.send_message(msg=message,
                                                   connection_id=connection_id)
            return fut

        return connection_info.connection.send(message_type,
                                               data,
                                               callback=callback)
Example #14
0
    def handle(self, message, responder):
        self._network.load(message.content)

        responder.send(validator_pb2.Message(
            sender=message.sender,
            message_type="system/load-response",
            correlation_id=message.correlation_id,
            content="{ 'status': 'SUCCESS' }".encode()))
Example #15
0
    def _do_heartbeat(self):

        ping = PingRequest()

        while True:
            try:
                if self._socket.getsockopt(zmq.TYPE) == zmq.ROUTER:
                    expired = \
                        [ident for ident in self._last_message_times
                         if time.time() - self._last_message_times[ident] >
                         self._heartbeat_interval]
                    for zmq_identity in expired:
                        if self._is_connection_lost(
                                self._last_message_times[zmq_identity]):
                            LOGGER.debug(
                                "No response from %s in %s seconds"
                                " - removing connection.", zmq_identity,
                                self._connection_timeout)
                            self.remove_connected_identity(zmq_identity)
                        else:
                            message = validator_pb2.Message(
                                correlation_id=_generate_id(),
                                content=ping.SerializeToString(),
                                message_type=validator_pb2.Message.PING_REQUEST
                            )
                            fut = future.Future(
                                message.correlation_id,
                                message.content,
                            )
                            self._futures.put(fut)
                            message_frame = [
                                bytes(zmq_identity),
                                message.SerializeToString()
                            ]
                            yield from self._send_message_frame(message_frame)
                elif self._socket.getsockopt(zmq.TYPE) == zmq.DEALER:
                    if self._last_message_time and \
                            self._is_connection_lost(self._last_message_time):
                        LOGGER.debug(
                            "No response from %s in %s seconds"
                            " - removing connection.", self._connection,
                            self._connection_timeout)
                        connection_id = hashlib.sha512(
                            self.connection.encode()).hexdigest()
                        if connection_id in self._connections:
                            del self._connections[connection_id]
                        yield from self._stop()
                yield from asyncio.sleep(self._heartbeat_interval)
            except CancelledError:
                # The concurrent.futures.CancelledError is caught by asyncio
                # when the Task associated with the coroutine is cancelled.
                # The raise is required to stop this component.
                raise
            except Exception as e:  # pylint: disable=broad-except
                LOGGER.exception(
                    "An error occurred while sending heartbeat: %s", e)
Example #16
0
    def send(self, message_type, content):
        LOGGER.debug("Client sending %s: %s", message_type, content)
        message = validator_pb2.Message(message_type=message_type,
                                        correlation_id=_generate_id(),
                                        content=content)
        my_future = future.Future(message.correlation_id)
        self._futures.put(my_future)

        self._send_receive_thread.send_message(message)
        return my_future
Example #17
0
    def handle(self, message, responder):
        self._network.load(message.content)

        responder.send(validator_pb2.Message(
            sender=message.sender,
            message_type=validator_pb2.Message.CLIENT_BATCH_SUBMIT_RESPONSE,
            correlation_id=message.correlation_id,
            content=client_pb2.ClientBatchSubmitResponse(
                status=client_pb2.ClientBatchSubmitResponse.OK
            ).SerializeToString()))
Example #18
0
        def do_next(result):
            message_info = self._message_information[message_id]
            LOGGER.debug("do_next: result %s",str(result))
            try:
                # check for a None result
                if result is None:
                    LOGGER.error(
                        "%s preprocessor returned None result for messsage %s",
                        preprocessor,
                        message_id)
                    return
                LOGGER.debug("do_next: status %s",str(result.status))
                # check for result status
                if result.status == HandlerStatus.DROP:
                    del self._message_information[message_id]
                    return

                if result.status == HandlerStatus.RETURN:
                    del self._message_information[message_id]

                    message = validator_pb2.Message(
                        content=result.message_out.SerializeToString(),
                        correlation_id=message_info.correlation_id,
                        message_type=result.message_type)

                    try:
                        self._send_message[message_info.connection](
                            msg=message,
                            connection_id=message_info.connection_id)
                    except KeyError:
                        LOGGER.warning(
                            "Can't send message %s back to "
                            "%s because connection %s not in dispatcher",
                            get_enum_name(message.message_type),
                            message_info.connection_id,
                            message_info.connection)

                    return

                # store the preprocessor result
                self._message_information[message_id] = \
                    _MessageInformation(
                        connection=message_info.connection,
                        connection_id=message_info.connection_id,
                        content=result.content,
                        correlation_id=message_info.correlation_id,
                        collection=message_info.collection,
                        message_type=message_info.message_type)

                self._process_next(message_id)

            except Exception:  # pylint: disable=broad-except
                LOGGER.exception(
                    "Unhandled exception after preprocessing")
Example #19
0
    def setUp(self):
        self._dispatcher = dispatch.Dispatcher()
        thread_pool = ThreadPoolExecutor()

        self._dispatcher.add_handler(
            validator_pb2.Message.DEFAULT,
            MockHandler1(),
            thread_pool)
        self._dispatcher.add_handler(
            validator_pb2.Message.DEFAULT,
            MockHandler2(),
            thread_pool)

        self.mock_send_message = MockSendMessage()
        self._dispatcher.set_send_message(self.mock_send_message.send_message)

        self._message_ids = [str(i) for i in range(10)]
        self._identities = [str(i) for i in range(10)]
        self._messages = [validator_pb2.Message(content=validator_pb2.Message(correlation_id=m_id).SerializeToString(),
                                                message_type=validator_pb2.Message.DEFAULT)
                          for m_id in self._message_ids]
Example #20
0
    def _determine_next(self, message_id, future):
        if future.result().status == HandlerStatus.DROP:
            with self._condition:
                del self._message_information[message_id]

        elif future.result().status == HandlerStatus.PASS:
            self._process(message_id)

        elif future.result().status == HandlerStatus.RETURN_AND_PASS:
            with self._condition:
                ident, original_message, _ = self._message_information[
                    message_id]

            message = validator_pb2.Message(
                content=future.result().message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=future.result().message_type)

            self._send_message(msg=message,
                               identity=ident)
            self._process(message_id)

        elif future.result().status == HandlerStatus.RETURN:
            with self._condition:
                ident, original_message, _ = self._message_information[
                    message_id]

                del self._message_information[message_id]

            message = validator_pb2.Message(
                content=future.result().message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=future.result().message_type)

            self._send_message(msg=message,
                               identity=ident)
        with self._condition:
            if len(self._message_information) == 0:
                self._condition.notify()
Example #21
0
 def handle(self, message, responder):
     set_request = state_context_pb2.TpStateSetRequest()
     set_request.ParseFromString(message.content)
     set_values_list = [{e.address: e.data} for e in set_request.entries]
     return_value = self._context_manager.set(set_request.context_id,
                                              set_values_list)
     response = state_context_pb2.TpStateSetResponse()
     if return_value is True:
         address_list = [e.address for e in set_request.entries]
         response.addresses.extend(address_list)
         responder.send(message=validator_pb2.Message(
             sender=message.sender,
             correlation_id=message.correlation_id,
             message_type=Message.TP_STATE_SET_RESPONSE,
             content=response.SerializeToString()))
     else:
         response.addresses.extend([])
         responder.send(message=validator_pb2.Message(
             sender=message.sender,
             correlation_id=message.correlation_id,
             message_type=Message.TP_STATE_SET_RESPONSE,
             content=response.SerializeToString()))
Example #22
0
    def __init__(self, identity, endpoint, peer_list, dispatcher):
        LOGGER.debug("Initializing Network service")
        self._identity = identity
        self._dispatcher = dispatcher
        self._handlers = {}
        self._peered_with_us = {}
        self.inbound_queue = queue.Queue()
        self._futures = future.FutureCollection()
        self._send_receive_thread = _ServerSendReceiveThread(endpoint,
                                                             self._handlers,
                                                             self._futures)

        self._send_receive_thread.daemon = True
        self.add_handler('default', DefaultHandler())
        self.add_handler('gossip/register',
                         PeerRegisterHandler(self))
        self.add_handler('gossip/unregister',
                         PeerUnregisterHandler(self))
        self.add_handler('gossip/msg',
                         GossipMessageHandler(self))
        self.start()

        if peer_list is not None:
            for peer in peer_list:
                self._send_receive_thread.add_connection(self._identity, peer)

            LOGGER.info("Sleeping 5 seconds and then broadcasting messages "
                        "to connected peers")
            time.sleep(5)

            content = GossipMessage(content=bytes(
                str("This is a gossip payload"), 'UTF-8')).SerializeToString()

            for _ in range(1000):
                message = validator_pb2.Message(
                    message_type=b'gossip/msg',
                    correlation_id=_generate_id(),
                    content=content)

                self.broadcast_message(message)

                # If we transmit as fast as possible, we populate the
                # buffers and get faster throughput but worse avg. message
                # latency. If we sleep here or otherwise throttle input,
                # the overall duration is longer, but the per message
                # latency is low. The process is CPU bound on Vagrant VM
                # core at ~0.001-0.01 duration sleeps.
                time.sleep(0.01)
Example #23
0
    def _receive_message(self):
        """
        Internal coroutine for receiving messages
        """
        zmq_identity = None
        with self._condition:
            self._condition.wait_for(lambda: self._socket is not None)
        while True:
            if self._socket.getsockopt(zmq.TYPE) == zmq.ROUTER:
                zmq_identity, msg_bytes = \
                    yield from self._socket.recv_multipart()
                self._received_from_identity(zmq_identity)
            else:
                msg_bytes = yield from self._socket.recv()
                self._last_message_time = time.time()

            message = validator_pb2.Message()
            message.ParseFromString(msg_bytes)
            LOGGER.debug("%s receiving %s message: %s bytes",
                         self._connection,
                         get_enum_name(message.message_type),
                         sys.getsizeof(msg_bytes))

            try:
                self._futures.set_result(
                    message.correlation_id,
                    future.FutureResult(message_type=message.message_type,
                                        content=message.content))
            except future.FutureCollectionKeyError:
                if zmq_identity is not None:
                    connection_id = \
                        self._identity_to_connection_id(zmq_identity)
                else:
                    connection_id = \
                        self._identity_to_connection_id(
                            self._connection.encode())
                self._dispatcher.dispatch(self._connection,
                                          message,
                                          connection_id)
            else:
                my_future = self._futures.get(message.correlation_id)

                LOGGER.debug("message round "
                             "trip: %s %s",
                             get_enum_name(message.message_type),
                             my_future.get_duration())

                self._futures.remove(message.correlation_id)
Example #24
0
 def handle(self, message, responder):
     get_request = state_context_pb2.TpStateGetRequest()
     get_request.ParseFromString(message.content)
     return_values = self._context_manager.get(get_request.context_id,
                                               get_request.addresses)
     return_list = return_values if return_values is not None else []
     LOGGER.debug("GET: %s", return_list)
     entry_list = [
         state_context_pb2.Entry(address=a, data=d) for a, d in return_list
     ]
     responder.send(message=validator_pb2.Message(
         sender=message.sender,
         correlation_id=message.correlation_id,
         message_type=Message.TP_STATE_GET_RESPONSE,
         content=state_context_pb2.TpStateGetResponse(
             entries=entry_list).SerializeToString()))
Example #25
0
    def handle(self, message, peer):
        LOGGER.debug("PingHandler message: %s", message)
        request = PingRequest()
        request.ParseFromString(message.content)

        LOGGER.debug("Got ping message %s "
                     "from %s. sending ack", message.content, message.sender)

        ack = NetworkAcknowledgement()
        ack.status = ack.OK

        peer.send(
            validator_pb2.Message(sender=message.sender,
                                  message_type='gossip/ack',
                                  correlation_id=message.correlation_id,
                                  content=ack.SerializeToString()))
    def send(self, message_type, data):
        """
        Send a message of message_type
        :param message_type: validator_pb2.Message.* enum value
        :param data: bytes serialized protobuf
        :return: future.Future
        """
        message = validator_pb2.Message(correlation_id=_generate_id(),
                                        content=data,
                                        message_type=message_type)

        fut = future.Future(message.correlation_id, message.content)
        self._futures.put(fut)

        self._send_receive_thread.send_message(message)
        return fut
Example #27
0
    def handle(self, message, peer):
        LOGGER.debug("GossipMessageHandler message: %s", message.sender)

        LOGGER.debug("Got gossip message %s "
                     "from %s. sending ack", message.content, message.sender)

        self._ingest_message(message)

        ack = NetworkAcknowledgement()
        ack.status = ack.OK

        peer.send(
            validator_pb2.Message(
                sender=message.sender,
                message_type=validator_pb2.Message.GOSSIP_ACK,
                correlation_id=message.correlation_id,
                content=ack.SerializeToString()))
Example #28
0
    def handle(self, message, peer):
        request = PeerUnregisterRequest()
        request.ParseFromString(message.content)

        self._service.unregister_peer(message.sender, request.identity)

        LOGGER.debug("Got peer unregister message "
                     "from %s. Sending ack", message.sender)

        ack = NetworkAcknowledgement()
        ack.status = ack.OK

        peer.send(
            validator_pb2.Message(sender=message.sender,
                                  message_type='gossip/ack',
                                  correlation_id=message.correlation_id,
                                  content=ack.SerializeToString()))
Example #29
0
    def send_message(self, data):
        if isinstance(data, str):
            msg = GossipMessage(content_type="BlockRequest",
                                content=data.encode("utf-8"))
        elif isinstance(data, block_pb2.Block):
            msg = GossipMessage(content_type="Block",
                                content=data.SerializeToString())
        elif isinstance(data, batch_pb2.Batch):
            msg = GossipMessage(content_type="Batch",
                                content=data.SerializeToString())

        content = msg.SerializeToString()
        message = validator_pb2.Message(
            message_type=validator_pb2.Message.GOSSIP_MESSAGE,
            correlation_id=_generate_id(),
            content=content)

        self._put_on_inbound(message)
Example #30
0
    def _receive_message(self):
        """
        Internal coroutine for receiving messages
        """
        with self._condition:
            self._condition.wait_for(lambda: self._socket is not None)
        while True:
            if self._socket.getsockopt(zmq.TYPE) == zmq.ROUTER:
                identity, msg_bytes = yield from self._socket.recv_multipart()
            else:
                msg_bytes = yield from self._socket.recv()

            message = validator_pb2.Message()
            message.ParseFromString(msg_bytes)

            LOGGER.debug("%s receiving %s message: %s bytes",
                         self._connection,
                         get_enum_name(message.message_type),
                         sys.getsizeof(msg_bytes))

            try:
                self._futures.set_result(
                    message.correlation_id,
                    future.FutureResult(message_type=message.message_type,
                                        content=message.content))
            except future.FutureCollectionKeyError:
                if self._socket.getsockopt(zmq.TYPE) == zmq.ROUTER:
                    self._dispatcher.dispatch(self._connection,
                                              message,
                                              identity=identity)
                else:
                    # Because this is a zmq.DEALER socket, there is no
                    # outbound identity
                    self._dispatcher.dispatch(self._connection,
                                              message)
            else:
                my_future = self._futures.get(message.correlation_id)

                LOGGER.debug("message round "
                             "trip: %s %s",
                             get_enum_name(message.message_type),
                             my_future.get_duration())

                self._futures.remove(message.correlation_id)