spike: add benchmark (#2716)

Signed-off-by: Taccat Isid <taccatisid@protonmail.com>

Co-authored-by: Sally MacFarlane <sally.macfarlane@consensys.net>
pull/2815/head
taccatisid 3 years ago committed by GitHub
parent 2aeae39560
commit ce28aae8b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 28
      .circleci/config.yml
  2. 0
      benchmark/caliper-benchmarks/.keep
  3. 1
      benchmark/config/besu-keystore/key
  4. 69
      benchmark/config/caliper-benchconfig-offchain.yaml
  5. 80
      benchmark/config/caliper-benchconfig-onchain.yaml
  6. 35
      benchmark/config/caliper-networkconfig-offchain.json
  7. 35
      benchmark/config/caliper-networkconfig-onchain.json
  8. 31
      benchmark/config/caliper-offchain.yaml
  9. 49
      benchmark/config/caliper-onchain.yaml
  10. 75
      benchmark/config/genesis.json
  11. 37
      benchmark/config/storage.json
  12. 109
      benchmark/config/store.js
  13. 48
      benchmark/config/tessera/config.json
  14. 109
      benchmark/docker-compose.yml
  15. 5
      build.gradle

@ -264,6 +264,25 @@ jobs:
# docker login "${ACR_REPO}" --username "${ACR_USER_RW}" --password "${ACR_PASSWORD_RW}"
./gradlew --no-daemon "-Pbranch=${CIRCLE_BRANCH}" dockerUpload
benchmark:
executor: xl_machine_executor
steps:
- attach_workspace:
at: ~/project
- run:
name: Benchmark
command: |
cd benchmark
chmod a+w caliper-benchmarks
docker-compose run --rm caliper-onchain
docker-compose down
docker-compose run --rm caliper-offchain
- store_artifacts:
name: Benchmark results
path: benchmark/caliper-benchmarks
destination: benchmark-results
when: always
workflows:
version: 2
default:
@ -320,4 +339,11 @@ workflows:
- besu-dockerhub-ro
- besu-dockerhub-rw
- besu-acr-rw
- benchmark:
filters:
branches:
only:
- main
- /^release-.*/
requires:
- publishDocker

@ -0,0 +1 @@
0xa67bee5d6fb43acd42e307eb67547ab5006ad2fbb9567829e9b4b2ef3580acea

@ -0,0 +1,69 @@
#
# 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: Simple Storage
description: Test private transactions
workers:
type: local
number: 1
rounds:
- label: warm-up (ignore results)
txDuration: 10
rateControl:
type: fixed-load
opts:
startingTps: 200
transactionLoad: 200
workload:
module: /config/store.js
arguments:
contract: private_storage_offchain
private: legacy_group
- label: legacy private transaction (run 1)
txDuration: 10
rateControl:
type: fixed-load
opts:
startingTps: 200
transactionLoad: 200
workload:
module: /config/store.js
arguments:
contract: private_storage_offchain
private: legacy_group
- label: public transaction (run 2)
txDuration: 10
rateControl:
type: fixed-load
opts:
startingTps: 200
transactionLoad: 200
workload:
module: /config/store.js
arguments:
contract: public_storage
- label: legacy private transaction (run 2)
txDuration: 10
rateControl:
type: fixed-load
opts:
startingTps: 200
transactionLoad: 200
workload:
module: /config/store.js
arguments:
contract: private_storage_offchain
private: legacy_group

@ -0,0 +1,80 @@
#
# 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: Simple Storage
description: Test private transactions
workers:
type: local
number: 1
rounds:
- label: warm-up (ignore results)
txDuration: 10
rateControl:
type: fixed-load
opts:
startingTps: 200
transactionLoad: 200
workload:
module: /config/store.js
arguments:
contract: private_storage_onchain
private: onchain_group
- label: public transaction (run 1)
txDuration: 10
rateControl:
type: fixed-load
opts:
startingTps: 200
transactionLoad: 200
workload:
module: /config/store.js
arguments:
contract: public_storage
- label: onchain private transaction (run 1)
txDuration: 10
rateControl:
type: fixed-load
opts:
startingTps: 200
transactionLoad: 200
workload:
module: /config/store.js
arguments:
contract: private_storage_onchain
private: onchain_group
- label: public transaction (run 2)
txDuration: 10
rateControl:
type: fixed-load
opts:
startingTps: 200
transactionLoad: 200
workload:
module: /config/store.js
arguments:
contract: public_storage
- label: onchain private transaction (run 2)
txDuration: 10
rateControl:
type: fixed-load
opts:
startingTps: 200
transactionLoad: 200
workload:
module: /config/store.js
arguments:
contract: private_storage_onchain
private: onchain_group

@ -0,0 +1,35 @@
{
"caliper": {
"blockchain": "ethereum"
},
"ethereum": {
"url": "ws://besu:8546",
"contractDeployerAddress": "0xD1cf9D73a91DE6630c2bb068Ba5fDdF9F0DEac09",
"contractDeployerAddressPrivateKey": "0x797c13f7235c627f6bd013dc17fff4c12213ab49abcf091f77c83f16db10e90b",
"fromAddressSeed": "0x3f841bf589fdf83a521e55d51afddc34fa65351161eead24f064855fc29c9580",
"transactionConfirmationBlocks": 1,
"chainId": 48122,
"privacy": {
"legacy_group": {
"groupType": "legacy",
"privateFrom": "GGilEkXLaQ9yhhtbpBT03Me9iYa7U/mWXxrJhnbl1XY=",
"privateFor": ["GGilEkXLaQ9yhhtbpBT03Me9iYa7U/mWXxrJhnbl1XY="]
}
},
"contracts": {
"public_storage": {
"path": "/config/storage.json",
"gas": {
"update": 30000
}
},
"private_storage_offchain": {
"path": "/config/storage.json",
"gas": {
"update": 30000
},
"private": "legacy_group"
}
}
}
}

@ -0,0 +1,35 @@
{
"caliper": {
"blockchain": "ethereum"
},
"ethereum": {
"url": "ws://besu:8546",
"contractDeployerAddress": "0xD1cf9D73a91DE6630c2bb068Ba5fDdF9F0DEac09",
"contractDeployerAddressPrivateKey": "0x797c13f7235c627f6bd013dc17fff4c12213ab49abcf091f77c83f16db10e90b",
"fromAddressSeed": "0x3f841bf589fdf83a521e55d51afddc34fa65351161eead24f064855fc29c9580",
"transactionConfirmationBlocks": 1,
"chainId": 48122,
"privacy": {
"onchain_group": {
"groupType": "onchain",
"privateFrom": "GGilEkXLaQ9yhhtbpBT03Me9iYa7U/mWXxrJhnbl1XY=",
"privateKey": "uTJGpd4ZEEtDPFSZM0+GT11xn5NFIr2KGP2Q4SdVPRM="
}
},
"contracts": {
"public_storage": {
"path": "/config/storage.json",
"gas": {
"update": 30000
}
},
"private_storage_onchain": {
"path": "/config/storage.json",
"gas": {
"update": 30000
},
"private": "onchain_group"
}
}
}
}

@ -0,0 +1,31 @@
#
# 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.
#
caliper:
report:
path: 'report-offchain.html'
benchconfig: caliper-benchconfig.yaml
networkconfig: caliper-networkconfig.json
txupdatetime: 500
workspace: ./
logging:
targets:
console:
target: console
enabled: true
options:
level: info
file:
target: file
enabled: false

@ -0,0 +1,49 @@
#
# 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.
#
caliper:
report:
path: 'report-onchain.html'
benchconfig: caliper-benchconfig.yaml
networkconfig: caliper-networkconfig.json
txupdatetime: 500
workspace: ./
logging:
template: '%timestamp%%level%%module%%message%%metadata%'
formats:
timestamp: 'YYYY.MM.DD-HH:mm:ss.SSS ZZ'
label: false
json: false
pad: true
align: false
attributeformat:
level: ' %attribute%'
module: ' [%attribute%] '
metadata: ' (%attribute%)'
colorize:
all: true
colors:
info: green
error: red
warn: yellow
debug: grey
targets:
console:
target: console
enabled: true
options:
level: info
file:
target: file
enabled: false

@ -0,0 +1,75 @@
{
"config": {
"chainId": 48122,
"berlinblock": 0,
"clique": {
"blockperiodseconds": 1,
"epoch": 30000
}
},
"nonce": "0x0",
"timestamp": "0x5ca916c6",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000c0A8e4D217eB85b812aeb1226fAb6F588943C2C20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x47b760",
"difficulty": "0x1",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0xc0A8e4D217eB85b812aeb1226fAb6F588943C2C2",
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"alloc": {
"0xc0A8e4D217eB85b812aeb1226fAb6F588943C2C2": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
},
"0xD1cf9D73a91DE6630c2bb068Ba5fDdF9F0DEac09": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000",
"privatekey": "0x797c13f7235c627f6bd013dc17fff4c12213ab49abcf091f77c83f16db10e90b",
"derivation": "m/44'/60'/0'/0/0"
},
"0xd826E703658FA2CE8D1018D42E637C08d9846A17": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000",
"privatekey": "0x4be84b298ccb944e96befc4f03b943ec13709f6a8e5b5d8595c486dfa88fd254",
"derivation": "m/44'/60'/1'/0/0"
},
"0x247DdfA00415710E0416f8c103b5E6428782C916": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000",
"privatekey": "0xaa682edca26f3e17889d69276e6c6a4fcf1594af97e48f4dc3ac6dbb29e7924b",
"derivation": "m/44'/60'/2'/0/0"
},
"0x500a8704F86C0d9126Dfb949fDC4dc248c228fB4": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000",
"privatekey": "0x45d09c64e4973b16422b31d5e4a1fbf57ae8fd25037566af8bc1d046022d754b",
"derivation": "m/44'/60'/3'/0/0"
},
"0x32d9ad8F398995fFF658E74430749d65E0ee6702": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000",
"privatekey": "0x2f51f2d881e0a6f7f249139a2afe8da084424616d08aa0ce9fb1c960b49f022f",
"derivation": "m/44'/60'/4'/0/0"
},
"0xd32d3f6dA1664C4ee7acae64fEC3661cEa6ee448": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000",
"privatekey": "0x87abeb4c0230ca6fdf42f7d2cb2baa510856e42f039ab7670b13845e45dc3245",
"derivation": "m/44'/60'/5'/0/0"
},
"0x5F6C5F2431CE84f2Fa84deB6B27A1764DB6feB1a": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000",
"privatekey": "0x5f0ad910e681553c9407582f620d9560541fa8b8c4d03e9e2e3caed5eea6a220",
"derivation": "m/44'/60'/6'/0/0"
},
"0x9fCDe74bf5465D5C32a09f158047803a061B3C1B": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000",
"privatekey": "0x76930906e95c96a9be735b0f182184424f450feca5ea71bf743a8c47ea6e2635",
"derivation": "m/44'/60'/7'/0/0"
},
"0xb582703c0a0e2b598f9362A5e5c17Ab6865b0342": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000",
"privatekey": "0x32e90654e141cb4f92dd9fccef100778c112636b20b9017a9ae56be9a8c2c648",
"derivation": "m/44'/60'/8'/0/0"
},
"0x179740E29B1E7b2C61F6004b8d5caD575D6eaa88": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000",
"privatekey": "0x028bf0ee2807cf9a8d22db99f12aea783a2e6b4897c9ddb7557e33291c7d35c5",
"derivation": "m/44'/60'/9'/0/0"
}
}
}

