0
votes

This is a follow-up Question to the one which I asked previously(here) and I am trying to implement the solution suggested by @david_k.

I am using the Fabcar example as a base and building up on that.

I ran the startFabric.sh, I got the message that "Successfully submitted proposal to join channel"

docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/[email protected]/msp" peer0.org1.example.com peer channel create -o orderer.example.com:7050 -c mychannel -f /etc/hyperledger/configtx/channel.tx

2019-03-11 08:54:51.857 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized

2019-03-11 08:54:52.076 UTC [cli.common] readBlock -> INFO 002 Received block: 0

Join peer0.org1.example.com to the channel.

docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/[email protected]/msp" peer0.org1.example.com peer channel join -b mychannel.block

2019-03-11 08:54:52.387 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized

2019-03-11 08:54:52.481 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

Then I try to initialize the channelEventHub from the 'Channel' Class using the Fabric Node SDK (fabric-client), to subscribe to events emitted from my chaincode.

const channel = new Channel('mychannel',ccp);
const channelEventHub = channel.getChannelEventHub('peer0.org1.example.com')

I get the following error:

Failed to submit transaction: Error: Failed to discover::Error: Peer with name "peer1.org1.example.com" not assigned to this channel

After which I tried using getPeers() function from Channel Object but got an empty array, which otherwise should have returned an array of peers registered on the channel.

const channel = new Channel('mychannel',ccp);

let peers = channel.getChannelPeers();

I Console logged peers and it returned [].

