Ejemplo n.º 1
0
    def handle(self, connection_id, message_content):
        block_request_message = network_pb2.GossipBlockRequest()
        block_request_message.ParseFromString(message_content)
        if block_request_message.nonce in self._seen_requests:
            LOGGER.debug("Received repeat GossipBlockRequest 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[block_request_message.nonce] = \
            block_request_message.block_id

        block_id = block_request_message.block_id
        node_id = block_request_message.node_id
        block = self._responder.check_for_block(block_id)
        if block is None:
            # No block found, broadcast original message to other peers
            # and add to pending requests
            if block_id == "HEAD":
                LOGGER.debug("No chain head available. Cannot respond to block"
                             " requests.")
            else:
                if not self._responder.already_requested(block_id):
                    self._gossip.broadcast(
                        block_request_message,
                        validator_pb2.Message.GOSSIP_BLOCK_REQUEST,
                        exclude=[connection_id])
                else:
                    LOGGER.debug("Block %s has already been requested",
                                 block_id)

                self._responder.add_request(block_id, connection_id)
        else:
            LOGGER.debug("Responding to block requests: %s",
                         block.get_block().header_signature)

            block_response = network_pb2.GossipBlockResponse(
                content=block.get_block().SerializeToString(), node_id=node_id)

            self._gossip.send(validator_pb2.Message.GOSSIP_BLOCK_RESPONSE,
                              block_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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
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)
Ejemplo n.º 4
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)

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

        return HandlerResult(HandlerStatus.RETURN,
                             message_out=ack,
                             message_type=validator_pb2.Message.NETWORK_ACK)
Ejemplo n.º 5
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)
            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.ids
        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):
            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 != []:
            if not_requested != []:
                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
                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)

        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)

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

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