Ejemplo n.º 1
0
    def get_events(self,
                   tx_context,
                   channel_name,
                   start=None,
                   stop=None,
                   filtered=True,
                   behavior='BLOCK_UNTIL_READY'):
        """ get the events of the channel.
        Return: the events in success or None in fail.
        """
        _logger.info("get events")

        seek_info = create_seek_info(start, stop, behavior)

        kwargs = {}
        if self._client_cert_path:
            with open(self._client_cert_path, 'rb') as f:
                b64der = pem_to_der(f.read())
                kwargs['tls_cert_hash'] = sha256(b64der).digest()

        seek_info_header = build_channel_header(
            common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id,
            channel_name, current_timestamp(), tx_context.epoch, **kwargs)

        seek_header = build_header(tx_context.identity, seek_info_header,
                                   tx_context.nonce)

        seek_payload_bytes = create_seek_payload(seek_header, seek_info)
        sig = tx_context.sign(seek_payload_bytes)
        envelope = create_envelope(sig, seek_payload_bytes)

        # this is a stream response
        return self.delivery(envelope, filtered=filtered)
Ejemplo n.º 2
0
    def get_genesis_block(self, tx_context, channel_name):
        """ get the genesis block of the channel.
        Return: the genesis block in success or None in fail.
        """
        _logger.info("get genesis block - start")

        seek_info = create_seek_info(0, 0)
        seek_info_header = build_channel_header(
            common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id,
            channel_name, current_timestamp(), tx_context.epoch)

        seek_header = build_header(tx_context.identity, seek_info_header,
                                   tx_context.nonce)

        seek_payload_bytes = create_seek_payload(seek_header, seek_info)
        sig = tx_context.sign(seek_payload_bytes)
        envelope = create_envelope(sig, seek_payload_bytes)
        response = self.delivery(envelope)

        if response[0].block is None or response[0].block == '':
            _logger.error("fail to get genesis block")
            return None

        _logger.info("get genesis block successfully, block=%s",
                     response[0].block.header)
        return response[0].block
Ejemplo n.º 3
0
    def join_channel(self, request):
        """
        To join the peer to a channel.

        Args:
            request: the request to join a channel
        Return:
            True in sucess or False in failure
        """
        _logger.debug('channel_join - start')

        for key in ['targets', 'block', 'tx_context']:
            if key not in request:
                err_msg = "Missing parameter {}".format(key)
                _logger.error('channel_join error: {}'.format(err_msg))
                raise ValueError(err_msg)

        chaincode_input = chaincode_pb2.ChaincodeInput()
        chaincode_input.args.extend([proto_b("JoinChain"), request['block']])
        chaincode_id = chaincode_pb2.ChaincodeID()
        chaincode_id.name = proto_str("cscc")

        cc_spec = create_cc_spec(chaincode_input, chaincode_id, 'GOLANG')
        cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec()
        cc_invoke_spec.chaincode_spec.CopyFrom(cc_spec)

        tx_context = request['tx_context']
        extension = proposal_pb2.ChaincodeHeaderExtension()
        extension.chaincode_id.name = proto_str('cscc')
        channel_header = build_channel_header(
            common_pb2.HeaderType.Value('ENDORSER_TRANSACTION'),
            tx_context.tx_id,
            '',
            current_timestamp(),
            tx_context.epoch,
            extension=extension.SerializeToString())

        header = build_header(tx_context.identity, channel_header,
                              tx_context.nonce)
        proposal = build_cc_proposal(cc_invoke_spec, header,
                                     request['transient_map'])

        try:
            responses = send_transaction_proposal(proposal, tx_context,
                                                  request['targets'])
        except Exception as e:
            raise IOError("fail to send transanction proposal", e)

        q = Queue(1)
        result = True
        for r in responses:
            r.subscribe(on_next=lambda x: q.put(x),
                        on_error=lambda x: q.put(x))
            res = q.get(timeout=5)
            proposal_res = res[0]
            result = result and (proposal_res.response.status == 200)
        if result:
            _logger.info("successfully join the peers")

        return result
Ejemplo n.º 4
0
    def test_build_header(self):
        timestamp = utils.current_timestamp()

        client = Client()
        client.state_store = FileKeyValueStore(self.kv_store_path)

        orderer_org_admin = get_orderer_org_admin(client)
        orderer_org_admin_tx_context = \
            TXContext(orderer_org_admin, Ecies(), {})
        client.tx_context = orderer_org_admin_tx_context

        orderer_org_admin_serialized = utils.create_serialized_identity(
            orderer_org_admin)
        serialized_identity = identities_pb2.SerializedIdentity()
        serialized_identity.ParseFromString(orderer_org_admin_serialized)

        proto_channel_header = utils.build_channel_header(
            common_pb2.HeaderType.Value('CONFIG_UPDATE'),
            orderer_org_admin_tx_context.tx_id,
            self.channel_id,
            timestamp
        )

        channel_header = utils.build_header(
            orderer_org_admin_tx_context.identity,
            proto_channel_header,
            orderer_org_admin_tx_context.nonce
        )
        self.assertIsInstance(channel_header, common_pb2.Header)
