示例#1
0
    def handle(self, connection_id, message_content):
        block_response = network_pb2.GossipBlockResponse()
        block_response.ParseFromString(message_content)
        block = block_pb2.Block()
        block.ParseFromString(block_response.content)
        open_request = self._responder.get_request(block.header_signature)

        if open_request is None:
            return HandlerResult(status=HandlerStatus.PASS)

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

        self._responder.remove_request(block.header_signature)
        ack = network_pb2.NetworkAcknowledgement()
        ack.status = ack.OK

        return HandlerResult(HandlerStatus.RETURN,
                             message_out=ack,
                             message_type=validator_pb2.Message.NETWORK_ACK)
示例#2
0
    def do_block_responder_handler():
        before_message = network_pb2.GossipBlockRequest(block_id="ABC",
                                                        nonce="1",
                                                        time_to_live=1)

        after_message = network_pb2.GossipBlockRequest(block_id="ABC",
                                                       nonce="1",
                                                       time_to_live=0)

        testResponder.block_request_handler.handle(
            "Connection_1", before_message.SerializeToString())
        # If we cannot respond to the request, broadcast the block request
        # and add to pending request
        testResponder.assert_message_was_broadcasted(
            after_message, validator_pb2.Message.GOSSIP_BLOCK_REQUEST)

        testResponder.assert_request_pending(requested_id="ABC",
                                             connection_id="Connection_1")
        testResponder.assert_message_not_sent(connection_id="Connection_1")

        # Add the block to the completer and resend the Block Request
        block = block_pb2.Block(header_signature="ABC")
        testResponder.completer.add_block(block)

        message = network_pb2.GossipBlockRequest(block_id="ABC",
                                                 nonce="2",
                                                 time_to_live=1)

        testResponder.block_request_handler.handle("Connection_1",
                                                   message.SerializeToString())

        # Check that the a Block Response was sent back to "Connection_1"
        testResponder.assert_message_sent(
            connection_id="Connection_1",
            message_type=validator_pb2.Message.GOSSIP_BLOCK_RESPONSE)
示例#3
0
    def test_block_responder_handler(self):
        """
        Test that the BlockResponderHandler correctly broadcasts a received
        request that the Responder cannot respond to, or sends a
        GossipBlockResponse back to the connection_id the handler received
        the request from.
        """
        # The completer does not have the requested block
        message = network_pb2.GossipBlockRequest(block_id="ABC", node_id=b"1")
        self.block_request_handler.handle("Connection_1",
                                          message.SerializeToString())
        # If we cannot respond to the request, broadcast the block request
        # and add to pending request
        self.assert_message_was_broadcasted(
            message, validator_pb2.Message.GOSSIP_BLOCK_REQUEST)

        self.assert_request_pending(requested_id="ABC",
                                    connection_id="Connection_1")
        self.assert_message_not_sent(connection_id="Connection_1")

        # Add the block to the completer and resend the Block Request
        block = block_pb2.Block(header_signature="ABC")
        self.completer.add_block(block)
        self.block_request_handler.handle("Connection_1",
                                          message.SerializeToString())

        # Check that the a Block Response was sent back to "Connection_1"
        self.assert_message_sent(
            connection_id="Connection_1",
            message_type=validator_pb2.Message.GOSSIP_BLOCK_RESPONSE)
示例#4
0
def test_block_responder_handler():
    """
    Test that the BlockResponderHandler correctly broadcasts a received
    request that the Responder cannot respond to, or sends a
    GossipBlockResponse back to the connection_id the handler received
    the request from.
    """
    # The completer does not have the requested block

    testResponder = TestResponder()

    before_message = network_pb2.GossipBlockRequest(block_id="ABC",
                                                    nonce="1",
                                                    time_to_live=1)

    after_message = network_pb2.GossipBlockRequest(block_id="ABC",
                                                   nonce="1",
                                                   time_to_live=0)

    testResponder.block_request_handler.handle(
        "Connection_1", before_message.SerializeToString())
    # If we cannot respond to the request, broadcast the block request
    # and add to pending request
    # Add the block to the completer and resend the Block Request
    block = block_pb2.Block(header_signature="ABC")
    testResponder.completer.add_block(block)

    message = network_pb2.GossipBlockRequest(block_id="ABC",
                                             nonce="2",
                                             time_to_live=1)

    testResponder.block_request_handler.handle("Connection_1",
                                               message.SerializeToString())
