diff --git a/packages/caliper-ethereum/lib/ethereum.js b/packages/caliper-ethereum/lib/ethereum.js index 50fb1e12d..738c9c69b 100644 --- a/packages/caliper-ethereum/lib/ethereum.js +++ b/packages/caliper-ethereum/lib/ethereum.js @@ -52,7 +52,11 @@ class Ethereum extends BlockchainInterface { * @return {object} Promise True if the account got unlocked successful otherwise false. */ init() { - return this.web3.eth.personal.unlockAccount(this.ethereumConfig.contractDeployerAddress, this.ethereumConfig.contractDeployerAddressPassword, 1000); + if (this.ethereumConfig.contractDeployerAddressPrivateKey) { + this.web3.eth.accounts.wallet.add(this.ethereumConfig.contractDeployerAddressPrivateKey); + } else if (this.ethereumConfig.contractDeployerAddressPassword) { + return this.web3.eth.personal.unlockAccount(this.ethereumConfig.contractDeployerAddress, this.ethereumConfig.contractDeployerAddressPassword, 1000); + } } /** @@ -90,7 +94,13 @@ class Ethereum extends BlockchainInterface { for (const key of Object.keys(args.contracts)) { context.contracts[key] = new this.web3.eth.Contract(args.contracts[key].abi, args.contracts[key].address); } - await context.web3.eth.personal.unlockAccount(this.ethereumConfig.fromAddress, this.ethereumConfig.fromAddressPassword, 1000); + context.nonces = {}; + context.nonces[this.ethereumConfig.fromAddress] = await this.web3.eth.getTransactionCount(this.ethereumConfig.fromAddress); + if (this.ethereumConfig.fromAddressPrivateKey) { + this.web3.eth.accounts.wallet.add(this.ethereumConfig.fromAddressPrivateKey); + } else if (this.ethereumConfig.fromAddressPassword) { + await context.web3.eth.personal.unlockAccount(this.ethereumConfig.fromAddress, this.ethereumConfig.fromAddressPassword, 1000); + } return context; } @@ -161,17 +171,24 @@ class Ethereum extends BlockchainInterface { */ async sendTransaction(context, contractID, contractVer, methodCall, timeout) { let status = new TxStatus(); + let params = {from: context.fromAddress}; try { context.engine.submitCallback(1); let receipt = null; let methodType = 'send'; if (methodCall.isView) { methodType = 'call'; + } else { + let nonce = context.nonces[context.fromAddress]; + context.nonces[context.fromAddress] = nonce + 1; + params.nonce = nonce; } if (methodCall.args) { - receipt = await context.contracts[contractID].methods[methodCall.verb](...methodCall.args)[methodType]({from: context.fromAddress}); + params.gas = 1000 + await context.contracts[contractID].methods[methodCall.verb](...methodCall.args).estimateGas(); + receipt = await context.contracts[contractID].methods[methodCall.verb](...methodCall.args)[methodType](params); } else { - receipt = await context.contracts[contractID].methods[methodCall.verb]()[methodType]({from: context.fromAddress}); + params.gas = 1000 + await context.contracts[contractID].methods[methodCall.verb].estimateGas(params); + receipt = await context.contracts[contractID].methods[methodCall.verb]()[methodType](params); } status.SetID(receipt.transactionHash); status.SetResult(receipt); @@ -179,7 +196,7 @@ class Ethereum extends BlockchainInterface { status.SetStatusSuccess(); } catch (err) { status.SetStatusFail(); - logger.error('Failed tx on ' + contractID + ' calling method ' + methodCall.verb); + logger.error('Failed tx on ' + contractID + ' calling method ' + methodCall.verb + ' nonce ' + params.nonce); logger.error(err); } return Promise.resolve(status); diff --git a/packages/caliper-samples/network/besu/1node-clique/Dockerfile b/packages/caliper-samples/network/besu/1node-clique/Dockerfile new file mode 100644 index 000000000..395046028 --- /dev/null +++ b/packages/caliper-samples/network/besu/1node-clique/Dockerfile @@ -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. + +FROM hyperledger/besu:latest +COPY ./data/ /root/ +VOLUME [ "/root/.ethereum/keystore/" ] +ENTRYPOINT [ "/opt/besu/bin/besu", "--genesis-file=/root/genesis.json", "--node-private-key-file=/root/.ethereum/keystore/key" ] diff --git a/packages/caliper-samples/network/besu/1node-clique/data/genesis.json b/packages/caliper-samples/network/besu/1node-clique/data/genesis.json new file mode 100644 index 000000000..565f5b0d6 --- /dev/null +++ b/packages/caliper-samples/network/besu/1node-clique/data/genesis.json @@ -0,0 +1,31 @@ +{ + "config": { + "chainId": 48122, + "homesteadBlock": 1, + "eip150Block": 2, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 3, + "eip158Block": 3, + "byzantiumBlock": 4, + "constantinopleBlock": 5, + "clique": { + "blockperiodseconds": 5, + "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" + } + } +} diff --git a/packages/caliper-samples/network/besu/1node-clique/docker-compose.yml b/packages/caliper-samples/network/besu/1node-clique/docker-compose.yml new file mode 100644 index 000000000..cc0fca116 --- /dev/null +++ b/packages/caliper-samples/network/besu/1node-clique/docker-compose.yml @@ -0,0 +1,25 @@ +# +# 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. +# + +version: "3" +services: + node: + build: . + image: caliper-besu-clique + container_name: besu_clique + volumes: + - ./keys:/root/.ethereum/keystore + ports: + - 8545-8547:8545-8547 + command: --revert-reason-enabled --rpc-http-enabled --rpc-http-host 0.0.0.0 --host-whitelist=* --rpc-http-apis admin,eth,miner,web3,net --graphql-http-enabled --discovery-enabled=false \ No newline at end of file diff --git a/packages/caliper-samples/network/besu/1node-clique/ethereum.json b/packages/caliper-samples/network/besu/1node-clique/ethereum.json new file mode 100644 index 000000000..c65f1db10 --- /dev/null +++ b/packages/caliper-samples/network/besu/1node-clique/ethereum.json @@ -0,0 +1,22 @@ +{ + "caliper": { + "blockchain": "ethereum", + "command" : { + "start": "docker-compose -f network/besu/1node-clique/docker-compose.yml up -d && sleep 10", + "end" : "docker-compose -f network/besu/1node-clique/docker-compose.yml down" + } + }, + "ethereum": { + "url": "http://localhost:8545", + "contractDeployerAddress": "0xc0A8e4D217eB85b812aeb1226fAb6F588943C2C2", + "contractDeployerAddressPrivateKey": "0xa67bee5d6fb43acd42e307eb67547ab5006ad2fbb9567829e9b4b2ef3580acea", + "fromAddress": "0xc0A8e4D217eB85b812aeb1226fAb6F588943C2C2", + "fromAddressPrivateKey": "0xa67bee5d6fb43acd42e307eb67547ab5006ad2fbb9567829e9b4b2ef3580acea", + "transactionConfirmationBlocks": 2, + "contracts": { + "simple": { + "path": "src/contract/ethereum/simple/simple.json" + } + } + } +} \ No newline at end of file diff --git a/packages/caliper-samples/network/besu/1node-clique/keys/key b/packages/caliper-samples/network/besu/1node-clique/keys/key new file mode 100644 index 000000000..ba5d3af1a --- /dev/null +++ b/packages/caliper-samples/network/besu/1node-clique/keys/key @@ -0,0 +1 @@ +0xa67bee5d6fb43acd42e307eb67547ab5006ad2fbb9567829e9b4b2ef3580acea \ No newline at end of file diff --git a/packages/caliper-samples/package.json b/packages/caliper-samples/package.json index c1a50381a..2eba07fb1 100644 --- a/packages/caliper-samples/package.json +++ b/packages/caliper-samples/package.json @@ -30,8 +30,9 @@ "coverage", "log", "benchmark/smallbank/.Rhistory", + "network/besu/1node-clique/keys", + "network/besu/1node-clique/Dockerfile", "network/burrow/simple/chain/keys/names", - "network/sawtooth/simplenetwork/Dockerfile", "network/ethereum/1node/keys", "network/ethereum/1node/Dockerfile", "network/ethereum/1node-clique/keys", @@ -44,6 +45,7 @@ "network/fabric-v1.4/kafka/config/.gitignore", "network/fabric-v1.4.1/config/.gitignore", "network/fabric-v1.4.1/raft/config/.gitignore", + "network/sawtooth/simplenetwork/Dockerfile", "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"