Skip to content

Commit 50b69f6

Browse files
Add document about how to benchmark the performance using Hyperledger Caliper (#1238)
Add document about how to benchmark the performance using Hyperledger Caliper Signed-off-by: takayuki-nagai <[email protected]> Co-authored-by: Tatsuya Sato <[email protected]>
1 parent 604a0a5 commit 50b69f6

File tree

2 files changed

+206
-0
lines changed

2 files changed

+206
-0
lines changed

test-network-k8s/docs/CALIPER.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Benchmarking the performance using Hyperledger Caliper
2+
3+
This document introduces how to use [Hyperledger Caliper](https://hyperledger.github.io/caliper/) to benchmark the performance of the Hyperledger Fabric environment created with test-network-k8s.
4+
5+
[Fabric adapter manual of Hyperledger Caliper v0.6.0](https://hyperledger.github.io/caliper/v0.6.0/fabric-config/new/) only describes how to connect to test-network. Furthermore, these chaincodes need to be executed as services to run in a K8s environment, but this is not supported by default, requiring customization. So we will explain how to benchmark the performance of the Kubernetes test network using Hyperledger Caliper and Asset Transfer Basic chaincode, which is most basic in current sample chaincodes.
6+
7+
The following documentation assumes that test-network-k8s and Hyperledger Caliper v0.6.0 are located on the same host.
8+
9+
## Setting of test-network-k8s side
10+
11+
As described in the README of test-network-k8s, launch the network, create a channel, and deploy and invoke the basic-asset-transfer smart contract:
12+
13+
```shell
14+
./network kind
15+
16+
./network cluster init
17+
18+
./network up
19+
20+
./network channel create
21+
22+
./network chaincode deploy asset-transfer-basic ../asset-transfer-basic/chaincode-java
23+
24+
./network chaincode invoke asset-transfer-basic '{"Args":["InitLedger"]}'
25+
```
26+
27+
REST API will not be used in the procedure described below, but the connection profile will be generated by launching it:
28+
```shell
29+
./network rest-easy
30+
```
31+
32+
## Setting of Hyperledger Caliper side
33+
34+
Following [Install manual of Hyperledger Caliper v0.6.0](https://hyperledger.github.io/caliper/v0.6.0/installing-caliper/), install Hyperledger Caliper from npm:
35+
36+
```shell
37+
git clone https://github.com/hyperledger/caliper-benchmarks.git
38+
cd caliper-benchmarks
39+
npm install --only=prod @hyperledger/[email protected]
40+
npx caliper bind --caliper-bind-sut fabric:fabric-gateway
41+
```
42+
43+
Copy the connection profile created in test-network-k8s environment to Caliper environment.
44+
45+
```shell
46+
cp <fabric-samples install dir>/test-network-k8s/build/fabric-rest-sample-config/HLF_CONNECTION_PROFILE_ORG1 networks/fabric/connection-profile.json
47+
```
48+
Replace `*.test-network.svc.cluster.local` with `*.localho.st` in "url" and "grpcOptions" section of connection-profile.json as below:
49+
50+
```json
51+
"peers": {
52+
"org1-peers": {
53+
"url": "grpcs://org1-peer1.localho.st:443",
54+
"tlsCACerts": {
55+
"pem": <contents of pem file>"
56+
},
57+
"grpcOptions": {
58+
"ssl-target-name-override": "org1-peer1.localho.st",
59+
"hostnameOverride": "org1-peer1.localho.st"
60+
}
61+
}
62+
},
63+
```
64+
`*.localho.st` is wildcard domain defined for accessing K8s pod from external network via Nginx ingress controller. Please see [Working with Kubernetes](KUBERNETES.md) document for details.
65+
66+
Open networks/fabric/test-network.yaml and edit it as below:
67+
68+
69+
```yaml
70+
name: Caliper Benchmarks
71+
version: "2.0.0"
72+
73+
caliper:
74+
blockchain: fabric
75+
76+
channels:
77+
# channelName of mychannel matches the name of the channel created by test network
78+
- channelName: mychannel
79+
# the chaincodeIDs of all the fabric chaincodes in caliper-benchmarks
80+
contracts:
81+
- id: fabcar
82+
- id: fixed-asset
83+
- id: marbles
84+
- id: simple
85+
- id: smallbank
86+
- id: asset-transfer-basic
87+
88+
organizations:
89+
- mspid: Org1MSP
90+
# Identities come from cryptogen created material for test-network
91+
identities:
92+
certificates:
93+
- name: 'User1'
94+
clientPrivateKey:
95+
path: '<fabric-samples install absolute dir>/test-network-k8s/build/enrollments/org1/users/org1admin/msp/keystore/key.pem'
96+
97+
clientSignedCert:
98+
path: '<fabric-samples install absolute dir>/test-network-k8s/build/enrollments/org1/users/org1admin/msp/signcerts/cert.pem'
99+
100+
connectionProfile:
101+
path: 'networks/fabric/connection-profile.json'
102+
discover: true
103+
```
104+
105+
Currently, sample code for running a performance benchmark targeting asset-transfer-basic is not published on the Caliper repository. Therefore, use the sample code published in [Caliper's user manual to build a test workload.](https://hyperledger.github.io/caliper/vNext/fabric-tutorial/tutorials-fabric-existing/)
106+
107+
108+
As shown in "Step 3" of the above document, create workload/readAsset.js file and edit it as below:
109+
110+
111+
```javascript
112+
'use strict';
113+
114+
const { WorkloadModuleBase } = require('@hyperledger/caliper-core');
115+
116+
class MyWorkload extends WorkloadModuleBase {
117+
constructor() {
118+
super();
119+
}
120+
121+
async initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext) {
122+
await super.initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext);
123+
124+
for (let i=0; i<this.roundArguments.assets; i++) {
125+
const assetID = `${this.workerIndex}_${i}`;
126+
console.log(`Worker ${this.workerIndex}: Creating asset ${assetID}`);
127+
const request = {
128+
contractId: this.roundArguments.contractId,
129+
contractFunction: 'CreateAsset',
130+
invokerIdentity: 'User1',
131+
contractArguments: [assetID,'blue','20','penguin','500'],
132+
readOnly: false
133+
};
134+
135+
await this.sutAdapter.sendRequests(request);
136+
}
137+
}
138+
139+
async submitTransaction() {
140+
const randomId = Math.floor(Math.random()*this.roundArguments.assets);
141+
const myArgs = {
142+
contractId: this.roundArguments.contractId,
143+
contractFunction: 'ReadAsset',
144+
invokerIdentity: 'User1',
145+
contractArguments: [`${this.workerIndex}_${randomId}`],
146+
readOnly: true
147+
};
148+
149+
await this.sutAdapter.sendRequests(myArgs);
150+
}
151+
152+
async cleanupWorkloadModule() {
153+
for (let i=0; i<this.roundArguments.assets; i++) {
154+
const assetID = `${this.workerIndex}_${i}`;
155+
console.log(`Worker ${this.workerIndex}: Deleting asset ${assetID}`);
156+
const request = {
157+
contractId: this.roundArguments.contractId,
158+
contractFunction: 'DeleteAsset',
159+
invokerIdentity: 'User1',
160+
contractArguments: [assetID],
161+
readOnly: false
162+
};
163+
164+
await this.sutAdapter.sendRequests(request);
165+
}
166+
}
167+
}
168+
169+
function createWorkloadModule() {
170+
return new MyWorkload();
171+
}
172+
173+
module.exports.createWorkloadModule = createWorkloadModule;
174+
```
175+
176+
As shown in "Step 4" of the above document, create benchmarks/myAssetBenchmark.yaml file and edit it as below:
177+
178+
179+
```yaml
180+
test:
181+
name: basic-contract-benchmark
182+
description: test benchmark
183+
workers:
184+
number: 2
185+
rounds:
186+
- label: readAsset
187+
description: Read asset benchmark
188+
txDuration: 30
189+
rateControl:
190+
type: fixed-load
191+
opts:
192+
transactionLoad: 2
193+
workload:
194+
module: workload/readAsset.js
195+
arguments:
196+
assets: 10
197+
contractId: asset-transfer-basic
198+
```
199+
200+
After creating the above files, you can run a performance benchmark with the following command, which will create some assets and measure the time it takes to reference the assets.
201+
202+
```shell
203+
204+
npx caliper launch manager --caliper-workspace . --caliper-benchconfig benchmarks/myAssetBenchmark.yaml --caliper-networkconfig networks/fabric/test-network.yaml
205+
```

test-network-k8s/docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@ _Chaincode-as-a-Service_ running in a shared Kubernetes namespace.
4444
- [Debugging Chaincode](CHAINCODE_AS_A_SERVICE.md)
4545
- [Working with Applications](APPLICATIONS.md)
4646
- [High Availability](HIGH_AVAILABILITY.md)
47+
- [Benchmarking the performance using Hyperledger Caliper](CALIPER.md)

0 commit comments

Comments
 (0)