Adapting Hyperledger Caliper to Custom Hyperledger Fabric Networks

Nithin D J
Sep 7, 2018 · 4 min read

Hyperledger Fabric is one of the leading frameworks based on blockchain technology. Although it provided several advanced features, there was no straightforward solution to test the network performance until Hyperledger introduced Caliper.

Caliper is a performance testing tool for Hyperledger blockchain solutions like Fabric, Composer, Iroha, and others. Since Caliper is yet to come up with the complete instructions on adapting Caliper for custom existing Hyperledger Fabric networks, this article is an attempt to provide the complete instructions to do so.

Requirements for configuring Caliper to test on existing network.

  1. Crypto Artifacts — The Crypto-config folder that contains the crypto artifacts generated using cryptogen.
  2. MSP IDs of orderer and member organizations in the network.
  3. Host and port information of the orderer, ca and all peers of organizations.
  4. Channel name and channel configuration (a.k.a. channel creation transaction file).
  5. Chaincode (which is installed on the channel).
  6. Node.js files that could carry on the operations on chaincode are installed. These files are created by referring to the existing files that came with Caliper.

There are two config files need to be changed to run the test for Fabric.

  1. config.json — has configurations of the tests to be run.
  2. fabric.json — has the fabric network information.

Changes to fabric.json

  1. Change the path of crypto-config to the custom network crypto directory.
  2. Change orderer MSP ID, orderer user key, orderer URL, hostname and tlscerts according to the custom network that is up and running.
  3. Change all organizations MSP ID, user key, peer URLs, and peer tlscerts of all organizations accordingly.
  4. Change the channel name, and provide the channel creation configuration file path. Also, update the organization’s name accordingly under channel section.
  5. Change the chaincode name, provide the chaincode path, version, language and channel name.
  6. Context specifies the operation to be carried out while testing. Context object takes the operation name and channel name. Change the operating name and channel name accordingly. The operations specified will be required by config.json.

Example of modified fabric.json

{
"fabric": {
"cryptodir": "/home/user1/fabric/artifacts/crypto-config/",
"network": {
"orderer": {
"name": "orderer",
"mspid": "ordererMSP",
"msp": "/home/user1/fabric/artifacts/crypto-config/ordererOrganizations/example.com/msp/",
"user": {
"key": "/home/user1/fabric/artifacts/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/msp/keystore/2b146e00b013c09d4dd887dc93142f6609509867d89aabb072533c3ee6f74240_sk",
"cert": "/home/user1/fabric/artifacts/crypto-config/ordererOrganizations/example.com/users/Admin@example.com/msp/signcerts/Admin@example.com-cert.pem"
},
"url": "grpcs://0.0.0.0:7050",
"server-hostname": "orderer.example.com",
"tls_cacerts": "/home/user1/fabric/artifacts/crypto-config/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
},
"org1": {
"name": "peerorg1",
"mspid": "org1MSP",
"msp": "/home/user1/fabric/artifacts/crypto-config/peerOrganizations/org1.example.com/msp/",
"user": {
"key": "/home/user1/fabric/artifacts/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/4e17cd69344ea538c8251106a63136fc07ca92ac0becb875a1516f82a456e53b_sk",
"cert": "/home/user1/fabric/artifacts/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem"
},
"ca": {
"url": "https://ca.org1.example.com:7054",
"name": ""
},
"peer1": {
"requests": "grpcs://peer0.org1.example.com:6000",
"events": "grpcs://peer0.org1.example.com:7000",
"server-hostname": "peer0.org1.example.com",
"tls_cacerts": "/home/user1/fabric/artifacts/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
},
"peer2": {
"requests": "grpcs://peer1.org1.example.com:8000",
"events": "grpcs://peer1.org1.example.com:9000",
"server-hostname": "peer1.org1.example.com",
"tls_cacerts": "/home/user1/fabric/artifacts/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt"
}},
"org2": {
"name": "peerorg2",
"mspid": "org2MSP",
"msp": "/home/user1/fabric/artifacts/crypto-config/peerOrganizations/org2.example.com/msp/",
"user": {
"key": "/home/user1/fabric/artifacts/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore/84204ff40fba240df3704fcd483f41c085cf26b5e86377ef743e607869201ffe_sk",
"cert": "/home/user1/fabric/artifacts/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem"
},
"ca": {
"url": "https://ca.org2.example.com:7054",
"name": ""
},
"peer1": {
"requests": "grpcs://peer0.org2.example.com:6001",
"events": "grpcs://peer0.org2.example.com:7001",
"server-hostname": "peer0.org2.example.com",
"tls_cacerts": "/home/user1/fabric/artifacts/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt"
},
"peer2": {
"requests": "grpcs://peer1.org2.example.com:8001",
"events": "grpcs://peer1.org2.example.com:9001",
"server-hostname": "peer1.org2.example.com",
"tls_cacerts": "/home/user1/fabric/artifacts/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt"
}}},
"channel": [{
"name": "common",
"deployed": false,
"config": "/home/user1/fabric/artifacts/channel/common.tx",
"organizations": ["org1", "org2"]
}],
"chaincodes": [{
"id": "auditpro",
"path": "/home/user1/fabric/artifacts/chaincode/go/auditpro",
"version": "1.0",
"language":"golang",
"channel": "common"
}],
"endorsement-policy": {
"identities": [
{
"role": {
"name": "member",
"mspId": "org1MSP"
}},
{
"role": {
"name": "member",
"mspId": "org2MSP"
}},
{
"role": {
"name": "admin",
"mspId": "org1MSP"
}}],
"policy": { "2-of": [{"signed-by": 0}, {"signed-by": 1}]}
},
"context": {
"create": "common",
"retrive": "common"
}},
"info" : {
"Version": "1.1.0",
"Size": "4 Peers",
"Orderer": "Solo",
"Distribution": "Single Host"
}}