Ejemplo n.º 5
0
    def get_genesis_block(self, tx_context, channel_name):
        """get the genesis block of the channel

        :return: the genesis block in success or None in fail
        :rtype: Block/None
        """
        _logger.info("get genesis block - start")

        seek_info = create_seek_info(0, 0)

        kwargs = {}
        if self._client_cert_path:
            with open(self._client_cert_path, 'rb') as f:
                b64der = pem_to_der(f.read())
                kwargs['tls_cert_hash'] = sha256(b64der).digest()

        seek_info_header = build_channel_header(
            common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id,
            channel_name, current_timestamp(), tx_context.epoch, **kwargs)

        seek_header = build_header(tx_context.identity, seek_info_header,
                                   tx_context.nonce)

        seek_payload_bytes = create_seek_payload(seek_header, seek_info)
        sig = tx_context.sign(seek_payload_bytes)
        envelope = create_envelope(sig, seek_payload_bytes)

        # this is a stream response
        return self.delivery(envelope)
    def get_block_between(self, tx_context, orderer, start, end):
        """
        Args:
            tx_context: tx_context instance
            orderer: orderer instance
            start: id of block to start query for
            end: id of block to end query for

        Returns: block(s)
        """
        seek_info = create_seek_info(start, end)
        seek_info_header = build_channel_header(
            common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id,
            self._name, current_timestamp(), tx_context.epoch)

        seek_header = build_header(tx_context.identity, seek_info_header,
                                   tx_context.nonce)

        seek_payload_bytes = create_seek_payload(seek_header, seek_info)
        sig = tx_context.sign(seek_payload_bytes)

        envelope = create_envelope(sig, seek_payload_bytes)
        response = orderer.delivery(envelope)

        if response[0].block is None or response[0].block == '':
            _logger.error("fail to get block start from %s to %s" %
                          (str(start), str(end)))
            return None

        _logger.info("get block successfully, start from %s to %s" %
                     (str(start), str(end)))

        return response[0].block
Ejemplo n.º 7
0
    def _get_stream(self):
        """ get the events of the channel.
        Return: the events in success or None in fail.
        """
        _logger.info("create peer delivery stream")

        if self._signed_event is not None:
            return self._peer.delivery(self._signed_event,
                                       filtered=self._filtered)

        seek_info = self._create_seek_info(self._start, self._stop)

        kwargs = {}
        if self._peer._client_cert_path:
            with open(self._peer._client_cert_path, 'rb') as f:
                b64der = pem_to_der(f.read())
                kwargs['tls_cert_hash'] = sha256(b64der).digest()

        tx_context = TXContext(self._requestor, self._requestor.cryptoSuite,
                               TXProposalRequest())

        seek_info_header = build_channel_header(
            common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id,
            self._channel_name, current_timestamp(), tx_context.epoch,
            **kwargs)

        seek_header = build_header(tx_context.identity, seek_info_header,
                                   tx_context.nonce)

        seek_payload_bytes = create_seek_payload(seek_header, seek_info)
        sig = tx_context.sign(seek_payload_bytes)
        envelope = create_envelope(sig, seek_payload_bytes)

        # this is a stream response
        return self._peer.delivery(envelope, filtered=self._filtered)
Ejemplo n.º 8
0
    def _send_tx_proposal(channel_id,
                          tx_context,
                          peers,
                          cc_type=CC_TYPE_GOLANG):

        request = tx_context.tx_prop_req

        args = []
        if request.fcn:
            args.append(proto_b(request.fcn))
        else:
            args.append(proto_b(CC_INVOKE))

        for arg in request.args:
            if isinstance(arg, bytes):
                args.append(arg)
            else:
                args.append(proto_b(arg))

        cc_id = chaincode_pb2.ChaincodeID()
        cc_id.name = request.cc_name
        if request.prop_type not in (CC_QUERY, CC_INVOKE):
            cc_id.version = request.cc_version

        cc_input = chaincode_pb2.ChaincodeInput()
        cc_input.args.extend(args)

        cc_spec = chaincode_pb2.ChaincodeSpec()
        cc_spec.type = chaincode_pb2.ChaincodeSpec.Type.Value(cc_type)
        cc_spec.chaincode_id.CopyFrom(cc_id)
        cc_spec.input.CopyFrom(cc_input)

        extension = proposal_pb2.ChaincodeHeaderExtension()
        extension.chaincode_id.name = request.cc_name
        cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec()
        cc_invoke_spec.chaincode_spec.CopyFrom(cc_spec)

        channel_header = build_channel_header(
            common_pb2.ENDORSER_TRANSACTION,
            tx_context.tx_id,
            channel_id,
            current_timestamp(),
            tx_context.epoch,
            extension=extension.SerializeToString())

        header = build_header(tx_context.identity, channel_header,
                              tx_context.nonce)

        # chaincode real proposal
        proposal = build_cc_proposal(cc_invoke_spec, header,
                                     request.transient_map)
        signed_proposal = utils.sign_proposal(tx_context, proposal)
        responses = [peer.send_proposal(signed_proposal) for peer in peers]

        # chaincode proposal without transient map
        # https://jira.hyperledger.org/browse/FAB-12536?focusedCommentId=52438&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-52438 # noqa
        proposal = build_cc_proposal(cc_invoke_spec, header, None)

        return responses, proposal, header
