Ejemplo n.º 1
0
    def chaincode_invoke(self, requestor, channel_name, peer_names, args,
                         cc_name, cc_version, cc_type=CC_TYPE_JAVA, timeout=10):
        """
        Invoke chaincode for ledger update

        :param requestor: User role who issue the request
        :param channel_name: the name of the channel to send tx proposal
        :param peer_names: Names of the peers to install
        :param args (list): arguments (keys and values) for initialization
        :param cc_name: chaincode name
        :param cc_version: chaincode version
        :param cc_type: chaincode language
        :param timeout: Timeout to wait
        :return: True or False
        """
        peers = []
        for peer_name in peer_names:
            peer = self.get_peer(peer_name)
            peers.append(peer)

        tran_prop_req = create_tx_prop_req(
            prop_type=CC_INVOKE,
            cc_type=cc_type,
            cc_name=cc_name,
            cc_version=cc_version,
            fcn='invoke',
            args=args
        )

        tx_context = create_tx_context(
            requestor,
            ecies(),
            tran_prop_req
        )

        res = self.get_channel(
            channel_name).send_tx_proposal(tx_context, peers)

        tran_req = utils.build_tx_req(res)
        tx_context_tx = create_tx_context(
            requestor,
            ecies(),
            tran_req
        )

        utils.send_transaction(self.orderers, tran_req, tx_context_tx)

        queue = Queue(1)
        res.subscribe(
            on_next=lambda x: queue.put(x),
            on_error=lambda x: queue.put(x)
        )

        res = queue.get(timeout=timeout)
        _logger.debug(res)
        return res[0][0][0].response
Ejemplo n.º 2
0
    def cc_invoke(self, args, cc_name, fcn, cc_version, queryonly=False):
        loop = asyncio.get_event_loop()
        crypto = ecies()

        endorses = self._get_endorsers(queryonly)

        tran_prop_req = create_tx_prop_req(
            prop_type=CC_INVOKE,
            cc_type=CC_TYPE_GOLANG, cc_name=cc_name, fcn=fcn,
            cc_version=cc_version, args=args)

        tx_context = create_tx_context(self.user, crypto, tran_prop_req)

        responses, proposal, header = self.channel.send_tx_proposal(
            tx_context, endorses.values())

        res = loop.run_until_complete(asyncio.gather(*responses))

        if queryonly:
            return res

        tran_req = build_tx_req((res, proposal, header))

        tx_context_tx = create_tx_context(self.user,
                                          crypto,
                                          TXProposalRequest())

        responses = loop.run_until_complete(base.get_stream_result(
            send_transaction(self.client.orderers, tran_req, tx_context_tx)))

        logger.info('Tx response: {0}'.format(responses))

        return responses
Ejemplo n.º 3
0
    def test_instantiate_chaincode(self):

        channel = self.client.new_channel(self.channel_name)
        org1 = 'org1.example.com'
        peer_config = test_network['org1.example.com']['peers']['peer0']
        tls_cacerts = peer_config['tls_cacerts']
        opts = (('grpc.ssl_target_name_override',
                 peer_config['server_hostname']), )
        endpoint = peer_config['grpc_request_endpoint']

        peer = create_peer(endpoint=endpoint,
                           tls_cacerts=tls_cacerts,
                           opts=opts)

        org1_admin = get_peer_org_user(org1, 'Admin', self.client.state_store)
        crypto = ecies()

        # for chain code install
        tran_prop_req_in = create_tx_prop_req(prop_type=CC_INSTALL,
                                              cc_path=CC_PATH,
                                              cc_type=CC_TYPE_GOLANG,
                                              cc_name=CC_NAME,
                                              cc_version=CC_VERSION)

        # install chain code
        tx_context_in = create_tx_context(org1_admin, crypto, tran_prop_req_in)

        # for chain code deploy
        args = ['a', '100', 'b', '40']
        tran_prop_req_dep = create_tx_prop_req(prop_type=CC_INSTANTIATE,
                                               cc_type=CC_TYPE_GOLANG,
                                               cc_name=CC_NAME,
                                               cc_version=CC_VERSION,
                                               args=args,
                                               fcn='init')

        # deploy the chain code
        tx_context_dep = create_tx_context(org1_admin, crypto,
                                           tran_prop_req_dep)

        # create a channel
        request = build_channel_request(self.client, self.channel_tx,
                                        self.channel_name)

        self.client._create_channel(request)

        # join channel
        join_req = build_join_channel_req(org1, channel, self.client)
        channel.join_channel(join_req)

        self.client.send_install_proposal(tx_context_in, [peer])

        # send the transaction to the channel
        res = channel.send_instantiate_proposal(tx_context_dep, [peer])
        tran_req = build_tx_req(res)

        tx_context = create_tx_context(org1_admin, crypto, TXProposalRequest())
        response = send_transaction(channel.orderers, tran_req, tx_context)

        self.assertEqual(response[0].status, 200)