Changes to config.json

  1. Remove the values of start and end in command section.
  2. Callback under the rounds section, takes the argument of node.js script file corresponding to the operation. Without callback js file, the test cannot run. Every time a transaction is submitted, it will be submitted using the callback javascript.

Example of modified config.json

{
"blockchain": {
"type": "fabric",
"config": "benchmark/simple/customNetworkConfig.json"
},
"command" : {
"start": "",
"end" : ""
},
"test": {
"name": "test",
"description" : "Benchmark for test scenario",
"clients": {
"type": "local",
"number": 1
},
"rounds": [
{
"label" : "create",
"txNumber" : [300]
"arguments": {},
"rateControl" : [{"type": "fixed-rate", "opts": {"tps" : 50}}],
"callback" : "benchmark/drm/create.js"
},
{
"label" : "retrive",
"txNumber" : [100],
"rateControl" : [{"type": "fixed-rate", "opts": {"tps" : 10}}],
"callback" : "benchmark/drm/retrive.js"
}]
},
"monitor": {
"type": "docker",
"docker":{
"name": ["peer0.org1.example.com", "peer0.org2.example.com", "orderer.example.com"]
},
"interval": 1
}
}

Changes to Caliper/src/comm/bench-flow.js

This is to avoid Caliper creating the channel and installing and instantiating the chaincode as it would be already finished as part of your network set-up. Change the lines (line number 303–311) in /src/comm/bench-flow.js as shown below.

function startTest(){
return client.init().then((number)=>{
return blockchain.prepareClients(number);
});
}
let start = startTest();// startPromise.then(() => {
// return blockchain.init();
// }).then( () => {
// return blockchain.installSmartContract();
// }).then( () => {
// return client.init().then((number)=>{
// return blockchain.prepareClients(number);
// });
start.then( (clientArgs) => {

Steps to run Caliper for custom network.

  1. Ensure the completion of the prerequisite steps mentioned here.
  2. Place the config.json,fabric.json and the callback javascript files to one of the folder under benchmark folder of Caliper.
  3. Run the test with the config file that has been modified for the custom network with Caliper run benchmark command.

You can even test the distributed network with Caliper using similar steps. Remember to copy the files and folders required from different machines to the machine where you want to run the test. Then edit the files accordingly and run the Caliper.

Edit Note : Thanks to Keanu Nurherbyanto for noticing that I missed to mention the changes to Caliper/src/comm/bench-flow.js.

Tallyx

Official account for Tallyx — Simplify global trade transactions for every buyer, seller and financier, by creating a level playing field and delivering value through a global trade platform.

Nithin D J

Written by

Software Engineer @Tallyx

Tallyx

Tallyx

Official account for Tallyx — Simplify global trade transactions for every buyer, seller and financier, by creating a level playing field and delivering value through a global trade platform.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade