栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

fisco-bcos使用caliper进行压力测试

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

fisco-bcos使用caliper进行压力测试

使用caliper对fisco-bcos进行压力测试 通过Caliper进行压力测试程序

注意:官网给出的测试案例会出现错误,我会给出相应的解决方案,本文以centos系统为例进行测试

1. 环境要求 第一步:配置基本环境
  1. 部署Caliper的计算机需要安装有以下软件:python 2.7、make、g++、gcc及git。
  2. 操作系统满足以下要求:centos>=7
第二步:安装NodeJs

NodeJS 版本建议 8 (LTS), 9, 或 10 (LTS)。
安装步骤:

# 安装nvm
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash

# 若出现因网络问题导致长时间下载失败,可尝试以下命令
curl -o- https://gitee.com/mirrors/nvm/raw/v0.33.2/install.sh | bash

# 加载nvm配置
source ~/.$(basename $SHELL)rc
# 安装Node.js 8
nvm install 8
# 使用Node.js 8
nvm use 8
第三步:部署Docker

版本要求:>= 18.06.01
安装步骤:

sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum makecache fast
sudo yum install docker-ce
service docker start
ps -A | grep docker
systemctl enable docker
第四步:安装Docker Compose

版本要求:>= 1.22.0
安装步骤:

sudo curl -L “https://github.com/docker/compose/releases/download/1.24.0/docker-compose-(uname − s ) − (uname -s)-(uname −s)−(uname -m)” -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
2. Caliper部署 第一步:部署

Caliper提供了方便易用的命令行界面工具caliper-cli
具体步骤

1. 建立一个工作目录
mkdir benchmarks && cd benchmarks
2. 对npm项目进行初始化
npm init -y
3. 安装caliper-cli
npm install --only=prod @hyperledger/caliper-cli@0.2.0
4. 验证caliper-cli安装成功
npx caliper --version
5. 如安装成功,则会打印相应的版本信息,如下所示:

第二步:绑定

由于Caliper采用了轻量级的部署方式,因此需要显式的绑定步骤指定要测试的平台及适配器版本,caliper-cli会自动进行相应依赖项的安装。

使用如下方式绑定fisco-bcos
npx caliper bind --caliper-bind-sut fisco-bcos --caliper-bind-sdk latest

注意:在部署的时候可能会出现如下问题,

针对这个问题,去http://ping.chinaz.com/找海外节点信息即可

按照如下步骤进行配置域名

第三步:快速体验fisco-bcos的基准测试

为方便测试人员快速上手,FISCO BCOS已经为Caliper提供了一组预定义的测试样例,测试对象涵盖HelloWorld合约、Solidity版转账合约及预编译版转账合约。同时在测试样例中,Caliper测试脚本会使用docker在本地自动部署及运行4个互连的节点组成的链,因此测试人员无需手工搭链及编写测试用例便可直接运行这些测试样例。
具体的步骤如下

1. 在工作目录下下载预定义测试用例
# 拉取gitee代码
git clone https://gitee.com/vita-dounai/caliper-benchmarks.git
2. 执行HelloWorld合约测试
npx caliper benchmark run --caliper-workspace caliper-benchmarks --caliper-benchconfig benchmarks/samples/fisco-bcos/helloworld/config.yaml  --caliper-networkconfig networks/fisco-bcos/4nodes1group/fisco-bcos.json
################################测试结果如下#################################


3. 执行Solidity版转账合约测试
npx caliper benchmark run --caliper-workspace caliper-benchmarks --caliper-benchconfig benchmarks/samples/fisco-bcos/transfer/solidity/config.yaml  --caliper-networkconfig networks/fisco-bcos/4nodes1group/fisco-bcos.json
################################测试结果如下#################################


4.执行预编译版转账合约测试
npx caliper benchmark run --caliper-workspace caliper-benchmarks --caliper-benchconfig benchmarks/samples/fisco-bcos/transfer/precompiled/config.yaml  --caliper-networkconfig networks/fisco-bcos/4nodes1group/fisco-bcos.json
################################测试结果如下#################################