@ -0,0 +1,37 @@
{
"name": "storage",
"abi": [
{
"constant": false,
"inputs": [
{
"internalType": "uint256",
"name": "_value",
"type": "uint256"
}
],
"name": "update",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "value",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b5060c38061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80633fa4f24514603757806382ab890a146053575b600080fd5b603d607e565b6040518082815260200191505060405180910390f35b607c60048036036020811015606757600080fd5b81019080803590602001909291905050506084565b005b60005481565b806000819055505056fea265627a7a72315820e8496d56b71870b96edb4d71a4fd8101b771c4c269eb0d8ee8c27c6085fa76fc64736f6c63430005110032",
"gas": 3000000
}

@ -0,0 +1,109 @@
/*
* 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 { WorkloadModuleBase } = require('@hyperledger/caliper-core');
const Web3 = require('web3');
class StoreWorkload extends WorkloadModuleBase {
/**
* Initializes the parameters of the workload.
*/
constructor() {
super();
this.txIndex = -1;
this.private = false;
this.contract = {};
}
/**
* Generates simple workload.
* @returns {{verb: String, args: Object[]}[]} Array of workload argument objects.
*/
_generateWorkload() {
let web3 = new Web3(this.nodeUrl);
let workload = [];
for(let i= 0; i < this.roundArguments.txnPerBatch; i++) {
this.txIndex++;
let value = i;
let args = {
contract: this.roundArguments.contract,
verb: 'update',
args: [value],
readOnly: false,
}
if (this.isPrivate) {
args.privacy = this.privacyOpts;
args.privacy.sender = web3.eth.accounts.create();
args.privacy.sender.nonce = 0;
}
workload.push(args);
}
return workload;
}
/**
* Initialize the workload module with the given parameters.
* @param {number} workerIndex The 0-based index of the worker instantiating the workload module.
* @param {number} totalWorkers The total number of workers participating in the round.
* @param {number} roundIndex The 0-based index of the currently executing round.
* @param {Object} roundArguments The user-provided arguments for the round from the benchmark configuration file.
* @param {BlockchainConnector} sutAdapter The adapter of the underlying SUT.
* @param {Object} sutContext The custom context object provided by the SUT adapter.
* @async
*/
async initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext) {
await super.initializeWorkloadModule(workerIndex, totalWorkers, roundIndex, roundArguments, sutAdapter, sutContext);
if (!this.roundArguments.contract) {
throw new Error('store - argument "contract" missing');
}
this.nodeUrl = sutContext.url;
if(this.roundArguments.private) {
this.isPrivate = true;
this.privacyOpts = sutContext.privacy[this.roundArguments.private];
this.privacyOpts['id'] = this.roundArguments.private;
} else {
this.isPrivate = false;
}
if(!this.roundArguments.txnPerBatch) {
this.roundArguments.txnPerBatch = 1;
}
}
/**
* Assemble TXs for opening new accounts.
*/
async submitTransaction() {
let args = this._generateWorkload();
await this.sutAdapter.sendRequests(args);
}
}
function createWorkloadModule() {
return new StoreWorkload();
}
module.exports.createWorkloadModule = createWorkloadModule;

