Exemplo n.º 1
0
    def test_batch_by_id_responder_handler(self):
        """
        Test that the BatchByBatchIdResponderHandler correctly broadcasts a
        received request that the Responder cannot respond to, or sends a
        GossipBatchResponse back to the connection_id the handler received
        the request from.
        """
        # The completer does not have the requested batch
        message = network_pb2.GossipBatchByBatchIdRequest(
            id="abc",
            nonce="1")
        self.batch_request_handler.handle(
            "Connection_1", message.SerializeToString())
        # If we cannot respond to the request broadcast batch request and add
        # to pending request
        self.assert_message_was_broadcasted(
            message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST)
        self.assert_request_pending(
            requested_id="abc", connection_id="Connection_1")
        self.assert_message_not_sent(connection_id="Connection_1")

        # Add the batch to the completer and resend the BatchByBatchIdRequest
        message = network_pb2.GossipBatchByBatchIdRequest(
            id="abc",
            nonce="2")
        batch = batch_pb2.Batch(header_signature="abc")
        self.completer.add_batch(batch)
        self.batch_request_handler.handle(
            "Connection_1", message.SerializeToString())

        # Check that the a Batch Response was sent back to "Connection_1"
        self.assert_message_sent(
            connection_id="Connection_1",
            message_type=validator_pb2.Message.GOSSIP_BATCH_RESPONSE
            )
Exemplo n.º 2
0
    def do_batch_by_id_responder_handler():
        before_message = network_pb2.GossipBatchByBatchIdRequest(
            id="abc", nonce="1", time_to_live=1)

        after_message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                                nonce="1",
                                                                time_to_live=0)

        testResponder.batch_request_handler.handle(
            "Connection_1", before_message.SerializeToString())
        # If we cannot respond to the request broadcast batch request and add
        # to pending request
        testResponder.assert_message_was_broadcasted(
            after_message,
            validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST)
        testResponder.assert_request_pending(requested_id="abc",
                                             connection_id="Connection_1")
        testResponder.assert_message_not_sent(connection_id="Connection_1")

        # Add the batch to the completer and resend the BatchByBatchIdRequest
        message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                          nonce="2",
                                                          time_to_live=1)
        batch = batch_pb2.Batch(header_signature="abc")
        testResponder.completer.add_batch(batch)
        testResponder.batch_request_handler.handle("Connection_1",
                                                   message.SerializeToString())

        # Check that the a Batch Response was sent back to "Connection_1"
        testResponder.assert_message_sent(
            connection_id="Connection_1",
            message_type=validator_pb2.Message.GOSSIP_BATCH_RESPONSE)
Exemplo n.º 3
0
def test_batch_by_id_responder_handler_requested():
    """
    Test that the BatchByBatchIdResponderHandler correctly broadcasts
    a received request that the Responder cannot respond to, and does not
    rebroadcast the same request again.  If we have already recieved the
    request, do nothing.
    """
    # The completer does not have the requested batch
    testResponder = TestResponder()

    before_message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                             nonce="1",
                                                             time_to_live=1)

    after_message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                            nonce="1",
                                                            time_to_live=0)
    testResponder.batch_request_handler.handle(
        "Connection_1", before_message.SerializeToString())
    # If we cannot respond to the request broadcast batch request and add
    # to pending request

    testResponder.gossip.clear()

    # Message should be dropped since the same message has already been
    # handled
    testResponder.batch_request_handler.handle(
        "Connection_2", before_message.SerializeToString())

    message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                      nonce="2",
                                                      time_to_live=1)

    testResponder.batch_request_handler.handle("Connection_2",
                                               message.SerializeToString())
Exemplo n.º 4
0
def test_batch_by_id_responder_handler():
    """
    Test that the BatchByBatchIdResponderHandler correctly broadcasts a
    received request that the Responder cannot respond to, or sends a
    GossipBatchResponse back to the connection_id the handler received
    the request from.
    """
    # The completer does not have the requested batch
    testResponder = TestResponder()

    before_message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                             nonce="1",
                                                             time_to_live=1)

    after_message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                            nonce="1",
                                                            time_to_live=0)

    testResponder.batch_request_handler.handle(
        "Connection_1", before_message.SerializeToString())
    # Add the batch to the completer and resend the BatchByBatchIdRequest
    message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                      nonce="2",
                                                      time_to_live=1)
    batch = batch_pb2.Batch(header_signature="abc")
    testResponder.completer.add_batch(batch)
    testResponder.batch_request_handler.handle("Connection_1",
                                               message.SerializeToString())