Ejemplo n.º 4
0
    def chaincode_instantiate(self, requestor, channel_name, peer_names, args,
                              cc_name, cc_version, timeout=10):
        """
            Instantiate installed chaincode to particular peer in
            particular channel

        :param requestor: User role who issue the request
        :param channel_name: the name of the channel to send tx proposal
        :param peer_names: Names of the peers to install
        :param args (list): arguments (keys and values) for initialization
        :param cc_name: chaincode name
        :param cc_version: chaincode version
        :param timeout: Timeout to wait
        :return: True or False
        """
        peers = []
        for peer_name in peer_names:
            peer = self.get_peer(peer_name)
            peers.append(peer)

        tran_prop_req_dep = create_tx_prop_req(
            prop_type=CC_INSTANTIATE,
            cc_type=CC_TYPE_GOLANG,
            cc_name=cc_name,
            cc_version=cc_version,
            fcn='init',
            args=args
        )

        tx_context_dep = create_tx_context(
            requestor,
            ecies(),
            tran_prop_req_dep
        )

        res = self.send_instantiate_proposal(
            tx_context_dep, peers, channel_name)

        sleep(5)

        tx_context = create_tx_context(requestor,
                                       ecies(),
                                       TXProposalRequest())
        tran_req = utils.build_tx_req(res)
        response = utils.send_transaction(self.orderers, tran_req, tx_context)

        sleep(5)

        self.txid_for_test = tx_context_dep.tx_id  # used only for query test

        queue = Queue(1)
        response.subscribe(
            on_next=lambda x: queue.put(x),
            on_error=lambda x: queue.put(x)
        )

        res, _ = queue.get(timeout=timeout)
        _logger.debug(res)
        return res.status == 200
Ejemplo n.º 5
0
    def cc_invoke(self, args, cc_name, fcn, cc_version, queryonly=False):
        """
        Invoke a chaincode method.

        Parameters:
        args       JSON RPC serialized data used as the
                   sole parameter to invoke the chaincode
        cc_name    chaincode name
        fcn        chaincode function name to be invoked
        cc_version chaincode version to be used
        queryonly  If the invocation does not result in ledger change,
                   queryonly should be set to True.
                   If the invocation does result in ledger change, it should
                   be set to False.
        """
        if queryonly:
            return self.cc_query(args, cc_name, fcn)

        loop = asyncio.get_event_loop()
        crypto = ecies()

        endorses = self._get_endorsers(queryonly)

        tran_prop_req = create_tx_prop_req(prop_type=CC_INVOKE,
                                           cc_type=CC_TYPE_GOLANG,
                                           cc_name=cc_name,
                                           fcn=fcn,
                                           cc_version=cc_version,
                                           args=args)

        tx_context = create_tx_context(self.user, crypto, tran_prop_req)

        responses, proposal, header = self.channel.send_tx_proposal(
            tx_context, endorses.values())

        res = loop.run_until_complete(asyncio.gather(*responses))

        tran_req = build_tx_req((res, proposal, header))

        tx_context_tx = create_tx_context(self.user, crypto,
                                          TXProposalRequest())

        responses = loop.run_until_complete(
            base.get_stream_result(
                send_transaction(self.client.orderers, tran_req,
                                 tx_context_tx)))

        logger.info('Tx response: {}'.format(responses))
        return responses
