From af8395f64de075e457815e9de8df3a936a44b8b7 Mon Sep 17 00:00:00 2001 From: Ben Burns <803016+benjamincburns@users.noreply.github.com> Date: Tue, 31 Mar 2020 12:07:38 -0700 Subject: [PATCH] ethereum: prevent unnecessary additional requests Web3 has recently added features that lazily fetches missing information when signing and sending transactions. In our case, this was the chainId, and the current gasPrice. Because transactions are submitted asynchronously, these additional requests would sometimes cause transactions to be submitted out of order. Even if this probelm were mitigated, these additional requests added spurious latency spikes to some transactions, negatively impacting the test results. This partially addresses #776 by eliminating request reordering issues for stable websocket connections. This change does not however address transaction reordering for HTTP connections, or for websocket connections that require reconnects. It also does not solve the "christmas tree light" issue w.r.t. nonce errors. Signed-off-by: Ben Burns <803016+benjamincburns@users.noreply.github.com> --- packages/caliper-ethereum/lib/ethereum.js | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/caliper-ethereum/lib/ethereum.js b/packages/caliper-ethereum/lib/ethereum.js index 420b3715e7..776117b680 100644 --- a/packages/caliper-ethereum/lib/ethereum.js +++ b/packages/caliper-ethereum/lib/ethereum.js @@ -101,12 +101,22 @@ class Ethereum extends BlockchainInterface { */ async getContext(name, args) { let context = { + chainId: 1, clientIndex: this.clientIndex, + gasPrice: 0, contracts: {}, nonces: {}, web3: this.web3 }; + context.gasPrice = this.ethereumConfig.gasPrice !== undefined + ? this.ethereumConfig.gasPrice + : await this.web3.eth.getGasPrice(); + + context.chainId = this.ethereumConfig.chainId !== undefined + ? this.ethereumConfig.chainId + : await this.web3.eth.getChainId(); + for (const key of Object.keys(args.contracts)) { context.contracts[key] = { contract: new this.web3.eth.Contract(args.contracts[key].abi, args.contracts[key].address), @@ -212,6 +222,21 @@ class Ethereum extends BlockchainInterface { context.nonces[context.fromAddress] = nonce + 1; params.nonce = nonce; } + + if (context.gasPrice !== undefined) { + // leaving this value unset causes web3 to fetch gasPrice on the + // fly this can cause transactions to be reordered, which in + // turn causes nonce failures + params.gasPrice = context.gasPrice; + } + + if (context.chainId !== undefined) { + // leaving this value unset causes web3 to fetch chainId on the + // fly this can cause transactions to be reordered, which in + // turn causes nonce failures + params.chainId = context.chainId; + } + if (methodCall.args) { if (contractInfo.gas && contractInfo.gas[methodCall.verb]) { params.gas = contractInfo.gas[methodCall.verb];