예제 #1
0
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)
예제 #2
0
    def test_invoke(self):
        self.shutdown_test_env()
        self.start_test_env()
        time.sleep(5)
        client = Client()
        chain = client.new_channel(CHAIN_ID)
        client.set_state_store(file_key_value_store(self.kv_store_path))
        chain.add_peer(Peer())

        submitter = get_submitter()
        signing_identity = submitter.signing_identity
        # cc_invoke_req = create_invocation_proposal_req(
        #     CHAINCODE_NAME, CHAINCODE_VERSION, signing_identity,
        #     args=['move', 'a', 'b', '100'])
        queue = Queue(1)
        #
        # chain.invoke_chaincode(cc_invoke_req) \
        #     .subscribe(lambda x: queue.put(x))

        prop = queue.get(timeout=10)
        proposal_bytes = prop.proposal_bytes
        sig = prop.signature

        # verify the signature against the hash of proposal_bytes
        digest = signing_identity.msp.crypto_suite.hash(proposal_bytes)
        self.assertEqual(
            signing_identity.verify(str.encode(digest.hexdigest()), sig), True)
        self.shutdown_test_env()
예제 #3
0
    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
예제 #4
0
    def test_install(self):
        time.sleep(5)
        client = Client()
        chain = client.new_chain(CHAIN_ID)
        client.set_state_store(file_key_value_store(self.kv_store_path))
        chain.add_peer(Peer())
        chain.add_orderer(Orderer())

        submitter = get_submitter()

        signing_identity = submitter.signing_identity
        cc_install_req = create_installment_proposal_req(
            CHAINCODE_NAME, CHAINCODE_PATH, CHAINCODE_VERSION)
        queue = Queue(1)

        chain.install_chaincode(cc_install_req, signing_identity) \
            .subscribe(on_next=lambda x: queue.put(x),
                       on_error=lambda x: queue.put(x))

        response, _ = queue.get(timeout=5)
        # TODO: create channel not implement yet
        print(response.status)
        self.assertEqual(404, response.status)
예제 #5
0
def build_join_channel_req(org, channel, client):
    """
    For test, there is only one peer.

    Args:
        org: org
        channel: the channel to join
        client: client instance
    Return:
        return request for joining channel
        """

    def block_event_callback(block):

        pass

    client._crypto_suite = ecies()
    request = {}
    tx_prop_req = TXProposalRequest()

    # add the orderer
    orderer_config = test_network['orderer']
    endpoint = orderer_config['grpc_endpoint']
    ca_root_path = orderer_config['tls_cacerts']
    orderer = Orderer(endpoint=endpoint, tls_ca_cert_file=ca_root_path,
                      opts=(('grpc.ssl_target_name_override',
                             'orderer.example.com'),))
    channel.add_orderer(orderer)

    # get the genesis block
    orderer_admin = get_orderer_org_user(state_store=client.state_store)
    tx_context = TXContext(orderer_admin, ecies(), tx_prop_req)
    client.tx_context = tx_context
    genesis_block = channel.get_genesis_block().SerializeToString()

    # create the peer
    org_admin = get_peer_org_user(org, "Admin", client.state_store)
    client.tx_context = TXContext(org_admin, ecies(), tx_prop_req)
    tx_id = client.tx_context.tx_id

    peer_config = test_network[org]["peers"]['peer0']
    ca_root = peer_config["tls_cacerts"]

    endpoint = peer_config["grpc_request_endpoint"]
    opts = (('grpc.ssl_target_name_override',
             peer_config['server_hostname']),)
    peer = Peer(endpoint=endpoint, tls_cacerts=ca_root, opts=opts)

    """
    # connect the peer
    eh = EventHub()
    event = peer_config['grpc_event_endpoint']

    tx_id = client.tx_context.tx_id
    eh.set_peer_addr(event)
    eh.connect()
    eh.register_block_event(block_event_callback)
    all_ehs.append(eh)
    """

    request["targets"] = [peer]
    request["block"] = genesis_block
    request["tx_id"] = tx_id
    request["transient_map"] = {}

    return request
예제 #6
0
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)
예제 #7
0
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
예제 #8
0
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
예제 #9
0
 def test_create_peer_custom_endpoint(self):
     peer = Peer(self.custom_peer_endpoint)
     self.assertEqual(peer.endpoint, self.custom_peer_endpoint)