Ejemplo n.º 9
0
    def test_build_channel_header(self):
        timestamp = utils.current_timestamp()
        proto_channel_header = utils.build_channel_header(
            common_pb2.HeaderType.Value('CONFIG_UPDATE'), '12341234',
            self.channel_id, timestamp)

        self.assertIsInstance(proto_channel_header, common_pb2.ChannelHeader)
        self.assertEqual(proto_channel_header.channel_id, self.channel_id)
Ejemplo n.º 10
0
    def get_genesis_block(self, tx_context, channel_name):
        "채널의 제네시스 블록 생성, 스트림으로 응답"

        seek_info_header = build_channel_header(
            common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'),
            tx_context.tx_id,
            channel_name,
            current_timestamp(),
            tx_context.epoch,
            **kwargs
        )
        return self.delivery(envelope)
Ejemplo n.º 11
0
    def _send_tx_proposal(channel_id, tx_context, peers):

        request = tx_context.tx_prop_req

        args = []
        if request.fcn:
            args.append(proto_b(request.fcn))
        else:
            args.append(proto_b(CC_INVOKE))

        for arg in request.args:
            if isinstance(arg, bytes):
                args.append(arg)
            else:
                args.append(proto_b(arg))

        cc_id = chaincode_pb2.ChaincodeID()
        cc_id.name = request.cc_name
        if request.prop_type != CC_QUERY:
            cc_id.version = request.cc_version

        cc_input = chaincode_pb2.ChaincodeInput()
        cc_input.args.extend(args)

        cc_spec = chaincode_pb2.ChaincodeSpec()
        cc_spec.type = chaincode_pb2.ChaincodeSpec.Type.Value(CC_TYPE_GOLANG)
        cc_spec.chaincode_id.CopyFrom(cc_id)
        cc_spec.input.CopyFrom(cc_input)

        extension = proposal_pb2.ChaincodeHeaderExtension()
        extension.chaincode_id.name = request.cc_name
        cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec()
        cc_invoke_spec.chaincode_spec.CopyFrom(cc_spec)
        channel_header = build_channel_header(
            common_pb2.ENDORSER_TRANSACTION,
            tx_context.tx_id,
            channel_id,
            current_timestamp(),
            tx_context.epoch,
            extension=extension.SerializeToString())

        header = build_header(tx_context.identity, channel_header,
                              tx_context.nonce)
        proposal = build_cc_proposal(cc_invoke_spec, header,
                                     request.transient_map)
        signed_proposal = utils.sign_proposal(tx_context, proposal)
        send_executions = [
            peer.send_proposal(signed_proposal) for peer in peers
        ]

        return rx.Observable.merge(send_executions).to_iterable() \
            .map(lambda responses: (responses, proposal, header))
Ejemplo n.º 12
0
    def join_channel(self, request):
        """
        To join the peer to a channel.

        Args:
            request: the request to join a channel
        Return:
            A coroutine to handle thanks to asyncio with
             await asyncio.gather(*responses)
        """
        _logger.debug('channel_join - start')

        for key in ['targets', 'block', 'tx_context']:
            if key not in request:
                err_msg = "Missing parameter {}".format(key)
                _logger.error('channel_join error: {}'.format(err_msg))
                raise ValueError(err_msg)

        chaincode_input = chaincode_pb2.ChaincodeInput()
        chaincode_input.args.extend([proto_b("JoinChain"), request['block']])
        chaincode_id = chaincode_pb2.ChaincodeID()
        chaincode_id.name = proto_str("cscc")

        cc_spec = create_cc_spec(chaincode_input, chaincode_id, 'GOLANG')
        cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec()
        cc_invoke_spec.chaincode_spec.CopyFrom(cc_spec)

        tx_context = request['tx_context']
        extension = proposal_pb2.ChaincodeHeaderExtension()
        extension.chaincode_id.name = proto_str('cscc')
        channel_header = build_channel_header(
            common_pb2.HeaderType.Value('ENDORSER_TRANSACTION'),
            tx_context.tx_id,
            '',
            current_timestamp(),
            tx_context.epoch,
            extension=extension.SerializeToString())

        header = build_header(tx_context.identity,
                              channel_header,
                              tx_context.nonce)
        proposal = build_cc_proposal(cc_invoke_spec,
                                     header,
                                     request['transient_map'])

        return send_transaction_proposal(proposal,
                                         tx_context,
                                         request['targets'])
Ejemplo n.º 13
0
    def get_genesis_block(self, tx_context, channel_name):
        """ get the genesis block of the channel.
        Return: the genesis block in success or None in fail.
        """
        _logger.info("get genesis block - start")

        seek_info = create_seek_info(0, 0)
        seek_info_header = build_channel_header(
            common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id,
            channel_name, current_timestamp(), tx_context.epoch)

        seek_header = build_header(tx_context.identity, seek_info_header,
                                   tx_context.nonce)

        seek_payload_bytes = create_seek_payload(seek_header, seek_info)
        sig = tx_context.sign(seek_payload_bytes)
        envelope = create_envelope(sig, seek_payload_bytes)

        # this is a stream response
        return self.delivery(envelope)