Exemplo n.º 5
0
    def test_batch_by_id_responder_handler_requested(self):
        """
        Test that the BatchByBatchIdResponderHandler correctly broadcasts
        a received request that the Responder cannot respond to, and does not
        rebroadcast the same request again.  If we have already recieved the
        request, do nothing.
        """
        # The completer does not have the requested batch
        before_message = network_pb2.GossipBatchByBatchIdRequest(
            id="abc", nonce="1", time_to_live=1)

        after_message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                                nonce="1",
                                                                time_to_live=0)
        self.batch_request_handler.handle("Connection_1",
                                          before_message.SerializeToString())
        # If we cannot respond to the request broadcast batch request and add
        # to pending request
        self.assert_message_was_broadcasted(
            after_message,
            validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST)
        self.assert_request_pending(requested_id="abc",
                                    connection_id="Connection_1")
        self.assert_message_not_sent(connection_id="Connection_1")

        self.gossip.clear()

        # Message should be dropped since the same message has already been
        # handled
        self.batch_request_handler.handle("Connection_2",
                                          before_message.SerializeToString())

        self.assert_message_was_not_broadcasted(
            before_message,
            validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST)

        self.assert_request_not_pending(requested_id="abc",
                                        connection_id="Connection_2")

        message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                          nonce="2",
                                                          time_to_live=1)

        self.batch_request_handler.handle("Connection_2",
                                          message.SerializeToString())

        self.assert_message_was_not_broadcasted(
            message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST)

        self.assert_request_pending(requested_id="abc",
                                    connection_id="Connection_2")
        self.assert_message_not_sent(connection_id="Connection_2")
Exemplo n.º 6
0
    def handle(self, connection_id, message_content):
        batch_request_message = network_pb2.GossipBatchByBatchIdRequest()
        batch_request_message.ParseFromString(message_content)
        batch = None
        batch = self._responder.check_for_batch(batch_request_message.id)
        node_id = batch_request_message.node_id

        if batch is None:
            # No batch found, broadcast original message to other peers
            # and add to pending requests
            self._responder.add_request(batch_request_message.id,
                                        connection_id)
            self._gossip.broadcast(
                batch_request_message,
                validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST,
                exclude=[connection_id])
        else:
            LOGGER.debug("Responding to batch requests %s",
                         batch.header_signature)

            batch_response = network_pb2.GossipBatchResponse(
                content=batch.SerializeToString(), node_id=node_id)

            self._gossip.send(validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
                              batch_response.SerializeToString(),
                              connection_id)

        return HandlerResult(status=HandlerStatus.PASS)
Exemplo n.º 7
0
def test_responder_batch_response_handler():
    """
    Test that the ResponderBatchResponseHandler, after receiving a Batch
    Response, checks to see if the responder has any pending request for
    that batch and forwards the response on to the connection_id that
    had requested it.
    """
    # The Responder does not have any pending requests for block "ABC"

    testResponder = TestResponder()

    batch = batch_pb2.Batch(header_signature="abc")

    response_message = network_pb2.GossipBatchResponse(
        content=batch.SerializeToString())

    testResponder.batch_response_handler.handle(
        "Connection_1", (batch, response_message.SerializeToString()))

    # request queue.
    request_message = \
        network_pb2.GossipBatchByBatchIdRequest(id="abc", time_to_live=1)

    testResponder.batch_request_handler.handle(
        "Connection_2", request_message.SerializeToString())

    # Handle the the BatchResponse Message. Since Connection_2 had
    # requested the batch but it could not be fulfilled at that time of the
    # request the received BatchResponse is forwarded to Connection_2
    testResponder.batch_response_handler.handle(
        "Connection_1", (batch, response_message.SerializeToString()))