Ejemplo n.º 6
0
    def test_invoke_chaincode_sucess(self):

        channel = self.client.new_channel(self.channel_name)
        org1 = "org1.example.com"
        peer_config = test_network['org1.example.com']['peers']['peer0']
        tls_cacerts = peer_config['tls_cacerts']
        opts = (('grpc.ssl_target_name_override',
                 peer_config['server_hostname']), )
        endpoint = peer_config['grpc_request_endpoint']
        org1_peer = create_peer(endpoint=endpoint,
                                tls_cacerts=tls_cacerts,
                                opts=opts)
        org1_admin = get_peer_org_user(org1, "Admin", self.client.state_store)

        crypto = ecies()
        tran_prop_req_install = create_tx_prop_req(prop_type=CC_INSTALL,
                                                   cc_path=CC_PATH,
                                                   cc_type=CC_TYPE_GOLANG,
                                                   cc_name=CC_NAME,
                                                   cc_version=CC_VERSION)
        tx_context_install = create_tx_context(org1_admin, crypto,
                                               tran_prop_req_install)

        args_dep = ['a', '200', 'b', '300']
        tran_prop_req_dep = create_tx_prop_req(prop_type=CC_INSTANTIATE,
                                               cc_type=CC_TYPE_GOLANG,
                                               cc_name=CC_NAME,
                                               cc_version=CC_VERSION,
                                               args=args_dep,
                                               fcn='init')

        tx_context_dep = create_tx_context(org1_admin, crypto,
                                           tran_prop_req_dep)

        args = ['a', 'b', '100']
        tran_prop_req = create_tx_prop_req(prop_type=CC_INVOKE,
                                           cc_type=CC_TYPE_GOLANG,
                                           cc_name=CC_NAME,
                                           cc_version=CC_VERSION,
                                           fcn='invoke',
                                           args=args)
        tx_context = create_tx_context(org1_admin, crypto, tran_prop_req)

        request = build_channel_request(self.client, self.channel_tx,
                                        self.channel_name)
        self.client._create_channel(request)
        sleep(5)

        join_req = build_join_channel_req(org1, channel, self.client)
        channel.join_channel(join_req)
        sleep(5)

        self.client.send_install_proposal(tx_context_install, [org1_peer])
        sleep(5)

        res = channel.send_instantiate_proposal(tx_context_dep, [org1_peer])
        sleep(5)

        tran_req = build_tx_req(res)
        send_transaction(channel.orderers, tran_req, tx_context)
        sleep(5)

        tx_context_tx = create_tx_context(org1_admin, crypto,
                                          TXProposalRequest())
        res = channel.send_tx_proposal(tx_context, [org1_peer])

        tran_req = build_tx_req(res)
        response = send_transaction(channel.orderers, tran_req, tx_context_tx)
        q = Queue(1)
        response.subscribe(on_next=lambda x: q.put(x),
                           on_error=lambda x: q.put(x))
        res, _ = q.get(timeout=5)
        self.assertEqual(res.status, 200)
Ejemplo n.º 7
0
    async def invoke_chaincode(self):

        org1 = "org1.example.com"
        peer_config = test_network['org1.example.com']['peers']['peer0']
        tls_cacerts = peer_config['tls_cacerts']
        opts = (('grpc.ssl_target_name_override',
                 peer_config['server_hostname']), )
        endpoint = peer_config['grpc_request_endpoint']

        self.peer = create_peer(endpoint=endpoint,
                                tls_cacerts=tls_cacerts,
                                opts=opts)

        self.org1_admin = get_peer_org_user(org1, "Admin",
                                            self.client.state_store)

        # channel create
        request = build_channel_request(self.client, self.channel_tx,
                                        self.channel_name)
        responses = await self.client._create_or_update_channel(request)
        self.assertTrue(all([x.status == 200 for x in responses]))

        self.channel = self.client.new_channel(self.channel_name)

        # join channel

        join_req = await build_join_channel_req(org1, self.channel,
                                                self.client)

        responses = self.channel.join_channel(join_req)
        res = await asyncio.gather(*responses)
        self.assertTrue(all([x.response.status == 200 for x in res]))

        # install

        tran_prop_req_install = create_tx_prop_req(prop_type=CC_INSTALL,
                                                   cc_path=CC_PATH,
                                                   cc_type=CC_TYPE_GOLANG,
                                                   cc_name=CC_NAME,
                                                   cc_version=CC_VERSION)

        tx_context_install = create_tx_context(self.org1_admin,
                                               self.org1_admin.cryptoSuite,
                                               tran_prop_req_install)

        responses, proposal, header = self.client.send_install_proposal(
            tx_context_install, [self.peer])
        await asyncio.gather(*responses)

        # instantiate

        args_dep = ['a', '200', 'b', '300']

        tran_prop_req_dep = create_tx_prop_req(prop_type=CC_INSTANTIATE,
                                               cc_type=CC_TYPE_GOLANG,
                                               cc_name=CC_NAME,
                                               cc_version=CC_VERSION,
                                               args=args_dep,
                                               fcn='init')
        tx_context_dep = create_tx_context(self.org1_admin,
                                           self.org1_admin.cryptoSuite,
                                           tran_prop_req_dep)
        responses, proposal, header = self.channel.send_instantiate_proposal(
            tx_context_dep, [self.peer])
        res = await asyncio.gather(*responses)

        tran_req = build_tx_req((res, proposal, header))
        tx_context = create_tx_context(self.org1_admin,
                                       self.org1_admin.cryptoSuite,
                                       TXProposalRequest())
        await get_stream_result(
            send_transaction(self.client.orderers, tran_req, tx_context))

        # wait for event instantiate
        channel_event_hub = self.channel.newChannelEventHub(
            self.peer, self.org1_admin)
        stream = channel_event_hub.connect(filtered=False)

        channel_event_hub.registerTxEvent(tx_context_dep.tx_id,
                                          disconnect=True)

        try:
            await asyncio.wait_for(stream, timeout=30)
        except asyncio.TimeoutError:
            raise TimeoutError('waitForEvent timed out.')
        except Exception as e:
            if not isinstance(e, grpc._channel._Rendezvous) \
                    or not e.cancelled():
                raise e
        finally:
            channel_event_hub.disconnect()

        # invoke part
        args = ['a', 'b', '100']
        tran_prop_req = create_tx_prop_req(prop_type=CC_INVOKE,
                                           cc_type=CC_TYPE_GOLANG,
                                           cc_name=CC_NAME,
                                           fcn='invoke',
                                           args=args)

        tx_context = create_tx_context(self.org1_admin,
                                       self.org1_admin.cryptoSuite,
                                       tran_prop_req)

        responses, p, h = self.channel.send_tx_proposal(
            tx_context, [self.peer])
        res = await asyncio.gather(*responses)
        tran_req = build_tx_req((res, p, h))

        tx_context_tx = create_tx_context(self.org1_admin,
                                          self.org1_admin.cryptoSuite,
                                          tran_req)
        await get_stream_result(
            send_transaction(self.channel.orderers, tran_req, tx_context_tx))

        # wait for chaincode events
        channel_event_hub = self.channel.newChannelEventHub(
            self.peer, self.org1_admin)

        stream = channel_event_hub.connect(filtered=False)

        self.evts = {}
        # with tx event
        # channel_event_hub.registerTxEvent(tx_context.tx_id,
        #                                  unregister=True, disconnect=True,
        #                                  onEvent=self.onTxEvent)

        # with chaincode event
        self.registerChaincodeEvent(tx_context.tx_id, CC_NAME, '^invoked*',
                                    channel_event_hub)

        try:
            await asyncio.wait_for(stream, timeout=30)
        except asyncio.TimeoutError:
            raise TimeoutError('waitForEvent timed out.')
        except Exception as e:
            if not isinstance(e, grpc._channel._Rendezvous) \
                    or not e.cancelled():
                raise e
        finally:
            channel_event_hub.disconnect()

        return tx_context.tx_id