Ejemplo n.º 14
0
    def get_genesis_block(self):
        """ get the genesis block of the channel.
        Return: the genesis block in success or None in fail.
        """
        _logger.info("get genesis block - start")

        orderer = self._get_random_orderer()

        tx_context = self._client.tx_context

        seek_info = create_seek_info(0, 0)
        seek_info_header = build_channel_header(
            common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id,
            self.name, current_timestamp(), tx_context.epoch)

        seek_header = build_header(tx_context.identity, seek_info_header,
                                   tx_context.nonce)

        seek_payload_bytes = create_seek_payload(seek_header, seek_info)
        sig = tx_context.sign(seek_payload_bytes)

        envelope = create_envelope(sig, seek_payload_bytes)
        q = Queue(1)
        response = orderer.delivery(envelope)
        response.subscribe(on_next=lambda x: q.put(x),
                           on_error=lambda x: q.put(x))

        res, _ = q.get(timeout=5)

        if res.block is None or res.block == '':
            _logger.error("fail to get genesis block")
            return None

        _logger.info("get genesis block successfully, block=%s",
                     res.block.header)
        return res.block
Ejemplo n.º 15
0
    def send_install_proposal(self, tx_context, peers=None, scheduler=None):
        """ Send install chaincode proposal

        Args:
            schedule: Rx schedule
            install_proposal_req: install proposal request
            targets: a set of peer to send

        Returns: a set of proposal response

        """
        if peers is None:
            targets = self._peers.values()
        else:
            targets = peers
        # self._validate_state() # TODO: enable this later
        # self._validate_peers(targets)  # TODO: enable this later

        if not tx_context:
            raise ValueError("InstallProposalRequest is null.")

        cc_deployment_spec = chaincode_pb2.ChaincodeDeploymentSpec()
        cc_deployment_spec.chaincode_spec.type = \
            chaincode_pb2.ChaincodeSpec.Type.Value(
                proto_str(tx_context.tx_prop_req.cc_type))
        cc_deployment_spec.chaincode_spec.chaincode_id.name = \
            proto_str(tx_context.tx_prop_req.cc_name)
        cc_deployment_spec.chaincode_spec.chaincode_id.path = \
            proto_str(tx_context.tx_prop_req.cc_path)
        cc_deployment_spec.chaincode_spec.chaincode_id.version = \
            proto_str(tx_context.tx_prop_req.cc_version)
        if not self._is_dev_mode:
            if not tx_context.tx_prop_req.packaged_cc:
                cc_deployment_spec.code_package = \
                    self._package_chaincode(
                        tx_context.tx_prop_req.cc_path,
                        tx_context.tx_prop_req.cc_type)
            else:
                cc_deployment_spec.code_package = \
                    tx_context.tx_prop_req.packaged_cc

        cc_deployment_spec.effective_date.seconds = \
            tx_context.tx_prop_req.effective_date.seconds
        cc_deployment_spec.effective_date.nanos = \
            tx_context.tx_prop_req.effective_date.nanos

        channel_header_extension = proposal_pb2.ChaincodeHeaderExtension()
        channel_header_extension.chaincode_id.name = \
            proto_str("lscc")
        channel_header = utils.build_channel_header(
            common_pb2.ENDORSER_TRANSACTION, tx_context.tx_id, '',
            utils.current_timestamp(), tx_context.epoch,
            channel_header_extension.SerializeToString())

        header = utils.build_header(tx_context.identity, channel_header,
                                    tx_context.nonce)

        cci_spec = chaincode_pb2.ChaincodeInvocationSpec()
        cci_spec.chaincode_spec.type = \
            chaincode_pb2.ChaincodeSpec.Type.Value(CC_TYPE_GOLANG)
        cci_spec.chaincode_spec.chaincode_id.name = proto_str("lscc")
        cci_spec.chaincode_spec.input.args.extend(
            [proto_b(CC_INSTALL),
             cc_deployment_spec.SerializeToString()])
        proposal = utils.build_cc_proposal(
            cci_spec, header, tx_context.tx_prop_req.transient_map)
        signed_proposal = utils.sign_proposal(tx_context, proposal)

        send_executions = [
            peer.send_proposal(signed_proposal, scheduler) for peer in targets
        ]

        return rx.Observable.merge(send_executions).to_iterable() \
            .map(lambda responses: (responses, proposal, header))
