目录
要点
FISCO BCOS 的网络配置
fisco-bcos.json
{
"caliper": {
"blockchain": "fisco-bcos"
},
"fisco-bcos": {
"config": {
"privateKey": "680a16092121f069a00c5b9929da759c402ea08ad92e266c12f55734bb877626",
"account": "0x6afc5c609bb76b97677b42e452d660050d8548e2"
},
"network": {
"nodes": [
{
"ip": "127.0.0.1",
"rpcPort": "8545",
"channelPort": "20200"
},
{
"ip": "127.0.0.1",
"rpcPort": "8546",
"channelPort": "20201"
},
{
"ip": "127.0.0.1",
"rpcPort": "8547",
"channelPort": "20202"
},
{
"ip": "127.0.0.1",
"rpcPort": "8548",
"channelPort": "20203"
}
],
"authentication": {
"key": "/root/fisco/nodes/127.0.0.1/sdk/sdk.key",
"cert": "/root/fisco/nodes/127.0.0.1/sdk/sdk.crt",
"ca": "/root/fisco/nodes/127.0.0.1/sdk/ca.crt"
},
"groupID": 1,
"timeout": 100000
},
"smartContracts": [
{
"id": "helloworld",
"path": "contract/helloworld/HelloWorld.sol",
"language": "solidity",
"version": "v0"
}
]
},
"info": {
"Version": "2.0.0",
"Size": "4 Nodes",
"Distribution": "Single Host"
}
}
配置文件分解
caliper 平台类型
config 必要配置文件
network 网络信息
可以根据自己搭建的链来修改对应的端口
authentication 服务节点证书
可以根据自己搭建的链来修改对应的路径
smartContracts 智能合约列表
基准测试使用的智能合约列表
id , 智能合约的唯一 ID
language , 如果智能合约是由 Solidity 实现的,则该属性的值应为solidity。如果是FISCO BCOS 预编译合约,该属性值为precompile
path ,如果智能合约是由 Solidity实现的,则该属性需要设置为Solidity代码文件的路径,否则不使用该属性。
address , 果智能合约是FISCOBCOS预编译合约,则该属性应设置为合约预设地址,否则不使用该属性。
version , 智能合约的版本,默认为v0
Benchmark 配置
config.yaml
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
---
test:
name: Hello World
description: This is a helloworld benchmark of FISCO BCOS for caliper
clients:
type: local
number: 1 # 使用1个工作进程进行基准测试
rounds: # 这里将会有两轮测试
- label: get
description: Test performance of getting name
txNumber:
- 10
rateControl:
- type: fixed-rate
opts:
tps: 1 # 以每秒1TPS的速率提交10个TX
callback: config/helloworld/get.js # TX的内容get.js的工作负载模块决定
- label: set
description: Test performance of setting name
txNumber:
- 100
rateControl:
- type: fixed-rate
opts:
tps: 10
callback: config/helloworld/set.js
monitor:
type:
- docker
- process
docker:
name:
- node0
- node1
- node2
- node3
process:
- command: node
arguments: fiscoBcosClientWorker.js
multiOutput: avg
interval: 0.5
Workload 配置
首先工作负载模块必须导出以下三个异步函数:
init 函数
run 函数
end 函数
init 函数
init(blockchain: BlockchainInterface, context: object, args: object)
该 init 函数在回合开始之前调用。它接收:
参数中的 SUT 适配器实例 blockchain ;
由适配器创建的特定于 context 适配器的数据(通常包含有关网络的附加数据);
以及用户提供的设置对象,该对象在基准配置文件的属性 args 中设置(如果工作负载模块是可配置的)。 test.rounds[i].arguments
run 函数
run() => Promise<TxResult[]>
run 每次设置速率控制器启用下一个 TX 时都会调用该函数。该函数必须组装下一个 TX 的内容(使用任意逻辑)并调用适配器实例的 invokeSmartContract 或 querySmartContract 函数。有关上述功能的具体用法,请参阅适配器配置页面。
最后,该函数必须返回调用/查询调用的结果!
end 函数
end()
该 end 函数在回合结束后调用。此时工作负载模块可以执行资源清理或任何其他维护活动。
测试 JS 文件
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
module.exports.info = ' setting name';
let bc, contx;
let txnPerBatch;
// 在回合之前调用函数
// @blockchain
module.exports.init = function (blockchain, context, args) {
txnPerBatch = 1;
bc = blockchain;
contx = context;
return Promise.resolve();
};
/**
* 构造一个函数用于初始化args
* Generates simple workload
* @return {Object} array of json objects
*/
function generateWorkload() {
let workload = [];
for (let i = 0; i < txnPerBatch; i++) {
let w = {
'transaction_type': 'set(string)',
'name': 'hello! - from ' + process.pid.toString(), // process.pid.toString() 被用来生成一个包含进程 ID 的唯一字符串
};
workload.push(w);
}
return workload;
}
// 在运行的时候调用
module.exports.run = function () {
let args = generateWorkload();
return bc.invokeSmartContract(contx, 'helloworld', 'v0', args, null);
};
// 在结束的时候调用
module.exports.end = function () {
// Do nothing
return Promise.resolve();
};
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
module.exports.info = ' querying name';
let bc, contx;
module.exports.init = function (blockchain, context, args) {
// Do nothing
bc = blockchain;
contx = context;
return Promise.resolve();
};
module.exports.run = function () {
return bc.queryState(contx, 'helloworld', 'v0', null, 'get()');
};
module.exports.end = function () {
// Do nothing
return Promise.resolve();
};
对 blockchain 对象的入参详细说明:
bc.invokeSmartContract 是 Caliper 提供的一个方法,用于调用智能合约,用于执行交易并修改区块链的状态。它接受五个参数:
contx :上下文对象,代表当前测试的上下文环境。
'mycontract' :智能合约的名称,这里是一个示例名称,您可以根据实际情况替换为您要调用的智能合约的名称。要与 fisco-bcos.json 中 id 一样
'v0' :智能合约的版本,这里是一个示例版本号,您可以根据实际情况替换为您要调用的智能合约的版本号。
args :交易参数对象,用于指定智能合约调用的参数。
null : 交易超时时间(单位:秒),指定了调用智能合约的最长等待时间。可以为null,也可以设置为30等等
bc.queryState 是 Caliper 提供的方法之一,用于查询区块链上的数据而不执行交易,用于读取数据。它接受五个参数:
contx :上下文对象,代表当前测试的上下文环境。
'mycontract' :智能合约的名称,这里是一个示例名称,您可以根据实际情况替换为您要调用的智能合约的名称。要与 fisco-bcos.json 中 id 一样
'v0' :智能合约的版本,这里是一个示例版本号,您可以根据实际情况替换为您要调用的智能合约的版本号。
null : 交易超时时间(单位:秒),指定了调用智能合约的最长等待时间。可以为null,也可以设置为30等等
'get()' :调用具体的方法名称