3. 需要注意的事项

由于FISCO BCOS对于caliper0.2.0版本的适配存在部分不兼容情况,需要修改代码后方可正常运行。
这里给出需要修改后的文件(注意:如果没有出现问题就不用修改)

fiscoBcos.js文件如下:


'use strict';

const {
    BlockchainInterface,
    CaliperUtils
} = require('@hyperledger/caliper-core');
const installSmartContractImpl = require('./installSmartContract');
const invokeSmartContractImpl = require('./invokeSmartContract');
const generateRawTransactionImpl = require('./generateRawTransactions');
const sendRawTransactionImpl = require('./sendRawTransactions');
const Color = require('./common').Color;
const commLogger = CaliperUtils.getLogger('fiscoBcos.js');


class FiscoBcos extends BlockchainInterface {
    
    constructor(config_path, workspace_root) {
        super(config_path);
        this.bcType = 'fisco-bcos';
        this.workspaceRoot = workspace_root;
        this.fiscoBcosSettings = CaliperUtils.parseYaml(this.configPath)['fisco-bcos'];

        if (this.fiscoBcosSettings.network && this.fiscoBcosSettings.network.authentication) {
            for (let k in this.fiscoBcosSettings.network.authentication) {
                this.fiscoBcosSettings.network.authentication[k] = CaliperUtils.resolvePath(this.fiscoBcosSettings.network.authentication[k], workspace_root);
            }
        }
    }

    
    async init() {
        return Promise.resolve();
    }

    
    async installSmartContract() {
       const fiscoBcosSettings = this.fiscoBcosSettings;
        try {
            await installSmartContractImpl.run(fiscoBcosSettings, this.workspaceRoot);
        } catch (error) {
            commLogger.error(Color.error(`FISCO BCOS smart contract install failed: ${(error.stack ? error.stack : error)}`));
            throw error;
        }
    }

    
    async getContext(name, args, clientIdx) {
        return Promise.resolve();
    }

    
    async releaseContext(context) {
        return Promise.resolve();
    }

    
    async invokeSmartContract(context, contractID, contractVer, args, timeout) {
        let promises = [];
        try {
            args.forEach((arg) => {
                let fcn = null;
                let fcArgs = [];

                for (let key in arg) {
                    if (key === 'transaction_type') {
                        fcn = arg[key].toString();
                    } else {
                        fcArgs.push(arg[key].toString());
                    }
                }
                promises.push(invokeSmartContractImpl.run(context, this.fiscoBcosSettings, contractID, fcn, fcArgs, this.workspaceRoot));
            });

            return await Promise.all(promises);
        } catch (error) {
            commLogger.error(Color.error(`FISCO BCOS smart contract invoke failed: ${(error.stack ? error.stack : JSON.stringify(error))}`));
            throw error;
        }
    }

    
    async queryState(context, contractID, contractVer, key, fcn) {
        try {
            return invokeSmartContractImpl.run(context, this.fiscoBcosSettings, contractID, fcn, key, this.workspaceRoot, true);
        } catch (error) {
            commLogger.error(Color.error(`FISCO BCOS smart contract query failed: ${(error.stack ? error.stack : error)}`));
            throw error;
        }
    }

    
    async generateRawTransaction(context, contractID, arg, file) {
        return generateRawTransactionImpl.run(this.fiscoBcosSettings, this.workspaceRoot, context, contractID, arg, file);
    }

    
    async sendRawTransaction(context, transactions) {
        return sendRawTransactionImpl.run(this.fiscoBcosSettings, context, transactions);
    }
}

module.exports = FiscoBcos;

channelPromise.js如下所示:


'use strict';

const tls = require('tls');
const fs = require('fs');
const net = require('net');
const uuidv4 = require('uuid/v4');
const events = require('events');


