Learn how to use service discovery in the IBM Blockchain Platform

Note: If you are new to the IBM Blockchain Platform, you can try out the Build your first blockchain application developer pattern series, which is designed to get you started with blockchain.

Blockchain networks are managed using a program called the chaincode, which is written in Go, Node.js, or Java. Chaincode contains the business logic required to initialize and manage a blockchain ledger state based on the transactions made by the application for the blockchain network.

Applications that execute chaincode that has been instantiated on a blockchain network do so by connecting to the network using the Hyperledger Fabric API SDK (Node, Java, or Go). In order to successfully submit transactions to the orderers in the network, the application needs to have access to information such as the certificate authority (CA) and Transport Layer Security (TLS) certificates for the orderers and peers on the channel, their IP addresses and port numbers, the endorsement policies, as well as information about peers that have the chaincode installed (these are the peers that receive transaction proposals from the application).

Prior to Hyperledger Fabric v1.2, this information needed to be statically provided to the application. However, this approach isn’t reactive to changes that may occur in the network over time. These changes may include the addition of new peers that have the chaincode installed on them, temporary unavailability of existing peers, or modifications to endorsement policies. The application would also have no way of knowing which peers’ ledgers have been updated. In such a scenario, if the application submits a proposal to a peer whose ledger data is not updated and as a result is not in sync with the rest of the network, the transaction would eventually be invalidated upon commit.

The service discovery feature, which was made available in the Hyperledger Fabric v1.2, improves upon this approach by ensuring that when an application tries to invoke the chaincode, the peers can compute the network information that they need dynamically without needing to depend on a static network configuration that may or may not have changed since it was provided to the application.

This tutorial shows you how the service discovery feature can be used to dynamically obtain information (such as peers, orderers, and endorsement policies) about a blockchain network when trying to execute the chaincode on peers and submitting transactions to the orderer.

Prerequisites

We will also make use of the fabcar developer pattern to demonstrate how service discovery can be incorporated into a blockchain application. This tutorial assumes that you have an IBM ID and have set up the required IBM Cloud Services as described in the fabcar developer pattern.

Estimated time

Once the prerequisites have been installed, it should take you about 45-60 minutes to complete this tutorial (including the time required to complete the instructions for the fabcar developer pattern).

Steps

  1. Set up the anchor peers
  2. Enable service discovery

Step 1. Set up the anchor peers

The application needs to have knowledge about a group of peers that can be trusted to provide correct responses for discovery queries. Generally, a peer within the same organization as the user of the client application is a good candidate. Each peer in this group needs to have the EXTERNAL_ENDPOINT defined in order for them to be known to the discovery service.

In the IBM Blockchain Platform, this can be achieved by setting a peer as an “Anchor peer.” This can be done during the “Build a network” section of the fabcar developer pattern.

A peer can be set as an anchor in one of two ways:

  1. When joining the peer to the channel, the switch to set the peer as an “Anchor peer” is turned on by default.

    Anchor peer turned on by default

  2. If the peer has already been added to the channel and if the switch was disabled so that the peer is not an anchor peer for that channel, the channel details can later on be updated to add this peer as an anchor peer. To set an existing peer as an anchor peer, you can go to the Channels tab in the left navigation pane and select your channel mychannel. Go to the Channel details tab and scroll to bottom. Under section Anchor peers, click the Add anchor peer button and select the peer you want to set as an anchor peer.

    Updating channel details to add an anchor peer

Step 2. Enable service discovery

The application issues a configuration query to the discovery service and obtains all the static information it would have otherwise needed to communicate with the rest of the nodes in the network. This information can be refreshed at any point by sending a subsequent query to the discovery service of a peer.

The service runs on peers — not on the application — and uses the network metadata information that’s maintained by the gossip communication layer to determine which peers are online. It also fetches information, such as any relevant endorsement policies, from the peer’s state database.