Ejemplo n.º 16
0
    def _send_cc_proposal(self, tx_context, command, peers):

        args = []
        request = tx_context.tx_prop_req

        args.append(proto_b(request.fcn))
        for arg in request.args:
            args.append(proto_b(arg))

        # construct the deployment spec
        cc_id = chaincode_pb2.ChaincodeID()
        cc_id.name = request.cc_name
        cc_id.version = request.cc_version

        cc_input = chaincode_pb2.ChaincodeInput()
        cc_input.args.extend(args)
        cc_spec = create_cc_spec(cc_input, cc_id, CC_TYPE_GOLANG)

        cc_dep_spec = chaincode_pb2.ChaincodeDeploymentSpec()
        cc_dep_spec.chaincode_spec.CopyFrom(cc_spec)
        cc_dep_spec.effective_date.seconds = \
            tx_context.tx_prop_req.effective_date.seconds
        cc_dep_spec.effective_date.nanos = \
            tx_context.tx_prop_req.effective_date.nanos

        # construct the invoke spec
        # TODO: if the policy not provided, new one should be built.
        if request.cc_endorsement_policy:
            policy = request.cc_endorsement_policy
        else:
            policy = ''

        invoke_input = chaincode_pb2.ChaincodeInput()
        invoke_input.args.extend([
            proto_b(command),
            proto_b(self.name),
            cc_dep_spec.SerializeToString(),
            proto_b(policy),
            proto_b('escc'),
            proto_b('vscc')
        ])

        invoke_cc_id = chaincode_pb2.ChaincodeID()
        invoke_cc_id.name = proto_str('lscc')

        cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec()
        cc_invoke_spec.chaincode_spec.CopyFrom(
            create_cc_spec(invoke_input, invoke_cc_id, CC_TYPE_GOLANG))

        extension = proposal_pb2.ChaincodeHeaderExtension()
        extension.chaincode_id.name = proto_str('lscc')
        channel_header = build_channel_header(
            common_pb2.ENDORSER_TRANSACTION,
            tx_context.tx_id,
            self.name,
            current_timestamp(),
            epoch=0,
            extension=extension.SerializeToString())

        header = build_header(tx_context.identity, channel_header,
                              tx_context.nonce)
        proposal = build_cc_proposal(cc_invoke_spec, header,
                                     request.transient_map)

        signed_proposal = utils.sign_proposal(tx_context, proposal)
        send_executions = [
            peer.send_proposal(signed_proposal) for peer in peers
        ]

        return rx.Observable.merge(send_executions).to_iterable() \
            .map(lambda responses: (responses, proposal, header))
Ejemplo n.º 17
0
    async def get_channel_config_with_orderer(self, tx_context, orderer):
        """Query the current config block for this channel

        Args:
            tx_context: tx_context instance
            peers: peers in the channel

        Returns:
            :class:`ChaincodeQueryResponse` channelinfo with height,
            currently the only useful information.
        """

        seek_info = create_seek_info()

        kwargs = {}
        if orderer._client_cert_path:
            with open(orderer._client_cert_path, 'rb') as f:
                b64der = pem_to_der(f.read())
                kwargs['tls_cert_hash'] = sha256(b64der).digest()

        seek_info_header = build_channel_header(
            common_pb2.HeaderType.Value('DELIVER_SEEK_INFO'), tx_context.tx_id,
            self.name, current_timestamp(), tx_context.epoch, **kwargs)

        seek_header = build_header(tx_context.identity, seek_info_header,
                                   tx_context.nonce)

        seek_payload_bytes = create_seek_payload(seek_header, seek_info)
        sig = tx_context.sign(seek_payload_bytes)
        envelope = create_envelope(sig, seek_payload_bytes)

        # this is a stream response
        block = None
        stream = orderer.delivery(envelope)
        async for v in stream:
            if v.block is None or v.block == '':
                msg = "fail to get block"
                _logger.error(msg)
                raise Exception(msg)
            block = v.block
            break

        block = BlockDecoder().decode(block.SerializeToString())

        last_config = block['metadata']['metadata'][common_pb2.LAST_CONFIG]

        # if nor first block
        if 'index' in last_config['value']:
            seek_info = create_seek_info(last_config['value']['index'],
                                         last_config['value']['index'])
            seek_payload_bytes = create_seek_payload(seek_header, seek_info)
            sig = tx_context.sign(seek_payload_bytes)
            envelope = create_envelope(sig, seek_payload_bytes)

            block = None
            stream = orderer.delivery(envelope)
            async for v in stream:
                if v.block is None or v.block == '':
                    msg = "fail to get block"
                    _logger.error(msg)
                    raise Exception(msg)
                block = v.block
                break

            block = BlockDecoder().decode(block.SerializeToString())

        envelope = block['data']['data'][0]
        payload = envelope['payload']
        channel_header = payload['header']['channel_header']

        if channel_header['type'] != common_pb2.CONFIG:
            raise Exception(f'Block must be of type "CONFIG"'
                            f' ({common_pb2.CONFIG}), but got'
                            f' "{channel_header["type"]}" instead')

        config_envelope = payload['data']
        return config_envelope
