예제 #1
0
    def do_responder_batch_response_txn_handler():
        transaction = transaction_pb2.Transaction(header_signature="123")
        batch = batch_pb2.Batch(header_signature="abc",
                                transactions=[transaction])

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

        request_message = \
            network_pb2.GossipBatchByTransactionIdRequest(
                ids=["123"],
                time_to_live=1)

        # Send BatchByTransaciontIdRequest for txn "123" and add it to the
        # pending request cache
        testResponder.batch_request_handler.handle(
            "Connection_2", request_message.SerializeToString())

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

        # Send Batch Response that contains the batch that has txn "123"
        testResponder.batch_response_handler.handle(
            "Connection_1", (batch, response_message.SerializeToString()))

        # Handle the the BatchResponse Message. Since Connection_2 had
        # requested the txn_id in the batch but it could not be fulfilled at
        # that time of the request the received BatchResponse is forwarded to
        # Connection_2
        testResponder.assert_message_sent(
            connection_id="Connection_2",
            message_type=validator_pb2.Message.GOSSIP_BATCH_RESPONSE)
        # The request for transaction_id "123" from "Connection_2" is no
        # longer pending it should be removed from the pending request cache.
        testResponder.assert_request_not_pending(requested_id="123")
예제 #2
0
    def handle(self, connection_id, message_content):
        batch_response = network_pb2.GossipBatchResponse()
        batch_response.ParseFromString(message_content)
        batch = batch_pb2.Batch()
        batch.ParseFromString(batch_response.content)
        open_request = self._responder.get_request(batch.header_signature)

        if open_request is None:
            open_request = []

        requests_to_remove = [batch.header_signature]
        for txn in batch.transactions:
            requests_by_txn = self._responder.get_request(txn.header_signature)
            if requests_by_txn is not None:
                open_request += requests_by_txn
                requests_to_remove += [txn.header_signature]

        for connection in open_request:
            LOGGER.debug("Responding to batch requests: Send %s to %s",
                         batch.header_signature, connection)
            try:
                self._gossip.send(validator_pb2.Message.GOSSIP_BATCH_RESPONSE,
                                  message_content, connection)
            except ValueError:
                LOGGER.debug(
                    "Can't send batch response %s to closed "
                    "connection %s", batch.header_signature, connection)

        for requested_id in requests_to_remove:
            self._responder.remove_request(requested_id)

        return HandlerResult(HandlerStatus.PASS)
예제 #3
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)
예제 #4
0
def test_responder_batch_response_txn_handler():
    """
    Test that the ResponderBatchResponseHandler, after receiving a Batch
    Response, checks to see if the responder has any pending request for
    that transactions in the batch and forwards the response on to the
    connection_id that had them.
    """

    testResponder = TestResponder()

    transaction = transaction_pb2.Transaction(header_signature="123")
    batch = batch_pb2.Batch(header_signature="abc", transactions=[transaction])

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

    request_message = \
        network_pb2.GossipBatchByTransactionIdRequest(
            ids=["123"],
            time_to_live=1)

    # Send BatchByTransaciontIdRequest for txn "123" and add it to the
    # pending request cache
    testResponder.batch_request_handler.handle(
        "Connection_2", request_message.SerializeToString())

    # Send Batch Response that contains the batch that has txn "123"
    testResponder.batch_response_handler.handle(
        "Connection_1", (batch, response_message.SerializeToString()))
예제 #5
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()))
예제 #6
0
    def handle(self, connection_id, message_content):
        batch_response_message = network_pb2.GossipBatchResponse()
        batch_response_message.ParseFromString(message_content)

        batch = Batch()
        batch.ParseFromString(batch_response_message.content)
        self._completer.add_batch(batch)

        return HandlerResult(status=HandlerStatus.PASS)
예제 #7
0
    def handle(self, connection_id, message_content):
        batch_request_message = network_pb2.GossipBatchByTransactionIdRequest()
        batch_request_message.ParseFromString(message_content)
        node_id = batch_request_message.node_id
        batch = None
        batches = []
        unfound_txn_ids = []
        for txn_id in batch_request_message.ids:
            batch = self._responder.check_for_batch_by_transaction(
                txn_id)

            # The txn_id was not found.
            if batch is None:
                unfound_txn_ids.append(txn_id)

            # Check to see if a previous txn was in the same batch.
            elif batch not in batches:
                batches.append(batch)

            batch = None

        if batches == []:
            for txn_id in batch_request_message.ids:
                self._responder.add_request(txn_id, connection_id)
            self._gossip.broadcast(
                batch_request_message,
                validator_pb2.Message.
                GOSSIP_BATCH_BY_TRANSACTION_ID_REQUEST,
                exclude=[connection_id])

        elif unfound_txn_ids != []:
            new_request = network_pb2.GossipBatchByTransactionIdRequest()
            new_request.ids.extend(unfound_txn_ids)
            new_request.node_id = batch_request_message.node_id
            for txn_id in unfound_txn_ids:
                self._responder.add_request(txn_id, connection_id)
            self._gossip.broadcast(
                new_request,
                validator_pb2.Message.
                GOSSIP_BATCH_BY_TRANSACTION_ID_REQUEST,
                exclude=[connection_id])

        if batches != []:
            for batch in batches:
                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)