Exemplo n.º 8
0
    def do_batch_by_id_responder_handler_requested():
        before_message = network_pb2.GossipBatchByBatchIdRequest(
            id="abc", nonce="1", time_to_live=1)

        after_message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                                nonce="1",
                                                                time_to_live=0)
        testResponder.batch_request_handler.handle(
            "Connection_1", before_message.SerializeToString())
        # If we cannot respond to the request broadcast batch request and add
        # to pending request
        testResponder.assert_message_was_broadcasted(
            after_message,
            validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST)
        testResponder.assert_request_pending(requested_id="abc",
                                             connection_id="Connection_1")
        testResponder.assert_message_not_sent(connection_id="Connection_1")

        testResponder.gossip.clear()

        # Message should be dropped since the same message has already been
        # handled
        testResponder.batch_request_handler.handle(
            "Connection_2", before_message.SerializeToString())

        testResponder.assert_message_was_not_broadcasted(
            before_message,
            validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST)

        testResponder.assert_request_not_pending(requested_id="abc",
                                                 connection_id="Connection_2")

        message = network_pb2.GossipBatchByBatchIdRequest(id="abc",
                                                          nonce="2",
                                                          time_to_live=1)

        testResponder.batch_request_handler.handle("Connection_2",
                                                   message.SerializeToString())

        testResponder.assert_message_was_not_broadcasted(
            message, validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST)

        testResponder.assert_request_pending(requested_id="abc",
                                             connection_id="Connection_2")
        testResponder.assert_message_not_sent(connection_id="Connection_2")
Exemplo n.º 9
0
    def handle(self, connection_id, message_content):
        batch_request_message = network_pb2.GossipBatchByBatchIdRequest()
        batch_request_message.ParseFromString(message_content)
        if batch_request_message.nonce in self._seen_requests:
            LOGGER.debug("Received repeat GossipBatchByBatchIdRequest from %s",
                         connection_id)
            ack = network_pb2.NetworkAcknowledgement()
            ack.status = ack.OK

            return HandlerResult(
                HandlerStatus.RETURN,
                message_out=ack,
                message_type=validator_pb2.Message.NETWORK_ACK)

        self._seen_requests[batch_request_message.nonce] = \
            batch_request_message.id

        batch = None
        batch = self._responder.check_for_batch(batch_request_message.id)
        node_id = batch_request_message.node_id

        if batch is None:
            # No batch found, broadcast original message to other peers
            # and add to pending requests
            if not self._responder.already_requested(batch_request_message.id):
                self._gossip.broadcast(
                    batch_request_message,
                    validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST,
                    exclude=[connection_id])
            else:
                LOGGER.debug("Batch %s has already been requested",
                             batch_request_message.id)

            self._responder.add_request(batch_request_message.id,
                                        connection_id)
        else:
            LOGGER.debug("Responding to batch requests %s",
                         batch.header_signature)

            batch_response = network_pb2.GossipBatchResponse(
                content=batch.SerializeToString(), node_id=node_id)

            self._gossip.send(validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
                              batch_response.SerializeToString(),
                              connection_id)

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

        return HandlerResult(HandlerStatus.RETURN,
                             message_out=ack,
                             message_type=validator_pb2.Message.NETWORK_ACK)
Exemplo n.º 10
0
    def handle(self, connection_id, message_content):
        batch_request_message = network_pb2.GossipBatchByBatchIdRequest()
        batch_request_message.ParseFromString(message_content)
        if batch_request_message.nonce in self._seen_requests:
            LOGGER.debug("Received repeat GossipBatchByBatchIdRequest from %s",
                         connection_id)
            return HandlerResult(HandlerStatus.DROP)

        batch = None
        batch = self._responder.check_for_batch(batch_request_message.id)

        if batch is None:
            # No batch found, broadcast original message to other peers
            # and add to pending requests
            if not self._responder.already_requested(batch_request_message.id):

                if batch_request_message.time_to_live > 0:
                    time_to_live = batch_request_message.time_to_live
                    batch_request_message.time_to_live = time_to_live - 1
                    self._gossip.broadcast(
                        batch_request_message,
                        validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST,
                        exclude=[connection_id])

                    self._seen_requests[batch_request_message.nonce] = \
                        batch_request_message.id

                    self._responder.add_request(batch_request_message.id,
                                                connection_id)
            else:
                LOGGER.debug("Batch %s has already been requested",
                             batch_request_message.id)

                self._responder.add_request(batch_request_message.id,
                                            connection_id)
        else:
            LOGGER.debug("Responding to batch requests %s",
                         batch.header_signature)

            batch_response = network_pb2.GossipBatchResponse(
                content=batch.SerializeToString(), )

            self._gossip.send(validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
                              batch_response.SerializeToString(),
                              connection_id)

        return HandlerResult(HandlerStatus.PASS)
