From f4719818e92d508d79feaa7d90b573b18f04f25e Mon Sep 17 00:00:00 2001 From: Samuel Furter Date: Wed, 16 Oct 2019 16:04:39 +0900 Subject: [PATCH] receipt is missing on error event (#3129) * receipt added for error event listener on sending of a transaction * packages updated in package-lock because of security warnings from npm * passing of parameters to _fireError updated in Method object of the web3-core-method module * CHANGELOG.md updated * documentation for sendTransaction and contract.methods.myMethod.send() updated * Update packages/web3-core-method/src/index.js Co-Authored-By: cgewecke * Update docs/web3-eth.rst Co-Authored-By: cgewecke * wrongly passed parameters for the _fireError function fixed * Update docs/web3-eth-contract.rst Co-Authored-By: cgewecke --- CHANGELOG.md | 1 + docs/web3-eth-contract.rst | 2 +- docs/web3-eth.rst | 2 +- package-lock.json | 104 ++++++++++++------------- packages/web3-core-method/src/index.js | 55 ++++++++++--- packages/web3-utils/src/index.js | 7 +- 6 files changed, 102 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7b997fa2ed..17de47e063a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,3 +74,4 @@ Released with 1.0.0-beta.37 code base. - Gas check fixed (#2381) - Signing issues #1998, #2033, and #1074 fixed (#3125) - Fix hexToNumber and hexToNumberString prefix validation (#3086) +- The receipt will now returned on a EVM error (this got removed on beta.18) (#3129) diff --git a/docs/web3-eth-contract.rst b/docs/web3-eth-contract.rst index de710fba48c..98e7e756ea2 100644 --- a/docs/web3-eth-contract.rst +++ b/docs/web3-eth-contract.rst @@ -543,7 +543,7 @@ The **callback** will return the 32 bytes transaction hash. - ``"transactionHash"`` returns ``String``: is fired right after the transaction is sent and a transaction hash is available. - ``"receipt"`` returns ``Object``: is fired when the transaction *receipt* is available. Receipts from contracts will have no ``logs`` property, but instead an ``events`` property with event names as keys and events as properties. See :ref:`getPastEvents return values ` for details about the returned event object. - ``"confirmation"`` returns ``Number``, ``Object``: is fired for every confirmation up to the 24th confirmation. Receives the confirmation number as the first and the receipt as the second argument. Fired from confirmation 1 on, which is the block where it's minded. -- ``"error"`` returns ``Error``: is fired if an error occurs during sending. If a out of gas error, the second parameter is the receipt. +``"error"`` returns ``Error`` and ``Object|undefined``: Is fired if an error occurs during sending. If the transaction was rejected by the network with a receipt, the second parameter will be the receipt. ------- diff --git a/docs/web3-eth.rst b/docs/web3-eth.rst index 6b86ab07ffe..a35450e03fa 100644 --- a/docs/web3-eth.rst +++ b/docs/web3-eth.rst @@ -1010,7 +1010,7 @@ The **callback** will return the 32 bytes transaction hash. - ``"transactionHash"`` returns ``String``: Is fired right after the transaction is sent and a transaction hash is available. - ``"receipt"`` returns ``Object``: Is fired when the transaction receipt is available. - ``"confirmation"`` returns ``Number``, ``Object``: Is fired for every confirmation up to the 12th confirmation. Receives the confirmation number as the first and the :ref:`receipt ` as the second argument. Fired from confirmation 0 on, which is the block where its minded. -- ``"error"`` returns ``Error``: Is fired if an error occurs during sending. If a out of gas error, the second parameter is the receipt. +``"error"`` returns ``Error`` and ``Object|undefined``: Is fired if an error occurs during sending. If the transaction was rejected by the network with a receipt, the second parameter will be the receipt. ------- diff --git a/package-lock.json b/package-lock.json index d9f460f0ead..646f880cf42 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4424,7 +4424,8 @@ "version": "2.1.1", "resolved": false, "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4448,13 +4449,15 @@ "version": "1.0.0", "resolved": false, "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4471,19 +4474,22 @@ "version": "1.1.0", "resolved": false, "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "resolved": false, "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -4614,7 +4620,8 @@ "version": "2.0.3", "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -4628,6 +4635,7 @@ "resolved": false, "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4644,6 +4652,7 @@ "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4652,13 +4661,15 @@ "version": "0.0.8", "resolved": false, "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "resolved": false, "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -4679,6 +4690,7 @@ "resolved": false, "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -4767,7 +4779,8 @@ "version": "1.0.1", "resolved": false, "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -4781,6 +4794,7 @@ "resolved": false, "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -4876,7 +4890,8 @@ "version": "5.1.2", "resolved": false, "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -4918,6 +4933,7 @@ "resolved": false, "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4939,6 +4955,7 @@ "resolved": false, "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4987,13 +5004,15 @@ "version": "1.0.2", "resolved": false, "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "resolved": false, "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true + "dev": true, + "optional": true } } }, @@ -6509,9 +6528,9 @@ } }, "handlebars": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", - "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.3.tgz", + "integrity": "sha512-B0W4A2U1ww3q7VVthTKfh+epHx+q4mCt6iK+zEAzbMBpWQAwxCeKxEGpj/1oQTpzPXDNSOG7hmG14TsISH50yw==", "dev": true, "requires": { "neo-async": "^2.6.0", @@ -8084,9 +8103,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, "lodash._reinterpolate": { @@ -8120,9 +8139,9 @@ "dev": true }, "lodash.merge": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", - "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "lodash.template": { @@ -8597,9 +8616,9 @@ } }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -10633,9 +10652,9 @@ "dev": true }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -11749,38 +11768,15 @@ "dev": true }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "unique-stream": { @@ -12515,7 +12511,7 @@ "requires": { "underscore": "1.9.1", "web3-core-helpers": "1.2.1", - "websocket": "github:web3-js/WebSocket-Node#905deb4812572b344f5801f8c9ce8bb02799d82e" + "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis" } }, "web3-shh": { diff --git a/packages/web3-core-method/src/index.js b/packages/web3-core-method/src/index.js index a67c62a2dcc..6948332214f 100644 --- a/packages/web3-core-method/src/index.js +++ b/packages/web3-core-method/src/index.js @@ -257,7 +257,14 @@ Method.prototype._confirmTransaction = function (defer, result, payload) { .catch(function (err) { sub.unsubscribe(); promiseResolved = true; - utils._fireError({message: 'Failed to check for transaction receipt:', data: err}, defer.eventEmitter, defer.reject); + utils._fireError( + { + message: 'Failed to check for transaction receipt:', + data: err + }, + defer.eventEmitter, + defer.reject + ); }) // if CONFIRMATION listener exists check for confirmations, by setting canUnsubscribe = false .then(function(receipt) { @@ -303,7 +310,13 @@ Method.prototype._confirmTransaction = function (defer, result, payload) { promiseResolved = true; } - utils._fireError(new Error('The transaction receipt didn\'t contain a contract address.'), defer.eventEmitter, defer.reject); + utils._fireError( + new Error('The transaction receipt didn\'t contain a contract address.'), + defer.eventEmitter, + defer.reject, + null, + receipt + ); return; } @@ -330,7 +343,13 @@ Method.prototype._confirmTransaction = function (defer, result, payload) { } } else { - utils._fireError(new Error('The contract code couldn\'t be stored, please check your gas limit.'), defer.eventEmitter, defer.reject); + utils._fireError( + new Error('The contract code couldn\'t be stored, please check your gas limit.'), + defer.eventEmitter, + defer.reject, + null, + receipt + ); } if (canUnsubscribe) { @@ -344,9 +363,7 @@ Method.prototype._confirmTransaction = function (defer, result, payload) { }) // CHECK for normal tx check for receipt only .then(function(receipt) { - if (!isContractDeployment && !promiseResolved) { - if(!receipt.outOfGas && (!gasProvided || gasProvided !== utils.numberToHex(receipt.gasUsed)) && (receipt.status === true || receipt.status === '0x1' || typeof receipt.status === 'undefined')) { @@ -360,13 +377,23 @@ Method.prototype._confirmTransaction = function (defer, result, payload) { } else { receiptJSON = JSON.stringify(receipt, null, 2); + if (receipt.status === false || receipt.status === '0x0') { - utils._fireError(new Error("Transaction has been reverted by the EVM:\n" + receiptJSON), - defer.eventEmitter, defer.reject); + utils._fireError( + new Error("Transaction has been reverted by the EVM:\n" + receiptJSON), + defer.eventEmitter, + defer.reject, + null, + receipt + ); } else { utils._fireError( new Error("Transaction ran out of gas. Please provide more gas:\n" + receiptJSON), - defer.eventEmitter, defer.reject); + defer.eventEmitter, + defer.reject, + null, + receipt + ); } } @@ -387,13 +414,21 @@ Method.prototype._confirmTransaction = function (defer, result, payload) { if (timeoutCount - 1 >= POLLINGTIMEOUT) { sub.unsubscribe(); promiseResolved = true; - utils._fireError(new Error('Transaction was not mined within' + POLLINGTIMEOUT + ' seconds, please make sure your transaction was properly sent. Be aware that it might still be mined!'), defer.eventEmitter, defer.reject); + utils._fireError( + new Error('Transaction was not mined within ' + POLLINGTIMEOUT + ' seconds, please make sure your transaction was properly sent. Be aware that it might still be mined!'), + defer.eventEmitter, + defer.reject + ); } } else { if (timeoutCount - 1 >= TIMEOUTBLOCK) { sub.unsubscribe(); promiseResolved = true; - utils._fireError(new Error('Transaction was not mined within 50 blocks, please make sure your transaction was properly sent. Be aware that it might still be mined!'), defer.eventEmitter, defer.reject); + utils._fireError( + new Error('Transaction was not mined within 50 blocks, please make sure your transaction was properly sent. Be aware that it might still be mined!'), + defer.eventEmitter, + defer.reject + ); } } }); diff --git a/packages/web3-utils/src/index.js b/packages/web3-utils/src/index.js index 2736c07ef25..a1e3758d02b 100644 --- a/packages/web3-utils/src/index.js +++ b/packages/web3-utils/src/index.js @@ -38,9 +38,10 @@ var randombytes = require('randombytes'); * @param {Object} emitter * @param {Function} reject * @param {Function} callback + * @param {any} optionalData * @return {Object} the emitter */ -var _fireError = function (error, emitter, reject, callback) { +var _fireError = function (error, emitter, reject, callback, optionalData) { /*jshint maxcomplexity: 10 */ // add data if given @@ -57,7 +58,7 @@ var _fireError = function (error, emitter, reject, callback) { } if (_.isFunction(callback)) { - callback(error); + callback(error, optionalData); } if (_.isFunction(reject)) { // suppress uncatched error if an error listener is present @@ -76,7 +77,7 @@ var _fireError = function (error, emitter, reject, callback) { if(emitter && _.isFunction(emitter.emit)) { // emit later, to be able to return emitter setTimeout(function () { - emitter.emit('error', error); + emitter.emit('error', error, optionalData); emitter.removeAllListeners(); }, 1); }