Ejemplo n.º 8
0
    def test_invoke_chaincode_sucess(self):
        loop = asyncio.get_event_loop()

        channel = self.client.new_channel(self.channel_name)
        org1 = "org1.example.com"
        peer_config = test_network['org1.example.com']['peers']['peer0']
        tls_cacerts = peer_config['tls_cacerts']
        opts = (('grpc.ssl_target_name_override',
                 peer_config['server_hostname']), )
        endpoint = peer_config['grpc_request_endpoint']
        org1_peer = create_peer(endpoint=endpoint,
                                tls_cacerts=tls_cacerts,
                                opts=opts)
        org1_admin = get_peer_org_user(org1, "Admin", self.client.state_store)

        crypto = ecies()
        tran_prop_req_install = create_tx_prop_req(prop_type=CC_INSTALL,
                                                   cc_path=CC_PATH,
                                                   cc_type=CC_TYPE_GOLANG,
                                                   cc_name=CC_NAME,
                                                   cc_version=CC_VERSION)
        tx_context_install = create_tx_context(org1_admin, crypto,
                                               tran_prop_req_install)

        args_dep = ['a', '200', 'b', '300']
        tran_prop_req_dep = create_tx_prop_req(prop_type=CC_INSTANTIATE,
                                               cc_type=CC_TYPE_GOLANG,
                                               cc_name=CC_NAME,
                                               cc_version=CC_VERSION,
                                               args=args_dep,
                                               fcn='init')

        tx_context_dep = create_tx_context(org1_admin, crypto,
                                           tran_prop_req_dep)

        args = ['a', 'b', '100']
        tran_prop_req = create_tx_prop_req(prop_type=CC_INVOKE,
                                           cc_type=CC_TYPE_GOLANG,
                                           cc_name=CC_NAME,
                                           fcn='invoke',
                                           args=args)
        tx_context = create_tx_context(org1_admin, crypto, tran_prop_req)

        request = build_channel_request(self.client, self.channel_tx,
                                        self.channel_name)
        loop.run_until_complete(self.client._create_or_update_channel(request))

        join_req = loop.run_until_complete(
            build_join_channel_req(org1, channel, self.client))
        responses = channel.join_channel(join_req)
        res = loop.run_until_complete(asyncio.gather(*responses))
        self.assertTrue(all([x.response.status == 200 for x in res]))

        responses, proposal, header = self.client.send_install_proposal(
            tx_context_install, [org1_peer])
        loop.run_until_complete(asyncio.gather(*responses))

        responses, proposal, header = channel.send_instantiate_proposal(
            tx_context_dep, [org1_peer])
        res = loop.run_until_complete(asyncio.gather(*responses))

        tran_req = build_tx_req((res, proposal, header))
        send_transaction(channel.orderers, tran_req, tx_context)
        loop.run_until_complete(
            get_stream_result(
                send_transaction(channel.orderers, tran_req, tx_context)))

        tx_context_tx = create_tx_context(org1_admin, crypto,
                                          TXProposalRequest())
        responses, proposal, header = channel.send_tx_proposal(
            tx_context, [org1_peer])
        res = loop.run_until_complete(asyncio.gather(*responses))

        tran_req = build_tx_req((res, proposal, header))

        responses = loop.run_until_complete(
            get_stream_result(
                send_transaction(channel.orderers, tran_req, tx_context_tx)))

        self.assertTrue(all([x.status == 200 for x in responses]))
