Ejemplo n.º 1
0
    def _register(self):
        self._stream.wait_for_ready()

        request = consensus_pb2.ConsensusRegisterRequest(
            name=self._engine.name(),
            version=self._engine.version(),
        )

        for (name, version) in self._engine.additional_protocols():
            protocol = request.additional_protocols.add()
            protocol.name = name
            protocol.version = version

        while True:
            future = self._stream.send(
                message_type=Message.CONSENSUS_REGISTER_REQUEST,
                content=request.SerializeToString())
            response = consensus_pb2.ConsensusRegisterResponse()
            response.ParseFromString(future.result(REGISTER_TIMEOUT).content)

            if (response.status ==
                    consensus_pb2.ConsensusRegisterResponse.NOT_READY):
                continue

            if response.status == consensus_pb2.ConsensusRegisterResponse.OK:
                if (response.HasField('chain_head')
                        and response.HasField('local_peer_info')):
                    return StartupState(response.chain_head, response.peers,
                                        response.local_peer_info)

                return None

            raise exceptions.ReceiveError(
                'Registration failed with status {}'.format(response.status))
Ejemplo n.º 2
0
    def finalize_block(self, data):
        request = consensus_pb2.ConsensusFinalizeBlockRequest(data=data)

        response_type = consensus_pb2.ConsensusFinalizeBlockResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_FINALIZE_BLOCK_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.INVALID_STATE:
            raise exceptions.InvalidState(
                'Cannot finalize block in current state')

        if status == response_type.BLOCK_NOT_READY:
            raise exceptions.BLOCK_NOT_READY(
                'Block not ready to be finalized')

        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))

        return response.block_id
Ejemplo n.º 3
0
    def _register(self):
        self._stream.wait_for_ready()

        request = consensus_pb2.ConsensusRegisterRequest(
            name=self._engine.name(),
            version=self._engine.version(),
        ).SerializeToString()

        while True:
            future = self._stream.send(
                message_type=Message.CONSENSUS_REGISTER_REQUEST,
                content=request)
            response = consensus_pb2.ConsensusRegisterResponse()
            response.ParseFromString(future.result(REGISTER_TIMEOUT).content)

            if (response.status ==
                    consensus_pb2.ConsensusRegisterResponse.NOT_READY):
                continue

            if response.status == consensus_pb2.ConsensusRegisterResponse.OK:
                return StartupState(response.chain_head, response.peers,
                                    response.local_peer_info)

            raise exceptions.ReceiveError(
                'Registration failed with status {}'.format(response.status))
Ejemplo n.º 4
0
    def initialize_block(self, previous_id):
        request = (
            consensus_pb2.ConsensusInitializeBlockRequest(
                previous_id=previous_id)
            if previous_id
            else consensus_pb2.ConsensusInitializeBlockRequest()
        )

        response_type = consensus_pb2.ConsensusInitializeBlockResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_INITIALIZE_BLOCK_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.INVALID_STATE:
            raise exceptions.InvalidState(
                'Cannot initialize block in current state')

        if status == response_type.UNKNOWN_BLOCK:
            raise exceptions.UnknownBlock()

        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))
Ejemplo n.º 5
0
    def get_state(self, block_id, addresses):
        request = consensus_pb2.ConsensusStateGetRequest(
            block_id=block_id,
            addresses=addresses)

        response_type = consensus_pb2.ConsensusStateGetResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_STATE_GET_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.UNKNOWN_BLOCK:
            raise exceptions.UnknownBlock()

        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))

        return {
            entry.address: entry.data
            for entry in response.entries
        }
Ejemplo n.º 6
0
    def get_settings(self, block_id, settings):
        request = consensus_pb2.ConsensusSettingsGetRequest(
            block_id=block_id,
            keys=settings)

        response_type = consensus_pb2.ConsensusSettingsGetResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_SETTINGS_GET_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.UNKNOWN_BLOCK:
            raise exceptions.UnknownBlock()

        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))

        return {
            entry.key: entry.value
            for entry in response.entries
        }
