def wait(): with get_event_loop() as loop: channel_name = LEDGER['channel_name'] chaincode_name = LEDGER['chaincode_name'] peer = LEDGER['peer'] peer_port = peer["port"][os.environ.get('BACKEND_PEER_PORT', 'external')] client = Client() channel = client.new_channel(channel_name) target_peer = Peer(name=peer['name']) requestor_config = LEDGER['client'] target_peer.init_with_bundle({ 'url': f'{peer["host"]}:{peer_port}', 'grpcOptions': peer['grpcOptions'], 'tlsCACerts': { 'path': peer['tlsCACerts'] }, 'clientKey': { 'path': peer['clientKey'] }, 'clientCert': { 'path': peer['clientCert'] }, }) try: # can fail requestor = create_user( name=requestor_config['name'] + '_events', org=requestor_config['org'], state_store=FileKeyValueStore(requestor_config['state_store']), msp_id=requestor_config['msp_id'], key_path=glob.glob(requestor_config['key_path'])[0], cert_path=requestor_config['cert_path']) except BaseException: pass else: channel_event_hub = channel.newChannelEventHub( target_peer, requestor) # use chaincode event # uncomment this line if you want to replay blocks from the beginning for debugging purposes # stream = channel_event_hub.connect(start=0, filtered=False) stream = channel_event_hub.connect(filtered=False) channel_event_hub.registerChaincodeEvent(chaincode_name, 'tuples-updated', onEvent=on_tuples) loop.run_until_complete(stream)
def init_with_net_profile(self, profile_path='network.json'): """ Load the connection profile from external file to network_info. Init the handlers for orgs, peers, orderers, ca nodes :param profile_path: The connection profile file path :return: """ with open(profile_path, 'r') as profile: d = json.load(profile) self.network_info = d # read kv store path self.kv_store_path = self.get_net_info('client', 'credentialStore', 'path') if self.kv_store_path: self._state_store = FileKeyValueStore(self.kv_store_path) else: _logger.warning( 'No kv store path exists in profile {}'.format(profile_path)) # Init organizations orgs = self.get_net_info('organizations') for name in orgs: _logger.debug("create org with name={}".format(name)) org = create_org(name, orgs[name], self.state_store) self._organizations[name] = org # Init CAs # TODO # Init orderer nodes orderers = self.get_net_info('orderers') _logger.debug("Import orderers = {}".format(orderers.keys())) for name in orderers: orderer = Orderer(name=name, endpoint=orderers[name]['url']) orderer.init_with_bundle(orderers[name]) self.orderers[name] = orderer # Init peer nodes peers = self.get_net_info('peers') _logger.debug("Import peers = {}".format(peers.keys())) for name in peers: peer = Peer(name=name) peer.init_with_bundle(peers[name]) self._peers[name] = peer
def wait(channel_name): def on_channel_event(cc_event, block_number, tx_id, tx_status): on_event(channel_name, cc_event, block_number, tx_id, tx_status) with get_event_loop() as loop: client = Client() channel = client.new_channel(channel_name) target_peer = Peer(name=settings.LEDGER_PEER_NAME) target_peer.init_with_bundle({ 'url': f'{settings.LEDGER_PEER_HOST}:{settings.LEDGER_PEER_PORT}', 'grpcOptions': ledger_grpc_options(settings.LEDGER_PEER_HOST), 'tlsCACerts': { 'path': settings.LEDGER_PEER_TLS_CA_CERTS }, 'clientKey': { 'path': settings.LEDGER_PEER_TLS_CLIENT_KEY }, 'clientCert': { 'path': settings.LEDGER_PEER_TLS_CLIENT_CERT }, }) try: # can fail requestor = create_user(name=f'{settings.LEDGER_USER_NAME}_events', org=settings.ORG_NAME, state_store=FileKeyValueStore( settings.LEDGER_CLIENT_STATE_STORE), msp_id=settings.LEDGER_MSP_ID, key_path=glob.glob( settings.LEDGER_CLIENT_KEY_PATH)[0], cert_path=settings.LEDGER_CLIENT_CERT_PATH) except BaseException: pass else: # Note: # We do a loop to connect to the channel event hub because grpc may disconnect and create an exception # Since we're in a django app of backend, an exception here will not crash the server (if the "ready" # method has already returned "true"). # It makes it difficult to reconnect automatically because we need to kill the server # to trigger the connexion. # So we catch this exception (RPC error) and retry to connect to the event loop. while True: # use chaincode event channel_event_hub = channel.newChannelEventHub( target_peer, requestor) try: # We want to replay blocks from the beginning (start=0) if channel event hub was disconnected during # events emission stream = channel_event_hub.connect(start=0, filtered=False) channel_event_hub.registerChaincodeEvent( settings.LEDGER_CHANNELS[channel_name]['chaincode'] ['name'], 'chaincode-updates', onEvent=on_channel_event) logger.info( f'Connect to Channel Event Hub ({channel_name})') loop.run_until_complete(stream) except Exception as e: logger.error( f'Channel Event Hub failed for {channel_name} ({type(e)}): {e} re-connecting in 5s' ) time.sleep(5)
def get_hfc_client(): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) client = Client() # Add peer from backend ledger config file peer = Peer(name=LEDGER['peer']['name']) peer.init_with_bundle({ 'url': f'{LEDGER["peer"]["host"]}:{PEER_PORT}', 'grpcOptions': LEDGER['peer']['grpcOptions'], 'tlsCACerts': { 'path': LEDGER['peer']['tlsCACerts'] }, 'clientKey': { 'path': LEDGER['peer']['clientKey'] }, 'clientCert': { 'path': LEDGER['peer']['clientCert'] }, }) client._peers[LEDGER['peer']['name']] = peer # Check peer has joined channel response = loop.run_until_complete( client.query_channels(requestor=LEDGER['requestor'], peers=[peer], decode=True)) channels = [ch.channel_id for ch in response.channels] if not LEDGER['channel_name'] in channels: raise Exception( f'Peer has not joined channel: {LEDGER["channel_name"]}') channel = client.new_channel(LEDGER['channel_name']) # Check chaincode is instantiated in the channel responses = loop.run_until_complete( client.query_instantiated_chaincodes( requestor=LEDGER['requestor'], channel_name=LEDGER['channel_name'], peers=[peer], decode=True)) chaincodes = [cc.name for resp in responses for cc in resp.chaincodes] if not LEDGER['chaincode_name'] in chaincodes: raise Exception( f'Chaincode : {LEDGER["chaincode_name"]}' f' is not instantiated in the channel : {LEDGER["channel_name"]}') # Discover orderers and peers from channel discovery results = loop.run_until_complete( channel._discovery(LEDGER['requestor'], peer, config=True, local=False, interests=[{ 'chaincodes': [{ 'name': LEDGER['chaincode_name'] }] }])) results = deserialize_discovery(results) update_client_with_discovery(client, results) return loop, client
def update_client_with_discovery(client, discovery_results): # Get all msp tls root cert files tls_root_certs = {} for mspid, msp_info in discovery_results['config']['msps'].items(): tls_root_certs[mspid] = base64.decodebytes( msp_info['tls_root_certs'].pop().encode()) # Load one peer per msp for endorsing transaction for msp in discovery_results['members']: if not len(msp): continue peer_info = msp[0] if peer_info['mspid'] != LEDGER['client']['msp_id']: peer = Peer(name=peer_info['mspid']) with tempfile.NamedTemporaryFile() as tls_root_cert: tls_root_cert.write(tls_root_certs[peer_info['mspid']]) tls_root_cert.flush() url = peer_info['endpoint'] external_port = os.environ.get('BACKEND_PEER_PORT_EXTERNAL', None) # use case for external development if external_port: url = f"{peer_info['endpoint'].split(':')[0]}:{external_port}" peer.init_with_bundle({ 'url': url, 'grpcOptions': { 'grpc-max-send-message-length': 15, 'grpc.ssl_target_name_override': peer_info['endpoint'].split(':')[0] }, 'tlsCACerts': { 'path': tls_root_cert.name }, 'clientKey': { 'path': LEDGER['peer']['clientKey'] }, # use peer creds (mutual tls) 'clientCert': { 'path': LEDGER['peer']['clientCert'] }, # use peer creds (mutual tls) }) client._peers[peer_info['mspid']] = peer # Load one orderer for broadcasting transaction orderer_mspid, orderer_info = list( discovery_results['config']['orderers'].items())[0] orderer = Orderer(name=orderer_mspid) with tempfile.NamedTemporaryFile() as tls_root_cert: tls_root_cert.write(tls_root_certs[orderer_mspid]) tls_root_cert.flush() # Need loop orderer.init_with_bundle({ 'url': f"{orderer_info[0]['host']}:{orderer_info[0]['port']}", 'grpcOptions': { 'grpc-max-send-message-length': 15, 'grpc.ssl_target_name_override': orderer_info[0]['host'] }, 'tlsCACerts': { 'path': tls_root_cert.name }, 'clientKey': { 'path': LEDGER['peer']['clientKey'] }, # use peer creds (mutual tls) 'clientCert': { 'path': LEDGER['peer']['clientCert'] }, # use peer creds (mutual tls) }) client._orderers[orderer_mspid] = orderer
def _get_hfc(channel_name): global user loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) if not user: with user_lock: # Only call `create_user` once in the lifetime of the application. # Calling `create_user` twice breaks thread-safety (bug in fabric-sdk-py) user = create_user(name=settings.LEDGER_USER_NAME, org=settings.ORG_NAME, state_store=FileKeyValueStore( settings.LEDGER_CLIENT_STATE_STORE), msp_id=settings.LEDGER_MSP_ID, key_path=glob.glob( settings.LEDGER_CLIENT_KEY_PATH)[0], cert_path=settings.LEDGER_CLIENT_CERT_PATH) client = Client() # Add peer from backend ledger config file peer = Peer(name=settings.LEDGER_PEER_NAME) peer.init_with_bundle({ 'url': f'{settings.LEDGER_PEER_HOST}:{settings.LEDGER_PEER_PORT}', 'grpcOptions': ledger_grpc_options(settings.LEDGER_PEER_HOST), 'tlsCACerts': { 'path': settings.LEDGER_PEER_TLS_CA_CERTS }, 'clientKey': { 'path': settings.LEDGER_PEER_TLS_CLIENT_KEY }, 'clientCert': { 'path': settings.LEDGER_PEER_TLS_CLIENT_CERT }, }) client._peers[settings.LEDGER_PEER_NAME] = peer # Check peer has joined channel response = loop.run_until_complete( client.query_channels(requestor=user, peers=[peer], decode=True)) channels = [ch.channel_id for ch in response.channels] if channel_name not in channels: raise Exception(f'Peer has not joined channel: {channel_name}') channel = client.new_channel(channel_name) # This part is commented because `query_committed_chaincodes` is not implemented in # the last version of fabric-sdk-py # chaincode_name = settings.LEDGER_CHANNELS[channel_name]['chaincode']['name'] # /!\ New chaincode lifecycle. # Check chaincode is committed in the channel # responses = loop.run_until_complete( # client.query_committed_chaincodes( # requestor=user, # channel_name=channel_name, # peers=[peer], # decode=True # ) # ) # chaincodes = [cc.name # for resp in responses # for cc in resp.chaincode_definitions] # if chaincode_name not in chaincodes: # raise Exception(f'Chaincode : {chaincode_name}' # f' is not committed in the channel : {channel_name}') # Discover orderers and peers from channel discovery results = loop.run_until_complete( channel._discovery(user, peer, config=True, local=False, interests=[{ 'chaincodes': [{ 'name': "_lifecycle" }] }])) results = _deserialize_discovery(results) _validate_channels(channel_name, results) _update_client_with_discovery(client, results) return loop, client, user
def _update_client_with_discovery(client, discovery_results): # Get all msp tls root cert files tls_root_certs = {} for mspid, msp_info in discovery_results['config']['msps'].items(): tls_root_certs[mspid] = base64.decodebytes( msp_info['tls_root_certs'].pop().encode()) # Load one peer per msp for endorsing transaction for msp in discovery_results['members']: if not len(msp): continue peer_info = msp[0] if peer_info['mspid'] != settings.LEDGER_MSP_ID: peer = Peer(name=peer_info['mspid']) with tempfile.NamedTemporaryFile() as tls_root_cert: tls_root_cert.write(tls_root_certs[peer_info['mspid']]) tls_root_cert.flush() url = peer_info['endpoint'] peer.init_with_bundle({ 'url': url, 'grpcOptions': ledger_grpc_options(peer_info['endpoint'].split(':')[0]), 'tlsCACerts': { 'path': tls_root_cert.name }, 'clientKey': { 'path': settings.LEDGER_PEER_TLS_CLIENT_KEY }, 'clientCert': { 'path': settings.LEDGER_PEER_TLS_CLIENT_CERT } }) client._peers[peer_info['mspid']] = peer # Load one orderer for broadcasting transaction orderer_mspid, orderer_info = list( discovery_results['config']['orderers'].items())[0] orderer = Orderer(name=orderer_mspid) with tempfile.NamedTemporaryFile() as tls_root_cert: tls_root_cert.write(tls_root_certs[orderer_mspid]) tls_root_cert.flush() # Need loop orderer.init_with_bundle({ 'url': f"{orderer_info[0]['host']}:{orderer_info[0]['port']}", 'grpcOptions': ledger_grpc_options(orderer_info[0]['host']), 'tlsCACerts': { 'path': tls_root_cert.name }, 'clientKey': { 'path': settings.LEDGER_PEER_TLS_CLIENT_KEY }, 'clientCert': { 'path': settings.LEDGER_PEER_TLS_CLIENT_CERT } }) client._orderers[orderer_mspid] = orderer