Ejemplo n.º 18
0
    def _send_cc_proposal(self, tx_context, command, peers):

        args = []
        request = tx_context.tx_prop_req

        args.append(proto_b(request.fcn))
        for arg in request.args:
            args.append(proto_b(arg))

        # construct the deployment spec
        cc_id = chaincode_pb2.ChaincodeID()
        cc_id.name = request.cc_name
        cc_id.version = request.cc_version

        cc_input = chaincode_pb2.ChaincodeInput()
        cc_input.args.extend(args)
        cc_spec = create_cc_spec(cc_input, cc_id, CC_TYPE_GOLANG)

        cc_dep_spec = chaincode_pb2.ChaincodeDeploymentSpec()
        cc_dep_spec.chaincode_spec.CopyFrom(cc_spec)
        cc_dep_spec.effective_date.seconds = \
            tx_context.tx_prop_req.effective_date.seconds
        cc_dep_spec.effective_date.nanos = \
            tx_context.tx_prop_req.effective_date.nanos

        # construct the invoke spec
        # TODO: if the policy not provided, new one should be built.
        if request.cc_endorsement_policy:
            policy = request.cc_endorsement_policy
        else:
            policy = ''

        invoke_input = chaincode_pb2.ChaincodeInput()
        invoke_input.args.extend([
            proto_b(command),
            proto_b(self.name),
            cc_dep_spec.SerializeToString(),
            proto_b(policy),
            proto_b('escc'),
            proto_b('vscc')
        ])

        invoke_cc_id = chaincode_pb2.ChaincodeID()
        invoke_cc_id.name = proto_str('lscc')

        cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec()
        cc_invoke_spec.chaincode_spec.CopyFrom(
            create_cc_spec(invoke_input, invoke_cc_id, CC_TYPE_GOLANG))

        extension = proposal_pb2.ChaincodeHeaderExtension()
        extension.chaincode_id.name = proto_str('lscc')
        channel_header = build_channel_header(
            common_pb2.ENDORSER_TRANSACTION,
            tx_context.tx_id,
            self.name,
            current_timestamp(),
            epoch=0,
            extension=extension.SerializeToString())

        header = build_header(tx_context.identity, channel_header,
                              tx_context.nonce)
        proposal = build_cc_proposal(cc_invoke_spec, header,
                                     request.transient_map)

        try:
            responses = send_transaction_proposal(proposal, header, tx_context,
                                                  peers)
        except Exception as e:
            raise IOError("fail to send transanction proposal", e)

        q = Queue(1)
        result = True
        for r in responses:
            r.subscribe(on_next=lambda x: q.put(x),
                        on_error=lambda x: q.put(x))
            res, _ = q.get()
            result = result and (res.response.status == 200)

        return result
Ejemplo n.º 19
0
    def _send_cc_proposal(self, tx_context, command, peers):

        args = []
        request = tx_context.tx_prop_req

        args.append(proto_b(request.fcn))
        for arg in request.args:
            args.append(proto_b(arg))

        # construct the deployment spec
        cc_id = chaincode_pb2.ChaincodeID()
        cc_id.name = request.cc_name
        cc_id.version = request.cc_version

        cc_input = chaincode_pb2.ChaincodeInput()
        cc_input.args.extend(args)
        cc_spec = create_cc_spec(cc_input, cc_id, CC_TYPE_GOLANG)

        cc_dep_spec = chaincode_pb2.ChaincodeDeploymentSpec()
        cc_dep_spec.chaincode_spec.CopyFrom(cc_spec)

        # Pass msps, TODO create an MSPManager as done in fabric-sdk-node
        policy = self._build_policy(request.cc_endorsement_policy)

        args = [
            proto_b(command),
            proto_b(self.name),
            cc_dep_spec.SerializeToString(),
            policy,
            proto_b('escc'),
            proto_b('vscc'),
        ]

        # collections_configs need V1_2 or later capability enabled,
        # otherwise private channel collections and data are not available
        collections_configs = []
        if request.collections_config:
            for config in request.collections_config:
                static_config = collection_pb2.StaticCollectionConfig()
                static_config.name = config['name']
                static_config.member_orgs_policy.signature_policy. \
                    CopyFrom(self._build_policy(config['policy'],
                             returnProto=True))
                static_config.maximum_peer_count = config['maxPeerCount']
                static_config. \
                    required_peer_count = config.get('requiredPeerCount', 0)
                static_config.block_to_live = config.get('blockToLive', 0)
                static_config.member_only_read = config.get(
                    'memberOnlyRead', False)

                collections_config = collection_pb2.CollectionConfig()
                collections_config.static_collection_config.CopyFrom(
                    static_config)

                collections_configs.append(collections_config)

            cc_coll_cfg = collection_pb2.CollectionConfigPackage()
            cc_coll_cfg.config.extend(collections_configs)
            args.append(cc_coll_cfg.SerializeToString())

        # construct the invoke spec
        invoke_input = chaincode_pb2.ChaincodeInput()
        invoke_input.args.extend(args)

        invoke_cc_id = chaincode_pb2.ChaincodeID()
        invoke_cc_id.name = proto_str('lscc')

        cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec()
        cc_invoke_spec.chaincode_spec.CopyFrom(
            create_cc_spec(invoke_input, invoke_cc_id, CC_TYPE_GOLANG))

        extension = proposal_pb2.ChaincodeHeaderExtension()
        extension.chaincode_id.name = proto_str('lscc')
        channel_header = build_channel_header(
            common_pb2.ENDORSER_TRANSACTION,
            tx_context.tx_id,
            self.name,
            current_timestamp(),
            epoch=0,
            extension=extension.SerializeToString())

        header = build_header(tx_context.identity, channel_header,
                              tx_context.nonce)
        proposal = build_cc_proposal(cc_invoke_spec, header,
                                     request.transient_map)

        signed_proposal = utils.sign_proposal(tx_context, proposal)
        response = [peer.send_proposal(signed_proposal) for peer in peers]
        return response, proposal, header