With service discovery, applications no longer need to specify which peers they need endorsements from. The SDK can simply send a query to the discovery service asking which peers are needed given a channel and a chaincode ID.

Let’s take a look at how you can enable and utilize service discovery in the IBM Blockchain Platform using the Fabric Node SDK.

In order to create a transaction and add it to a block on the blockchain, the application needs to connect to the peers that will endorse the transaction and to the ordering service that will order the transaction. The connection endpoints for these peers and the ordering service can be provided to the application in the connection profile, which can be used to construct a Fabric Gateway. The Fabric Gateway then conducts interactions with the Fabric Network. See the IBM Cloud documentation for more information about using the connection profile to build a Fabric Gateway in order to connect to a blockchain network.

In order to use service discovery in your application, you need to use the following code to connect to your gateway:

await gateway.connect(ccp, { wallet, identity: userName, discovery: { "enabled": true, "asLocalhost": false } });

Here you are setting the value of "enabled" to true, which is what turns on service discovery. Essentially, this creates a dynamic gateway.

This is exactly what is done in the network.js script of the fabcar application; the only difference is that the discovery service configuration parameter of enabled is set to true in the config.json, which is then referenced in network.js.

Once the gateway is created, the blockchain network is easily and dynamically obtained using the following small piece of code:

// Get the network (channel) your contract is deployed to.
const network = await gateway.getNetwork('mychannel');
// Get the contract from the network.
const contract = network.getContract('fabcar');

Try setting "enabled" to false in the config.json. When you try to run the application, you should get an error as service discovery has been disabled and the network information can no longer be dynamically obtained.

2019-10-28T15:42:59.535Z - error: [Network]: _initializeInternalChannel: no suitable peers available to initialize from
Failed to evaluate transaction: Error: no suitable peers available to initialize from
(node:14135) UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token o in JSON at position 1
    at JSON.parse (<anonymous>)
    at network.queryAllCars.then (/Users/snyk/CognitiveApps/code-patterns/fabcar-blockchain-sample/web-app/server/src/app.js:19:35)
(node:14135) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:14135) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Service discovery and the endorsement policy

Once service discovery has been turned on, an endorsement request will be routed to the right peer(s) based on the endorsement policy. If the endorsement policy is set to "Any", the request can be routed to any peer on the network. However, you do have the opportunity to bind the policy directly to a particular organization’s peer(s).

The service discovery information provided by the peer supplies two pieces of information, Layouts and EndorsersByGroups. With these two pieces of data, the SDK has the ability to send the request to the peer(s) from different organizations that meet the endorsement policy requirements.

The Node.js SDK provides default code that uses Layouts and EndorsersByGroups and sends it to the appropriate peers as per the endorsement policy. This code can be customized if the provided logic does not meet the user’s needs. You can refer the Hyperledger Fabric docs on service discovery for more information on Layouts and EndorsersByGroups.

Effects of updates to the network

Now take a look at the mychannel_fabcar_profile.json file. It contains information about the network mychannel, the organization participating in this network, Org1 MSP, as well as the URLs and TLS CA certificates of the peer, the orderer, and the certificate authority.

If you create a new organization and add it to the channel, you need not update mychannel_fabcar_profile.json with the information about this new organization and the peer. The discovery service can simply use the information from the first peer (which is already in the connection file) and the gossip data dissemination protocol to get latest state of the network.

Adding a new peer

This ensures that the addition of new peers, as well as the temporary or permanent unavailability of previously added peers does not cause failures in the application as long as at least one reliable anchor peer’s information is provided to the application.

Summary

This tutorial showed you how to use service discovery to connect to a Fabric network that was created using the IBM Blockchain Platform. Now, when you use service discovery to submit a transaction for endorsement, the transaction request will automatically be sent to the right peer(s) based on the parameters such as endorsement policies specified within the network.

Learn more about blockchain and Hyperledger Fabric — check the links in the Resources and Recommended sections of this page.

Sandhya Nayak