Ejemplo n.º 9
0
    def invoke_chaincode(self):

        self.channel = self.client.new_channel(self.channel_name)
        org1 = "org1.example.com"
        peer_config = test_network['org1.example.com']['peers']['peer0']
        tls_cacerts = peer_config['tls_cacerts']
        opts = (('grpc.ssl_target_name_override',
                 peer_config['server_hostname']), )
        endpoint = peer_config['grpc_request_endpoint']
        self.org1_peer = create_peer(endpoint=endpoint,
                                     tls_cacerts=tls_cacerts,
                                     opts=opts)
        self.org1_admin = get_peer_org_user(org1, "Admin",
                                            self.client.state_store)

        crypto = ecies()
        tran_prop_req_install = create_tx_prop_req(prop_type=CC_INSTALL,
                                                   cc_path=CC_PATH,
                                                   cc_type=CC_TYPE_GOLANG,
                                                   cc_name=CC_NAME,
                                                   cc_version=CC_VERSION)
        tx_context_install = create_tx_context(self.org1_admin, crypto,
                                               tran_prop_req_install)

        args_dep = ['a', '200', 'b', '300']
        tran_prop_req_dep = create_tx_prop_req(prop_type=CC_INSTANTIATE,
                                               cc_type=CC_TYPE_GOLANG,
                                               cc_name=CC_NAME,
                                               cc_version=CC_VERSION,
                                               args=args_dep,
                                               fcn='init')

        tx_context_dep = create_tx_context(self.org1_admin, crypto,
                                           tran_prop_req_dep)

        args = ['a', 'b', '100']
        tran_prop_req = create_tx_prop_req(prop_type=CC_INVOKE,
                                           cc_type=CC_TYPE_GOLANG,
                                           cc_name=CC_NAME,
                                           cc_version=CC_VERSION,
                                           fcn='invoke',
                                           args=args)
        tx_context = create_tx_context(self.org1_admin, crypto, tran_prop_req)

        request = build_channel_request(self.client, self.channel_tx,
                                        self.channel_name)
        self.client._create_channel(request)

        join_req = build_join_channel_req(org1, self.channel, self.client)
        self.channel.join_channel(join_req)

        self.client.send_install_proposal(tx_context_install, [self.org1_peer])

        res = self.channel.send_instantiate_proposal(tx_context_dep,
                                                     [self.org1_peer])
        tran_req = build_tx_req(res)
        send_transaction(self.channel.orderers, tran_req, tx_context)

        tx_context_tx = create_tx_context(self.org1_admin, crypto,
                                          TXProposalRequest())

        res = self.channel.send_tx_proposal(tx_context, [self.org1_peer])

        tran_req = build_tx_req(res)

        res = send_transaction(self.channel.orderers, tran_req, tx_context_tx)

        tx_id = tx_context_dep.tx_id

        return tx_id