Ejemplo n.º 20
0
    def _send_cc_proposal(self, tx_context, command, peers):

        args = []
        request = tx_context.tx_prop_req

        args.append(proto_b(request.fcn))
        for arg in request.args:
            args.append(proto_b(arg))

        # construct the deployment spec
        cc_id = chaincode_pb2.ChaincodeID()
        cc_id.name = request.cc_name
        cc_id.version = request.cc_version

        cc_input = chaincode_pb2.ChaincodeInput()
        cc_input.args.extend(args)
        cc_spec = create_cc_spec(cc_input, cc_id, CC_TYPE_GOLANG)

        cc_dep_spec = chaincode_pb2.ChaincodeDeploymentSpec()
        cc_dep_spec.chaincode_spec.CopyFrom(cc_spec)

        # Pass msps, TODO create an MSPManager as done in fabric-sdk-node
        policy = self._build_policy(request.cc_endorsement_policy)

        # construct the invoke spec
        invoke_input = chaincode_pb2.ChaincodeInput()
        invoke_input.args.extend(
            [proto_b(command),
             proto_b(self.name),
             cc_dep_spec.SerializeToString(),
             policy,
             proto_b('escc'),
             proto_b('vscc')])

        invoke_cc_id = chaincode_pb2.ChaincodeID()
        invoke_cc_id.name = proto_str('lscc')

        cc_invoke_spec = chaincode_pb2.ChaincodeInvocationSpec()
        cc_invoke_spec.chaincode_spec.CopyFrom(create_cc_spec(invoke_input,
                                                              invoke_cc_id,
                                                              CC_TYPE_GOLANG)
                                               )

        extension = proposal_pb2.ChaincodeHeaderExtension()
        extension.chaincode_id.name = proto_str('lscc')
        channel_header = build_channel_header(
            common_pb2.ENDORSER_TRANSACTION,
            tx_context.tx_id,
            self.name,
            current_timestamp(),
            epoch=0,
            extension=extension.SerializeToString()
        )

        header = build_header(tx_context.identity,
                              channel_header,
                              tx_context.nonce)
        proposal = build_cc_proposal(
            cc_invoke_spec,
            header,
            request.transient_map)

        signed_proposal = utils.sign_proposal(tx_context, proposal)
        response = [peer.send_proposal(signed_proposal)
                    for peer in peers]
        return response, proposal, header
Ejemplo n.º 21
0
    def send_install_proposal(self, tx_context, peers=None):
        """Send install chaincode proposal

        :param install_proposal_req: install proposal request
        :param targets: a set of peer to send
        :param tx_context: a tx_context instance
        :param peers: peers (Default value = None)
        :return: a set of proposal response
        """
        if peers is None:
            targets = self._peers.values()
        else:
            targets = peers
        # self._validate_state() # TODO: enable this later
        # self._validate_peers(targets)  # TODO: enable this later

        if not tx_context:
            raise ValueError("InstallProposalRequest is null.")

        cc_deployment_spec = chaincode_pb2.ChaincodeDeploymentSpec()
        cc_deployment_spec.chaincode_spec.type = \
            chaincode_pb2.ChaincodeSpec.Type.Value(
                utils.proto_str(tx_context.tx_prop_req.cc_type))
        cc_deployment_spec.chaincode_spec.chaincode_id.name = \
            proto_str(tx_context.tx_prop_req.cc_name)
        cc_deployment_spec.chaincode_spec.chaincode_id.path = \
            proto_str(tx_context.tx_prop_req.cc_path)
        cc_deployment_spec.chaincode_spec.chaincode_id.version = \
            proto_str(tx_context.tx_prop_req.cc_version)
        if not self._is_dev_mode:
            if not tx_context.tx_prop_req.packaged_cc:
                cc_deployment_spec.code_package = \
                    package_chaincode(
                        tx_context.tx_prop_req.cc_path,
                        tx_context.tx_prop_req.cc_type)
            else:
                cc_deployment_spec.code_package = \
                    tx_context.tx_prop_req.packaged_cc

        channel_header_extension = proposal_pb2.ChaincodeHeaderExtension()
        channel_header_extension.chaincode_id.name = \
            proto_str("lscc")
        channel_header = utils.build_channel_header(
            common_pb2.ENDORSER_TRANSACTION,
            tx_context.tx_id,
            '',
            utils.current_timestamp(),
            tx_context.epoch,
            channel_header_extension.SerializeToString()
        )

        header = utils.build_header(tx_context.identity,
                                    channel_header,
                                    tx_context.nonce)

        cci_spec = chaincode_pb2.ChaincodeInvocationSpec()
        cci_spec.chaincode_spec.type = \
            chaincode_pb2.ChaincodeSpec.Type.Value(CC_TYPE_GOLANG)
        cci_spec.chaincode_spec.chaincode_id.name = proto_str("lscc")
        cci_spec.chaincode_spec.input.args.extend(
            [proto_b(CC_INSTALL), cc_deployment_spec.SerializeToString()])
        proposal = utils.build_cc_proposal(
            cci_spec, header,
            tx_context.tx_prop_req.transient_map)
        signed_proposal = utils.sign_proposal(tx_context, proposal)

        responses = [peer.send_proposal(signed_proposal)
                     for peer in targets]

        return responses, proposal, header