示例#5
0
def test_responder_block_response_handler():
    """
    Test that the ResponderBlockResponseHandler, after receiving a Block
    Response, checks to see if the responder has any pending request for
    that response 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()

    block = block_pb2.Block(header_signature="ABC")
    response_message = network_pb2.GossipBlockResponse(
        content=block.SerializeToString())

    testResponder.block_response_handler.handle(
        "Connection_1", (block, response_message.SerializeToString()))

    # ResponderBlockResponseHandler should not send any messages.
    # Handle a request message for block "ABC". This adds it to the pending
    # request queue.
    request_message = \
        network_pb2.GossipBlockRequest(block_id="ABC", time_to_live=1)

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

    # Handle the the BlockResponse Message. Since Connection_2 had
    # requested the block but it could not be fulfilled at that time of the
    # request the received BlockResponse is forwarded to Connection_2
    testResponder.block_response_handler.handle(
        "Connection_1", (block, response_message.SerializeToString()))
示例#6
0
def create_block():
    block_header = block_pb2.BlockHeader(block_num=85,
                                         state_root_hash="0987654321fedcba",
                                         previous_block_id="0000000000000000")
    block = BlockWrapper(
        block_pb2.Block(header_signature="abcdef1234567890",
                        header=block_header.SerializeToString()))
    return block
示例#7
0
def _build_block(block_num, block_id, previous_block_id):
    header = block_pb2.BlockHeader(
        block_num=block_num,
        previous_block_id=previous_block_id)

    return block_pb2.Block(
        header_signature=block_id,
        header=header.SerializeToString())
示例#8
0
def create_block(block_num=85,
                 previous_block_id="0000000000000000",
                 block_id="abcdef1234567890",
                 batches=None):
    if batches is None:
        batches = []
    block_header = block_pb2.BlockHeader(block_num=block_num,
                                         state_root_hash="0987654321fedcba",
                                         previous_block_id=previous_block_id)
    block = BlockWrapper(
        block_pb2.Block(header_signature=block_id,
                        header=block_header.SerializeToString(),
                        batches=batches))
    return block
示例#9
0
    def handle(self, connection_id, message_content):
        block_response = network_pb2.GossipBlockResponse()
        block_response.ParseFromString(message_content)
        block = block_pb2.Block()
        block.ParseFromString(block_response.content)
        open_request = self._responder.get_request(block.header_signature)

        if open_request is None:
            return HandlerResult(status=HandlerStatus.PASS)

        for connection in open_request:
            LOGGER.debug("Responding to block request: Send %s to %s",
                         block.header_signature, connection)
            self._gossip.send(validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
                              message_content, connection)

        self._responder.remove_request(block.header_signature)
        self._responder.purge_requests()
        return HandlerResult(status=HandlerStatus.PASS)
示例#10
0
    def test_responder_block_response_handler(self):
        """
        Test that the ResponderBlockResponseHandler, after receiving a Block
        Response, checks to see if the responder has any pending request for
        that response and forwards the response on to the connection_id that
        had requested it.
        """
        # The Responder does not have any pending requests for block "ABC"
        block = block_pb2.Block(header_signature="ABC")
        response_message = network_pb2.GossipBlockResponse(
            content=block.SerializeToString())

        self.block_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 block "ABC". This adds it to the pending
        # request queue.
        request_message = \
            network_pb2.GossipBlockRequest(block_id="ABC")

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

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

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

        self.assert_message_sent(
            connection_id="Connection_2",
            message_type=validator_pb2.Message.GOSSIP_BLOCK_RESPONSE
            )
        # The request for block "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
    def do_responder_block_response_handler():

        block = block_pb2.Block(header_signature="ABC")
        response_message = network_pb2.GossipBlockResponse(
            content=block.SerializeToString())

        testResponder.block_response_handler.handle(
            "Connection_1", (block, 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 block "ABC". This adds it to the pending
        # request queue.
        request_message = \
            network_pb2.GossipBlockRequest(block_id="ABC", time_to_live=1)

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

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

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

        testResponder.assert_message_sent(
            connection_id="Connection_2",
            message_type=validator_pb2.Message.GOSSIP_BLOCK_RESPONSE)
        # The request for block "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")