Exemplo n.º 11
0
    def handle(self, connection_id, message_content):
        gossip_message = network_pb2.GossipBatchByBatchIdRequest()
        gossip_message.ParseFromString(message_content)
        batch = None
        batch = self._responder.check_for_batch(gossip_message.id)

        if batch is None:
            self._gossip.broadcast(
                gossip_message,
                validator_pb2.Message.GOSSIP_BATCH_BY_BATCH_ID_REQUEST)

        else:
            LOGGER.debug("Responding to batch requests %s",
                         batch.header_signature)
            self._gossip.broadcast_batch(batch)

        return HandlerResult(status=HandlerStatus.PASS)
Exemplo n.º 12
0
    def test_responder_batch_response_handler(self):
        """
        Test that the ResponderBatchResponseHandler, after receiving a Batch
        Response, checks to see if the responder has any pending request for
        that batch and forwards the response on to the connection_id that
        had requested it.
        """
        # The Responder does not have any pending requests for block "ABC"
        batch = batch_pb2.Batch(header_signature="abc")

        response_message = network_pb2.GossipBatchResponse(
            content=batch.SerializeToString())

        self.batch_response_handler.handle(
            "Connection_1", response_message.SerializeToString())

        # ResponderBlockResponseHandler should not send any messages.
        self.assert_message_not_sent("Connection_1")
        self.assert_request_not_pending(requested_id="abc")

        # Handle a request message for batch "abc". This adds it to the pending
        # request queue.
        request_message = \
            network_pb2.GossipBatchByBatchIdRequest(id="abc")

        self.batch_request_handler.handle(
            "Connection_2", request_message.SerializeToString())

        self.assert_request_pending(
            requested_id="abc", connection_id="Connection_2")

        # Handle the the BatchResponse Message. Since Connection_2 had
        # requested the batch but it could not be fulfilled at that time of the
        # request the received BatchResponse is forwarded to Connection_2
        self.batch_response_handler.handle(
            "Connection_1", response_message.SerializeToString())

        self.assert_message_sent(
            connection_id="Connection_2",
            message_type=validator_pb2.Message.GOSSIP_BATCH_RESPONSE
            )
        # The request for batch "abc" from "Connection_2" is no longer pending
        # it should be removed from the pending request cache.
        self.assert_request_not_pending(requested_id="abc")
Exemplo n.º 13
0
    def do_responder_batch_response_handler():

        batch = batch_pb2.Batch(header_signature="abc")

        response_message = network_pb2.GossipBatchResponse(
            content=batch.SerializeToString())

        testResponder.batch_response_handler.handle(
            "Connection_1", (batch, response_message.SerializeToString()))

        # ResponderBlockResponseHandler should not send any messages.
        testResponder.assert_message_not_sent("Connection_1")
        testResponder.assert_request_not_pending(requested_id="abc")

        # Handle a request message for batch "abc". This adds it to the pending
        # request queue.
        request_message = \
            network_pb2.GossipBatchByBatchIdRequest(id="abc", time_to_live=1)

        testResponder.batch_request_handler.handle(
            "Connection_2", request_message.SerializeToString())

        testResponder.assert_request_pending(requested_id="abc",
                                             connection_id="Connection_2")

        # Handle the the BatchResponse Message. Since Connection_2 had
        # requested the batch but it could not be fulfilled at that time of the
        # request the received BatchResponse is forwarded to Connection_2
        testResponder.batch_response_handler.handle(
            "Connection_1", (batch, response_message.SerializeToString()))

        testResponder.assert_message_sent(
            connection_id="Connection_2",
            message_type=validator_pb2.Message.GOSSIP_BATCH_RESPONSE)
        # The request for batch "abc" from "Connection_2" is no longer pending
        # it should be removed from the pending request cache.
        testResponder.assert_request_not_pending(requested_id="abc")