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
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
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)
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
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
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)
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
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]))
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
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')
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
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
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
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