From 3a95bd637c9d5f59ca9bfe4350835b3cd02b02a5 Mon Sep 17 00:00:00 2001 From: "Nicholas J. Paterno" Date: Wed, 24 Jul 2019 17:00:51 -0400 Subject: [PATCH 1/6] Return errors when a tx fails in estimation --- lib/blockchain_double.js | 2 +- lib/utils/gasEstimation.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/blockchain_double.js b/lib/blockchain_double.js index 10ce7d0f83..bd1a802768 100644 --- a/lib/blockchain_double.js +++ b/lib/blockchain_double.js @@ -559,7 +559,7 @@ BlockchainDouble.prototype.estimateGas = function(tx, blockNumber, callback) { return; } - estimateGas(vm, runArgs, err, callback); + estimateGas(vm, runArgs, callback); }); }; diff --git a/lib/utils/gasEstimation.js b/lib/utils/gasEstimation.js index b6eba6df35..5a8d83d21c 100644 --- a/lib/utils/gasEstimation.js +++ b/lib/utils/gasEstimation.js @@ -1,12 +1,18 @@ const STIPEND = 2300; -module.exports = (vm, runArgs, err, callback) => { +module.exports = (vm, runArgs, callback) => { const steps = stepTracker(); vm.on("step", steps.collect); vm.runTx(runArgs, function(vmerr, result) { if (vmerr) { - return callback(vmerr, err); + return callback(vmerr); + } else if (result.vm.exception === 0) { + return callback( + result.vm.exceptionError + ? new Error(`execution error: ${result.vm.exceptionError.error}`) + : new Error("execution error") + ); } else if (steps.done()) { let estimate = result.gasUsed; result.gasEstimate = estimate; From e5de85e9006f3121e09dbcf544f30382795a5a54 Mon Sep 17 00:00:00 2001 From: "Nicholas J. Paterno" Date: Wed, 24 Jul 2019 17:00:51 -0400 Subject: [PATCH 2/6] Return errors when a tx fails in estimation --- lib/blockchain_double.js | 2 +- lib/utils/gasEstimation.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/blockchain_double.js b/lib/blockchain_double.js index 10ce7d0f83..bd1a802768 100644 --- a/lib/blockchain_double.js +++ b/lib/blockchain_double.js @@ -559,7 +559,7 @@ BlockchainDouble.prototype.estimateGas = function(tx, blockNumber, callback) { return; } - estimateGas(vm, runArgs, err, callback); + estimateGas(vm, runArgs, callback); }); }; diff --git a/lib/utils/gasEstimation.js b/lib/utils/gasEstimation.js index b6eba6df35..5a8d83d21c 100644 --- a/lib/utils/gasEstimation.js +++ b/lib/utils/gasEstimation.js @@ -1,12 +1,18 @@ const STIPEND = 2300; -module.exports = (vm, runArgs, err, callback) => { +module.exports = (vm, runArgs, callback) => { const steps = stepTracker(); vm.on("step", steps.collect); vm.runTx(runArgs, function(vmerr, result) { if (vmerr) { - return callback(vmerr, err); + return callback(vmerr); + } else if (result.vm.exception === 0) { + return callback( + result.vm.exceptionError + ? new Error(`execution error: ${result.vm.exceptionError.error}`) + : new Error("execution error") + ); } else if (steps.done()) { let estimate = result.gasUsed; result.gasEstimate = estimate; From b3f8b44a15c9b64ba3b489f5cfddb534df692cba Mon Sep 17 00:00:00 2001 From: David Murdoch Date: Wed, 21 Aug 2019 18:12:57 -0400 Subject: [PATCH 3/6] Add test --- test/gas/gas.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/gas/gas.js b/test/gas/gas.js index 6780113888..d163042ef1 100644 --- a/test/gas/gas.js +++ b/test/gas/gas.js @@ -83,6 +83,23 @@ describe("Gas", function() { } }); + it("Should fail to estimate gas when the transaction is invalid", async() => { + const { accounts, instance, send } = ContractFactory; + const txParams = { + from: accounts[0], + to: instance._address, + data: instance.methods.createInstance().encodeABI(), + // because ContractFactory's `createInstance` method isn't payable + // passing in a `value` will cause the execution to fail with a `revert` + value: 1000 + }; + await assert.rejects( + send("eth_estimateGas", txParams), + /^execution error: revert$/, + "Failling transaction doesn't reject" + ); + }); + it("Should estimate gas perfectly with EIP150 - recursive CALL", async() => { const { accounts, instance, send } = Fib; const txParams = { From 61710e61338713e860f7d0ee49fcf674945bc4f0 Mon Sep 17 00:00:00 2001 From: David Murdoch Date: Wed, 21 Aug 2019 18:43:49 -0400 Subject: [PATCH 4/6] Fix error message in test --- npm-shrinkwrap.json | 3 +-- test/gas/gas.js | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 067988fcec..76bcf7f113 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -12942,7 +12942,7 @@ "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" }, "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1cfbb13862f90f0b391d8a699544d5fe4dfb8c7b", + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#8431eab7b3384e65e8126a4602520b78031666fb", "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.11.8", @@ -13140,7 +13140,6 @@ "requires": { "debug": "^2.2.0", "es5-ext": "^0.10.50", - "gulp": "^4.0.2", "nan": "^2.14.0", "typedarray-to-buffer": "^3.1.5", "yaeti": "^0.0.6" diff --git a/test/gas/gas.js b/test/gas/gas.js index d163042ef1..fca2cc132f 100644 --- a/test/gas/gas.js +++ b/test/gas/gas.js @@ -95,8 +95,8 @@ describe("Gas", function() { }; await assert.rejects( send("eth_estimateGas", txParams), - /^execution error: revert$/, - "Failling transaction doesn't reject" + /^Error: execution error: revert$/, + "Failing transaction doesn't reject" ); }); From 520d3bfce164240da431cfd8b70c335ef25d91b7 Mon Sep 17 00:00:00 2001 From: David Murdoch Date: Wed, 21 Aug 2019 19:32:58 -0400 Subject: [PATCH 5/6] Change error behavior --- lib/provider.js | 5 ++++- lib/utils/gasEstimation.js | 10 +++++----- test/gas/gas.js | 17 ----------------- test/runTimeErrors.js | 16 ++++++++++++++++ 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/lib/provider.js b/lib/provider.js index 8014fd3f33..5b7ac218e4 100644 --- a/lib/provider.js +++ b/lib/provider.js @@ -198,6 +198,9 @@ Provider.prototype.cleanUpErrorObject = function(err, response) { errorObject.error.message = err.message; errorObject.error.data.stack = err.stack; errorObject.error.data.name = err.name; + if ("code" in err) { + errorObject.error.code = err.code; + } } else if (!response.error) { errorObject.error = { message: err.toString() @@ -242,7 +245,7 @@ Provider.prototype.reportErrorInResponse = function(request, err, response) { } } - if (request.method === "eth_call") { + if (request.method === "eth_call" || request.method === "eth_estimateGas") { if (err instanceof RuntimeError) { if (self.options.vmErrorsOnRPCResponse) { if (!response.error.data) { diff --git a/lib/utils/gasEstimation.js b/lib/utils/gasEstimation.js index 5a8d83d21c..6c901ac3a3 100644 --- a/lib/utils/gasEstimation.js +++ b/lib/utils/gasEstimation.js @@ -8,11 +8,11 @@ module.exports = (vm, runArgs, callback) => { if (vmerr) { return callback(vmerr); } else if (result.vm.exception === 0) { - return callback( - result.vm.exceptionError - ? new Error(`execution error: ${result.vm.exceptionError.error}`) - : new Error("execution error") - ); + const error = result.vm.exceptionError + ? new Error(`execution error: ${result.vm.exceptionError.error}`) + : new Error("execution error"); + error.code = -32000; + return callback(error); } else if (steps.done()) { let estimate = result.gasUsed; result.gasEstimate = estimate; diff --git a/test/gas/gas.js b/test/gas/gas.js index fca2cc132f..6780113888 100644 --- a/test/gas/gas.js +++ b/test/gas/gas.js @@ -83,23 +83,6 @@ describe("Gas", function() { } }); - it("Should fail to estimate gas when the transaction is invalid", async() => { - const { accounts, instance, send } = ContractFactory; - const txParams = { - from: accounts[0], - to: instance._address, - data: instance.methods.createInstance().encodeABI(), - // because ContractFactory's `createInstance` method isn't payable - // passing in a `value` will cause the execution to fail with a `revert` - value: 1000 - }; - await assert.rejects( - send("eth_estimateGas", txParams), - /^Error: execution error: revert$/, - "Failing transaction doesn't reject" - ); - }); - it("Should estimate gas perfectly with EIP150 - recursive CALL", async() => { const { accounts, instance, send } = Fib; const txParams = { diff --git a/test/runTimeErrors.js b/test/runTimeErrors.js index 6015adf8bc..cacd300cca 100644 --- a/test/runTimeErrors.js +++ b/test/runTimeErrors.js @@ -38,6 +38,22 @@ function tests(ganacheProviderOptions) { }); }); + it("Should fail to estimate gas when the transaction is invalid", async() => { + const { accounts, instance, send } = context; + const txParams = { + from: accounts[0], + // this errors: + to: instance.options.address + }; + const result = await send("eth_estimateGas", txParams); + assert.deepStrictEqual(result.response.error.code, -32000, "Gas estimation error code is not as expected"); + assert.deepStrictEqual( + result.response.error.message, + "execution error: revert", + "Gas estimation error message is not as expected" + ); + }); + it("should output the transaction hash even if a (out of gas) runtime error occurred", async function() { const { accounts, bytecode, provider, send } = context; From 46437226f7c240b84a21e60e1b7c2d80452bef25 Mon Sep 17 00:00:00 2001 From: David Murdoch Date: Thu, 22 Aug 2019 14:41:08 -0400 Subject: [PATCH 6/6] just triggering a build --- README.md | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 446b929479..2b54594398 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![npm](https://img.shields.io/npm/v/ganache-core.svg)]() -[![npm](https://img.shields.io/npm/dm/ganache-core.svg)]() +[![npm Version](https://img.shields.io/npm/v/ganache-core.svg)](https://www.npmjs.com/package/ganache-core) +[![npm Downloads](https://img.shields.io/npm/dm/ganache-core.svg)](https://www.npmjs.com/package/ganache-core) [![Build Status](https://travis-ci.org/trufflesuite/ganache-core.svg?branch=master)](https://travis-ci.org/trufflesuite/ganache-core) [![Coverage Status](https://coveralls.io/repos/github/trufflesuite/ganache-core/badge.svg?branch=develop)](https://coveralls.io/github/trufflesuite/ganache-core?branch=develop) # Ganache Core diff --git a/package.json b/package.json index c6d7a3cb31..86e91e89f2 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ }, "scripts": { "_mocha": "mocha --check-leaks --recursive --globals _scratch --opts ./test/.mocharc", - "nyc_mocha": "nyc mocha --check-leaks --recursive --globals _scratch --opts ./test/.mocharc", + "nyc_mocha": "nyc npm run _mocha", "_lint": "eslint --ignore-path .gitignore .", "build": "webpack-cli --config ./webpack/node/core.webpack.config.js", "build-web": "webpack-cli --config ./webpack/web-experimental/core.webpack.config.js",