Ejemplo n.º 10
0
    async def invoke(
            self,
            requestor,
            channel_name,
            peers,
            args,
            cc_type=CC_TYPE_GOLANG,
            fcn='invoke',
            cc_pattern=None,
            transient_map=None,
            wait_for_event=False,
            wait_for_event_timeout=DEFAULT_WAIT_FOR_EVENT_TIMEOUT,
            grpc_broker_unavailable_retry=0,
            grpc_broker_unavailable_retry_delay=GRPC_BROKER_UNAVAILABLE_RETRY_DELAY,  # ms
            raise_broker_unavailable=True):
        """
        Invoke chaincode for ledger update

        :param requestor: User role who issue the request
        :param channel_name: the name of the channel to send tx proposal
        :param peers: List of  peer name and/or Peer to install
        :param args (list): arguments (keys and values) for initialization
        :param cc_type: chaincode type language
        :param fcn: chaincode function
        :param cc_pattern: chaincode event name regex
        :param transient_map: transient map
        :param wait_for_event: Whether to wait for the event from each peer's
         deliver filtered service signifying that the 'invoke' transaction has
          been committed successfully
        :param wait_for_event_timeout: Time to wait for the event from each
         peer's deliver filtered service signifying that the 'invoke'
          transaction has been committed successfully (default 30s)
        :param grpc_broker_unavailable_retry: Number of retry if a broker
         is unavailable (default 0)
        :param grpc_broker_unavailable_retry_delay : Delay in ms to retry
         (default 3000 ms)
        :param raise_broker_unavailable: Raise if any broker is unavailable,
         else always send the proposal regardless of unavailable brokers.

        :return: invoke result
        """
        target_peers = self._client.get_target_peers(peers)

        tran_prop_req = create_tx_prop_req(prop_type=CC_INVOKE,
                                           cc_name=self._name,
                                           cc_type=cc_type,
                                           fcn=fcn,
                                           args=args,
                                           transient_map=transient_map)

        tx_context = create_tx_context(requestor, requestor.cryptoSuite,
                                       tran_prop_req)

        channel = self._client.get_channel(channel_name)

        # send proposal
        responses, proposal, header = channel.send_tx_proposal(
            tx_context, target_peers)

        # The proposal return does not contain the transient map
        # because we do not sent it in the real transaction later
        res = await asyncio.gather(*responses, return_exceptions=True)
        failed_res = list(
            map(lambda x: isinstance(x, _MultiThreadedRendezvous), res))

        # remove failed_res from res, orderer will take care of unmet policy (can be different between app,
        # you should costumize this method to your own needs)
        if any(failed_res):
            res = list(
                filter(
                    lambda x: hasattr(x, 'response') and x.response.status ==
                    SUCCESS_STATUS, res))

            # should we retry on failed?
            if grpc_broker_unavailable_retry:
                _logger.debug('Retry on failed proposal responses')

                retry = 0

                # get failed peers
                failed_target_peers = list(
                    itertools.compress(target_peers, failed_res))

                while retry < grpc_broker_unavailable_retry:
                    _logger.debug(
                        f'Retrying getting proposal responses from peers:'
                        f' {[x.name for x in failed_target_peers]}, retry: {retry}'
                    )

                    retry_responses, _, _ = channel.send_tx_proposal(
                        tx_context, failed_target_peers)
                    retry_res = await asyncio.gather(*retry_responses,
                                                     return_exceptions=True)

                    # get failed res
                    failed_res = list(
                        map(lambda x: isinstance(x, _MultiThreadedRendezvous),
                            retry_res))

                    # add successful responses to res and recompute failed_target_peers
                    res += list(
                        filter(
                            lambda x: hasattr(x, 'response') and x.response.
                            status == SUCCESS_STATUS, retry_res))
                    failed_target_peers = list(
                        itertools.compress(failed_target_peers, failed_res))

                    if len(failed_target_peers) == 0:
                        break

                    retry += 1
                    # TODO should we use a backoff?
                    _logger.debug(
                        f'Retry in {grpc_broker_unavailable_retry_delay}ms')
                    sleep(grpc_broker_unavailable_retry_delay /
                          1000)  # milliseconds

                if len(failed_target_peers) > 0:
                    if raise_broker_unavailable:
                        raise Exception(
                            f'Could not reach peer grpc broker {[x.name for x in failed_target_peers]}'
                            f' even after {grpc_broker_unavailable_retry} retries.'
                        )
                    else:
                        _logger.debug(
                            f'Could not reach peer grpc broker {[x.name for x in failed_target_peers]}'
                            f' even after {grpc_broker_unavailable_retry} retries.'
                        )
                else:
                    _logger.debug('Proposals retrying successful.')

        # if proposal was not good, return
        if any([x.response.status != SUCCESS_STATUS for x in res]):
            return '; '.join({
                x.response.message
                for x in res if x.response.status != SUCCESS_STATUS
            })

        # send transaction to the orderer
        tran_req = utils.build_tx_req((res, proposal, header))
        tx_context_tx = create_tx_context(requestor, requestor.cryptoSuite,
                                          tran_req)

        # response is a stream
        response = utils.send_transaction(self._client.orderers, tran_req,
                                          tx_context_tx)

        async for v in response:
            if not v.status == SUCCESS_STATUS:
                return v.message
        # wait for transaction id proposal available in ledger and block
        # commited
        if wait_for_event:
            await self.wait_for_event(tx_context, target_peers, channel,
                                      requestor, cc_pattern,
                                      wait_for_event_timeout)

        res = decode_proposal_response_payload(res[0].payload)
        return res['extension']['response']['payload'].decode('utf-8')