예제 #10
0
 def test_create_peer_default_endpoint(self):
     peer = Peer()
     self.assertEqual(peer.endpoint, self.default_peer_endpoint)
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
예제 #13
0
def update_cli(cli, orgs):
    for org in orgs:

        # add organization
        cli._organizations.update(
            {org['name']: create_org(org['name'], org, cli.state_store)})

        # register users except rca boostrap admin
        for user_name in org['users'].keys():
            org_user = org['users'][user_name]
            org_user_home = org_user['home']
            org_user_msp_dir = os.path.join(org_user_home, 'msp')

            # register user
            user_cert_path = os.path.join(org_user_msp_dir, 'signcerts',
                                          'cert.pem')
            user_key_path = os.path.join(org_user_msp_dir, 'keystore',
                                         'key.pem')

            user = create_user(name=org_user['name'],
                               org=org['name'],
                               state_store=cli.state_store,
                               msp_id=org['mspid'],
                               cert_path=user_cert_path,
                               key_path=user_key_path)

            cli._organizations[org['name']]._users.update(
                {org_user['name']: user})

        # register orderer
        if 'orderers' in org:
            for o in org['orderers']:
                tls_orderer_client_dir = os.path.join(
                    o['tls']['dir']['external'], o['tls']['client']['dir'])
                orderer = Orderer(
                    o['name'],
                    endpoint=f"{o['host']}:{o['port']['internal']}",
                    tls_ca_cert_file=os.path.join(tls_orderer_client_dir,
                                                  o['tls']['client']['ca']),
                    client_cert_file=os.path.join(tls_orderer_client_dir,
                                                  o['tls']['client']['cert']),
                    client_key_file=os.path.join(tls_orderer_client_dir,
                                                 o['tls']['client']['key']),
                )

                cli._orderers.update({o['name']: orderer})

        # register peers
        if 'peers' in org:
            for peer in org['peers']:
                tls_peer_client_dir = os.path.join(
                    peer['tls']['dir']['external'],
                    peer['tls']['client']['dir'])

                port = peer['port'][os.environ.get('ENV', 'external')]
                p = Peer(
                    name=peer['name'],
                    endpoint=f"{peer['host']}:{port}",
                    tls_ca_cert_file=os.path.join(tls_peer_client_dir,
                                                  peer['tls']['client']['ca']),
                    client_cert_file=os.path.join(
                        tls_peer_client_dir, peer['tls']['client']['cert']),
                    client_key_file=os.path.join(tls_peer_client_dir,
                                                 peer['tls']['client']['key']))
                cli._peers.update({peer['name']: p})

        # register system channel
        system_channel_name = org['misc']['system_channel_name']
        if not cli.get_channel(system_channel_name):
            cli.new_channel(system_channel_name)

    return cli
예제 #14
0
 def test_create_chain(self):
     # TODO impl
     chain = Chain()
     chain.add_peer(Peer())
     chain.add_orderer(Orderer())
     self.fail()
예제 #15
0
def build_join_channel_req(org, channel, client):
    """
    For test, there is only one peer.

    Args:
        org: org
        channel: the channel to join
        client: client instance
    Return:
        return request for joining channel
        """

    def block_event_callback(block):

        pass

    client._crypto_suite = ecies()
    all_ehs = []
    request = {}
    tx_prop_req = TXProposalRequest()

    # add the orderer
    orderer_config = test_network['orderer']
    endpoint = orderer_config['grpc_endpoint']
    opts = (('grpc.ssl_target_name_override',
             orderer_config['server_hostname']),)

    ca_root_path = orderer_config['tls_cacerts']
    with open(ca_root_path, 'rb') as f:
        pem = f.read()
    orderer = Orderer(endpoint=endpoint, pem=pem, opts=opts)
    channel.add_orderer(orderer)

    # get the genesis block
    orderer_admin = get_orderer_org_admin(client)
    tx_context = TXContext(orderer_admin, ecies(), tx_prop_req)
    client.tx_context = tx_context
    genesis_block = channel.get_genesis_block().SerializeToString()
    if not genesis_block:
        return None

    # create the peer
    org_admin = get_peer_org_user(client, org)
    client.tx_context = TXContext(org_admin, ecies(), tx_prop_req)

    peer_config = test_network[org]["peers"]['peer0']
    ca_root = peer_config["tls_cacerts"]
    with open(ca_root, 'rb') as f:
        pem = f.read()
    peer = Peer(pem=pem, opts=None)

    # connect the peer
    eh = EventHub()
    event = peer_config['grpc_event_endpoint']
    opts = {'pem': pem, 'hostname': peer_config['server_hostname']}

    tx_id = client.tx_context.tx_id
    eh.set_peer_addr(event)
    eh.connect()
    eh.register_block_event(block_event_callback)
    all_ehs.append(eh)

    request["targets"] = [peer]
    request["block"] = genesis_block
    request["tx_id"] = tx_id

    return request