From 714d4adcb0d96b749c60dcf57e07f0c39e4dd810 Mon Sep 17 00:00:00 2001 From: Chenxi Li Date: Wed, 7 Aug 2019 11:11:32 +0800 Subject: [PATCH] parent 3f9293a404d7a2023cdc766a9434f2499757aa46 author Chenxi Li 1565147492 +0800 committer Chenxi Li 1569833600 +0800 implements FISCO BCOS adapter Signed-off-by: Chenxi Li --- .gitignore | 9 + CONTRIBUTING.md | 1 + README.md | 1 + packages/caliper-cli/caliper.js | 2 +- packages/caliper-cli/package.json | 1 + packages/caliper-fisco-bcos/.editorconfig | 26 ++ packages/caliper-fisco-bcos/.eslintignore | 16 + packages/caliper-fisco-bcos/.eslintrc.yml | 48 +++ packages/caliper-fisco-bcos/index.js | 18 + .../caliper-fisco-bcos/lib/channelPromise.js | 250 ++++++++++++++ packages/caliper-fisco-bcos/lib/common.js | 75 +++++ packages/caliper-fisco-bcos/lib/fiscoBcos.js | 165 ++++++++++ .../caliper-fisco-bcos/lib/fiscoBcosApi.js | 275 ++++++++++++++++ .../lib/fiscoBcosClientFactory.js | 52 +++ .../lib/fiscoBcosClientWorker.js | 74 +++++ .../lib/generateRawTransactions.js | 67 ++++ .../lib/installSmartContract.js | 76 +++++ .../lib/invokeSmartContract.js | 66 ++++ .../lib/sendRawTransactions.js | 51 +++ .../caliper-fisco-bcos/lib/web3lib/config.js | 19 ++ .../lib/web3lib/transactionObject.js | 308 ++++++++++++++++++ .../caliper-fisco-bcos/lib/web3lib/utils.js | 225 +++++++++++++ .../lib/web3lib/web3sync.js | 127 ++++++++ packages/caliper-fisco-bcos/package.json | 99 ++++++ packages/caliper-samples/README.md | 10 + .../generate_txs_in_advance/addUser.js | 74 +++++ .../generate_txs_in_advance/config.yaml | 64 ++++ .../generate_txs_in_advance/generate.js | 66 ++++ .../generate_txs_in_advance/send.js | 93 ++++++ .../fisco-bcos/helloworld/config.yaml | 55 ++++ .../benchmark/fisco-bcos/helloworld/get.js | 35 ++ .../benchmark/fisco-bcos/helloworld/set.js | 53 +++ .../transfer/precompiled/addUser.js | 74 +++++ .../transfer/precompiled/config.yaml | 57 ++++ .../transfer/precompiled/transfer.js | 95 ++++++ .../fisco-bcos/transfer/solidity/addUser.js | 79 +++++ .../fisco-bcos/transfer/solidity/config.yaml | 57 ++++ .../fisco-bcos/transfer/solidity/transfer.js | 95 ++++++ .../4nodes1group/docker-compose.yaml | 56 ++++ .../fisco-bcos/4nodes1group/fisco-bcos.json | 71 ++++ .../fisco-bcos/4nodes1group/node0/conf/ca.crt | 20 ++ .../4nodes1group/node0/conf/group.1.genesis | 26 ++ .../4nodes1group/node0/conf/group.1.ini | 12 + .../4nodes1group/node0/conf/node.crt | 33 ++ .../4nodes1group/node0/conf/node.key | 5 + .../4nodes1group/node0/conf/node.nodeid | 1 + .../fisco-bcos/4nodes1group/node0/config.ini | 70 ++++ .../fisco-bcos/4nodes1group/node1/conf/ca.crt | 20 ++ .../4nodes1group/node1/conf/group.1.genesis | 26 ++ .../4nodes1group/node1/conf/group.1.ini | 12 + .../4nodes1group/node1/conf/node.crt | 33 ++ .../4nodes1group/node1/conf/node.key | 5 + .../4nodes1group/node1/conf/node.nodeid | 1 + .../fisco-bcos/4nodes1group/node1/config.ini | 70 ++++ .../fisco-bcos/4nodes1group/node2/conf/ca.crt | 20 ++ .../4nodes1group/node2/conf/group.1.genesis | 26 ++ .../4nodes1group/node2/conf/group.1.ini | 12 + .../4nodes1group/node2/conf/node.crt | 33 ++ .../4nodes1group/node2/conf/node.key | 5 + .../4nodes1group/node2/conf/node.nodeid | 1 + .../fisco-bcos/4nodes1group/node2/config.ini | 70 ++++ .../fisco-bcos/4nodes1group/node3/conf/ca.crt | 20 ++ .../4nodes1group/node3/conf/group.1.genesis | 26 ++ .../4nodes1group/node3/conf/group.1.ini | 12 + .../4nodes1group/node3/conf/node.crt | 33 ++ .../4nodes1group/node3/conf/node.key | 5 + .../4nodes1group/node3/conf/node.nodeid | 1 + .../fisco-bcos/4nodes1group/node3/config.ini | 70 ++++ .../fisco-bcos/4nodes1group/sdk/ca.crt | 20 ++ .../fisco-bcos/4nodes1group/sdk/node.crt | 33 ++ .../fisco-bcos/4nodes1group/sdk/node.key | 5 + packages/caliper-samples/package.json | 5 +- .../fisco-bcos/helloworld/HelloWorld.sol | 17 + .../fisco-bcos/transfer/ParallelContract.sol | 25 ++ .../fisco-bcos/transfer/ParallelOk.sol | 49 +++ .../caliper-tests-integration/package.json | 3 +- .../scripts/publishNpmPackages.js | 1 + 77 files changed, 3908 insertions(+), 3 deletions(-) create mode 100644 packages/caliper-fisco-bcos/.editorconfig create mode 100644 packages/caliper-fisco-bcos/.eslintignore create mode 100644 packages/caliper-fisco-bcos/.eslintrc.yml create mode 100644 packages/caliper-fisco-bcos/index.js create mode 100644 packages/caliper-fisco-bcos/lib/channelPromise.js create mode 100644 packages/caliper-fisco-bcos/lib/common.js create mode 100644 packages/caliper-fisco-bcos/lib/fiscoBcos.js create mode 100644 packages/caliper-fisco-bcos/lib/fiscoBcosApi.js create mode 100644 packages/caliper-fisco-bcos/lib/fiscoBcosClientFactory.js create mode 100644 packages/caliper-fisco-bcos/lib/fiscoBcosClientWorker.js create mode 100644 packages/caliper-fisco-bcos/lib/generateRawTransactions.js create mode 100644 packages/caliper-fisco-bcos/lib/installSmartContract.js create mode 100644 packages/caliper-fisco-bcos/lib/invokeSmartContract.js create mode 100644 packages/caliper-fisco-bcos/lib/sendRawTransactions.js create mode 100755 packages/caliper-fisco-bcos/lib/web3lib/config.js create mode 100755 packages/caliper-fisco-bcos/lib/web3lib/transactionObject.js create mode 100755 packages/caliper-fisco-bcos/lib/web3lib/utils.js create mode 100755 packages/caliper-fisco-bcos/lib/web3lib/web3sync.js create mode 100644 packages/caliper-fisco-bcos/package.json create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/addUser.js create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/config.yaml create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/generate.js create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/send.js create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/helloworld/config.yaml create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/helloworld/get.js create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/helloworld/set.js create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/addUser.js create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/config.yaml create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/transfer.js create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/addUser.js create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/config.yaml create mode 100644 packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/transfer.js create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/docker-compose.yaml create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/fisco-bcos.json create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/ca.crt create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/group.1.genesis create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/group.1.ini create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.crt create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.key create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.nodeid create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/config.ini create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/ca.crt create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/group.1.genesis create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/group.1.ini create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.crt create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.key create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.nodeid create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/config.ini create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/ca.crt create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/group.1.genesis create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/group.1.ini create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.crt create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.key create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.nodeid create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/config.ini create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/ca.crt create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/group.1.genesis create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/group.1.ini create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.crt create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.key create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.nodeid create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/config.ini create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/ca.crt create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/node.crt create mode 100644 packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/node.key create mode 100644 packages/caliper-samples/src/contract/fisco-bcos/helloworld/HelloWorld.sol create mode 100644 packages/caliper-samples/src/contract/fisco-bcos/transfer/ParallelContract.sol create mode 100644 packages/caliper-samples/src/contract/fisco-bcos/transfer/ParallelOk.sol diff --git a/.gitignore b/.gitignore index 9dd1e671d..79daed249 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,12 @@ _site/ # pm2 files **/.pm2/ + +# lerna log +lerna-debug.log + +# contract address file +**/*.address + +# Ignore data +data/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c0d6ebac1..885a3f33a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,6 +39,7 @@ Each `caliper-` is a separate package that contains a distinct adaptor - caliper-fabric - caliper-iroha - caliper-sawtooth +- caliper-fisco-bcos Each adaptor implements the `BlockchainInterface` from the core package, as well as a `ClientFactory` and `ClientWorker` that are bespoke to the adaptor. diff --git a/README.md b/README.md index 5f48dac68..35fe20053 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Currently supported blockchain solutions: * [sawtooth 1.0+](https://github.com/hyperledger/sawtooth-core) * [Iroha 1.0 beta-3](https://github.com/hyperledger/iroha) * [Burrow 1.0](https://github.com/hyperledger/burrow) +* [FISCO BCOS v2.0.0](https://github.com/FISCO-BCOS/FISCO-BCOS) [Hyperledger Composer](https://github.com/hyperledger/composer) is also supported. diff --git a/packages/caliper-cli/caliper.js b/packages/caliper-cli/caliper.js index 01df2e904..58c0e276a 100644 --- a/packages/caliper-cli/caliper.js +++ b/packages/caliper-cli/caliper.js @@ -40,6 +40,6 @@ results.thePromise.then( () => { } process.exit(0); }).catch((error) => { - cmdUtil.log(error+chalk.red('\nCommand failed\n')); + cmdUtil.log(error.stack+chalk.red('\nCommand failed\n')); process.exit(1); }); diff --git a/packages/caliper-cli/package.json b/packages/caliper-cli/package.json index 32963e200..da973f022 100644 --- a/packages/caliper-cli/package.json +++ b/packages/caliper-cli/package.json @@ -30,6 +30,7 @@ "@hyperledger/caliper-iroha": "^0.1.0", "@hyperledger/caliper-sawtooth": "^0.1.0", "@hyperledger/caliper-ethereum": "^0.1.0", + "@hyperledger/caliper-fisco-bcos": "^0.1.0", "chalk": "1.1.3", "yargs": "10.0.3" }, diff --git a/packages/caliper-fisco-bcos/.editorconfig b/packages/caliper-fisco-bcos/.editorconfig new file mode 100644 index 000000000..1a1ede6c8 --- /dev/null +++ b/packages/caliper-fisco-bcos/.editorconfig @@ -0,0 +1,26 @@ +# +# 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. +# + +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/packages/caliper-fisco-bcos/.eslintignore b/packages/caliper-fisco-bcos/.eslintignore new file mode 100644 index 000000000..9aa76ac0c --- /dev/null +++ b/packages/caliper-fisco-bcos/.eslintignore @@ -0,0 +1,16 @@ +# +# 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. +# + +coverage +node_modules \ No newline at end of file diff --git a/packages/caliper-fisco-bcos/.eslintrc.yml b/packages/caliper-fisco-bcos/.eslintrc.yml new file mode 100644 index 000000000..6616d4923 --- /dev/null +++ b/packages/caliper-fisco-bcos/.eslintrc.yml @@ -0,0 +1,48 @@ +env: + es6: true + node: true + mocha: true +extends: 'eslint:recommended' +parserOptions: + ecmaVersion: 8 + sourceType: + - script +rules: + indent: + - error + - 4 + linebreak-style: + - error + - unix + quotes: + - error + - single + semi: + - error + - always + no-unused-vars: + - error + - args: none + no-console: error + curly: error + eqeqeq: error + no-throw-literal: error + strict: error + no-var: error + dot-notation: error + no-tabs: error + no-trailing-spaces: error + no-use-before-define: error + no-useless-call: error + no-with: error + operator-linebreak: error + require-jsdoc: + - error + - require: + ClassDeclaration: true + MethodDefinition: true + FunctionDeclaration: true + valid-jsdoc: + - error + - requireReturn: false + yoda: error diff --git a/packages/caliper-fisco-bcos/index.js b/packages/caliper-fisco-bcos/index.js new file mode 100644 index 000000000..50cebd937 --- /dev/null +++ b/packages/caliper-fisco-bcos/index.js @@ -0,0 +1,18 @@ +/* +* 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.AdminClient = require('./lib/fiscoBcos'); +module.exports.ClientFactory = require('./lib/fiscoBcosClientFactory'); diff --git a/packages/caliper-fisco-bcos/lib/channelPromise.js b/packages/caliper-fisco-bcos/lib/channelPromise.js new file mode 100644 index 000000000..7882f3a25 --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/channelPromise.js @@ -0,0 +1,250 @@ +/* +* 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'; + +const tls = require('tls'); +const fs = require('fs'); +const net = require('net'); +const uuidv4 = require('uuid/v4'); +const events = require('events'); + +/** + * NetworkError exception class thrown in socket connection + */ +class NetworkError extends Error { + /** + * + * @param {String} msg exception message + */ + constructor(msg) { + super(msg); + this.name = 'NetworkError'; + } +} + +let emitters = new Map(); +let buffers = new Map(); +let sockets = new Map(); +let lastBytesRead = new Map(); + +/** + * Parse response returned by node + * @param {Buffer} response Node's response + */ +function parseResponse(response) { + let seq = response.slice(6, 38).toString(); + let result = JSON.parse(response.slice(42).toString()); + let emitter = emitters.get(seq).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()}`); + } +} + +/** + * Create a new TLS socket + * @param {String} ip IP of channel server + * @param {Number} port Port of channel server + * @param {Object} authentication A JSON object contains certificate file path, private key file path and CA file path + * @return {TLSSocket} A new TLS socket + */ +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; +} + +/** + * Prepare the data which will be sent to channel server + * @param {String} data JSON string of load + * @return {Object} UUID and packaged data + */ +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]) + }; +} + +/** + * Clear context when a message got response or timeout + * @param {String} uuid The ID of an `channelPromise`request + */ +function clearContext(uuid) { + clearTimeout(emitters.get(uuid).timer); + emitters.delete(uuid); + buffers.delete(uuid); +} + +/** + * Return channel promise for a request + * @param {Object} node A JSON object which contains IP and port configuration of channel server + * @param {Object} authentication A JSON object contains certificate file path, private key file path and CA file path + * @param {String} data JSON string of load + * @param {Number} timeout Timeout to wait response + * @param {Boolean} readOnly Is this request read-only? + * @return {Promise} a promise which will be resolved when the request is satisfied + */ +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; diff --git a/packages/caliper-fisco-bcos/lib/common.js b/packages/caliper-fisco-bcos/lib/common.js new file mode 100644 index 000000000..a3164d6fa --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/common.js @@ -0,0 +1,75 @@ +/* +* 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'; + +const isArray = require('isarray'); +const chalk = require('chalk'); +const path = require('path'); +const fs = require('fs'); +const CaliperUtils = require('caliper-core').CaliperUtils; +const commLogger = CaliperUtils.getLogger('common.js'); + +const Color = { + error: chalk.red.bold, + warn: chalk.yellow.bold, + info: chalk.blue.bold, + success: chalk.green.bold, + failure: chalk.red.bold +}; +module.exports.Color = Color; + +const TxErrorEnum = { + NoError: 0, + SendRawTransactionError: 1 +}; +module.exports.TxErrorEnum = TxErrorEnum; + +module.exports.findContractAddress = function(workspaceRoot, smartContracts, contractID) { + if (!isArray(smartContracts)) { + commLogger.error(Color.error('smartContracts should be an array')); + return null; + } + + let smartContract = smartContracts.find(smartContract => { + return smartContract.id === contractID; + }); + + if (smartContract === undefined) { + commLogger.error(Color.error(`Smart contract ${contractID} undefined`)); + return null; + } + + let contractType = smartContract.language; + if (contractType === 'solidity') { + let contractPath = path.join(workspaceRoot, smartContract.path); + let contractName = path.basename(contractPath, '.sol'); + + try { + let address = fs.readFileSync(path.join(path.dirname(contractPath), `${contractName}.address`)).toString(); + return address; + } catch (error) { + if (error.code === 'ENOENT') { + commLogger.error(Color.error(`Address of smart contract ${smartContract.id} can't be determinied, please install it first!`)); + } + return null; + } + } else if (contractType === 'precompiled') { + let address = smartContract.address; + return address; + } else { + commLogger.error(Color.error(`Smart contract of ${contractType} is not supported yet`)); + return null; + } +}; diff --git a/packages/caliper-fisco-bcos/lib/fiscoBcos.js b/packages/caliper-fisco-bcos/lib/fiscoBcos.js new file mode 100644 index 000000000..069c0b7da --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/fiscoBcos.js @@ -0,0 +1,165 @@ +/* +* 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'; + +const { + BlockchainInterface, + CaliperUtils +} = require('caliper-core'); +const installSmartContractImpl = require('./installSmartContract'); +const invokeSmartContractImpl = require('./invokeSmartContract'); +const generateRawTransactionImpl = require('./generateRawTransactions'); +const sendRawTransactionImpl = require('./sendRawTransactions'); +const Color = require('./common'); +const commLogger = CaliperUtils.getLogger('fiscoBcos.js'); + +/** + * Implements {BlockchainInterface} for a FISCO BCOS backend. + */ +class FiscoBcos extends BlockchainInterface { + /** + * Create a new instance of the {FISCO BCOS} class. + * @param {string} config_path The absolute path of the FISCO BCOS network configuration file. + * @param {string} workspace_root The absolute path to the root location for the application configuration files. + */ + constructor(config_path, workspace_root) { + super(config_path); + this.bcType = 'fisco-bcos'; + this.workspaceRoot = workspace_root; + this.fiscoBcosSettings = CaliperUtils.parseYaml(this.configPath)['fisco-bcos']; + } + + /** + * Initialize the {FISCO BCOS} object. + * @async + * @return {Promise} The promise for the result of the execution. + */ + async init() { + return Promise.resolve(); + } + + /** + * Deploy the smart contract specified in the network configuration file to all nodes. + * @async + */ + async installSmartContract() { + const fiscoBcosSettings = CaliperUtils.parseYaml(this.configPath)['fisco-bcos']; + 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; + } + } + + /** + * Get a context for subsequent operations + * 'engine' attribute of returned context object must be reserved for benchmark engine to extend the context + * engine = { + * submitCallback: callback which must be called once new transaction(s) is submitted, it receives a number argument which tells how many transactions are submitted + * } + * @param {String} name name of the context + * @param {Object} args adapter specific arguments + * @param {Integer} clientIdx the client index + * @return {Promise} The promise for the result of the execution. + */ + async getContext(name, args, clientIdx) { + return Promise.resolve(); + } + + /** + * Release a context as well as related resources + * @param {Object} context adapter specific object + * @return {Promise} The promise for the result of the execution. + */ + async releaseContext(context) { + return Promise.resolve(); + } + + /** + * Invoke the given smart contract according to the specified options. Multiple transactions will be generated according to the length of args. + * @param {object} context The FISCO BCOS context returned by {getContext}. + * @param {string} contractID The name of the smart contract. + * @param {string} contractVer The version of the smart contract. + * @param {Array} args Array of JSON formatted arguments for transaction(s). Each element contains arguments (including the function name) passing to the smart contract. JSON attribute named transaction_type is used by default to specify the function name. If the attribute does not exist, the first attribute will be used as the function name. + * @param {number} timeout The timeout to set for the execution in seconds. + * @return {Promise} The promise for the result of the execution. + */ + 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; + } + } + + /** + * Query state from the ledger + * @param {Object} context The FISCO BCOS context returned by {getContext} + * @param {String} contractID Identity of the contract + * @param {String} contractVer Version of the contract + * @param {String} key lookup key + * @param {String} fcn The smart contract query function name + * @return {Promise} The result of the query. + */ + 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; + } + } + + /** + * Generate an raw transaction and store in local file + * @param {Object} context The FISCO BCOS context returned by {getContext} + * @param {String} contractID Identity of the contract + * @param {Object} arg Arguments of the transaction + * @param {String} file File path which will be used to store then transaction + * @return {TaskStatus} Indicates whether the transaction is written to the file successfully or not + */ + async generateRawTransaction(context, contractID, arg, file) { + return generateRawTransactionImpl.run(this.fiscoBcosSettings, this.workspaceRoot, context, contractID, arg, file); + } + + /** + * Send raw transactions + * @param {Object} context The FISCO BCOS context returned by {getContext} + * @param {Array} transactions List of raw transactions + * @return {Promise} The promise for the result of the execution + */ + async sendRawTransaction(context, transactions) { + return sendRawTransactionImpl.run(this.fiscoBcosSettings, context, transactions); + } +} + +module.exports = FiscoBcos; diff --git a/packages/caliper-fisco-bcos/lib/fiscoBcosApi.js b/packages/caliper-fisco-bcos/lib/fiscoBcosApi.js new file mode 100644 index 000000000..9334a1ea8 --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/fiscoBcosApi.js @@ -0,0 +1,275 @@ +/* +* 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'; + +const CaliperUtils = require('caliper-core').CaliperUtils; +const fs = require('fs'); +const path = require('path'); +const childProcess = require('child_process'); +const ora = require('ora'); +const isArray = require('isarray'); +const web3Sync = require('./web3lib/web3sync'); +const channelPromise = require('./channelPromise'); +const requestPromise = require('request-promise'); +const Color = require('./common').Color; +const assert = require('assert'); +const events = require('events'); +const commLogger = CaliperUtils.getLogger('fiscoBcosApi.js'); + +/** + * Compile solidity contract locally + * @param {String} contractPath Contract path + * @param {String} outputDir Output directory + * @return {Promise} Promise of compiling + */ +async function compileContract(contractPath, outputDir) { + let spinner = ora(`Compiling ${contractPath} ...`).start(); + let contractName = path.basename(contractPath); + + let execEmitter = new events.EventEmitter(); + let execPromise = new Promise((resolve, reject) => { + execEmitter.on('done', () => { + resolve(); + }); + execEmitter.on('error', (stdout, stderr) => { + commLogger.error(Color.error(`Compiling error: ${stdout}\n${stderr}`)); + reject(); + }); + }); + + let cmd = 'docker run --rm ' + + `-v ${path.dirname(contractPath)}:/sources ` + + `-v ${outputDir}:/output ` + + 'ethereum/solc:0.4.25 ' + + '--overwrite --abi --bin ' + + '-o /output ' + + `/sources/${contractName}`; + childProcess.exec( + cmd, + (error, stdout, stderr) => { + if (!error) { + spinner.succeed(); + execEmitter.emit('done'); + } + else { + spinner.fail(); + execEmitter.emit('error', stdout, stderr); + } + }); + + return execPromise; +} + +module.exports.compileContract = compileContract; + +/** + * Select a node from node list randomly + * @param {Array} nodes Node list + * @return {Object} Node + */ +function selectNode(nodes) { + return nodes[Math.floor(Math.random() * nodes.length)]; +} + +module.exports.getBlockNumber = async function (networkConfig) { + let node = selectNode(networkConfig.nodes); + // Use RPC + let requestData = { + method: 'POST', + uri: `http://${node.ip}:${node.rpcPort}`, + json: true, + body: { + 'jsonrpc': '2.0', + 'method': 'getBlockNumber', + 'params': [networkConfig.groupID], + 'id': 1 + } + }; + + return requestPromise(requestData); +}; + +let currentBlockNumber = -1; +let initializeBlockNumberEventEmitter = new events.EventEmitter(); +let initializationPromise = null; + +/** + * Update current block number periodically + * @param {Object} networkConfig Config of network + */ +async function updateCurrentBlockNumber(networkConfig) { + module.exports.getBlockNumber(networkConfig).then((result) => { + if (!result.error && result.result) { + let blockNumber = parseInt(result.result); + if (blockNumber > currentBlockNumber) { + if (currentBlockNumber === -1) { + initializeBlockNumberEventEmitter.emit('initialized'); + } + currentBlockNumber = blockNumber; + } + + setTimeout(updateCurrentBlockNumber, 2000, networkConfig); + return Promise.resolve(true); + } else { + commLogger.warn(Color.warn(`Update current block number failed, result=${JSON.stringify(result)}`)); + return Promise.reject(); + } + }).catch(async (reason) => { + await CaliperUtils.sleep(2000); + updateCurrentBlockNumber(networkConfig); + }); +} + +/** + * Get current block number + * @param {Object} networkConfig Config of network + * @return {Number} Current block number + */ +async function getCurrentBlockNumber(networkConfig) { + // Lazy initialization for currentBlockNumber + if (initializationPromise === null) { + initializationPromise = new Promise((resolve) => { + initializeBlockNumberEventEmitter.on('initialized', () => { + resolve(); + }); + }); + updateCurrentBlockNumber(networkConfig); + } + await initializationPromise; + + assert(currentBlockNumber !== -1, 'Block number is not illegal'); + return currentBlockNumber; +} + +// Deploy solidity smart contract only +module.exports.deploy = async function (networkConfig, account, privateKey, contractPath) { + let outputDir = path.join('/tmp', './solcOutput'); + await compileContract(contractPath, outputDir); + + let contractName = path.basename(contractPath, '.sol'); + let contractBin = fs.readFileSync(path.join(outputDir, contractName + '.bin'), 'utf-8'); + let blockNumber = await getCurrentBlockNumber(networkConfig); + let groupID = networkConfig.groupID; + let signTx = web3Sync.getSignDeployTx(groupID, account, privateKey, contractBin, blockNumber + 500); + + let requestData = { + 'jsonrpc': '2.0', + 'method': 'sendRawTransaction', + 'params': [networkConfig.groupID, signTx], + 'id': 1 + }; + + let node = selectNode(networkConfig.nodes); + let spinner = ora(`Depolying ${contractName}.sol ...`).start(); + return channelPromise(node, networkConfig.authentication, requestData, networkConfig.timeout).then((result) => { + if (result.error) { + spinner.fail(); + } + else { + spinner.succeed(); + } + + return result; + }); +}; + +module.exports.call = async function (networkConfig, from, to, func, params) { + if (!isArray(params)) { + params = [params]; + } + + let txData = web3Sync.getTxData(func, params); + let requestData = { + 'jsonrpc': '2.0', + 'method': 'call', + 'params': [networkConfig.groupID, { + 'from': from, + 'to': to, + 'value': '0x0', + 'data': txData + }], + 'id': 1 + }; + + let node = selectNode(networkConfig.nodes); + return channelPromise(node, networkConfig.authentication, requestData, networkConfig.timeout); +}; + +module.exports.generateRawTransaction = async function (networkConfig, account, privateKey, to, func, params) { + if (!isArray(params)) { + params = [params]; + } + + let blockNumber = await getCurrentBlockNumber(networkConfig); + let groupID = networkConfig.groupID; + let signTx = web3Sync.getSignTx(groupID, account, privateKey, to, func, params, blockNumber + 500); + return signTx; +}; + +module.exports.sendRawTransaction = async function (networkConfig, tx) { + let requestData = { + 'jsonrpc': '2.0', + 'method': 'sendRawTransaction', + 'params': [networkConfig.groupID, tx], + 'id': 1 + }; + + let node = selectNode(networkConfig.nodes); + return channelPromise(node, networkConfig.authentication, requestData, networkConfig.timeout); +}; + +module.exports.sendTransaction = async function (networkConfig, account, privateKey, to, func, params) { + let signTx = await this.generateRawTransaction(networkConfig, account, privateKey, to, func, params); + return this.sendRawTransaction(networkConfig, signTx); +}; + +module.exports.getTxReceipt = async function (networkConfig, txHash) { + let node = selectNode(networkConfig.nodes); + // Use RPC + let requestData = { + method: 'POST', + uri: `http://${node.ip}:${node.rpcPort}`, + json: true, + body: { + 'jsonrpc': '2.0', + 'method': 'getTransactionReceipt', + 'params': [networkConfig.groupID, txHash], + 'id': 1 + } + }; + + return requestPromise(requestData); +}; + +module.exports.getCode = async function (networkConfig, address) { + let node = selectNode(networkConfig.nodes); + // Use RPC + let requestData = { + method: 'POST', + uri: `http://${node.ip}:${node.rpcPort}`, + json: true, + body: { + 'jsonrpc': '2.0', + 'method': 'getCode', + 'params': [ + networkConfig.groupID, + address + ], + 'id': 1 + } + }; + + return requestPromise(requestData); +}; diff --git a/packages/caliper-fisco-bcos/lib/fiscoBcosClientFactory.js b/packages/caliper-fisco-bcos/lib/fiscoBcosClientFactory.js new file mode 100644 index 000000000..1f8b86d34 --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/fiscoBcosClientFactory.js @@ -0,0 +1,52 @@ +/* +* 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'; + +const childProcess = require('child_process'); +const path = require('path'); + +/** + * Class used to spawn FISCO BCOS client workers + */ +class FiscoBcosClientFactory { + /** + * Require paths to configuration data used when calling new on fiscoBcos.js + * @param {String} absNetworkFile absolute workerPath + * @param {Sting} workspace_root root location + */ + constructor(absNetworkFile, workspace_root) { + this.absNetworkFile = absNetworkFile; + this.workspaceRoot = workspace_root; + } + + /** + * Spawn the worker and perform required init + * @returns {Object} the child process + */ + spawnWorker() { + const child = childProcess.fork(path.join(__dirname, './fiscoBcosClientWorker.js'), process.argv.slice(1), { env: process.env }); + + const msg = { + type: 'init', + absNetworkFile: this.absNetworkFile, + networkRoot: this.workspaceRoot + }; + child.send(msg); + + return child; + } +} + +module.exports = FiscoBcosClientFactory; diff --git a/packages/caliper-fisco-bcos/lib/fiscoBcosClientWorker.js b/packages/caliper-fisco-bcos/lib/fiscoBcosClientWorker.js new file mode 100644 index 000000000..5053d4745 --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/fiscoBcosClientWorker.js @@ -0,0 +1,74 @@ +/* +* 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'; + +const { + CaliperLocalClient, + CaliperUtils +} = require('caliper-core'); +const fiscoBcosClient = require('./fiscoBcos'); + +let caliperClient; + +/** + * Messages handler + */ +process.on('message', async (message) => { + if (!message.hasOwnProperty('type')) { + process.send({ + type: 'error', + data: 'unknown message type' + }); + return; + } + + try { + switch (message.type) { + case 'init': { + const blockchain = new fiscoBcosClient(message.absNetworkFile, message.networkRoot); + caliperClient = new CaliperLocalClient(blockchain); + process.send({ + type: 'ready', + data: { + pid: process.pid, + complete: true + } + }); + break; + } + case 'test': { + let result = await caliperClient.doTest(message); + + await CaliperUtils.sleep(200); + process.send({ + type: 'testResult', + data: result + }); + break; + } + default: { + process.send({ + type: 'error', + data: `unknown message type [${message.type}]` + }); + } + } + } catch (error) { + process.send({ + type: 'error', + data: error.toString() + }); + } +}); diff --git a/packages/caliper-fisco-bcos/lib/generateRawTransactions.js b/packages/caliper-fisco-bcos/lib/generateRawTransactions.js new file mode 100644 index 000000000..5aeeb6d8e --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/generateRawTransactions.js @@ -0,0 +1,67 @@ +/* +* 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'; + +const fs = require('fs'); +const { CaliperUtils, TxStatus } = require('caliper-core'); +const { Color, TxErrorEnum, findContractAddress } = require('./common'); +const uuid = require('uuid/v4'); +const fiscoBcosApi = require('./fiscoBcosApi'); +const commLogger = CaliperUtils.getLogger('generateRawTransactions.js'); + +module.exports.run = async function (fiscoBcosSettings, workspaceRoot, context, contractID, arg, file) { + if (context && context.engine) { + context.engine.submitCallback(1); + } + + let smartContracts = fiscoBcosSettings.smartContracts; + let address = findContractAddress(workspaceRoot, smartContracts, contractID); + let account = fiscoBcosSettings.config.account; + let privateKey = fiscoBcosSettings.config.privateKey; + let network = fiscoBcosSettings.network; + let invokeStatus = new TxStatus(uuid()); + + try { + let fcn = null; + let fcArgs = []; + + for (let key in arg) { + if (key === 'transaction_type') { + fcn = arg[key].toString(); + } else { + fcArgs.push(arg[key].toString()); + } + } + + let tx = await fiscoBcosApi.generateRawTransaction(network, + account, + privateKey, + address, + fcn, + fcArgs, + workspaceRoot); + + fs.appendFileSync(file, tx + '\n'); + + invokeStatus.SetFlag(TxErrorEnum.NoError); + invokeStatus.SetResult(tx); + invokeStatus.SetVerification(true); + invokeStatus.SetStatusSuccess(); + return invokeStatus; + } catch (error) { + commLogger.error(Color.error(`FISCO BCOS generate raw transaction failed: ${(error.stack ? error.stack : JSON.stringify(error))}`)); + throw error; + } +}; diff --git a/packages/caliper-fisco-bcos/lib/installSmartContract.js b/packages/caliper-fisco-bcos/lib/installSmartContract.js new file mode 100644 index 000000000..e2614c2dc --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/installSmartContract.js @@ -0,0 +1,76 @@ +/* +* 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'; + +const CaliperUtils = require('caliper-core').CaliperUtils; +const isArray = require('isarray'); +const fs = require('fs-extra'); +const path = require('path'); +const fiscoBcosApi = require('./fiscoBcosApi'); +const assert = require('assert'); +const Color = require('./common').Color; +const commLogger = CaliperUtils.getLogger('installSmartContract.js'); + +module.exports.run = async function (fiscoBcosSettings, workspaceRoot) { + const fiscoBcosConfig = fiscoBcosSettings.config; + const account = fiscoBcosConfig.account; + const privateKey = fiscoBcosConfig.privateKey; + + const networkConfig = fiscoBcosSettings.network; + const smartContracts = fiscoBcosSettings.smartContracts; + + if (!isArray(smartContracts)) { + throw new Error('No available configuration for smart contracts'); + } + + commLogger.info(Color.info('Deploying smart contracts ...')); + + for (let smartContract of smartContracts) { + commLogger.info(Color.info(`Deploying ${smartContract.id} ...`)); + let contractType = smartContract.language; + if (contractType === 'solidity') { + let contractPath = path.join(workspaceRoot, smartContract.path); + try { + let deployPromise = fiscoBcosApi.deploy(networkConfig, account, privateKey, contractPath); + + deployPromise.then(function (body) { + let result = JSON.parse(JSON.stringify(body)); + if (result.status && result.status === '0x0') { + let contractAddress = result.contractAddress; + assert(contractAddress !== undefined, JSON.stringify(result)); + + let contractName = path.basename(contractPath, '.sol'); + fs.outputFileSync(path.join(path.dirname(contractPath), `${contractName}.address`), contractAddress); + commLogger.info(Color.success(`Deployed smart contract ${smartContract.id}, path=${smartContract.path}, address=${contractAddress}`)); + } else { + commLogger.error(Color.error(`Deploy receipt status error: ${JSON.stringify(body)}`)); + } + }).catch((reason)=>{ + commLogger.error(Color.error(`Depolying error: ${reason}`)); + }); + + await deployPromise; + } catch (error) { + commLogger.error(Color.failure(`Failed to install smart contract ${smartContract.id}, path=${contractPath}`)); + throw error; + } + } else if (contractType === 'precompiled') { + commLogger.info(Color.success(`Precompiled smart contract ${smartContract.id} appointed, address=${smartContract.address}`)); + } else { + commLogger.error(Color.error(`Smart contract of ${contractType} is not supported yet`)); + throw new Error('Smart contract type not supported'); + } + } +}; diff --git a/packages/caliper-fisco-bcos/lib/invokeSmartContract.js b/packages/caliper-fisco-bcos/lib/invokeSmartContract.js new file mode 100644 index 000000000..926f27bab --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/invokeSmartContract.js @@ -0,0 +1,66 @@ +/* +* 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'; + +const { + CaliperUtils, + TxStatus +} = require('caliper-core'); +const fiscoBcosApi = require('./fiscoBcosApi'); +const { TxErrorEnum, Color, findContractAddress } = require('./common'); +const commLogger = CaliperUtils.getLogger('invokeSmartContract.js'); + +module.exports.run = async function (context, fiscoBcosSettings, contractID, fcn, args, workspaceRoot, readOnly = false) { + let smartContracts = fiscoBcosSettings.smartContracts; + let address = findContractAddress(workspaceRoot, smartContracts, contractID); + if (address === null) { + throw new Error(`Can't invoke smart contract ${contractID}`); + } + + const networkConfig = fiscoBcosSettings.network; + const account = fiscoBcosSettings.config.account; + + let invokeStatus = new TxStatus(account); + invokeStatus.SetFlag(TxErrorEnum.NoError); + let receipt = null; + + try { + if (context && context.engine) { + context.engine.submitCallback(1); + } + + if (readOnly) { + receipt = await fiscoBcosApi.call(networkConfig, account, address, fcn, args); + } else { + const privateKey = fiscoBcosSettings.config.privateKey; + receipt = await fiscoBcosApi.sendTransaction(networkConfig, account, privateKey, address, fcn, args); + } + + invokeStatus.SetID(receipt.result); + invokeStatus.SetResult(receipt); + invokeStatus.SetVerification(true); + if (receipt.error === undefined && (receipt.status === '0x0' || (receipt.result && receipt.result.status === '0x0'))) { + invokeStatus.SetStatusSuccess(); + } else { + commLogger.error(Color.failure('Failed to invoke smart contract: ' + JSON.stringify(receipt))); + invokeStatus.SetStatusFail(); + } + + return invokeStatus; + } catch (error) { + commLogger.error(Color.failure(`Failed to invoke smart contract ${contractID}: ${JSON.stringify(error)}`)); + throw error; + } +}; diff --git a/packages/caliper-fisco-bcos/lib/sendRawTransactions.js b/packages/caliper-fisco-bcos/lib/sendRawTransactions.js new file mode 100644 index 000000000..542b1344c --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/sendRawTransactions.js @@ -0,0 +1,51 @@ +/* +* 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'; + +const { CaliperUtils, TxStatus } = require('caliper-core'); +const { Color, TxErrorEnum } = require('./common'); +const uuid = require('uuid/v4'); +const fiscoBcosApi = require('./fiscoBcosApi'); +const commLogger = CaliperUtils.getLogger('generateRawTransactions.js'); + +module.exports.run = async function (fiscoBcosSettings, context, transactions) { + let promises = []; + let hasEngine = context && context.engine; + let network = fiscoBcosSettings.network; + + for (let transaction of transactions) { + let invokeStatus = new TxStatus(uuid()); + + if(hasEngine) { + context.engine.submitCallback(1); + } + + promises.push(fiscoBcosApi.sendRawTransaction(network, transaction).then(receipt => { + invokeStatus.SetFlag(TxErrorEnum.NoError); + invokeStatus.SetResult(receipt.result); + invokeStatus.SetVerification(true); + + if (receipt.error === undefined && (receipt.status === '0x0' || (receipt.result && receipt.result.status === '0x0'))) { + invokeStatus.SetStatusSuccess(); + } else { + commLogger.error(Color.failure('Failed to invoke smart contract: ' + JSON.stringify(receipt))); + invokeStatus.SetStatusFail(); + } + + return invokeStatus; + })); + } + return Promise.all(promises); +}; diff --git a/packages/caliper-fisco-bcos/lib/web3lib/config.js b/packages/caliper-fisco-bcos/lib/web3lib/config.js new file mode 100755 index 000000000..4c4568304 --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/web3lib/config.js @@ -0,0 +1,19 @@ +/* +* 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 = { + EncryptType: 0 // 0: ECDSA, other types are not supported yet +}; diff --git a/packages/caliper-fisco-bcos/lib/web3lib/transactionObject.js b/packages/caliper-fisco-bcos/lib/web3lib/transactionObject.js new file mode 100755 index 000000000..593afdc31 --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/web3lib/transactionObject.js @@ -0,0 +1,308 @@ +/* +* 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'; + +let utils = require('./utils'); +const encryptType = require('./config').EncryptType; +const ethjsUtil = require('ethereumjs-util'); +const BN = ethjsUtil.BN; + +/** + * Constructor of transaction + * @param {data} data transaction data + */ +function Transaction(data) { + data = data || {}; + let fields = null; + + if (encryptType === 1) { + fields = [{ + name: 'randomid', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'gasPrice', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'gasLimit', + alias: 'gas', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'blockLimit', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'to', + allowZero: true, + length: 20, + default: Buffer.from([]) + }, { + name: 'value', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'data', + alias: 'input', + allowZero: true, + default: Buffer.from([]) + }, { + name: 'pub', + length: 64, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'r', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 's', + length: 32, + allowLess: true, + default: Buffer.from([]) + }]; + } else { + fields = [{ + name: 'randomid', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'gasPrice', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'gasLimit', + alias: 'gas', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'blockLimit', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'to', + allowZero: true, + length: 20, + default: Buffer.from([]) + }, { + name: 'value', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'data', + alias: 'input', + allowZero: true, + default: Buffer.from([]) + }, { + name: 'chainId', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'groupId', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 'extraData', + allowZero: true, + default: Buffer.from([]) + }, { + name: 'v', + length: 1, + default: Buffer.from([0x1c]) + }, { + name: 'r', + length: 32, + allowLess: true, + default: Buffer.from([]) + }, { + name: 's', + length: 32, + allowLess: true, + default: Buffer.from([]) + }]; + } + + ethjsUtil.defineProperties(this, fields, data); + + Object.defineProperty(this, 'from', { + enumerable: true, + configurable: true, + get: this.getSenderAddress.bind(this) + }); + + let sigV = ethjsUtil.bufferToInt(this.v); + let chainId = Math.floor((sigV - 35) / 2); + if (chainId < 0) { + chainId = 0; + } + + this._chainId = chainId || data.chainId || 0; + this._homestead = true; +} + +/** + * If the tx's `to` is to the creation address + * @return {Boolean} returns `true` if tx is to to the creation address, otherwise returns `false` + */ +Transaction.prototype.toCreationAddress = function () { + return this.to.toString('hex') === ''; +}; + +/** + * Computes a sha3-256 hash of the serialized tx + * @param {Boolean} [includeSignature=true] whether or not to inculde the signature + * @return {Buffer} a sha3-256 hash of the serialized tx + */ +Transaction.prototype.hash = function (includeSignature) { + if (includeSignature === undefined) { + includeSignature = true; + } + // backup original signature + const rawCopy = this.raw.slice(0); + + // modify raw for signature generation only + if (this._chainId > 0) { + includeSignature = true; + this.v = this._chainId; + this.r = 0; + this.s = 0; + } + // generate rlp params for hash + let txRawForHash = includeSignature ? this.raw : this.raw.slice(0, this.raw.length - 3); + //var txRawForHash = includeSignature ? this.raw : this.raw.slice(0, 7) + + // restore original signature + this.raw = rawCopy.slice(); + + // create hash + return utils.rlphash(txRawForHash); +}; + +/** + * returns the chain ID + * @return {Number} chain ID + */ +Transaction.prototype.getChainId = function () { + return this._chainId; +}; + +/** + * returns the sender's address + * @return {Buffer} sender's address + */ +Transaction.prototype.getSenderAddress = function () { + if (this._from) { + return this._from; + } + const pubkey = this.getSenderPublicKey(); + this._from = ethjsUtil.publicToAddress(pubkey); + return this._from; +}; + +/** + * returns the public key of the sender + * @return {Buffer} the public key of the sender + */ +Transaction.prototype.getSenderPublicKey = function () { + if (!this._senderPubKey || !this._senderPubKey.length) { + if (!this.verifySignature()) { + throw new Error('Invalid Signature'); + } + } + return this._senderPubKey; +}; + +/** + * Determines if the signature is valid + * @return {Boolean} whether the signature is valid + */ +Transaction.prototype.verifySignature = function () { + let SECP256K1_N_DIV_2 = new BN('7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0', 16); + const msgHash = this.hash(false); + // All transaction signatures whose s-value is greater than secp256k1n/2 are considered invalid. + if (this._homestead && new BN(this.s).cmp(SECP256K1_N_DIV_2) === 1) { + return false; + } + + try { + let v = ethjsUtil.bufferToInt(this.v); + if (this._chainId > 0) { + v -= this._chainId * 2 + 8; + } + this._senderPubKey = utils.ecrecover(msgHash, v, this.r, this.s); + } catch (e) { + return false; + } + + return !!this._senderPubKey; +}; + +/** + * sign a transaction with a given private key + * @param {Buffer} privateKey private key + */ +Transaction.prototype.sign = function (privateKey) { + const msgHash = this.hash(false); + const sig = utils.ecsign(msgHash, privateKey); + Object.assign(this, sig); +}; + +/** + * the up front amount that an account must have for this transaction to be valid + * @return {BN} up front amount + */ +Transaction.prototype.getUpfrontCost = function () { + return new BN(this.gasLimit) + .imul(new BN(this.gasPrice)) + .iadd(new BN(this.value)); +}; + +/** + * validates the signature and checks to see if it has enough gas + * @param {Boolean} [stringError=false] whether to return a string with a dscription of why the validation failed or return a Bloolean + * @return {Boolean|String} validation result + */ +Transaction.prototype.validate = function (stringError) { + const errors = []; + if (!this.verifySignature()) { + errors.push('Invalid Signature'); + } + + if (this.getBaseFee().cmp(new BN(this.gasLimit)) > 0) { + errors.push([`gas limit is to low. Need at least ${this.getBaseFee()}`]); + } + + if (stringError === undefined || stringError === false) { + return errors.length === 0; + } else { + return errors.join(' '); + } +}; + +exports.Transaction = Transaction; diff --git a/packages/caliper-fisco-bcos/lib/web3lib/utils.js b/packages/caliper-fisco-bcos/lib/web3lib/utils.js new file mode 100755 index 000000000..237ef1dd2 --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/web3lib/utils.js @@ -0,0 +1,225 @@ +/* +* 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'; + +const secp256k1 = require('secp256k1'); +const cryptoJSSha3 = require('crypto-js/sha3'); +const keccak = require('keccak'); +const assert = require('assert'); +const rlp = require('rlp'); +const coder = require('web3/lib/solidity/coder'); +const ethjsUtil = require('ethjs-util'); +const encryptType = require('./config').EncryptType; + +/** + * Convert data to Buffer + * @param {any} data data to be transformed to buffer + * @return {Buffer} transformation result + */ +function toBuffer(data) { + if (!Buffer.isBuffer(data)) { + if (Array.isArray(data)) { + data = Buffer.from(data); + } else if (data instanceof String) { + if (ethjsUtil.isHexPrefixed(data)) { + data = Buffer.from(ethjsUtil.padToEven(ethjsUtil.stripHexPrefix(data)), 'hex'); + } else { + data = Buffer.from(data); + } + } else if (Number.isInteger(data)) { + data = ethjsUtil.intToBuffer(data); + } else if (data === null || data === undefined) { + data = Buffer.allocUnsafe(0); + } else if (data.toArray) { + data = Buffer.from(data.toArray()); + } else { + throw new Error('invalid type'); + } + } + return data; +} + +/** + * Calculate hash of data + * @param {any} data data + * @param {int} bits length of hash + * @return {Buffer} hash of data + */ +function sha3(data, bits) { + if (encryptType === 0) { + data = toBuffer(data); + if (!bits) { + bits = 256; + } + let digestData = keccak('keccak' + bits).update(data).digest(); + return digestData; + } else { + throw new Error('Unsupported type of encryption'); + } +} + +/** + * Calculate public key from private key + * @param {Buffer} privateKey A private key must be 256 bits wide + * @return {Buffer} public key + */ +function privateKeyToPublicKey(privateKey) { + if (encryptType === 0) { + privateKey = ethjsUtil.toBuffer(privateKey); + let publicKey = keccak.publicKeyCreate(privateKey, false).slice(1); + return publicKey; + } else { + throw new Error('Unsupported type of encryption'); + } +} + +/** + * Calculate address from public key + * @param {Buffer} publicKey public key + * @param {bool} sanitize whether to sanitize publicKey + * @return {Buffer} address + */ +function publicKeyToAddress(publicKey, sanitize = false) { + if (encryptType === 0) { + if (sanitize && (publicKey.length !== 64)) { + publicKey = secp256k1.publicKeyConvert(publicKey, false).slice(1); + } + assert(publicKey.length === 64); + } + // Only take the lower 160bits of the hash as address + return sha3(publicKey).slice(-20); +} + +/** + * Calculate address from private key + * @param {Buffer} privateKey private key + * @return {Buffer} address + */ +function privateKeyToAddress(privateKey) { + return publicKeyToAddress(privateKeyToPublicKey(privateKey)); +} + +/** + * Recover public key from (v, r, s) + * @param {String} msgHash message hash + * @param {String} v v + * @param {String} r r + * @param {String} s s + * @return {String} public key recovered from (v, r, s) + */ +function ecrecover(msgHash, v, r, s) { + let signature = Buffer.concat([ethjsUtil.setLength(r, 32), ethjsUtil.setLength(s, 32)], 64); + let recovery = v - 27; + if (recovery !== 0 && recovery !== 1) { + throw new Error('Invalid signature v value'); + } + let senderPubickKey = secp256k1.recover(msgHash, signature, recovery); + return secp256k1.publicKeyConvert(senderPubickKey, false).slice(1); +} + +/** + * Create sign data + * @param {String} msgHash message hash + * @param {String} privateKey private key + * @return {Object} returns (v, r, s) for secp256k1 + */ +function ecsign(msgHash, privateKey) { + let ret = {}; + if (encryptType === 0) { + let sig = secp256k1.sign(msgHash, privateKey); + ret.r = sig.signature.slice(0, 32); + ret.s = sig.signature.slice(32, 64); + ret.v = sig.recovery + 27; + } else { + throw new Error('Unsupported type of encryption'); + } + return ret; +} + +/** + * Calcuate hash of RLP data + * @param {rlp} data RLP data + * @return {String} the hash of data + */ +function rlphash(data) { + return sha3(rlp.encode(data)); +} + +/** + * encode params + * @param {Array} types types + * @param {Array} params params + * @return {Buffer} params' code + */ +function encodeParams(types, params) { + let ret = coder.encodeParams(types, params); + return ret; +} + +/** + * decode params + * @param {Array} types types + * @param {Buffer} bytes params' code + * @return {Array} params + */ +function decodeParams(types, bytes) { + let ret = coder.decodeParams(types, bytes); + return ret; +} + +/** + * encode function name + * @param {String} fcn function name + * @return {Buffer} function name's code + */ +function encodeFunctionName(fcn) { + let digest = null; + if (encryptType === 1) { + digest = sha3(fcn, 256).toString('hex'); + } else { + digest = cryptoJSSha3(fcn, { + outputLength: 256 + }).toString(); + } + let ret = '0x' + digest.slice(0, 8); + return ret; +} + +/** + * encode transaction data + * @param {String} fcn function name + * @param {Array} types types + * @param {Array} params params + * @return {Buffer} tx data's code + */ +function encodeTxData(fcn, types, params) { + let txDataCode = encodeFunctionName(fcn); + let paramsCode = encodeParams(types, params); + txDataCode += paramsCode; + return txDataCode; +} + +module.exports.privateKeyToPublicKey = privateKeyToPublicKey; +module.exports.publicKeyToAddress = publicKeyToAddress; +module.exports.privateKeyToAddress = privateKeyToAddress; +module.exports.rlphash = rlphash; +module.exports.ecrecover = ecrecover; +module.exports.ecsign = ecsign; +module.exports.sha3 = sha3; +module.exports.toBuffer = toBuffer; + +module.exports.encodeTxData = encodeTxData; +module.exports.decodeParams = decodeParams; +module.exports.encodeParams = encodeParams; diff --git a/packages/caliper-fisco-bcos/lib/web3lib/web3sync.js b/packages/caliper-fisco-bcos/lib/web3lib/web3sync.js new file mode 100755 index 000000000..a3768f64f --- /dev/null +++ b/packages/caliper-fisco-bcos/lib/web3lib/web3sync.js @@ -0,0 +1,127 @@ +/* +* 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'; + +const uuidv4 = require('uuid/v4'); +const utils = require('./utils'); +const Transaction = require('./transactionObject').Transaction; + +/** + * Generate a random number via UUID + * @return {Number} random number + */ +function genRandomID() { + let uuid = uuidv4(); + uuid = uuid.replace(/-/g, ''); + + return uuid; +} + +/** + * Sign a transaction with private key and callback + * @param {String} txData transaction data + * @param {Buffer} privKey private key + * @param {callback} callback callback function + * @return {String} signed transaction data + */ +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; + } +} + +/** + * get transaction data + * @param {String} func function name + * @param {Array} params params + * @return {String} transaction data + */ +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); +} + +/** + * get signed transaction data + * @param {Number} groupId ID of the group where this transaction will be sent to + * @param {Buffer} account user account + * @param {Buffer} privateKey private key + * @param {Buffer} to target address + * @param {String} func function name + * @param {Array} params params + * @param {Number} blockLimit block limit + * @return {String} signed transaction data + */ +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: '' + }; + + return signTransaction(postdata, privateKey, null); +} + +/** + * get signed deploy tx + * @param {Number} groupId ID of the group where this transaction will be sent to + * @param {Buffer} account user account + * @param {Buffer} privateKey private key + * @param {Buffer} bin contract bin + * @param {Number} blockLimit block limit + * @return {String} signed deploy transaction data + */ +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: '' + }; + + return signTransaction(postdata, privateKey, null); +} + +module.exports.getSignDeployTx = getSignDeployTx; +module.exports.signTransaction = signTransaction; +module.exports.getSignTx = getSignTx; +module.exports.getTxData = getTxData; diff --git a/packages/caliper-fisco-bcos/package.json b/packages/caliper-fisco-bcos/package.json new file mode 100644 index 000000000..4a0ddd42a --- /dev/null +++ b/packages/caliper-fisco-bcos/package.json @@ -0,0 +1,99 @@ +{ + "name": "@hyperledger/caliper-fisco-bcos", + "version": "0.1.0", + "description": "Caliper adapter of FISCO BCOS blockchain backend", + "repository": { + "type": "git", + "url": "https://github.com/hyperledger/caliper" + }, + "scripts": { + "pretest": "npm run licchk", + "licchk": "license-check-and-add", + "test": "npm run lint", + "lint": "npx eslint .", + "nyc": "nyc mocha --recursive -t 10000" + }, + "engineStrict": true, + "engines": { + "node": ">=8.10.0", + "npm": ">=5.6.0" + }, + "files": [ + "*", + "src/comm/template/report.html" + ], + "dependencies": { + "caliper-core": "^0.1.0", + "nconf": "^0.10.0", + "isarray": "^2.0.4", + "web3": "0.20.7", + "fs-extra": "^8.0.1", + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.1.0", + "crypto-js": "^3.1.9-1", + "ora": "^1.2.0", + "uuid": "^3.3.2", + "tls": "^0.0.1", + "chalk": "^1.1.3", + "request-promise": "^4.2.1" + }, + "devDependencies": { + "license-check-and-add": "2.3.6" + }, + "license-check-and-add-config": { + "folder": ".", + "license": "../../LICENSE.txt", + "exact_paths_method": "EXCLUDE", + "exact_paths": [ + "node_modules", + ".nyc_output", + "coverage", + ".gitignore", + "log" + ], + "file_type_method": "EXCLUDE", + "file_types": [ + ".yml", + ".log" + ], + "insert_license": false, + "license_formats": { + "js": { + "prepend": "/*", + "append": "*/", + "eachLine": { + "prepend": "* " + } + }, + "editorconfig": { + "prepend": "#", + "append": "#", + "eachLine": { + "prepend": "# " + } + } + } + }, + "nyc": { + "exclude": [ + "lib/**" + ], + "reporter": [ + "text-summary", + "html" + ], + "all": true, + "check-coverage": false, + "statements": 5, + "branches": 8, + "functions": 7, + "lines": 5 + }, + "license": "Apache-2.0", + "licenses": [ + { + "type": "Apache-2.0", + "url": "https://github.com/hyperledger/caliper/blob/master/LICENSE" + } + ] +} diff --git a/packages/caliper-samples/README.md b/packages/caliper-samples/README.md index 9c14af7f2..90075552b 100644 --- a/packages/caliper-samples/README.md +++ b/packages/caliper-samples/README.md @@ -18,6 +18,11 @@ caliper benchmark run -w -c benchmark/composer/config.yaml -n n caliper benchmark run -w -c benchmark/simple/config-sawtooth.yaml -n network/sawtooth/simplenetwork/sawtooth.json ``` +- FISCO BCOS +``` +caliper benchmark run -w -c benchmark/fisco-bcos/transfer/solidity/config.yaml -n network/fisco-bcos/4nodes1group/fisco-bcos.json +``` + ## Benchmarks Under Construction - Burrow @@ -30,6 +35,11 @@ caliper benchmark run -w -c benchmark/simple/config.yaml -n net caliper benchmark run -w -c benchmark/simple/config-iroha.yaml -n network/iroha/simplenetwork/iroha.json ``` +- FISCO BCOS +```bash +caliper benchmark run -w -c benchmark/fisco-bcos/transfer/solidity/config.yaml -n network/fisco-bcos/4nodes1group/fisco-bcos.json +``` + ## Starting and using a Zookeeper client ```bash diff --git a/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/addUser.js b/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/addUser.js new file mode 100644 index 000000000..d6e91fc6d --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/addUser.js @@ -0,0 +1,74 @@ +/* +* 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'; + +const uuidv4 = require('uuid/v4'); + +module.exports.info = ' adding users'; + +let accountList = []; +let initMoney = 100000000; +let prefix; +let bc, contx; + +module.exports.init = function (blockchain, context, args) { + prefix = uuidv4(); + + bc = blockchain; + contx = context; + + return Promise.resolve(); +}; + +/** + * Generate unique account key for the transaction + * @param {Number} index account index + * @returns {String} account key + */ +function generateAccount(index) { + return prefix + index; +} + +/** + * Generates simple workload + * @returns {Object} array of json objects + */ +function generateWorkload() { + let workload = []; + let index = accountList.length; + let accountID = generateAccount(index); + accountList.push({ + 'accountID': accountID, + 'balance': initMoney + }); + + workload.push({ + 'transaction_type': 'userAdd(string,uint256)', + 'name': accountID, + 'num': initMoney + }); + return workload; +} + +module.exports.run = function () { + let args = generateWorkload(); + return bc.invokeSmartContract(contx, 'dagtransfer', 'v0', args, null); +}; + +module.exports.end = function () { + return Promise.resolve(); +}; + +module.exports.accountList = accountList; diff --git a/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/config.yaml b/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/config.yaml new file mode 100644 index 000000000..ce348a500 --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/config.yaml @@ -0,0 +1,64 @@ +# +# 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: Precompiled Transfer + description: This is a precompiled transfer benchmark of FISCO BCOS for caliper + clients: + type: local + number: 4 + rounds: + - label: addUser + description: generate users for transfer test later + txNumber: + - 1000 + rateControl: + - type: fixed-rate + opts: + tps: 1000 + callback: benchmark/fisco-bcos/generate_txs_in_advance/addUser.js + - label: generate + description: transfer money between users + txNumber: + - 10000 + rateControl: + - type: fixed-rate + opts: + tps: 10000 + callback: benchmark/fisco-bcos/generate_txs_in_advance/generate.js + - label: send + description: transfer money between users + txNumber: + - 10000 + rateControl: + - type: fixed-rate + opts: + tps: 10000 + callback: benchmark/fisco-bcos/generate_txs_in_advance/send.js +monitor: + type: + - docker + - process + docker: + name: + - node0 + - node1 + - node2 + - node3 + process: + - command: node + arguments: fiscoBcosClientWorker.js + multiOutput: avg + interval: 0.2 diff --git a/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/generate.js b/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/generate.js new file mode 100644 index 000000000..db3648664 --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/generate.js @@ -0,0 +1,66 @@ +/* +* 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'; + +const path = require('path'); +const uuid = require('uuid/v4'); + +let accountList, bc, contx; +let file = path.join(__dirname, `.${uuid()}.transactions`); + +module.exports.info = ' generate transactions'; + +module.exports.init = function (blockchain, context) { + bc = blockchain; + contx = context; + + const addUser = require('./addUser'); + accountList = addUser.accountList; +}; + +let index = 0; + +/** + * Generates simple workload + * @return {Object} array of json objects + */ +function generateWorkload() { + let fromIndex = index % accountList.length; + let toIndex = (index + Math.floor(accountList.length / 2)) % accountList.length; + let value = Math.floor(Math.random() * 100); + let args = { + 'transaction_type': 'userTransfer(string,string,uint256)', + 'from': accountList[fromIndex].accountID, + 'to': accountList[toIndex].accountID, + 'num': value + }; + + index++; + accountList[fromIndex].balance -= value; + accountList[toIndex].balance += value; + return args; +} + +module.exports.run = function () { + let workload = generateWorkload(); + return bc.bcObj.generateRawTransaction(contx, 'dagtransfer', workload, file); +}; + +module.exports.end = function () { + return Promise.resolve(); +}; + +module.exports.file = file; + diff --git a/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/send.js b/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/send.js new file mode 100644 index 000000000..8501aff44 --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/generate_txs_in_advance/send.js @@ -0,0 +1,93 @@ +/* +* 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'; + +const chalk = require('chalk'); +const fs = require('fs'); + +let accountList; +let file; +let transactions; +let bc, contx; +let txnPerBatch; + +module.exports.info = ' transferring money'; + +module.exports.init = function (blockchain, context, args) { + args = args || {}; + if (!args.hasOwnProperty('txnPerBatch')) { + args.txnPerBatch = 1; + } + txnPerBatch = args.txnPerBatch; + + bc = blockchain; + contx = context; + + const addUser = require('./addUser'); + accountList = addUser.accountList; + + const generate = require('./generate'); + file = generate.file; + + transactions = fs.readFileSync(file).toString().split('\n'); +}; + +let index = 0; +/** + * Generates simple workload + * @return {Object} array of json objects + */ +function generateWorkload() { + let workload = []; + for (let i = 0; i < txnPerBatch; i++) { + let transaction = transactions[index]; + workload.push(transaction); + index++; + } + return workload; +} + +module.exports.run = function () { + let workload = generateWorkload(); + return bc.bcObj.sendRawTransaction(contx, workload); +}; + +module.exports.end = async function () { + console.info(chalk.blue.bold('Start balance validation ...')); + let correctAcccountNum = accountList.length; + for (let i = 0; i < accountList.length; ++i) { + let account = accountList[i]; + let accountID = account.accountID; + let balance = account.balance; + let state = await bc.queryState(contx, 'dagtransfer', 'v0', accountID, 'userBalance(string)'); + let remoteBalance = state.status.result.result.output; + remoteBalance = parseInt(remoteBalance, 16); + if (remoteBalance !== balance) { + console.error(chalk.red.bold(`Abnormal account state: AccountID=${accountID}, LocalBalance=${balance}, RemoteBalance=${remoteBalance}`)); + correctAcccountNum--; + } + } + + fs.unlinkSync(file); + + if (correctAcccountNum === accountList.length) { + console.info(chalk.green.bold('Balance validation succeeded')); + return Promise.resolve(); + } + else { + console.error(chalk.red.bold(`Balance validation failed: success=${correctAcccountNum}, fail=${accountList.length - correctAcccountNum}`)); + return Promise.reject(); + } +}; diff --git a/packages/caliper-samples/benchmark/fisco-bcos/helloworld/config.yaml b/packages/caliper-samples/benchmark/fisco-bcos/helloworld/config.yaml new file mode 100644 index 000000000..05e1028db --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/helloworld/config.yaml @@ -0,0 +1,55 @@ +# +# 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 + rounds: + - label: get + description: Test performance of getting name + txNumber: + - 10000 + rateControl: + - type: fixed-rate + opts: + tps: 1000 + callback: benchmark/fisco-bcos/helloworld/get.js + - label: set + description: Test performance of setting name + txNumber: + - 10000 + rateControl: + - type: fixed-rate + opts: + tps: 1000 + callback: benchmark/fisco-bcos/helloworld/set.js +monitor: + type: + - docker + - process + docker: + name: + - node0 + - node1 + - node2 + - node3 + process: + - command: node + arguments: fiscoBcosClientWorker.js + multiOutput: avg + interval: 0.5 diff --git a/packages/caliper-samples/benchmark/fisco-bcos/helloworld/get.js b/packages/caliper-samples/benchmark/fisco-bcos/helloworld/get.js new file mode 100644 index 000000000..088653804 --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/helloworld/get.js @@ -0,0 +1,35 @@ +/* +* 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(); +}; diff --git a/packages/caliper-samples/benchmark/fisco-bcos/helloworld/set.js b/packages/caliper-samples/benchmark/fisco-bcos/helloworld/set.js new file mode 100644 index 000000000..fbb3ef35f --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/helloworld/set.js @@ -0,0 +1,53 @@ +/* +* 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; + +module.exports.init = function (blockchain, context, args) { + txnPerBatch = 1; + bc = blockchain; + contx = context; + return Promise.resolve(); +}; + +/** + * 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(), + }; + 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(); +}; diff --git a/packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/addUser.js b/packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/addUser.js new file mode 100644 index 000000000..d6e91fc6d --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/addUser.js @@ -0,0 +1,74 @@ +/* +* 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'; + +const uuidv4 = require('uuid/v4'); + +module.exports.info = ' adding users'; + +let accountList = []; +let initMoney = 100000000; +let prefix; +let bc, contx; + +module.exports.init = function (blockchain, context, args) { + prefix = uuidv4(); + + bc = blockchain; + contx = context; + + return Promise.resolve(); +}; + +/** + * Generate unique account key for the transaction + * @param {Number} index account index + * @returns {String} account key + */ +function generateAccount(index) { + return prefix + index; +} + +/** + * Generates simple workload + * @returns {Object} array of json objects + */ +function generateWorkload() { + let workload = []; + let index = accountList.length; + let accountID = generateAccount(index); + accountList.push({ + 'accountID': accountID, + 'balance': initMoney + }); + + workload.push({ + 'transaction_type': 'userAdd(string,uint256)', + 'name': accountID, + 'num': initMoney + }); + return workload; +} + +module.exports.run = function () { + let args = generateWorkload(); + return bc.invokeSmartContract(contx, 'dagtransfer', 'v0', args, null); +}; + +module.exports.end = function () { + return Promise.resolve(); +}; + +module.exports.accountList = accountList; diff --git a/packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/config.yaml b/packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/config.yaml new file mode 100644 index 000000000..586ed14d4 --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/config.yaml @@ -0,0 +1,57 @@ +# +# 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: Precompiled Transfer + description: This is a precompiled transfer benchmark of FISCO BCOS for caliper + clients: + type: local + number: 4 + rounds: + - label: addUser + description: generate users for transfer test later + txNumber: + - 1000 + rateControl: + - type: fixed-rate + opts: + tps: 1000 + callback: benchmark/fisco-bcos/transfer/precompiled/addUser.js + - label: transfer + description: transfer money between users + txNumber: + - 10000 + rateControl: + - type: fixed-rate + opts: + tps: 1000 + arguments: + txnPerBatch: 10 + callback: benchmark/fisco-bcos/transfer/precompiled/transfer.js +monitor: + type: + - docker + - process + docker: + name: + - node0 + - node1 + - node2 + - node3 + process: + - command: node + arguments: fiscoBcosClientWorker.js + multiOutput: avg + interval: 0.2 diff --git a/packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/transfer.js b/packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/transfer.js new file mode 100644 index 000000000..3713d7ee1 --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/transfer/precompiled/transfer.js @@ -0,0 +1,95 @@ +/* +* 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'; + +const chalk = require('chalk'); + +let accountList; +let bc, contx; +let txnPerBatch; + +module.exports.info = ' transferring money'; + +module.exports.init = function (blockchain, context, args) { + args = args || {}; + if (!args.hasOwnProperty('txnPerBatch')) { + args.txnPerBatch = 1; + } + txnPerBatch = args.txnPerBatch; + + bc = blockchain; + contx = context; + + const addUser = require('./addUser'); + accountList = addUser.accountList; +}; + +let index = 0; +/** + * Generates simple workload + * @return {Object} array of json objects + */ +function generateWorkload() { + let workload = []; + for (let i = 0; i < txnPerBatch; i++) { + let fromIndex = index % accountList.length; + let toIndex = (index + Math.floor(accountList.length / 2)) % accountList.length; + let value = Math.floor(Math.random() * 100); + let args = { + 'transaction_type': 'userTransfer(string,string,uint256)', + 'from': accountList[fromIndex].accountID, + 'to': accountList[toIndex].accountID, + 'num': value + }; + workload.push(args); + + index++; + accountList[fromIndex].balance -= value; + accountList[toIndex].balance += value; + } + return workload; +} + +module.exports.run = function () { + let workload = generateWorkload(); + return bc.invokeSmartContract(contx, 'dagtransfer', 'v0', workload, null); + +}; + +module.exports.end = async function () { + console.info(chalk.blue.bold('Start balance validation ...')); + let correctAcccountNum = accountList.length; + for (let i = 0; i < accountList.length; ++i) { + let account = accountList[i]; + let accountID = account.accountID; + let balance = account.balance; + let state = await bc.queryState(contx, 'dagtransfer', 'v0', accountID, 'userBalance(string)'); + let remoteBalance = state.status.result.result.output; + remoteBalance = parseInt(remoteBalance, 16); + if (remoteBalance !== balance) { + console.error(chalk.red.bold(`Abnormal account state: AccountID=${accountID}, LocalBalance=${balance}, RemoteBalance=${remoteBalance}`)); + correctAcccountNum--; + } + } + + if (correctAcccountNum === accountList.length) { + console.info(chalk.green.bold('Balance validation succeeded')); + return Promise.resolve(); + } + else { + console.error(chalk.red.bold(`Balance validation failed: success=${correctAcccountNum}, fail=${accountList.length - correctAcccountNum}`)); + return Promise.reject(); + } +}; diff --git a/packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/addUser.js b/packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/addUser.js new file mode 100644 index 000000000..9d863c848 --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/addUser.js @@ -0,0 +1,79 @@ +/* +* 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'; + +const uuidv4 = require('uuid/v4'); + +module.exports.info = ' adding users'; + +let accountList = []; +let initMoney = 100000000; +let prefix; +let bc, contx; + +module.exports.init = function (blockchain, context, args) { + prefix = uuidv4(); + + bc = blockchain; + contx = context; + + let workload = [{ + 'transaction_type': 'enableParallel()' + }]; + + // Enable parallel transacion executor first, this transaction should *NOT* be recorded by context + return bc.invokeSmartContract(null, 'parallelok', 'v0', workload, null); +}; + +/** + * Generate unique account key for the transaction + * @param {Number} index account index + * @returns {String} account key + */ +function generateAccount(index) { + return prefix + index; +} + +/** + * Generates simple workload + * @returns {Object} array of json objects + */ +function generateWorkload() { + let workload = []; + let index = accountList.length; + let accountID = generateAccount(index); + accountList.push({ + 'accountID': accountID, + 'balance': initMoney + }); + + workload.push({ + 'transaction_type': 'set(string,uint256)', + 'name': accountID, + 'num': initMoney + }); + return workload; +} + +module.exports.run = function () { + let args = generateWorkload(); + return bc.invokeSmartContract(contx, 'parallelok', 'v0', args, null); +}; + +module.exports.end = function () { + return Promise.resolve(); +}; + +module.exports.accountList = accountList; diff --git a/packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/config.yaml b/packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/config.yaml new file mode 100644 index 000000000..0f496ee7e --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/config.yaml @@ -0,0 +1,57 @@ +# +# 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: Solidity Transfer + description: This is a solidity transfer benchmark of FISCO BCOS for caliper + clients: + type: local + number: 4 + rounds: + - label: addUser + description: generate users for transfer test later + txNumber: + - 1000 + rateControl: + - type: fixed-rate + opts: + tps: 1000 + callback: benchmark/fisco-bcos/transfer/solidity/addUser.js + - label: transfer + description: transfer money between users + txNumber: + - 10000 + rateControl: + - type: fixed-rate + opts: + tps: 1000 + arguments: + txnPerBatch: 10 + callback: benchmark/fisco-bcos/transfer/solidity/transfer.js +monitor: + type: + - docker + - process + docker: + name: + - node0 + - node1 + - node2 + - node3 + process: + - command: node + arguments: fiscoBcosClientWorker.js + multiOutput: avg + interval: 0.2 diff --git a/packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/transfer.js b/packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/transfer.js new file mode 100644 index 000000000..99978c2fc --- /dev/null +++ b/packages/caliper-samples/benchmark/fisco-bcos/transfer/solidity/transfer.js @@ -0,0 +1,95 @@ +/* +* 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'; + +const chalk = require('chalk'); + +let accountList; +let bc, contx; +let txnPerBatch; + +module.exports.info = ' transferring money'; + +module.exports.init = function (blockchain, context, args) { + args = args || {}; + if (!args.hasOwnProperty('txnPerBatch')) { + args.txnPerBatch = 1; + } + txnPerBatch = args.txnPerBatch; + + bc = blockchain; + contx = context; + + const addUser = require('./addUser'); + accountList = addUser.accountList; +}; + +let index = 0; +/** + * Generates simple workload + * @return {Object} array of json objects + */ +function generateWorkload() { + let workload = []; + for (let i = 0; i < txnPerBatch; i++) { + let fromIndex = index % accountList.length; + let toIndex = (index + Math.floor(accountList.length / 2)) % accountList.length; + let value = Math.floor(Math.random() * 100); + let args = { + 'transaction_type': 'transfer(string,string,uint256)', + 'from': accountList[fromIndex].accountID, + 'to': accountList[toIndex].accountID, + 'num': value + }; + workload.push(args); + + index++; + accountList[fromIndex].balance -= value; + accountList[toIndex].balance += value; + } + return workload; +} + +module.exports.run = function () { + let workload = generateWorkload(); + return bc.invokeSmartContract(contx, 'parallelok', 'v0', workload, null); + +}; + +module.exports.end = async function () { + console.info(chalk.blue.bold('Start balance validation ...')); + let correctAcccountNum = accountList.length; + for (let i = 0; i < accountList.length; ++i) { + let account = accountList[i]; + let accountID = account.accountID; + let balance = account.balance; + let state = await bc.queryState(contx, 'parallelok', 'v0', accountID, 'balanceOf(string)'); + let remoteBalance = state.status.result.result.output; + remoteBalance = parseInt(remoteBalance, 16); + if (remoteBalance !== balance) { + console.error(chalk.red.bold(`Abnormal account state: AccountID=${accountID}, LocalBalance=${balance}, RemoteBalance=${remoteBalance}`)); + correctAcccountNum--; + } + } + + if (correctAcccountNum === accountList.length) { + console.info(chalk.green.bold('Balance validation succeeded')); + return Promise.resolve(); + } + else { + console.error(chalk.red.bold(`Balance validation failed: success=${correctAcccountNum}, fail=${accountList.length - correctAcccountNum}`)); + return Promise.reject(); + } +}; diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/docker-compose.yaml b/packages/caliper-samples/network/fisco-bcos/4nodes1group/docker-compose.yaml new file mode 100644 index 000000000..aba2480b3 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/docker-compose.yaml @@ -0,0 +1,56 @@ +version: "3" + +services: + node0: + image: fiscoorg/fiscobcos:latest + ports: + - "20914:20914" + - "8914:8914" + - "30914:30914" + working_dir: /data + volumes: + - ./node0:/data + container_name: node0 + command: /usr/local/bin/fisco-bcos -c config.ini + + node1: + image: fiscoorg/fiscobcos:latest + ports: + - "20915:20915" + - "8915:8915" + - "30915:30915" + working_dir: "/data" + volumes: + - ./node1:/data + container_name: node1 + command: /usr/local/bin/fisco-bcos -c config.ini + depends_on: + - "node0" + + node2: + image: fiscoorg/fiscobcos:latest + ports: + - "20916:20916" + - "8916:8916" + - "30916:30916" + working_dir: "/data" + volumes: + - ./node2:/data + container_name: node2 + command: /usr/local/bin/fisco-bcos -c config.ini + depends_on: + - "node1" + + node3: + image: fiscoorg/fiscobcos:latest + ports: + - "20917:20917" + - "8917:8917" + - "30917:30917" + working_dir: "/data" + volumes: + - ./node3:/data + container_name: node3 + command: /usr/local/bin/fisco-bcos -c config.ini + depends_on: + - "node2" diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/fisco-bcos.json b/packages/caliper-samples/network/fisco-bcos/4nodes1group/fisco-bcos.json new file mode 100644 index 000000000..aed76f8e8 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/fisco-bcos.json @@ -0,0 +1,71 @@ +{ + "caliper": { + "blockchain": "fisco-bcos", + "command": { + "start": "docker-compose -f network/fisco-bcos/4nodes1group/docker-compose.yaml up -d; sleep 3s", + "end": "docker-compose -f network/fisco-bcos/4nodes1group/docker-compose.yaml down" + } + }, + "fisco-bcos": { + "config": { + "privateKey": "bcec428d5205abe0f0cc8a734083908d9eb8563e31f943d760786edf42ad67dd", + "account": "0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3" + }, + "network": { + "nodes": [ + { + "ip": "127.0.0.1", + "rpcPort": "8914", + "channelPort": "20914" + }, + { + "ip": "127.0.0.1", + "rpcPort": "8915", + "channelPort": "20915" + }, + { + "ip": "127.0.0.1", + "rpcPort": "8916", + "channelPort": "20916" + }, + { + "ip": "127.0.0.1", + "rpcPort": "8917", + "channelPort": "20917" + } + ], + "authentication": { + "key": "../caliper-samples/network/fisco-bcos/4nodes1group/sdk/node.key", + "cert": "../caliper-samples/network/fisco-bcos/4nodes1group/sdk/node.crt", + "ca": "../caliper-samples/network/fisco-bcos/4nodes1group/sdk/ca.crt" + }, + "groupID": 1, + "timeout": 100000 + }, + "smartContracts": [ + { + "id": "helloworld", + "path": "src/contract/fisco-bcos/helloworld/HelloWorld.sol", + "language": "solidity", + "version": "v0" + }, + { + "id": "parallelok", + "path": "src/contract/fisco-bcos/transfer/ParallelOk.sol", + "language": "solidity", + "version": "v0" + }, + { + "id": "dagtransfer", + "address": "0x0000000000000000000000000000000000005002", + "language": "precompiled", + "version": "v0" + } + ] + }, + "info": { + "Version": "2.0.0", + "Size": "4 Nodes", + "Distribution": "Single Host" + } +} diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/ca.crt b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/ca.crt new file mode 100644 index 000000000..09bfbbde0 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPTCCAiWgAwIBAgIJAOGxa7KkPpF8MA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNV +BAMMBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAe +Fw0xOTA2MTEwMzMxMjZaFw0yOTA2MDgwMzMxMjZaMDUxDjAMBgNVBAMMBWNoYWlu +MRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALvzIKFr9UnSQnOExe5NkKN1hN5RRcOPSPfs +MrUJ6k5Om/WfCMMCgIlIZASaK0WKBo45IvDLFuQmng/XziY7/i9mO3xgvyQxfQMj +qHGKpKmNxtj9wuORKT+w/5Ino+avMatucO5FrWrw9PloaEz8cmy8SVnD6E6JSbbr +uiTRoR5OXGiEzVaECMBeCobAbdy2hQSaaZnHJYtXYFqvo4Xnh5/PT5hVQCuKih8P +OXRune4Zvl2mydW+t3QSWrT33gUaPVZDrvaLWpbLeEXVwZ4jvUMo5qCiMzbX69db +F4K+VIT6PXi35OI6uxSjiaisDFUItZv/srGE4ikQxBuIP7PAizsCAwEAAaNQME4w +HQYDVR0OBBYEFCuHzKdBsmgEDTF28/PT/Jhn8DwPMB8GA1UdIwQYMBaAFCuHzKdB +smgEDTF28/PT/Jhn8DwPMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AIPDj3p7xhS5+fI78A/qpToJDZvgwHs56jnJ8XtECfjrvtT0FinMI4pLPs+scj8b +Lm0RM+WKSpig7TtO1Zjwma22CSssr/MJAWOa8Y200qgVmuiOmtuVBPw+mMcI1Ijt +GDEgXVWL1odIHWjookjAzSRiOvU5KUGctImHZ3RPQozOt7TTVx3usH5qJiWVg2IB +DBiBdCVzwSR5EGkIr0cC6cih/08R0fDaLXwUrHgeJi6VUDdp+rV6h76frJowwbJc +Q3s8fdVW3ti7YUOHJD08WWz0+1PblVHwlCIYBxdH06m5nFYZyeoLg+I+xduH5hNH +VH3h/8g8OQvRZnc6nF/mXpU= +-----END CERTIFICATE----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/group.1.genesis b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/group.1.genesis new file mode 100644 index 000000000..553ac0014 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/group.1.genesis @@ -0,0 +1,26 @@ +;consensus configuration +[consensus] + ;consensus algorithm type, now support PBFT(consensus_type=pbft) and Raft(consensus_type=raft) + consensus_type=pbft + ;the max number of transactions of a block + max_trans_num=10000 + ;the node id of leaders + node.0=0522afb1b6178903bef0fe9c78c91f8e1cda785c86a164beb0194eb19e977bd5aa4f7ad7a34d56cf7df1d86e8b37a9020643d8e2231e4ab42235f53b2251b697 + node.1=d0f6425fc9214cdd99f2fe15cf5c9d818113afac9c4a54366a5cc42e267c6384fa2e79eaae2c87e8103f41726585811c9089f20bca3454819f0fccdf406df0d8 + node.2=1e765dc25326d1c23c120355b01e11f6b3a23f5a2332151bde20aac292b35afee66fbec641dcabb888dccf4e65bd3e56cfdfe9af69883154b3ad3800cac4a2b5 + node.3=e2edc5a18abaf072836f48eb1050279171409ee45306fba37e1fc8b62691efe5d6bfccffe134794b6f420b49bbff53c6c4df70fa742c8f5059d4db7a1994bdfa + +[storage] + ;storage db type, leveldb or external + type=LevelDB + topic=DB +[state] + ;support mpt/storage + type=storage + +;tx gas limit +[tx] + gas_limit=300000000 +[group] + id=1 + timestamp=1560223886000 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/group.1.ini b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/group.1.ini new file mode 100644 index 000000000..cb8253f83 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/group.1.ini @@ -0,0 +1,12 @@ +; the ttl for broadcasting pbft message +[consensus] + ;ttl=2 + ;min block generation time(ms), the max block generation time is 1000 ms + ;min_block_generation_time=500 + ;enable_dynamic_block_size=true + +;txpool limit +[tx_pool] + limit=150000 +[tx_execute] + enable_parallel=true diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.crt b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.crt new file mode 100644 index 000000000..8575712e7 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIICOjCCASKgAwIBAgIJAIr5gH0OTKgwMA0GCSqGSIb3DQEBCwUAMDcxDzANBgNV +BAMMBmFnZW5jeTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5 +MB4XDTE5MDYxMTAzMzEyN1oXDTI5MDYwODAzMzEyN1owNDEOMAwGA1UEAwwFbm9k +ZTAxEzARBgNVBAoMCmZpc2NvLWJjb3MxDTALBgNVBAsMBG5vZGUwVjAQBgcqhkjO +PQIBBgUrgQQACgNCAAQFIq+xtheJA77w/px4yR+OHNp4XIahZL6wGU6xnpd71apP +etejTVbPffHYbos3qQIGQ9jiIx5KtCI19TsiUbaXoxowGDAJBgNVHRMEAjAAMAsG +A1UdDwQEAwIF4DANBgkqhkiG9w0BAQsFAAOCAQEA7jjd6E3uT0P40/Hr6BIgLhp9 +SVTDXGGGzvOQSU+1eAvFIT18ZSM8frvHOwuSo3d2FTi7V/iVcT+aOX9nEHWKos/f +kWMfuNxJwfGhGg2WXkZ20CWDhqRZDksmFWx55W0rT16wH1/v2uSGDkdbSLyLyT8T +Q/Cvvi/a9Cwn1rCBy2AceHkUqOD8NXr1hdKPtdw2Op+Sge4G6juN1hQvtqNgXXfe +rHyXd88G/YphBSpKHIdhWOhYn38+HgAqkdyp1qqBdAvJs3rNjaMylbhTWwbsR7F4 +feNMI6gq0FBk9y40d5liVNRv6n97UPv7VzcS7aCVJ0IdG57T2VmsDT6fmQU10Q== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIJAJohET2vzuAvMA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNV +BAMMBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAe +Fw0xOTA2MTEwMzMxMjdaFw0yOTA2MDgwMzMxMjdaMDcxDzANBgNVBAMMBmFnZW5j +eTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/QA51rMRyFZPNyb/MfrMe6Q3Oy5nWcZH +R1oDcdhBdSQs/CR1GFI0xDXQH5KjnC7yJsnnRdKdPQ/0x1thefS8WYwDie/wba7N +6hKhthiIiqRIGv1RzEKM3N69iux6KelCwuUmbLHQYl7WsmoD6+oDCtLHtb4QakAU +Ga7JPvWgbBfFQ24pud/7APCyYqOBfwtLtnuM7hEzaQxpwa9hUfCwElK3i+WqI10U +2OQBEL33Vj7eRgUNaxEF6OGhP15wAtR6ZIVrOyjrnd2zyudstLe4XC2iMNS2mkmX +7avgjXwGpSG4uT3x6LPHTNyRdJz8zd3NJdImwaMZpA4bzh3rik7f5wIDAQABoxAw +DjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA1nHpk+WGkIBPe5c9t +pJ9lVVqmUFiAYW75GoyPRix8YX0BcKWQmC3Gch0mqOcJ8UZg3fN4z+U177MluTxZ +fC8a7Ju//4Dcbc7JSRLCqzvvtLwUydDoF+7lIzZi30ssLjM6Vb7OHl0z74NuUKOw +Jn5TCRKjiMiO3d0iCyE/TP6KJSt1m8yRGc4/mHEuCdLuHhSMIeKg8NIrP2/cTv3L +8/L0/rkHFTg9CQWWtC39uWOzXVpYG5U9ryCNNkFtu5hlS7MVlGaqQvaNlP1DnTiJ +0/KyZKkwpo9pQjjlWwe/O5CNsL12vri8MROX5yBxBcM3QXwsTz+Z3wJB3F19cyBi +5SXJ +-----END CERTIFICATE----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.key b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.key new file mode 100644 index 000000000..1557c0666 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.key @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgWJwTtcTzhTBagb052aC2 +pkIceIZk8HW6uF1Lsk+1CqOhRANCAAQFIq+xtheJA77w/px4yR+OHNp4XIahZL6w +GU6xnpd71apPetejTVbPffHYbos3qQIGQ9jiIx5KtCI19TsiUbaX +-----END PRIVATE KEY----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.nodeid b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.nodeid new file mode 100644 index 000000000..2c6284a7c --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/conf/node.nodeid @@ -0,0 +1 @@ +0522afb1b6178903bef0fe9c78c91f8e1cda785c86a164beb0194eb19e977bd5aa4f7ad7a34d56cf7df1d86e8b37a9020643d8e2231e4ab42235f53b2251b697 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/config.ini b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/config.ini new file mode 100644 index 000000000..449d4e225 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node0/config.ini @@ -0,0 +1,70 @@ +[rpc] + ; rpc listen ip + listen_ip=0.0.0.0 + ; channelserver listen port + channel_listen_port=20914 + ; jsonrpc listen port + jsonrpc_listen_port=8914 +[p2p] + ; p2p listen ip + listen_ip=0.0.0.0 + ; p2p listen port + listen_port=30914 + ; nodes to connect + node.0=172.17.0.1:30914 + node.1=172.17.0.1:30915 + node.2=172.17.0.1:30916 + node.3=172.17.0.1:30917 + + ;enable/disable network compress + ;enable_compress=false + +;certificate rejected list +[certificate_blacklist] + ; crl.0 should be nodeid, nodeid's length is 128 + ;crl.0= + +;group configurations +;WARNING: group 0 is forbided +[group] + group_data_path=data/ + group_config_path=conf/ + +;certificate configuration +[network_security] + ; directory the certificates located in + data_path=conf/ + ; the node private key file + key=node.key + ; the node certificate file + cert=node.crt + ; the ca certificate file + ca_cert=ca.crt + +; storage security releated configurations +[storage_security] +; enable storage_security or not +;enable=true +; the IP of key mananger +;key_manager_ip= +; the Port of key manager +;key_manager_port= +;cipher_data_key= + +[chain] + id=1 +[compatibility] + supported_version=2.0.0-rc2 +;log configurations +[log] + ; the directory of the log + log_path=./log + ; info debug trace + level=info + ; MB + max_log_file_size=200 + ; control log auto_flush + flush=true + ; easylog config + format=%level|%datetime{%Y-%M-%d %H:%m:%s:%g}|%msg + log_flush_threshold=100 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/ca.crt b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/ca.crt new file mode 100644 index 000000000..09bfbbde0 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPTCCAiWgAwIBAgIJAOGxa7KkPpF8MA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNV +BAMMBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAe +Fw0xOTA2MTEwMzMxMjZaFw0yOTA2MDgwMzMxMjZaMDUxDjAMBgNVBAMMBWNoYWlu +MRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALvzIKFr9UnSQnOExe5NkKN1hN5RRcOPSPfs +MrUJ6k5Om/WfCMMCgIlIZASaK0WKBo45IvDLFuQmng/XziY7/i9mO3xgvyQxfQMj +qHGKpKmNxtj9wuORKT+w/5Ino+avMatucO5FrWrw9PloaEz8cmy8SVnD6E6JSbbr +uiTRoR5OXGiEzVaECMBeCobAbdy2hQSaaZnHJYtXYFqvo4Xnh5/PT5hVQCuKih8P +OXRune4Zvl2mydW+t3QSWrT33gUaPVZDrvaLWpbLeEXVwZ4jvUMo5qCiMzbX69db +F4K+VIT6PXi35OI6uxSjiaisDFUItZv/srGE4ikQxBuIP7PAizsCAwEAAaNQME4w +HQYDVR0OBBYEFCuHzKdBsmgEDTF28/PT/Jhn8DwPMB8GA1UdIwQYMBaAFCuHzKdB +smgEDTF28/PT/Jhn8DwPMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AIPDj3p7xhS5+fI78A/qpToJDZvgwHs56jnJ8XtECfjrvtT0FinMI4pLPs+scj8b +Lm0RM+WKSpig7TtO1Zjwma22CSssr/MJAWOa8Y200qgVmuiOmtuVBPw+mMcI1Ijt +GDEgXVWL1odIHWjookjAzSRiOvU5KUGctImHZ3RPQozOt7TTVx3usH5qJiWVg2IB +DBiBdCVzwSR5EGkIr0cC6cih/08R0fDaLXwUrHgeJi6VUDdp+rV6h76frJowwbJc +Q3s8fdVW3ti7YUOHJD08WWz0+1PblVHwlCIYBxdH06m5nFYZyeoLg+I+xduH5hNH +VH3h/8g8OQvRZnc6nF/mXpU= +-----END CERTIFICATE----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/group.1.genesis b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/group.1.genesis new file mode 100644 index 000000000..553ac0014 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/group.1.genesis @@ -0,0 +1,26 @@ +;consensus configuration +[consensus] + ;consensus algorithm type, now support PBFT(consensus_type=pbft) and Raft(consensus_type=raft) + consensus_type=pbft + ;the max number of transactions of a block + max_trans_num=10000 + ;the node id of leaders + node.0=0522afb1b6178903bef0fe9c78c91f8e1cda785c86a164beb0194eb19e977bd5aa4f7ad7a34d56cf7df1d86e8b37a9020643d8e2231e4ab42235f53b2251b697 + node.1=d0f6425fc9214cdd99f2fe15cf5c9d818113afac9c4a54366a5cc42e267c6384fa2e79eaae2c87e8103f41726585811c9089f20bca3454819f0fccdf406df0d8 + node.2=1e765dc25326d1c23c120355b01e11f6b3a23f5a2332151bde20aac292b35afee66fbec641dcabb888dccf4e65bd3e56cfdfe9af69883154b3ad3800cac4a2b5 + node.3=e2edc5a18abaf072836f48eb1050279171409ee45306fba37e1fc8b62691efe5d6bfccffe134794b6f420b49bbff53c6c4df70fa742c8f5059d4db7a1994bdfa + +[storage] + ;storage db type, leveldb or external + type=LevelDB + topic=DB +[state] + ;support mpt/storage + type=storage + +;tx gas limit +[tx] + gas_limit=300000000 +[group] + id=1 + timestamp=1560223886000 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/group.1.ini b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/group.1.ini new file mode 100644 index 000000000..cb8253f83 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/group.1.ini @@ -0,0 +1,12 @@ +; the ttl for broadcasting pbft message +[consensus] + ;ttl=2 + ;min block generation time(ms), the max block generation time is 1000 ms + ;min_block_generation_time=500 + ;enable_dynamic_block_size=true + +;txpool limit +[tx_pool] + limit=150000 +[tx_execute] + enable_parallel=true diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.crt b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.crt new file mode 100644 index 000000000..4a84f9d8b --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIICOjCCASKgAwIBAgIJAIr5gH0OTKgyMA0GCSqGSIb3DQEBCwUAMDcxDzANBgNV +BAMMBmFnZW5jeTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5 +MB4XDTE5MDYxMTAzMzEyN1oXDTI5MDYwODAzMzEyN1owNDEOMAwGA1UEAwwFbm9k +ZTExEzARBgNVBAoMCmZpc2NvLWJjb3MxDTALBgNVBAsMBG5vZGUwVjAQBgcqhkjO +PQIBBgUrgQQACgNCAATQ9kJfySFM3Zny/hXPXJ2BgROvrJxKVDZqXMQuJnxjhPou +eequLIfoED9BcmWFgRyQifILyjRUgZ8PzN9AbfDYoxowGDAJBgNVHRMEAjAAMAsG +A1UdDwQEAwIF4DANBgkqhkiG9w0BAQsFAAOCAQEA3tSFYo2QcIC8HpAF+5IsMvCv +lW5czJm7ybmN6gi+2KtJWfhupjyiEkxDU7+BJdNvdIBDLqR+/ctiyqDX2hDiDNIJ +LlWKZaprTjxpGeDUzSS7/JryzSLhIreqNeqn/b2oGZuV2LVWPt0jak5wKvjlrgu3 +wn4jjuwl3LfM23WyvlYotQes9tRXoUh2Fuv4yUTX+ywEuESk1o8jVDXEkqMVtSoe +vc/MndZEKl+wh4Eqr+sDg97AgjBOmr4Y52KFS8TWdkyU9U4H+Fv5rtNk/0w6V2Qb +yKcJg6Te3TokW3jM6wBWqhHyENSgysmHFju4Y/l8vxO7hiqtJibyj6MmHeAP3w== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIJAJohET2vzuAvMA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNV +BAMMBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAe +Fw0xOTA2MTEwMzMxMjdaFw0yOTA2MDgwMzMxMjdaMDcxDzANBgNVBAMMBmFnZW5j +eTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/QA51rMRyFZPNyb/MfrMe6Q3Oy5nWcZH +R1oDcdhBdSQs/CR1GFI0xDXQH5KjnC7yJsnnRdKdPQ/0x1thefS8WYwDie/wba7N +6hKhthiIiqRIGv1RzEKM3N69iux6KelCwuUmbLHQYl7WsmoD6+oDCtLHtb4QakAU +Ga7JPvWgbBfFQ24pud/7APCyYqOBfwtLtnuM7hEzaQxpwa9hUfCwElK3i+WqI10U +2OQBEL33Vj7eRgUNaxEF6OGhP15wAtR6ZIVrOyjrnd2zyudstLe4XC2iMNS2mkmX +7avgjXwGpSG4uT3x6LPHTNyRdJz8zd3NJdImwaMZpA4bzh3rik7f5wIDAQABoxAw +DjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA1nHpk+WGkIBPe5c9t +pJ9lVVqmUFiAYW75GoyPRix8YX0BcKWQmC3Gch0mqOcJ8UZg3fN4z+U177MluTxZ +fC8a7Ju//4Dcbc7JSRLCqzvvtLwUydDoF+7lIzZi30ssLjM6Vb7OHl0z74NuUKOw +Jn5TCRKjiMiO3d0iCyE/TP6KJSt1m8yRGc4/mHEuCdLuHhSMIeKg8NIrP2/cTv3L +8/L0/rkHFTg9CQWWtC39uWOzXVpYG5U9ryCNNkFtu5hlS7MVlGaqQvaNlP1DnTiJ +0/KyZKkwpo9pQjjlWwe/O5CNsL12vri8MROX5yBxBcM3QXwsTz+Z3wJB3F19cyBi +5SXJ +-----END CERTIFICATE----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.key b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.key new file mode 100644 index 000000000..0a634a182 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.key @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgB5dNhWs34bn0spho3mWB +pzn203dkiHZszGtbdFRq/2uhRANCAATQ9kJfySFM3Zny/hXPXJ2BgROvrJxKVDZq +XMQuJnxjhPoueequLIfoED9BcmWFgRyQifILyjRUgZ8PzN9AbfDY +-----END PRIVATE KEY----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.nodeid b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.nodeid new file mode 100644 index 000000000..179585c68 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/conf/node.nodeid @@ -0,0 +1 @@ +d0f6425fc9214cdd99f2fe15cf5c9d818113afac9c4a54366a5cc42e267c6384fa2e79eaae2c87e8103f41726585811c9089f20bca3454819f0fccdf406df0d8 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/config.ini b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/config.ini new file mode 100644 index 000000000..36ef19ddc --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node1/config.ini @@ -0,0 +1,70 @@ +[rpc] + ; rpc listen ip + listen_ip=0.0.0.0 + ; channelserver listen port + channel_listen_port=20915 + ; jsonrpc listen port + jsonrpc_listen_port=8915 +[p2p] + ; p2p listen ip + listen_ip=0.0.0.0 + ; p2p listen port + listen_port=30915 + ; nodes to connect + node.0=172.17.0.1:30914 + node.1=172.17.0.1:30915 + node.2=172.17.0.1:30916 + node.3=172.17.0.1:30917 + + ;enable/disable network compress + ;enable_compress=false + +;certificate rejected list +[certificate_blacklist] + ; crl.0 should be nodeid, nodeid's length is 128 + ;crl.0= + +;group configurations +;WARNING: group 0 is forbided +[group] + group_data_path=data/ + group_config_path=conf/ + +;certificate configuration +[network_security] + ; directory the certificates located in + data_path=conf/ + ; the node private key file + key=node.key + ; the node certificate file + cert=node.crt + ; the ca certificate file + ca_cert=ca.crt + +; storage security releated configurations +[storage_security] +; enable storage_security or not +;enable=true +; the IP of key mananger +;key_manager_ip= +; the Port of key manager +;key_manager_port= +;cipher_data_key= + +[chain] + id=1 +[compatibility] + supported_version=2.0.0-rc2 +;log configurations +[log] + ; the directory of the log + log_path=./log + ; info debug trace + level=info + ; MB + max_log_file_size=200 + ; control log auto_flush + flush=true + ; easylog config + format=%level|%datetime{%Y-%M-%d %H:%m:%s:%g}|%msg + log_flush_threshold=100 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/ca.crt b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/ca.crt new file mode 100644 index 000000000..09bfbbde0 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPTCCAiWgAwIBAgIJAOGxa7KkPpF8MA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNV +BAMMBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAe +Fw0xOTA2MTEwMzMxMjZaFw0yOTA2MDgwMzMxMjZaMDUxDjAMBgNVBAMMBWNoYWlu +MRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALvzIKFr9UnSQnOExe5NkKN1hN5RRcOPSPfs +MrUJ6k5Om/WfCMMCgIlIZASaK0WKBo45IvDLFuQmng/XziY7/i9mO3xgvyQxfQMj +qHGKpKmNxtj9wuORKT+w/5Ino+avMatucO5FrWrw9PloaEz8cmy8SVnD6E6JSbbr +uiTRoR5OXGiEzVaECMBeCobAbdy2hQSaaZnHJYtXYFqvo4Xnh5/PT5hVQCuKih8P +OXRune4Zvl2mydW+t3QSWrT33gUaPVZDrvaLWpbLeEXVwZ4jvUMo5qCiMzbX69db +F4K+VIT6PXi35OI6uxSjiaisDFUItZv/srGE4ikQxBuIP7PAizsCAwEAAaNQME4w +HQYDVR0OBBYEFCuHzKdBsmgEDTF28/PT/Jhn8DwPMB8GA1UdIwQYMBaAFCuHzKdB +smgEDTF28/PT/Jhn8DwPMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AIPDj3p7xhS5+fI78A/qpToJDZvgwHs56jnJ8XtECfjrvtT0FinMI4pLPs+scj8b +Lm0RM+WKSpig7TtO1Zjwma22CSssr/MJAWOa8Y200qgVmuiOmtuVBPw+mMcI1Ijt +GDEgXVWL1odIHWjookjAzSRiOvU5KUGctImHZ3RPQozOt7TTVx3usH5qJiWVg2IB +DBiBdCVzwSR5EGkIr0cC6cih/08R0fDaLXwUrHgeJi6VUDdp+rV6h76frJowwbJc +Q3s8fdVW3ti7YUOHJD08WWz0+1PblVHwlCIYBxdH06m5nFYZyeoLg+I+xduH5hNH +VH3h/8g8OQvRZnc6nF/mXpU= +-----END CERTIFICATE----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/group.1.genesis b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/group.1.genesis new file mode 100644 index 000000000..553ac0014 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/group.1.genesis @@ -0,0 +1,26 @@ +;consensus configuration +[consensus] + ;consensus algorithm type, now support PBFT(consensus_type=pbft) and Raft(consensus_type=raft) + consensus_type=pbft + ;the max number of transactions of a block + max_trans_num=10000 + ;the node id of leaders + node.0=0522afb1b6178903bef0fe9c78c91f8e1cda785c86a164beb0194eb19e977bd5aa4f7ad7a34d56cf7df1d86e8b37a9020643d8e2231e4ab42235f53b2251b697 + node.1=d0f6425fc9214cdd99f2fe15cf5c9d818113afac9c4a54366a5cc42e267c6384fa2e79eaae2c87e8103f41726585811c9089f20bca3454819f0fccdf406df0d8 + node.2=1e765dc25326d1c23c120355b01e11f6b3a23f5a2332151bde20aac292b35afee66fbec641dcabb888dccf4e65bd3e56cfdfe9af69883154b3ad3800cac4a2b5 + node.3=e2edc5a18abaf072836f48eb1050279171409ee45306fba37e1fc8b62691efe5d6bfccffe134794b6f420b49bbff53c6c4df70fa742c8f5059d4db7a1994bdfa + +[storage] + ;storage db type, leveldb or external + type=LevelDB + topic=DB +[state] + ;support mpt/storage + type=storage + +;tx gas limit +[tx] + gas_limit=300000000 +[group] + id=1 + timestamp=1560223886000 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/group.1.ini b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/group.1.ini new file mode 100644 index 000000000..cb8253f83 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/group.1.ini @@ -0,0 +1,12 @@ +; the ttl for broadcasting pbft message +[consensus] + ;ttl=2 + ;min block generation time(ms), the max block generation time is 1000 ms + ;min_block_generation_time=500 + ;enable_dynamic_block_size=true + +;txpool limit +[tx_pool] + limit=150000 +[tx_execute] + enable_parallel=true diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.crt b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.crt new file mode 100644 index 000000000..defb612b3 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIICOjCCASKgAwIBAgIJAIr5gH0OTKg0MA0GCSqGSIb3DQEBCwUAMDcxDzANBgNV +BAMMBmFnZW5jeTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5 +MB4XDTE5MDYxMTAzMzEyN1oXDTI5MDYwODAzMzEyN1owNDEOMAwGA1UEAwwFbm9k +ZTIxEzARBgNVBAoMCmZpc2NvLWJjb3MxDTALBgNVBAsMBG5vZGUwVjAQBgcqhkjO +PQIBBgUrgQQACgNCAAQedl3CUybRwjwSA1WwHhH2s6I/WiMyFRveIKrCkrNa/uZv +vsZB3Ku4iNzPTmW9PlbP3+mvaYgxVLOtOADKxKK1oxowGDAJBgNVHRMEAjAAMAsG +A1UdDwQEAwIF4DANBgkqhkiG9w0BAQsFAAOCAQEAuCnvOW7VK5PURmZMN6+scBgh +idJ4aD7iHLqiSMFxcB3Inl4DmK3My+CMFjSsHhWuct7S88PooGFE1HvzjhjAErIk +sS+vwy4qArQYpIpejeyddtchdSuKE5OL9o/JIhsw5WcRw56DG0KC2V5OppCXxg3j +ffKQHcM8PSIS7GLMT3nZCktRLpLLw5N0/87loSAkJhQW32lpjKrPsmdxaqpVR+bD +zXQrp44PxYJORalFhOGhxMgGXmn5RpGX/6TgLgQaTiKi3B66jR9mLliv0JQRmdih +JKNzrXN2fQqUOLQ2RmKpmzdlF5lKAxA9wm4qk3i0Vhi2lBTMJQiKUxe8osFd8A== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIJAJohET2vzuAvMA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNV +BAMMBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAe +Fw0xOTA2MTEwMzMxMjdaFw0yOTA2MDgwMzMxMjdaMDcxDzANBgNVBAMMBmFnZW5j +eTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/QA51rMRyFZPNyb/MfrMe6Q3Oy5nWcZH +R1oDcdhBdSQs/CR1GFI0xDXQH5KjnC7yJsnnRdKdPQ/0x1thefS8WYwDie/wba7N +6hKhthiIiqRIGv1RzEKM3N69iux6KelCwuUmbLHQYl7WsmoD6+oDCtLHtb4QakAU +Ga7JPvWgbBfFQ24pud/7APCyYqOBfwtLtnuM7hEzaQxpwa9hUfCwElK3i+WqI10U +2OQBEL33Vj7eRgUNaxEF6OGhP15wAtR6ZIVrOyjrnd2zyudstLe4XC2iMNS2mkmX +7avgjXwGpSG4uT3x6LPHTNyRdJz8zd3NJdImwaMZpA4bzh3rik7f5wIDAQABoxAw +DjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA1nHpk+WGkIBPe5c9t +pJ9lVVqmUFiAYW75GoyPRix8YX0BcKWQmC3Gch0mqOcJ8UZg3fN4z+U177MluTxZ +fC8a7Ju//4Dcbc7JSRLCqzvvtLwUydDoF+7lIzZi30ssLjM6Vb7OHl0z74NuUKOw +Jn5TCRKjiMiO3d0iCyE/TP6KJSt1m8yRGc4/mHEuCdLuHhSMIeKg8NIrP2/cTv3L +8/L0/rkHFTg9CQWWtC39uWOzXVpYG5U9ryCNNkFtu5hlS7MVlGaqQvaNlP1DnTiJ +0/KyZKkwpo9pQjjlWwe/O5CNsL12vri8MROX5yBxBcM3QXwsTz+Z3wJB3F19cyBi +5SXJ +-----END CERTIFICATE----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.key b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.key new file mode 100644 index 000000000..b605421a7 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.key @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgMxCjKuN2kv/KYxRikpHu +cmIvcXGNI2JVtsNEeiYGTHKhRANCAAQedl3CUybRwjwSA1WwHhH2s6I/WiMyFRve +IKrCkrNa/uZvvsZB3Ku4iNzPTmW9PlbP3+mvaYgxVLOtOADKxKK1 +-----END PRIVATE KEY----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.nodeid b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.nodeid new file mode 100644 index 000000000..0711da3d1 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/conf/node.nodeid @@ -0,0 +1 @@ +1e765dc25326d1c23c120355b01e11f6b3a23f5a2332151bde20aac292b35afee66fbec641dcabb888dccf4e65bd3e56cfdfe9af69883154b3ad3800cac4a2b5 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/config.ini b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/config.ini new file mode 100644 index 000000000..199ea0d72 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node2/config.ini @@ -0,0 +1,70 @@ +[rpc] + ; rpc listen ip + listen_ip=0.0.0.0 + ; channelserver listen port + channel_listen_port=20916 + ; jsonrpc listen port + jsonrpc_listen_port=8916 +[p2p] + ; p2p listen ip + listen_ip=0.0.0.0 + ; p2p listen port + listen_port=30916 + ; nodes to connect + node.0=172.17.0.1:30914 + node.1=172.17.0.1:30915 + node.2=172.17.0.1:30916 + node.3=172.17.0.1:30917 + + ;enable/disable network compress + ;enable_compress=false + +;certificate rejected list +[certificate_blacklist] + ; crl.0 should be nodeid, nodeid's length is 128 + ;crl.0= + +;group configurations +;WARNING: group 0 is forbided +[group] + group_data_path=data/ + group_config_path=conf/ + +;certificate configuration +[network_security] + ; directory the certificates located in + data_path=conf/ + ; the node private key file + key=node.key + ; the node certificate file + cert=node.crt + ; the ca certificate file + ca_cert=ca.crt + +; storage security releated configurations +[storage_security] +; enable storage_security or not +;enable=true +; the IP of key mananger +;key_manager_ip= +; the Port of key manager +;key_manager_port= +;cipher_data_key= + +[chain] + id=1 +[compatibility] + supported_version=2.0.0-rc2 +;log configurations +[log] + ; the directory of the log + log_path=./log + ; info debug trace + level=info + ; MB + max_log_file_size=200 + ; control log auto_flush + flush=true + ; easylog config + format=%level|%datetime{%Y-%M-%d %H:%m:%s:%g}|%msg + log_flush_threshold=100 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/ca.crt b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/ca.crt new file mode 100644 index 000000000..09bfbbde0 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPTCCAiWgAwIBAgIJAOGxa7KkPpF8MA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNV +BAMMBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAe +Fw0xOTA2MTEwMzMxMjZaFw0yOTA2MDgwMzMxMjZaMDUxDjAMBgNVBAMMBWNoYWlu +MRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALvzIKFr9UnSQnOExe5NkKN1hN5RRcOPSPfs +MrUJ6k5Om/WfCMMCgIlIZASaK0WKBo45IvDLFuQmng/XziY7/i9mO3xgvyQxfQMj +qHGKpKmNxtj9wuORKT+w/5Ino+avMatucO5FrWrw9PloaEz8cmy8SVnD6E6JSbbr +uiTRoR5OXGiEzVaECMBeCobAbdy2hQSaaZnHJYtXYFqvo4Xnh5/PT5hVQCuKih8P +OXRune4Zvl2mydW+t3QSWrT33gUaPVZDrvaLWpbLeEXVwZ4jvUMo5qCiMzbX69db +F4K+VIT6PXi35OI6uxSjiaisDFUItZv/srGE4ikQxBuIP7PAizsCAwEAAaNQME4w +HQYDVR0OBBYEFCuHzKdBsmgEDTF28/PT/Jhn8DwPMB8GA1UdIwQYMBaAFCuHzKdB +smgEDTF28/PT/Jhn8DwPMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AIPDj3p7xhS5+fI78A/qpToJDZvgwHs56jnJ8XtECfjrvtT0FinMI4pLPs+scj8b +Lm0RM+WKSpig7TtO1Zjwma22CSssr/MJAWOa8Y200qgVmuiOmtuVBPw+mMcI1Ijt +GDEgXVWL1odIHWjookjAzSRiOvU5KUGctImHZ3RPQozOt7TTVx3usH5qJiWVg2IB +DBiBdCVzwSR5EGkIr0cC6cih/08R0fDaLXwUrHgeJi6VUDdp+rV6h76frJowwbJc +Q3s8fdVW3ti7YUOHJD08WWz0+1PblVHwlCIYBxdH06m5nFYZyeoLg+I+xduH5hNH +VH3h/8g8OQvRZnc6nF/mXpU= +-----END CERTIFICATE----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/group.1.genesis b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/group.1.genesis new file mode 100644 index 000000000..553ac0014 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/group.1.genesis @@ -0,0 +1,26 @@ +;consensus configuration +[consensus] + ;consensus algorithm type, now support PBFT(consensus_type=pbft) and Raft(consensus_type=raft) + consensus_type=pbft + ;the max number of transactions of a block + max_trans_num=10000 + ;the node id of leaders + node.0=0522afb1b6178903bef0fe9c78c91f8e1cda785c86a164beb0194eb19e977bd5aa4f7ad7a34d56cf7df1d86e8b37a9020643d8e2231e4ab42235f53b2251b697 + node.1=d0f6425fc9214cdd99f2fe15cf5c9d818113afac9c4a54366a5cc42e267c6384fa2e79eaae2c87e8103f41726585811c9089f20bca3454819f0fccdf406df0d8 + node.2=1e765dc25326d1c23c120355b01e11f6b3a23f5a2332151bde20aac292b35afee66fbec641dcabb888dccf4e65bd3e56cfdfe9af69883154b3ad3800cac4a2b5 + node.3=e2edc5a18abaf072836f48eb1050279171409ee45306fba37e1fc8b62691efe5d6bfccffe134794b6f420b49bbff53c6c4df70fa742c8f5059d4db7a1994bdfa + +[storage] + ;storage db type, leveldb or external + type=LevelDB + topic=DB +[state] + ;support mpt/storage + type=storage + +;tx gas limit +[tx] + gas_limit=300000000 +[group] + id=1 + timestamp=1560223886000 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/group.1.ini b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/group.1.ini new file mode 100644 index 000000000..cb8253f83 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/group.1.ini @@ -0,0 +1,12 @@ +; the ttl for broadcasting pbft message +[consensus] + ;ttl=2 + ;min block generation time(ms), the max block generation time is 1000 ms + ;min_block_generation_time=500 + ;enable_dynamic_block_size=true + +;txpool limit +[tx_pool] + limit=150000 +[tx_execute] + enable_parallel=true diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.crt b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.crt new file mode 100644 index 000000000..cd01dc3ad --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIICOjCCASKgAwIBAgIJAIr5gH0OTKg2MA0GCSqGSIb3DQEBCwUAMDcxDzANBgNV +BAMMBmFnZW5jeTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5 +MB4XDTE5MDYxMTAzMzEyN1oXDTI5MDYwODAzMzEyN1owNDEOMAwGA1UEAwwFbm9k +ZTMxEzARBgNVBAoMCmZpc2NvLWJjb3MxDTALBgNVBAsMBG5vZGUwVjAQBgcqhkjO +PQIBBgUrgQQACgNCAATi7cWhirrwcoNvSOsQUCeRcUCe5FMG+6N+H8i2JpHv5da/ +zP/hNHlLb0ILSbv/U8bE33D6dCyPUFnU23oZlL36oxowGDAJBgNVHRMEAjAAMAsG +A1UdDwQEAwIF4DANBgkqhkiG9w0BAQsFAAOCAQEArkUui84yWQkLpENWrMWlDn3O +SHM5j4XnsAxD0c9TS4asuh4ehEChwLulyygQ2Qj7Fsrm1UQGmIERb0a2UYe74BW9 +oF9FuUVimggIQGGkXgiThZD/u8oe3dXpblzlIqDyqBRyB11FelZiJTVCKUPptIuv +xhXxjqzR6xPfq7rzzxIR+EcU2Adv5W6gxY7hUbYpHxUGiWiEAa7eKzJeRIyvFtOT +pJVAt5hJf1nMo9fx96RvhkL8P9Veob3uaOLHEu5qQgzGXRInAubeZ9A5KNejFGKw +dKaIEVZyGEbJ3TtOXOox4wfZsD6s/VINOo4G8E8i+8tkz/S7kUWxTGVrIKi9lw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIJAJohET2vzuAvMA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNV +BAMMBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAe +Fw0xOTA2MTEwMzMxMjdaFw0yOTA2MDgwMzMxMjdaMDcxDzANBgNVBAMMBmFnZW5j +eTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/QA51rMRyFZPNyb/MfrMe6Q3Oy5nWcZH +R1oDcdhBdSQs/CR1GFI0xDXQH5KjnC7yJsnnRdKdPQ/0x1thefS8WYwDie/wba7N +6hKhthiIiqRIGv1RzEKM3N69iux6KelCwuUmbLHQYl7WsmoD6+oDCtLHtb4QakAU +Ga7JPvWgbBfFQ24pud/7APCyYqOBfwtLtnuM7hEzaQxpwa9hUfCwElK3i+WqI10U +2OQBEL33Vj7eRgUNaxEF6OGhP15wAtR6ZIVrOyjrnd2zyudstLe4XC2iMNS2mkmX +7avgjXwGpSG4uT3x6LPHTNyRdJz8zd3NJdImwaMZpA4bzh3rik7f5wIDAQABoxAw +DjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA1nHpk+WGkIBPe5c9t +pJ9lVVqmUFiAYW75GoyPRix8YX0BcKWQmC3Gch0mqOcJ8UZg3fN4z+U177MluTxZ +fC8a7Ju//4Dcbc7JSRLCqzvvtLwUydDoF+7lIzZi30ssLjM6Vb7OHl0z74NuUKOw +Jn5TCRKjiMiO3d0iCyE/TP6KJSt1m8yRGc4/mHEuCdLuHhSMIeKg8NIrP2/cTv3L +8/L0/rkHFTg9CQWWtC39uWOzXVpYG5U9ryCNNkFtu5hlS7MVlGaqQvaNlP1DnTiJ +0/KyZKkwpo9pQjjlWwe/O5CNsL12vri8MROX5yBxBcM3QXwsTz+Z3wJB3F19cyBi +5SXJ +-----END CERTIFICATE----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.key b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.key new file mode 100644 index 000000000..a8919a81c --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.key @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgWE9yd400eHS/1J7I7csp +X6HRw3KBMBxYs6Y/rRzcU9WhRANCAATi7cWhirrwcoNvSOsQUCeRcUCe5FMG+6N+ +H8i2JpHv5da/zP/hNHlLb0ILSbv/U8bE33D6dCyPUFnU23oZlL36 +-----END PRIVATE KEY----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.nodeid b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.nodeid new file mode 100644 index 000000000..58c012727 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/conf/node.nodeid @@ -0,0 +1 @@ +e2edc5a18abaf072836f48eb1050279171409ee45306fba37e1fc8b62691efe5d6bfccffe134794b6f420b49bbff53c6c4df70fa742c8f5059d4db7a1994bdfa diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/config.ini b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/config.ini new file mode 100644 index 000000000..09dc30fad --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/node3/config.ini @@ -0,0 +1,70 @@ +[rpc] + ; rpc listen ip + listen_ip=0.0.0.0 + ; channelserver listen port + channel_listen_port=20917 + ; jsonrpc listen port + jsonrpc_listen_port=8917 +[p2p] + ; p2p listen ip + listen_ip=0.0.0.0 + ; p2p listen port + listen_port=30917 + ; nodes to connect + node.0=172.17.0.1:30914 + node.1=172.17.0.1:30915 + node.2=172.17.0.1:30916 + node.3=172.17.0.1:30917 + + ;enable/disable network compress + ;enable_compress=false + +;certificate rejected list +[certificate_blacklist] + ; crl.0 should be nodeid, nodeid's length is 128 + ;crl.0= + +;group configurations +;WARNING: group 0 is forbided +[group] + group_data_path=data/ + group_config_path=conf/ + +;certificate configuration +[network_security] + ; directory the certificates located in + data_path=conf/ + ; the node private key file + key=node.key + ; the node certificate file + cert=node.crt + ; the ca certificate file + ca_cert=ca.crt + +; storage security releated configurations +[storage_security] +; enable storage_security or not +;enable=true +; the IP of key mananger +;key_manager_ip= +; the Port of key manager +;key_manager_port= +;cipher_data_key= + +[chain] + id=1 +[compatibility] + supported_version=2.0.0-rc2 +;log configurations +[log] + ; the directory of the log + log_path=./log + ; info debug trace + level=info + ; MB + max_log_file_size=200 + ; control log auto_flush + flush=true + ; easylog config + format=%level|%datetime{%Y-%M-%d %H:%m:%s:%g}|%msg + log_flush_threshold=100 diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/ca.crt b/packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/ca.crt new file mode 100644 index 000000000..09bfbbde0 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/ca.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPTCCAiWgAwIBAgIJAOGxa7KkPpF8MA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNV +BAMMBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAe +Fw0xOTA2MTEwMzMxMjZaFw0yOTA2MDgwMzMxMjZaMDUxDjAMBgNVBAMMBWNoYWlu +MRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALvzIKFr9UnSQnOExe5NkKN1hN5RRcOPSPfs +MrUJ6k5Om/WfCMMCgIlIZASaK0WKBo45IvDLFuQmng/XziY7/i9mO3xgvyQxfQMj +qHGKpKmNxtj9wuORKT+w/5Ino+avMatucO5FrWrw9PloaEz8cmy8SVnD6E6JSbbr +uiTRoR5OXGiEzVaECMBeCobAbdy2hQSaaZnHJYtXYFqvo4Xnh5/PT5hVQCuKih8P +OXRune4Zvl2mydW+t3QSWrT33gUaPVZDrvaLWpbLeEXVwZ4jvUMo5qCiMzbX69db +F4K+VIT6PXi35OI6uxSjiaisDFUItZv/srGE4ikQxBuIP7PAizsCAwEAAaNQME4w +HQYDVR0OBBYEFCuHzKdBsmgEDTF28/PT/Jhn8DwPMB8GA1UdIwQYMBaAFCuHzKdB +smgEDTF28/PT/Jhn8DwPMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AIPDj3p7xhS5+fI78A/qpToJDZvgwHs56jnJ8XtECfjrvtT0FinMI4pLPs+scj8b +Lm0RM+WKSpig7TtO1Zjwma22CSssr/MJAWOa8Y200qgVmuiOmtuVBPw+mMcI1Ijt +GDEgXVWL1odIHWjookjAzSRiOvU5KUGctImHZ3RPQozOt7TTVx3usH5qJiWVg2IB +DBiBdCVzwSR5EGkIr0cC6cih/08R0fDaLXwUrHgeJi6VUDdp+rV6h76frJowwbJc +Q3s8fdVW3ti7YUOHJD08WWz0+1PblVHwlCIYBxdH06m5nFYZyeoLg+I+xduH5hNH +VH3h/8g8OQvRZnc6nF/mXpU= +-----END CERTIFICATE----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/node.crt b/packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/node.crt new file mode 100644 index 000000000..d164b9b3f --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/node.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIICODCCASCgAwIBAgIJAIr5gH0OTKg3MA0GCSqGSIb3DQEBCwUAMDcxDzANBgNV +BAMMBmFnZW5jeTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5 +MB4XDTE5MDYxMTAzMzEyN1oXDTI5MDYwODAzMzEyN1owMjEMMAoGA1UEAwwDc2Rr +MRMwEQYDVQQKDApmaXNjby1iY29zMQ0wCwYDVQQLDARub2RlMFYwEAYHKoZIzj0C +AQYFK4EEAAoDQgAE6AII4zTYaX+a8l1eNrDvaMDI1C0SV03XjE7Hc+mONgAk/C3X +ZyPyXTZGJM5zlp96L4cmoTSInMM/x/3/eWDSRqMaMBgwCQYDVR0TBAIwADALBgNV +HQ8EBAMCBeAwDQYJKoZIhvcNAQELBQADggEBAJ1XZrZPqlG/Frk3n3EqaLugB4MK +5t3pI9XLQMHsqRLbG7519psM5Oxetcg3n+hvrAeII6xQSiZlSrGyc30dPafZEFfj +Of2rY+60BPH9Eqh4cFnGACB8GQ17pMAYERFBfv/90LgBQb0C8EWnQeMK3c4W2oLX +m81fwQzv72Ek8XQxmhO/cPOK3gkhgQm4RxNb9NptN/Fd3bkISqmLGcstGwe3pyS1 +/WEby+ovR+Lzo/WZUJ6fw1aCWXTLoP3EffMFzQMduz9jCtGMC4CaIvClu3zOj99J +AbnLfV+K025+jAUWY7m5FXZLQsMZCZiDu0wZc4nd2RIEjYSJ5oLGg4l2Dm4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIJAJohET2vzuAvMA0GCSqGSIb3DQEBCwUAMDUxDjAMBgNV +BAMMBWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAe +Fw0xOTA2MTEwMzMxMjdaFw0yOTA2MDgwMzMxMjdaMDcxDzANBgNVBAMMBmFnZW5j +eTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/QA51rMRyFZPNyb/MfrMe6Q3Oy5nWcZH +R1oDcdhBdSQs/CR1GFI0xDXQH5KjnC7yJsnnRdKdPQ/0x1thefS8WYwDie/wba7N +6hKhthiIiqRIGv1RzEKM3N69iux6KelCwuUmbLHQYl7WsmoD6+oDCtLHtb4QakAU +Ga7JPvWgbBfFQ24pud/7APCyYqOBfwtLtnuM7hEzaQxpwa9hUfCwElK3i+WqI10U +2OQBEL33Vj7eRgUNaxEF6OGhP15wAtR6ZIVrOyjrnd2zyudstLe4XC2iMNS2mkmX +7avgjXwGpSG4uT3x6LPHTNyRdJz8zd3NJdImwaMZpA4bzh3rik7f5wIDAQABoxAw +DjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA1nHpk+WGkIBPe5c9t +pJ9lVVqmUFiAYW75GoyPRix8YX0BcKWQmC3Gch0mqOcJ8UZg3fN4z+U177MluTxZ +fC8a7Ju//4Dcbc7JSRLCqzvvtLwUydDoF+7lIzZi30ssLjM6Vb7OHl0z74NuUKOw +Jn5TCRKjiMiO3d0iCyE/TP6KJSt1m8yRGc4/mHEuCdLuHhSMIeKg8NIrP2/cTv3L +8/L0/rkHFTg9CQWWtC39uWOzXVpYG5U9ryCNNkFtu5hlS7MVlGaqQvaNlP1DnTiJ +0/KyZKkwpo9pQjjlWwe/O5CNsL12vri8MROX5yBxBcM3QXwsTz+Z3wJB3F19cyBi +5SXJ +-----END CERTIFICATE----- diff --git a/packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/node.key b/packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/node.key new file mode 100644 index 000000000..92df74032 --- /dev/null +++ b/packages/caliper-samples/network/fisco-bcos/4nodes1group/sdk/node.key @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgG2s8qW+v4uAVqlXkeqsi +5bu9qx8ltLP6o6zSOJfdhWyhRANCAAToAgjjNNhpf5ryXV42sO9owMjULRJXTdeM +Tsdz6Y42ACT8LddnI/JdNkYkznOWn3ovhyahNIicwz/H/f95YNJG +-----END PRIVATE KEY----- diff --git a/packages/caliper-samples/package.json b/packages/caliper-samples/package.json index c1a50381a..ff5c41d83 100644 --- a/packages/caliper-samples/package.json +++ b/packages/caliper-samples/package.json @@ -46,7 +46,10 @@ "network/fabric-v1.4.1/raft/config/.gitignore", "src/contract/sawtooth/simple/simple_python/simple-tp-python", "src/contract/sawtooth/simple/simple_python/packaging/systemd/sawtooth-simple-tp-python", - "src/contract/sawtooth/docker/sawtooth-int-simple-tp-python" + "src/contract/sawtooth/docker/sawtooth-int-simple-tp-python", + "network/fisco-bcos/4nodes1group", + "src/contract/fisco-bcos/helloworld/HelloWorld.address", + "src/contract/fisco-bcos/transfer/ParallelOk.address" ], "file_type_method": "EXCLUDE", "file_types": [ diff --git a/packages/caliper-samples/src/contract/fisco-bcos/helloworld/HelloWorld.sol b/packages/caliper-samples/src/contract/fisco-bcos/helloworld/HelloWorld.sol new file mode 100644 index 000000000..26ce51e98 --- /dev/null +++ b/packages/caliper-samples/src/contract/fisco-bcos/helloworld/HelloWorld.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.4.2; + +contract HelloWorld { + string name; + + constructor() public { + name = "Hello, World!"; + } + + function get() public view returns(string) { + return name; + } + + function set(string n) public { + name = n; + } +} diff --git a/packages/caliper-samples/src/contract/fisco-bcos/transfer/ParallelContract.sol b/packages/caliper-samples/src/contract/fisco-bcos/transfer/ParallelContract.sol new file mode 100644 index 000000000..9b06294e8 --- /dev/null +++ b/packages/caliper-samples/src/contract/fisco-bcos/transfer/ParallelContract.sol @@ -0,0 +1,25 @@ +pragma solidity ^0.4.25; + +contract ParallelConfigPrecompiled +{ + function registerParallelFunctionInternal(address, string, uint256) public returns (int); + function unregisterParallelFunctionInternal(address, string) public returns (int); +} + +contract ParallelContract +{ + ParallelConfigPrecompiled precompiled = ParallelConfigPrecompiled(0x1006); + + function registerParallelFunction(string functionName, uint256 criticalSize) public + { + precompiled.registerParallelFunctionInternal(address(this), functionName, criticalSize); + } + + function unregisterParallelFunction(string functionName) public + { + precompiled.unregisterParallelFunctionInternal(address(this), functionName); + } + + function enableParallel() public; + function disableParallel() public; +} diff --git a/packages/caliper-samples/src/contract/fisco-bcos/transfer/ParallelOk.sol b/packages/caliper-samples/src/contract/fisco-bcos/transfer/ParallelOk.sol new file mode 100644 index 000000000..99a868a31 --- /dev/null +++ b/packages/caliper-samples/src/contract/fisco-bcos/transfer/ParallelOk.sol @@ -0,0 +1,49 @@ +pragma solidity ^0.4.25; + +import "./ParallelContract.sol"; + +// A parallel contract example +contract ParallelOk is ParallelContract +{ + mapping (string => uint256) _balance; + + // Just an example, overflow is ok, use 'SafeMath' if needed + function transfer(string from, string to, uint256 num) public + { + _balance[from] -= num; + _balance[to] += num; + } + + // Just for testing whether the parallel revert function is working well, no practical use + function transferWithRevert(string from, string to, uint256 num) public + { + _balance[from] -= num; + _balance[to] += num; + require(num <= 100); + } + + function set(string name, uint256 num) public + { + _balance[name] = num; + } + + function balanceOf(string name) public view returns (uint256) + { + return _balance[name]; + } + + // Register parallel function + function enableParallel() public + { + // critical number is to define how many critical params from start + registerParallelFunction("transfer(string,string,uint256)", 2); // critical: string string + registerParallelFunction("set(string,uint256)", 1); // critical: string + } + + // Disable register parallel function + function disableParallel() public + { + unregisterParallelFunction("transfer(string,string,uint256)"); + unregisterParallelFunction("set(string,uint256)"); + } +} \ No newline at end of file diff --git a/packages/caliper-tests-integration/package.json b/packages/caliper-tests-integration/package.json index aea5f8507..52822ee8e 100644 --- a/packages/caliper-tests-integration/package.json +++ b/packages/caliper-tests-integration/package.json @@ -48,7 +48,8 @@ "scripts/storage", "log", "fabric_tests/.gitignore", - "fabric_tests/config/.gitignore" + "fabric_tests/config/.gitignore", + ".DS_Store" ], "file_type_method": "EXCLUDE", "file_types": [ diff --git a/packages/caliper-tests-integration/scripts/publishNpmPackages.js b/packages/caliper-tests-integration/scripts/publishNpmPackages.js index 8685aa30b..6eed28c04 100644 --- a/packages/caliper-tests-integration/scripts/publishNpmPackages.js +++ b/packages/caliper-tests-integration/scripts/publishNpmPackages.js @@ -31,6 +31,7 @@ const packages = [ 'caliper-fabric', 'caliper-iroha', 'caliper-sawtooth', + 'caliper-fisco-bcos', 'caliper-cli' ];