Ejemplo n.º 11
0
    async def _instantiate_or_upgrade(
            self,
            operation_name,
            requestor,
            channel_name,
            peers,
            cc_version,
            cc_endorsement_policy=None,
            fcn='init',
            args=None,
            transient_map=None,
            collections_config=None,
            wait_for_event=False,
            wait_for_event_timeout=DEFAULT_WAIT_FOR_EVENT_TIMEOUT,
            cc_type=CC_TYPE_GOLANG):
        """
            Instantiate installed chaincode to particular peer in
            particular channel

        :param operation_name: CC_INSTANTIATE or CC_UPGRADE
        :param requestor: User role who issue the request
        :param channel_name: the name of the channel to send tx proposal
        :param peers: List of  peer name and/or Peer to install
        :param cc_version: chaincode version
        :param cc_endorsement_policy: chaincode endorsement policy
        :param fcn: chaincode function to send
        :param args (list): arguments (keys and values) for initialization
        :param transient_map: transient map
        :param collections_config: collection configuration
        :param wait_for_event: Whether to wait for the event from each peer's
         deliver filtered service signifying that the 'invoke' transaction has
          been committed successfully
        :param wait_for_event_timeout: Time to wait for the event from each
         peer's deliver filtered service signifying that the 'invoke'
          transaction has been committed successfully (default 30s)
        :param cc_type: the language type of the chaincode
        :return: chaincode data payload
        """
        target_peers = self._client.get_target_peers(peers)
        operation = self.operation_mapping[operation_name](fcn)

        tran_prop_req_dep = create_tx_prop_req(
            prop_type=operation.operation_type,
            cc_type=cc_type,
            cc_name=self._name,
            cc_version=cc_version,
            cc_endorsement_policy=cc_endorsement_policy,
            fcn=operation.fcn,
            args=args,
            transient_map=transient_map,
            collections_config=collections_config)

        tx_context_dep = create_tx_context(requestor, requestor.cryptoSuite,
                                           tran_prop_req_dep)

        channel = self._client.get_channel(channel_name)

        responses, proposal, header = operation.send_proposal(
            tx_context_dep, target_peers, channel)
        res = await asyncio.gather(*responses)
        # if proposal was not good, return
        if not all([x.response.status == SUCCESS_STATUS for x in res]):
            raise RuntimeError(res[0].response.message)

        tran_req = utils.build_tx_req((res, proposal, header))

        tx_context = create_tx_context(requestor, requestor.cryptoSuite,
                                       TXProposalRequest())
        responses = utils.send_transaction(self._client.orderers, tran_req,
                                           tx_context)

        # responses will be a stream
        async for v in responses:
            if not v.status == SUCCESS_STATUS:
                raise RuntimeError(v.message)

        res = decode_proposal_response_payload(res[0].payload)

        # wait for transaction id proposal available in ledger and block
        # commited
        if wait_for_event:
            await self.wait_for_event(tx_context_dep, target_peers, channel,
                                      requestor, None, wait_for_event_timeout)

        ccd = ChaincodeData()
        payload = res['extension']['response']['payload']
        ccd.ParseFromString(payload)

        cdsData = CDSData()
        cdsData.ParseFromString(ccd.data)

        policy = decode_signature_policy_envelope(
            ccd.policy.SerializeToString())
        instantiation_policy = decode_signature_policy_envelope(
            ccd.instantiation_policy.SerializeToString())
        chaincode = {
            'name': ccd.name,
            'version': ccd.version,
            'escc': ccd.escc,
            'vscc': ccd.vscc,
            'policy': policy,
            'data': {
                'hash': cdsData.hash,
                'metadatahash': cdsData.metadatahash,
            },
            'id': ccd.id,
            'instantiation_policy': instantiation_policy,
        }
        return chaincode
Ejemplo n.º 12
0
    def chaincode_invoke(self,
                         requestor,
                         channel_name,
                         peer_names,
                         args,
                         cc_name,
                         cc_version,
                         cc_type=CC_TYPE_GOLANG,
                         fcn='invoke',
                         timeout=10):
        """
        Invoke chaincode for ledger update

        :param requestor: User role who issue the request
        :param channel_name: the name of the channel to send tx proposal
        :param peer_names: Names of the peers to install
        :param args (list): arguments (keys and values) for initialization
        :param cc_name: chaincode name
        :param cc_version: chaincode version
        :param cc_type: chaincode type language
        :param fcn: chaincode function
        :param timeout: Timeout to wait
        :return: True or False
        """
        peers = []
        for peer_name in peer_names:
            peer = self.get_peer(peer_name)
            peers.append(peer)

        tran_prop_req = create_tx_prop_req(prop_type=CC_INVOKE,
                                           cc_name=cc_name,
                                           cc_version=cc_version,
                                           cc_type=cc_type,
                                           fcn=fcn,
                                           args=args)

        tx_context = create_tx_context(requestor, ecies(), tran_prop_req)

        res = self.get_channel(channel_name).send_tx_proposal(
            tx_context, peers)

        tran_req = utils.build_tx_req(res)

        tx_context_tx = create_tx_context(requestor, ecies(), tran_req)

        responses = utils.send_transaction(self.orderers, tran_req,
                                           tx_context_tx)

        res = tran_req.responses[0].response
        if not (res.status == 200 and responses[0].status == 200):
            return res.message

        # Wait until chaincode invoke is really effective
        # Note : we will remove this part when we have channel event hub
        starttime = int(time.time())
        payload = None
        while int(time.time()) - starttime < timeout:
            try:
                response = self.query_transaction(requestor=requestor,
                                                  channel_name=channel_name,
                                                  peer_names=peer_names,
                                                  tx_id=tx_context.tx_id,
                                                  decode=False)

                if response.response.status == 200:
                    payload = tran_req.responses[0].response.payload
                    return payload.decode('utf-8')

                time.sleep(1)
            except Exception:
                time.sleep(1)

        msg = 'Failed to invoke chaincode. Query check returned: %s'
        return msg % payload.message