예제 #8
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)
예제 #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)
            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)
예제 #10
0
파일: tests.py 프로젝트: patricknieves/seth
    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")
예제 #11
0
파일: tests.py 프로젝트: patricknieves/seth
    def test_responder_batch_response_txn_handler(self):
        """
        Test that the ResponderBatchResponseHandler, after receiving a Batch
        Response, checks to see if the responder has any pending request for
        that transactions in the batch and forwards the response on to the
        connection_id that had them.
        """
        transaction = transaction_pb2.Transaction(header_signature="123")
        batch = batch_pb2.Batch(
            header_signature="abc", transactions=[transaction])

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

        request_message = \
            network_pb2.GossipBatchByTransactionIdRequest(
                ids=["123"])

        # Send BatchByTransaciontIdRequest for txn "123" and add it to the
        # pending request cache
        self.batch_request_handler.handle(
            "Connection_2", request_message.SerializeToString())

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

        # Send Batch Response that contains the batch that has txn "123"
        self.batch_response_handler.handle(
            "Connection_1", response_message.SerializeToString())

        # Handle the the BatchResponse Message. Since Connection_2 had
        # requested the txn_id in the batch but it could not be fulfilled at
        # that time of the request the received BatchResponse is forwarded to
        # Connection_2
        self.assert_message_sent(
            connection_id="Connection_2",
            message_type=validator_pb2.Message.GOSSIP_BATCH_RESPONSE
            )
        # The request for transaction_id "123" from "Connection_2" is no
        # longer pending it should be removed from the pending request cache.
        self.assert_request_not_pending(requested_id="123")
예제 #12
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")
예제 #13
0
    def handle(self, connection_id, message_content):
        batch_request_message = network_pb2.GossipBatchByTransactionIdRequest()
        batch_request_message.ParseFromString(message_content)
        if batch_request_message.nonce in self._seen_requests:
            LOGGER.debug(
                "Received repeat GossipBatchByTransactionIdRequest"
                " from %s", connection_id)

            return HandlerResult(HandlerStatus.DROP)

        batch = None
        batches = []
        unfound_txn_ids = []
        not_requested = []
        for txn_id in batch_request_message.ids:
            batch = self._responder.check_for_batch_by_transaction(txn_id)

            # The txn_id was not found.
            if batch is None:
                unfound_txn_ids.append(txn_id)
                if not self._responder.already_requested(txn_id):
                    not_requested.append(txn_id)
                else:
                    LOGGER.debug(
                        "Batch containing Transaction %s has already "
                        "been requested", txn_id)

            # Check to see if a previous txn was in the same batch.
            elif batch not in batches:
                batches.append(batch)

            batch = None

        if batches == [] and len(not_requested) == \
                len(batch_request_message.ids):

            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_TRANSACTION_ID_REQUEST,
                                       exclude=[connection_id])

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

                for txn_id in batch_request_message.ids:
                    self._responder.add_request(txn_id, connection_id)

        elif unfound_txn_ids != []:
            if not_requested != []:
                if batch_request_message.time_to_live > 0:
                    self._seen_requests[batch_request_message.nonce] = \
                        batch_request_message.ids
                    new_request = \
                        network_pb2.GossipBatchByTransactionIdRequest()
                    # only request batches we have not requested already
                    new_request.ids.extend(not_requested)
                    # Keep same nonce as original message
                    new_request.nonce = batch_request_message.nonce
                    time_to_live = batch_request_message.time_to_live
                    new_request.time_to_live = time_to_live - 1

                    self._gossip.broadcast(
                        new_request,
                        validator_pb2.Message.
                        GOSSIP_BATCH_BY_TRANSACTION_ID_REQUEST,
                        exclude=[connection_id])
                    # Add all requests to responder
                    for txn_id in unfound_txn_ids:
                        self._responder.add_request(txn_id, connection_id)
            else:
                # Add all requests to responder
                for txn_id in unfound_txn_ids:
                    self._responder.add_request(txn_id, connection_id)

        if batches != []:
            for batch in batches:
                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)