My Connection Profile JSON is as follows (Its the one in Basic Network, I haven't changed it.)

{"name":"basic-network","version":"1.0.0", "client":{"organization":"Org1", "connection":{"timeout":{"peer":{"endorser":"300"},"orderer":"300"}}}, "channels": {"mychannel": { "orderers":["orderer.example.com"], "peers": { "peer0.org1.example.com":{} } } },"organizations":{"Org1":{"mspid":"Org1MSP","peers":["peer0.org1.example.com"],"certificateAuthorities":["ca.example.com"]},"Org2":{"mspid":"Org2MSP","peers":["peer0.org2.example.com"],"certificateAuthorities":["ca.example.com"]}},"orderers":{"orderer.example.com":{"url":"grpc://localhost:7050"}},"peers":{"peer0.org1.example.com":{"url":"grpc://localhost:7051"},"peer0.org2.example.com":{"url":"grpc://localhost:7052"}},"certificateAuthorities":{"ca.example.com":{"url":"http://localhost:7054","caName":"ca.example.com"}}}

Here you can clearly see that the peer is defined in the channel.

I am not understanding why I am getting this error. Any pointers on how to fix this will be hugely appreciated.

Update:

I created a StateStore class Which Implements the fabric_client.IKeyValueStore Interface

Instantiated it. Then set the state store using

await fabric_client.setStateStore(stateStore);

After which I created a user and set the User context using the following commands

    let user = await fabric_client.createUser(userOpts);
    // Set the userContext by passing the User Context
    await fabric_client.setUserContext(user);

Then I set the Admin Signing Authority (Not sure if it's needed). Then saved the user to the State Store.

await fabric_client.setAdminSigningIdentity(admin_pk,admin_cert,admin_mspid);

await fabric_client.saveUserToStateStore();

Then I console Logged the EventHub, which clearly shows that there is a clientContext.

{
  "_last_block_seen": null,
  "_starting_block_number": null,
  "_ending_block_number": null,
  "_ending_block_seen": false,
  "_ending_block_newest": false,
  "_allowRegistration": true,
  "_start_stop_registration": null,
  "_chaincodeRegistrants": {},
  "_block_registrant_count": 0,
  "_blockRegistrations": {},
  "connectCallback": null,
  "_transactionRegistrations": {},
  "_event_client": null,
  "_stream": null,
  "_connected": false,
  "_connect_running": false,
  "_disconnect_running": false,
  "_filtered_stream": true,
  "_current_stream": 0,
  "_clientContext": {
    "name": "basic-network",
    "version": "1.0.0",
    "client": {
      "organization": "Org1",
      "connection": {
        "timeout": {
          "peer": {
            "endorser": "300"
          },
          "orderer": "300"
        }
      }
    },
    "channels": {
      "mychannel": {
        "orderers": [
          "orderer.example.com"
        ],
        "peers": {
          "peer0.org1.example.com": {}
        }
      }
    },
    "organizations": {
      "Org1": {
        "mspid": "Org1MSP",
        "peers": [
          "peer0.org1.example.com"
        ],
        "certificateAuthorities": [
          "ca.example.com"
        ]
      },
      "Org2": {
        "mspid": "Org2MSP",
        "peers": [
          "peer0.org2.example.com"
        ],
        "certificateAuthorities": [
          "ca.example.com"
        ]
      }
    },
    "orderers": {
      "orderer.example.com": {
        "url": "grpc://localhost:7050"
      }
    },
    "peers": {
      "peer0.org1.example.com": {
        "url": "grpc://localhost:7051"
      },
      "peer0.org2.example.com": {
        "url": "grpc://localhost:7052"
      }
    },
    "certificateAuthorities": {
      "ca.example.com": {
        "url": "http://localhost:7054",
        "caName": "ca.example.com"
      }
    }
  },
  "_channel": {
    "_name": "mychannel",
    "_channel_peers": {},
    "_anchor_peers": [],
    "_orderers": {},
    "_kafka_brokers": [],
    "_clientContext": {
      "name": "basic-network",
      "version": "1.0.0",
      "client": {
        "organization": "Org1",
        "connection": {
          "timeout": {
            "peer": {
              "endorser": "300"
            },
            "orderer": "300"
          }
        }
      },
      "channels": {
        "mychannel": {
          "orderers": [
            "orderer.example.com"
          ],
          "peers": {
            "peer0.org1.example.com": {}
          }
        }
      },
      "organizations": {
        "Org1": {
          "mspid": "Org1MSP",
          "peers": [
            "peer0.org1.example.com"
          ],
          "certificateAuthorities": [
            "ca.example.com"
          ]
        },
        "Org2": {
          "mspid": "Org2MSP",
          "peers": [
            "peer0.org2.example.com"
          ],
          "certificateAuthorities": [
            "ca.example.com"
          ]
        }
      },
      "orderers": {
        "orderer.example.com": {
          "url": "grpc://localhost:7050"
        }
      },
      "peers": {
        "peer0.org1.example.com": {
          "url": "grpc://localhost:7051"
        },
        "peer0.org2.example.com": {
          "url": "grpc://localhost:7052"
        }
      },
      "certificateAuthorities": {
        "ca.example.com": {
          "url": "http://localhost:7054",
          "caName": "ca.example.com"
        }
      }
    },
    "_msp_manager": {
      "_msps": {}
    },
    "_discovery_interests": {},
    "_discovery_results": null,
    "_last_discover_timestamp": null,
    "_discovery_peer": null,
    "_use_discovery": false,
    "_as_localhost": true,
    "_endorsement_handler": null,
    "_commit_handler": null
  },
  "_peer": {
    "_options": {
      "grpc.max_receive_message_length": -1,
      "grpc.max_send_message_length": -1
    },
    "_url": "grpc://localhost:7051",
    "_endpoint": {
      "addr": "localhost:7051",
      "creds": {}
    },
    "_name": "localhost:7051",
    "_request_timeout": 45000,
    "_grpc_wait_for_ready_timeout": 3000,
    "_endorserClient": {
      "$interceptors": [],
      "$interceptor_providers": [],
      "$channel": {}
    },
    "_discoveryClient": {
      "$interceptors": [],
      "$interceptor_providers": [],
      "$channel": {}
    }
  }
}

But still, when I try to connect using EventHub.connect(true), I get the following error.

Failed to submit transaction: Error: Error connect the ChannelEventhub to peer, either the clientContext has not been properly initialized, missing userContext or admin identity or missing signedEvent

2
Does this have something to do with setting the 'discovery' option?Dheeraj Kumar
Looking at what you are trying to do, I think you should use the fabric-network api's to begin with rather than the fabric-client apis. They do make it simpler to get started. But if you want to persevere, then the problem you have is that you aren't creating your channel object correctly. To use a common connection profile you would use the api Client.loadFromConfig(ccp) to read a ccp and generate the appropriate channel, peer and orderer objects. Note you need to decide whether you want to use discovery or not which is enabled by default and by default sets urls to localhost.david_k
Will try it out. But I have actually tried with both APIs. Interchanged them and still didn't solve the problem. I don't understand why they have multiple APIs doing the same function. For example, the ChannelEventHub, it can be implemented using 3 APIs.Dheeraj Kumar
If you want to see an example of fabric-network version 1.4.0 being used with support for chaincode events, you can see it here github.com/davidkel/bnaport/tree/master/trade-network/native/… fabric-network in a future release will provide integrated support for handling chaincode events.david_k
Thank you so much. Will use this as a reference. :)Dheeraj Kumar

2 Answers

0
votes

I am not sure if this is the solution, but on my side, it works and there is a small difference.

Instead of passing the name of the peer to the event hub, I pass a peer object:

var peer = fabric_client.newPeer(creds.peers['org1-peer1'].url, { pem: creds.peers['org1-peer1'].tlsCACerts.pem, 'ssl-target-name-override': null });
var channel = fabric_client.newChannel('defaultchannel');
let event_hub = channel.newChannelEventHub(peer);

Note: creds is the object containing the connection profile aas json.

Full sample available here: https://github.com/IBM/car-auction-network-fabric-node-sdk

0
votes

I used @david_k 's approach and implemented the ChaincodeEventEmitter Class and just used the fabric-network API's to create the channel.

    const walletPath = path.join(process.cwd(), 'wallet');
    const wallet = new FileSystemWallet(walletPath);
    const useDiscovery = false;
    const convertDiscoveredToLocalHost = null;
    const userExists = await wallet.exists('user1');
        if (!userExists) {
            console.log('An identity for the user "user1" does not exist in the wallet');
            console.log('Run the registerUser.js application before retrying');
            return;
        }
    const gateway = new Gateway();
    const discoveryOptions = {
            enabled: useDiscovery
        };
    if (useDiscovery && convertDiscoveredToLocalHost !== null) {
            discoveryOptions.asLocalhost = convertDiscoveredToLocalHost;
     }

    await gateway.connect(ccp, {
            wallet,
            identity: 'user1',
            discovery: discoveryOptions
    });

    const network = await gateway.getNetwork('mychannel');
    const chaincodeEventEmitter = new ChaincodeEventEmitter(network, 'Org1MSP', 'Fabcae');
    await chaincodeEventEmitter.initialize();

    chaincodeEventEmitter.on('eventName', async (event) => {
            console.log('Event Received');
            console.log('Received Event --> ', event);

    });

    await gateway.disconnect();

And I used the same code for the ChaincodeEventEmitter Class as here https://github.com/davidkel/bnaport/blob/master/trade-network/native/client-new-js/chaincodeeventemitter.js.

Once again @david_k Thank you!!!