Ejemplo n.º 13
0
    def chaincode_instantiate(self,
                              requestor,
                              channel_name,
                              peer_names,
                              args,
                              cc_name,
                              cc_version,
                              timeout=10):
        """
            Instantiate installed chaincode to particular peer in
            particular channel

        :param requestor: User role who issue the request
        :param channel_name: the name of the channel to send tx proposal
        :param peer_names: Names of the peers to install
        :param args (list): arguments (keys and values) for initialization
        :param cc_name: chaincode name
        :param cc_version: chaincode version
        :param timeout: Timeout to wait
        :return: True or False
        """
        peers = []
        for peer_name in peer_names:
            peer = self.get_peer(peer_name)
            peers.append(peer)

        tran_prop_req_dep = create_tx_prop_req(prop_type=CC_INSTANTIATE,
                                               cc_type=CC_TYPE_GOLANG,
                                               cc_name=cc_name,
                                               cc_version=cc_version,
                                               fcn='init',
                                               args=args)

        tx_context_dep = create_tx_context(requestor, ecies(),
                                           tran_prop_req_dep)

        res = self.send_instantiate_proposal(tx_context_dep, peers,
                                             channel_name)

        tx_context = create_tx_context(requestor, ecies(), TXProposalRequest())
        tran_req = utils.build_tx_req(res)
        responses = utils.send_transaction(self.orderers, tran_req, tx_context)

        if not (tran_req.responses[0].response.status == 200
                and responses[0].status == 200):
            return False

        # Wait until chaincode is really instantiated
        # Note : we will remove this part when we have channel event hub
        starttime = int(time.time())
        while int(time.time()) - starttime < timeout:
            try:
                response = self.query_transaction(requestor=requestor,
                                                  channel_name=channel_name,
                                                  peer_names=peer_names,
                                                  tx_id=tx_context_dep.tx_id,
                                                  decode=False)

                if response.response.status == 200:
                    return True

                time.sleep(1)
            except Exception:
                time.sleep(1)

        return False
Ejemplo n.º 14
0
    def __cc_call(self, fcn, args, prop_type=CC_INVOKE):
        """Instantiate chaincode or invoke a cc function with args

        Args:
            fcn:        Chaincode function name
            args:       Chaincode function arguments
            prop_type:  Proposal request type (defaults to CC_INVOKE)
        Returns:
            Chaincode response
            None when prop_type is not valid
        """

        tran_prop_req = create_tx_prop_req(
            prop_type=prop_type,
            cc_type=CC_TYPE_GOLANG,
            cc_name=CC_NAME,
            cc_version=CC_VERSION,
            fcn=fcn,
            args=args)
        tx_ctx = create_tx_context(self.ixp_admin, self.crypto, tran_prop_req)

        # invoke calls
        if prop_type == CC_INVOKE:
            # send standard invocation
            res = self.channel.send_tx_proposal(tx_ctx, self.peers)

        # query calls
        elif prop_type == CC_QUERY:
            response = self.channel.send_tx_proposal(tx_ctx, [self.peers[0]])
            q = Queue(1)
            response.subscribe(
                on_next=lambda x: q.put(x), on_error=lambda x: q.put(x))

            try:
                res = q.get(timeout=DEFAULT_SLEEP)
                logger.debug(res)
                response = res[0][0][0]
                if response.response:
                    pld = response.response.payload
                    logger.debug("Query Payload: %s", pld)
                    pld = json.loads(pld.decode('utf-8'))
                    return pld
                return response

            except Exception:
                logger.error("Failed to query chaincode: {}", sys.exc_info()[0])
                raise

        # instantiate calls
        elif prop_type == CC_INSTANTIATE:
            # instantiate chaincode and wait for propagation
            res = self.channel.send_instantiate_proposal(tx_ctx, [self.peers[0]])
            time.sleep(LONGER_SLEEP)

        # invalid call
        else:
            logger.error("Invalid proposal request type." + \
            "Must be {} or {}.".format(CC_INVOKE, CC_INSTANTIATE))

            return None

        # send the transaction to the channel
        tran_req = build_tx_req(res)
        tx_2_ctx = create_tx_context(self.ixp_admin, self.crypto,
                                     TXProposalRequest())
        response = send_transaction(self.channel.orderers, tran_req, tx_2_ctx)

        # wait for chaincode instantiation consensus
        if prop_type == CC_INSTANTIATE:
            time.sleep(LONGER_SLEEP)

        # collect results
        q = Queue(1)
        response.subscribe(
            on_next=lambda x: q.put(x), on_error=lambda x: q.put(x))
        res, _ = q.get(timeout=DEFAULT_SLEEP)

        return res