class NetworkError extends Error {
    
    constructor(msg) {
        super(msg);
        this.name = 'NetworkError';
    }
}

let emitters = new Map();
let buffers = new Map();
let sockets = new Map();
let lastBytesRead = new Map();


function parseResponse(response) {
    let seq = response.slice(6, 38).toString();
    let result = JSON.parse(response.slice(42).toString());
    let emitter = emitters.get(seq);
    if(!emitter) {
        //Stale message receieved
        return;
    }
    emitter = emitter.emitter;

    if (emitter) {
        let readonly = Object.getOwnPropertyDescriptor(emitter, 'readOnly').value;
        if (readOnly) {
            if (result.error || result.result !== undefined ) {
                emitter.emit('gotresult', result);
            }
        } else {
            if (result.error || result.status || (result.result && result.result.status)) {
                emitter.emit('gotresult', result);
            } else {
                if (!result.result) {
                    throw new NetworkError(`unknown message receieved, seq=${seq}, data=${response.toString()}`);
                }
            }
        }
    } else {
        throw new NetworkError(`unknown owner message receieved, seq=${seq}, data=${response.toString()}`);
    }
}


function createNewSocket(ip, port, authentication) {
    let secureContextOptions = {
        key: fs.readFileSync(authentication.key),
        cert: fs.readFileSync(authentication.cert),
        ca: fs.readFileSync(authentication.ca),
        ecdhCurve: 'secp256k1',
    };

    let secureContext = tls.createSecureContext(secureContextOptions);

    let socket = new net.Socket();
    socket.connect(port, ip);

    let clientOptions = {
        rejectUnauthorized: false,
        secureContext: secureContext,
        socket: socket
    };

    let tlsSocket = tls.connect(clientOptions);

    tlsSocket.on('error', function (error) {
        throw new Error(error);
    });

    let socketID = `${ip}:${port}`;

    lastBytesRead.set(socketID, 0);

    tlsSocket.on('data', function (data) {
        let response = null;
        if (data instanceof Buffer) {
            response = data;
        }
        else {
            response = Buffer.from(data, 'ascii');
        }

        if (!buffers.has(socketID)) {
            // First time to read data from this socket
            let expectedLength = null;
            if (tlsSocket.bytesRead - lastBytesRead.get(socketID) >= 4) {
                expectedLength = response.readUIntBE(0, 4);
            }

            if (!expectedLength || tlsSocket.bytesRead < lastBytesRead.get(socketID) + expectedLength) {
                buffers.set(socketID, {
                    expectedLength: expectedLength,
                    buffer: response
                });
            } else {
                lastBytesRead.set(socketID, lastBytesRead.get(socketID) + expectedLength);
                parseResponse(response);
                buffers.delete(socketID);
            }
        } else {
            // Multiple reading
            let cache = buffers.get(socketID);
            cache.buffer = Buffer.concat([cache.buffer, response]);
            if (!cache.expectedLength && tlsSocket.bytesRead - lastBytesRead.get(socketID) >= 4) {
                cache.expectedLength = cache.buffer.readUIntBE(0, 4);
            }

            if (cache.expectedLength && tlsSocket.bytesRead - lastBytesRead.get(socketID) >= cache.expectedLength) {
                lastBytesRead.set(socketID, lastBytesRead.get(socketID) + cache.expectedLength);
                parseResponse(buffers.get(socketID).buffer);
                buffers.delete(socketID);
            }
        }
    });

    return tlsSocket;
}


function packageData(data) {
    const headerLength = 4 + 2 + 32 + 4;

    let length = Buffer.alloc(4);
    length.writeUInt32BE(headerLength + data.length);
    let type = Buffer.alloc(2);
    type.writeUInt16BE(0x12);
    let uuid = uuidv4();
    uuid = uuid.replace(/-/g, '');
    let seq = Buffer.from(uuid, 'ascii');
    let result = Buffer.alloc(4);
    result.writeInt32BE(0);
    let msg = Buffer.from(data, 'ascii');

    return {
        'uuid': uuid,
        'packagedData': Buffer.concat([length, type, seq, result, msg])
    };
}