Ejemplo n.º 22
0
    def _create_or_update_channel_request(self, request, have_envelope):
        """Inits the create of update channel process.

        Args:
            request (dct): A create_update channel request.
            have_envelope (bool): Signals if the requests contains a finished
            protobuf envelope.

        Returns:
            rx.Observable: An observable for the orderer_response
                or an error.

        """
        _logger.debug('_create_or_update_channel - start')

        error_msg = None

        if 'config' not in request and not have_envelope:
            error_msg = 'Missing config request parameter containing ' \
                        'the configuration of the channel'

        if 'signatures' not in request and not have_envelope:
            error_msg = 'Missing signatures request parameter for the ' \
                        'new channel'
        elif 'signatures' in request and \
                not isinstance(request['signatures'], list) \
                and not have_envelope:
            error_msg = 'Signatures request parameter must be an array ' \
                        'of signatures'

        if 'tx_id' not in request and not have_envelope:
            error_msg = 'Missing tx_id request parameter'

        if 'nonce' not in request and not have_envelope:
            error_msg = 'Missing nonce request parameter'

        if 'orderer' not in request:
            error_msg = 'Missing orderer request parameter'

        if 'channel_name' not in request:
            error_msg = 'Missing channel_name request parameter'

        if error_msg:
            _logger.error(
                '_create_or_update_channel error: {}'.format(error_msg))
            raise ValueError(error_msg)

        if have_envelope:
            _logger.debug('_create_or_update_channel - have envelope')
            envelope = common_pb2.Envelope()
            envelope.ParseFromString(request['envelope'])

            signature = envelope.signature
            payload = envelope.payload

        else:
            _logger.debug('_create_or_update_channel - have config_update')
            proto_config_update_envelope = configtx_pb2.ConfigUpdateEnvelope()

            proto_config_update_envelope.config_update = request['config']

            # convert signatures to protobuf signature
            signatures = request['signatures']
            proto_signatures = utils.string_to_signature(signatures)

            proto_config_update_envelope.signatures.extend(proto_signatures)

            proto_channel_header = utils.build_channel_header(
                common_pb2.HeaderType.Value('CONFIG_UPDATE'), request['tx_id'],
                request['channel_name'], utils.current_timestamp())

            proto_header = utils.build_header(self.tx_context.identity,
                                              proto_channel_header,
                                              request['nonce'])

            proto_payload = common_pb2.Payload()

            proto_payload.header.CopyFrom(proto_header)
            proto_payload.data = proto_config_update_envelope \
                .SerializeToString()
            payload_bytes = proto_payload.SerializeToString()

            signature_bytes = self.tx_context.sign(payload_bytes)

            signature = signature_bytes
            payload = payload_bytes

        # assemble the final envelope
        out_envelope = common_pb2.Envelope()
        out_envelope.signature = signature
        out_envelope.payload = payload

        orderer = request['orderer']

        return orderer.broadcast(out_envelope)
Ejemplo n.º 23
0
    def join_channel(self, request):
        """
        To join the peer to a channel.

        Args:
            request: the request to join a channel
        Return:
            True in sucess or False in failure
        """
        _logger.debug('join_channel - start')

        err_msg = None
        if (not request):
            err_msg = "Missing all required input request parameters"

        if 'targets' not in request:
            err_msg = "Missing peers parameter"

        if 'block' not in request:
            err_msg = "Missing genesis block parameter"

        if 'tx_id' not in request:
            err_msg = "Missing transaction id parameter"

        if err_msg:
            _logger.error('join_channel error: {}'.format(err_msg))
            raise ValueError(err_msg)

        tx_context = self._client.tx_context
        chaincode_spec = create_chaincode_spec(request['block'], 'cscc',
                                               "GOLANG")

        extension = chaincode_spec.SerializeToString()
        channel_header = build_channel_header(
            common_pb2.HeaderType.Value('ENDORSER_TRANSACTION'),
            tx_context.tx_id,
            self.name,
            current_timestamp(),
            tx_context.epoch,
            extension=extension)

        creator = create_serialized_identity(tx_context.user)
        header = build_header(creator, channel_header, tx_context.nonce)
        proposal = build_cc_proposal(chaincode_spec, header, {})

        try:
            responses = send_transaction_proposal(proposal, header, tx_context,
                                                  request['targets'])
        except Exception as e:
            raise IOError("fail to send transanction proposal", e)

        q = Queue(1)
        for r in responses:
            r.subscribe(on_next=lambda x: q.put(x),
                        on_error=lambda x: q.put(x))
            res = q.get(timeout=5)

            result = True and (res.response.status == 200)

        _logger.info("The return status is:", result)
        return result