Ejemplo n.º 7
0
    def _process(self, message):
        type_tag = message.message_type

        if type_tag == Message.CONSENSUS_NOTIFY_PEER_CONNECTED:
            notification = consensus_pb2.ConsensusNotifyPeerConnected()
            notification.ParseFromString(message.content)

            data = notification.peer_info

        elif type_tag == Message.CONSENSUS_NOTIFY_PEER_DISCONNECTED:
            notification = consensus_pb2.ConsensusNotifyPeerDisconnected()
            notification.ParseFromString(message.content)

            data = notification.peer_id

        elif type_tag == Message.CONSENSUS_NOTIFY_PEER_MESSAGE:
            notification = consensus_pb2.ConsensusNotifyPeerMessage()
            notification.ParseFromString(message.content)

            data = notification.message, notification.sender_id

        elif type_tag == Message.CONSENSUS_NOTIFY_BLOCK_NEW:
            notification = consensus_pb2.ConsensusNotifyBlockNew()
            notification.ParseFromString(message.content)

            data = notification.block

        elif type_tag == Message.CONSENSUS_NOTIFY_BLOCK_VALID:
            notification = consensus_pb2.ConsensusNotifyBlockValid()
            notification.ParseFromString(message.content)

            data = notification.block_id

        elif type_tag == Message.CONSENSUS_NOTIFY_BLOCK_INVALID:
            notification = consensus_pb2.ConsensusNotifyBlockInvalid()
            notification.ParseFromString(message.content)

            data = notification.block_id

        elif type_tag == Message.CONSENSUS_NOTIFY_BLOCK_COMMIT:
            notification = consensus_pb2.ConsensusNotifyBlockCommit()
            notification.ParseFromString(message.content)

            data = notification.block_id

        else:
            raise exceptions.ReceiveError(
                'Received unexpected message type: {}'.format(type_tag))

        self._stream.send_back(
            message_type=Message.CONSENSUS_NOTIFY_ACK,
            correlation_id=message.correlation_id,
            content=consensus_pb2.ConsensusNotifyAck().SerializeToString())

        return type_tag, data
Ejemplo n.º 8
0
    def broadcast(self, message_type, payload):
        request = consensus_pb2.ConsensusBroadcastRequest(
            message_type=message_type, content=payload)

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_BROADCAST_REQUEST,
            response_type=consensus_pb2.ConsensusBroadcastResponse)

        if response.status != consensus_pb2.ConsensusBroadcastResponse.OK:
            raise exceptions.ReceiveError('Failed with status {}'.format(
                response.status))
Ejemplo n.º 9
0
    def send_to(self, receiver_id, message_type, payload):
        request = consensus_pb2.ConsensusSendToRequest(
            message_type=message_type,
            content=payload,
            receiver_id=receiver_id)

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_SEND_TO_REQUEST,
            response_type=consensus_pb2.ConsensusSendToResponse)

        if response.status != consensus_pb2.ConsensusSendToResponse.OK:
            raise exceptions.ReceiveError('Failed with status {}'.format(
                response.status))
Ejemplo n.º 10
0
    def _register(self):
        self._stream.wait_for_ready()

        future = self._stream.send(
            message_type=Message.CONSENSUS_REGISTER_REQUEST,
            content=consensus_pb2.ConsensusRegisterRequest(
                name=self._engine.name(),
                version=self._engine.version(),
            ).SerializeToString(),
        )

        response = consensus_pb2.ConsensusRegisterResponse()
        response.ParseFromString(future.result().content)

        if response.status != consensus_pb2.ConsensusRegisterResponse.OK:
            raise exceptions.ReceiveError(
                'Registration failed with status {}'.format(response.status))
Ejemplo n.º 11
0
    def fail_block(self, block_id):
        request = consensus_pb2.ConsensusFailBlockRequest(block_id=block_id)

        response_type = consensus_pb2.ConsensusFailBlockResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_FAIL_BLOCK_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.UNKNOWN_BLOCK:
            raise exceptions.UnknownBlock()

        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))
Ejemplo n.º 12
0
    def check_blocks(self, priority):
        request = consensus_pb2.ConsensusCheckBlocksRequest(block_ids=priority)

        response_type = consensus_pb2.ConsensusCheckBlocksResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_CHECK_BLOCKS_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.UNKNOWN_BLOCK:
            raise exceptions.UnknownBlock()

        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))
Ejemplo n.º 13
0
    def cancel_block(self):
        request = consensus_pb2.ConsensusCancelBlockRequest()

        response_type = consensus_pb2.ConsensusCancelBlockResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_CANCEL_BLOCK_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.INVALID_STATE:
            raise exceptions.InvalidState(
                'Cannot cancel block in current state')

        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))
Ejemplo n.º 14
0
    def broadcast_to_arbiter(self, message_type, payload):
        """
        FIXME - better use special message like CONSENSUS_BROADCAST_REQUEST and send only one message and validator take cluster's peer from topology
        """
        message = consensus_pb2.ConsensusPeerMessage(message_type=message_type,
                                                     content=payload,
                                                     name=self._name,
                                                     version=self._version)

        request = consensus_pb2.ConsensusBroadcastArbiterRequest(
            message=message)
        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_BROADCAST_ARBITER_REQUEST,
            response_type=consensus_pb2.ConsensusBroadcastArbiterResponse)

        if response.status != consensus_pb2.ConsensusBroadcastArbiterResponse.OK:
            raise exceptions.ReceiveError('Failed with status {}'.format(
                response.status))