@ -0,0 +1,48 @@
{
"mode": "orion",
"useWhiteList": false,
"jdbc": {
"username": "sa",
"password": "",
"url": "jdbc:h2:/data/tm/db;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=0",
"autoCreateTables": true
},
"serverConfigs": [
{
"app": "ThirdParty",
"serverAddress": "http://tessera:9080",
"communicationType": "REST"
},
{
"app": "Q2T",
"serverAddress": "http://tessera:9101",
"sslConfig": {
"tls": "OFF"
},
"communicationType": "REST"
},
{
"app": "P2P",
"serverAddress": "http://tessera:9000",
"sslConfig": {
"tls": "OFF"
},
"communicationType": "REST"
}
],
"peer": [
{
"url": "http://tessera:9000"
}
],
"keys": {
"passwords": [],
"keyData": [
{
"config": {"data":{"bytes":"uTJGpd4ZEEtDPFSZM0+GT11xn5NFIr2KGP2Q4SdVPRM="},"type":"unlocked"},
"publicKey": "GGilEkXLaQ9yhhtbpBT03Me9iYa7U/mWXxrJhnbl1XY="
}
]
},
"alwaysSendTo": []
}

@ -0,0 +1,109 @@
version: '2'
x-besu:
&besu
container_name: besu
image: "hyperledger/besu:develop"
cpuset: 4-5
environment:
- NODE_INGRESS_CONTRACT_ADDRESS=0x0000000000000000000000000000000000009999
- ACCOUNT_INGRESS_CONTRACT_ADDRESS=0x0000000000000000000000000000000000008888
- BESU_NODE_PERM_ACCOUNT=D1cf9D73a91DE6630c2bb068Ba5fDdF9F0DEac09
- BESU_NODE_PERM_KEY=797c13f7235c627f6bd013dc17fff4c12213ab49abcf091f77c83f16db10e90b
- CHAIN_ID=48122
volumes:
- ./config:/config:ro
x-caliper:
&caliper
container_name: caliper
# TODO: this image is build using the custom branch
# https://github.com/taccatisid/caliper/tree/besu-performance-benchmark-container. Once
# all the changes of this branch are merged into the caliper main
# branch, we should use the official caliper image here.
image: "taccatisid/caliper"
cpuset: 0-3
entrypoint: caliper launch manager
volumes:
- ./config:/config:ro
- ./caliper-benchmarks:/hyperledger/caliper/workspace
services:
caliper-offchain:
<< : *caliper
environment:
- CALIPER_PROJECTCONFIG=/config/caliper-offchain.yaml
- CALIPER_BIND_SUT=besu:latest
- CALIPER_BENCHCONFIG=/config/caliper-benchconfig-offchain.yaml
- CALIPER_NETWORKCONFIG=/config/caliper-networkconfig-offchain.json
depends_on:
besu-offchain:
condition: service_started
tessera:
condition: service_healthy
caliper-onchain:
<< : *caliper
environment:
- CALIPER_PROJECTCONFIG=/config/caliper-onchain.yaml
- CALIPER_BIND_SUT=besu:latest
- CALIPER_BENCHCONFIG=/config/caliper-benchconfig-onchain.yaml
- CALIPER_NETWORKCONFIG=/config/caliper-networkconfig-onchain.json
depends_on:
besu-onchain:
condition: service_started
tessera:
condition: service_healthy
besu-offchain:
<< : *besu
entrypoint:
- /opt/besu/bin/besu
- --genesis-file=/config/genesis.json
- --node-private-key-file=/config/besu-keystore/key
- --min-gas-price=0
- --revert-reason-enabled
- --rpc-ws-enabled
- --rpc-ws-apis=admin,eth,miner,web3,net,priv,eea
- --rpc-ws-host=0.0.0.0
- --host-whitelist=*
- --graphql-http-enabled
- --discovery-enabled=false
- --privacy-enabled=true
- --privacy-url=http://tessera:9101
- --privacy-public-key-file=/config/orion/key/orion.pub
besu-onchain:
<< : *besu
entrypoint:
- /opt/besu/bin/besu
- --genesis-file=/config/genesis.json
- --node-private-key-file=/config/besu-keystore/key
- --min-gas-price=0
- --revert-reason-enabled
- --rpc-ws-enabled
- --rpc-ws-apis=admin,eth,miner,web3,net,priv,eea
- --rpc-ws-host=0.0.0.0
- --host-whitelist=*
- --graphql-http-enabled
- --discovery-enabled=false
- --privacy-enabled=true
- --privacy-url=http://tessera:9101
- --privacy-public-key-file=/config/orion/key/orion.pub
- --privacy-flexible-groups-enabled
tessera:
container_name: tessera
image: quorumengineering/tessera:latest
healthcheck:
test: ["CMD", "wget", "--spider", "--proxy", "off", "http://localhost:9000/upcheck"]
interval: 1s
timeout: 1s
retries: 10
volumes:
- ./config/tessera:/config:ro
entrypoint:
- /bin/sh
- -c
- |
mkdir -p /data/tm/;
/tessera/bin/tessera -configfile /config/config.json

@ -632,6 +632,11 @@ task distDocker {
executable "sh"
args "-c", "docker tag '${imageName}:${dockerBuildVersion}-${dockerVariants[0]}' '${imageName}:${dockerBuildVersion}'"
}
// create a static tag for the benchmark target
exec {
executable "sh"
args "-c", "docker tag '${imageName}:${dockerBuildVersion}-${dockerVariants[0]}' '${imageName}:benchmark'"
}
}
}

Loading…
Cancel
Save