function clearContext(uuid) {
    clearTimeout(emitters.get(uuid).timer);
    emitters.delete(uuid);
    buffers.delete(uuid);
}


function channelPromise(node, authentication, data, timeout, readonly = false) {
    let ip = node.ip;
    let port = node.channelPort;

    let connectionID = `${ip}${port}`;
    if (!sockets.has(connectionID)) {
        let newSocket = createNewSocket(ip, port, authentication);
        newSocket.unref();
        sockets.set(connectionID, newSocket);
    }
    let tlsSocket = sockets.get(connectionID);

    let dataPackage = packageData(JSON.stringify(data));
    let uuid = dataPackage.uuid;

    tlsSocket.socketID = uuid;
    let packagedData = dataPackage.packagedData;
    let channelPromise = new Promise(async (resolve, reject) => {
        let eventEmitter = new events.EventEmitter();
        Object.defineProperty(eventEmitter, 'readOnly', {
            value: readOnly,
            writable: false,
            configurable: false,
            enumerable: false
        });

        eventEmitter.on('gotresult', (result) => {
            clearContext(uuid);
            if (result.error) {
                reject(result);
            } else {
                resolve(result);
            }
            return; // This `return` is not necessary, but it may can avoid future trap
        });

        eventEmitter.on('timeout', () => {
            clearContext(uuid);
            reject({ 'error': 'timeout' });
            return; // This `return` is not necessary, but it may can avoid future trap
        });

        emitters.set(uuid, {
            emitter: eventEmitter,
            timer: setTimeout(() => {
                eventEmitter.emit('timeout');
            }, timeout)
        });

        tlsSocket.write(packagedData);
    });
    return channelPromise;
}

module.exports = channelPromise;

web3sync.js如下所示:


'use strict';

const uuidv4 = require('uuid/v4');
const utils = require('./utils');
const Transaction = require('./transactionObject').Transaction;


function genRandomID() {
    let uuid = uuidv4();
    uuid = '0x' + uuid.replace(/-/g, '');

    return uuid;
}


function signTransaction(txData, privKey, callback) {
    let tx = new Transaction(txData);
    let privateKey = Buffer.from(privKey, 'hex');
    tx.sign(privateKey);

    // Build a serialized hex version of the tx
    let serializedTx = '0x' + tx.serialize().toString('hex');
    if (callback !== null) {
        callback(serializedTx);
    } else {
        return serializedTx;
    }
}


function getTxData(func, params) {
    let r = /^w+((.*))$/g.exec(func);
    let types = [];
    if (r[1]) {
        types = r[1].split(',');
    }
    return utils.encodeTxData(func, types, params);
}


function getSignTx(groupId, account, privateKey, to, func, params, blockLimit) {
    let txData = getTxData(func, params);

    let postdata = {
        data: txData,
        from: account,
        to: to,
        gas: 1000000,
        randomid: genRandomID(),
        blockLimit: blockLimit,
        chainId: 1,
        groupId: groupId,
         extraData: '0x0'
    };

    return signTransaction(postdata, privateKey, null);
}


function getSignDeployTx(groupId, account, privateKey, bin, blockLimit) {
    let txData = bin.indexOf('0x') === 0 ? bin : ('0x' + bin);

    let postdata = {
        data: txData,
        from: account,
        to: null,
        gas: 1000000,
        randomid: genRandomID(),
        blockLimit: blockLimit,
        chainId: 1,
        groupId: groupId,
        extraData: '0x0'
    };

    return signTransaction(postdata, privateKey, null);
}

module.exports.getSignDeployTx = getSignDeployTx;
module.exports.signTransaction = signTransaction;
module.exports.getSignTx = getSignTx;
module.exports.getTxData = getTxData;
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/388933.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号