Ejemplo n.º 15
0
    def get_chain_head(self):
        request = consensus_pb2.ConsensusChainHeadGetRequest()

        response_type = consensus_pb2.ConsensusChainHeadGetResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_CHAIN_HEAD_GET_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.NO_CHAIN_HEAD:
            raise exceptions.NoChainHead()

        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))

        return Block(response.block)
Ejemplo n.º 16
0
    def get_blocks(self, block_ids):
        request = consensus_pb2.ConsensusBlocksGetRequest(block_ids=block_ids)

        response_type = consensus_pb2.ConsensusBlocksGetResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_BLOCKS_GET_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.UNKNOWN_BLOCK:
            raise exceptions.UnknownBlock()

        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))

        return {block.block_id: Block(block) for block in response.blocks}
Ejemplo n.º 17
0
    def get_chain_head(self, parent_id=None, new_parent_id=None, is_new=False):
        request = consensus_pb2.ConsensusChainHeadGetRequest(
            parent_id=parent_id, new_parent_id=new_parent_id, is_new=is_new)

        response_type = consensus_pb2.ConsensusChainHeadGetResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_CHAIN_HEAD_GET_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.NO_CHAIN_HEAD:
            raise exceptions.NoChainHead()
        if status == response_type.TOO_MANY_BRANCH:
            raise exceptions.TooManyBranch()
        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))

        #LOGGER.debug('get_chain_head: block=%s',response.block)
        return Block(response.block)
Ejemplo n.º 18
0
    def summarize_block(self):
        request = consensus_pb2.ConsensusSummarizeBlockRequest()

        response_type = consensus_pb2.ConsensusSummarizeBlockResponse

        response = self._send(
            request=request,
            message_type=Message.CONSENSUS_SUMMARIZE_BLOCK_REQUEST,
            response_type=response_type)

        status = response.status

        if status == response_type.INVALID_STATE:
            raise exceptions.InvalidState(
                'Cannot summarize block in current state')

        if status == response_type.BLOCK_NOT_READY:
            raise exceptions.BlockNotReady('Block not ready to be summarize')

        if status != response_type.OK:
            raise exceptions.ReceiveError(
                'Failed with status {}'.format(status))

        return response.summary
    def _process(self, message):
        type_tag = message.message_type

        if type_tag == Message.CONSENSUS_NOTIFY_PEER_CONNECTED:
            notification = consensus_pb2.ConsensusNotifyPeerConnected()
            notification.ParseFromString(message.content)

            data = notification.peer_info

        elif type_tag == Message.CONSENSUS_NOTIFY_PEER_DISCONNECTED:
            notification = consensus_pb2.ConsensusNotifyPeerDisconnected()
            notification.ParseFromString(message.content)

            data = notification.peer_id

        elif type_tag == Message.CONSENSUS_NOTIFY_PEER_MESSAGE:
            notification = consensus_pb2.ConsensusNotifyPeerMessage()
            notification.ParseFromString(message.content)

            header = consensus_pb2.ConsensusPeerMessageHeader()
            header.ParseFromString(notification.message.header)

            peer_message = PeerMessage(
                header=header,
                header_bytes=notification.message.header,
                header_signature=notification.message.header_signature,
                content=notification.message.content)

            data = peer_message, notification.sender_id

        elif type_tag == Message.CONSENSUS_NOTIFY_BLOCK_NEW:
            notification = consensus_pb2.ConsensusNotifyBlockNew()
            notification.ParseFromString(message.content)

            data = notification.block

        elif type_tag == Message.CONSENSUS_NOTIFY_BLOCK_VALID:
            notification = consensus_pb2.ConsensusNotifyBlockValid()
            notification.ParseFromString(message.content)

            data = notification.block_id

        elif type_tag == Message.CONSENSUS_NOTIFY_BLOCK_INVALID:
            notification = consensus_pb2.ConsensusNotifyBlockInvalid()
            notification.ParseFromString(message.content)

            data = notification.block_id

        elif type_tag == Message.CONSENSUS_NOTIFY_BLOCK_COMMIT:
            notification = consensus_pb2.ConsensusNotifyBlockCommit()
            notification.ParseFromString(message.content)

            data = notification.block_id

        elif type_tag == Message.CONSENSUS_NOTIFY_ENGINE_DEACTIVATED:
            self.stop()
            data = None

        elif type_tag == Message.PING_REQUEST:
            data = None

        else:
            raise exceptions.ReceiveError(
                'Received unexpected message type: {}'.format(type_tag))

        self._stream.send_back(
            message_type=Message.CONSENSUS_NOTIFY_ACK,
            correlation_id=message.correlation_id,
            content=consensus_pb2.ConsensusNotifyAck().SerializeToString())

        return type_tag, data