diff --git a/package.json b/package.json index 067a5befe5e..3294e4fae89 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "gulp-uglify": "^3.0.0", "istanbul": "^0.4.4", "jshint": ">=2.5.0", - "lerna": "^2.0.0", + "lerna": "^2.5.1", "mocha": ">=2.3.3", "sandboxed-module": "^2.0.2", "underscore": "^1.8.3", diff --git a/packages/web3-core-requestmanager/src/index.js b/packages/web3-core-requestmanager/src/index.js index 72c9a1e30b8..9a0dbc78069 100644 --- a/packages/web3-core-requestmanager/src/index.js +++ b/packages/web3-core-requestmanager/src/index.js @@ -158,7 +158,7 @@ RequestManager.prototype.sendBatch = function (data, callback) { } var payload = Jsonrpc.toBatchPayload(data); - this.provider.send(payload, function (err, results) { + this.provider[this.provider.sendAsync ? 'sendAsync' : 'send'](payload, function (err, results) { if (err) { return callback(err); } @@ -241,4 +241,3 @@ module.exports = { Manager: RequestManager, BatchManager: BatchManager }; - diff --git a/packages/web3-eth-abi/src/formatters.js b/packages/web3-eth-abi/src/formatters.js index 2985880622d..600e563158c 100644 --- a/packages/web3-eth-abi/src/formatters.js +++ b/packages/web3-eth-abi/src/formatters.js @@ -142,7 +142,11 @@ var signedIsNegative = function (value) { * @returns {BN} right-aligned output bytes formatted to big number */ var formatOutputInt = function (param) { - var value = param.staticPart() || "0"; + var value = param.staticPart(); + + if(!value && !param.rawValue) { + throw new Error('Couldn\'t decode '+ name +' from ABI: 0x'+ param.rawValue); + } // check if it's negative number // it it is, return two's complement @@ -162,7 +166,7 @@ var formatOutputInt = function (param) { var formatOutputUInt = function (param, name) { var value = param.staticPart(); - if(!value && param.rawValue) { + if(!value && !param.rawValue) { throw new Error('Couldn\'t decode '+ name +' from ABI: 0x'+ param.rawValue); } @@ -176,12 +180,13 @@ var formatOutputUInt = function (param, name) { * * @method formatOutputBool * @param {SolidityParam} param + * @param {String} name type name * @returns {Boolean} right-aligned input bytes formatted to bool */ var formatOutputBool = function (param, name) { var value = param.staticPart(); - if(!value) { + if(!value && !param.rawValue) { throw new Error('Couldn\'t decode '+ name +' from ABI: 0x'+ param.rawValue); } @@ -212,10 +217,17 @@ var formatOutputBytes = function (param, name) { * * @method formatOutputDynamicBytes * @param {SolidityParam} param left-aligned hex representation of string + * @param {String} name type name * @returns {String} hex string */ -var formatOutputDynamicBytes = function (param) { - var length = (new BN(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2; +var formatOutputDynamicBytes = function (param, name) { + var hex = param.dynamicPart().slice(0, 64); + + if (!hex) { + throw new Error('Couldn\'t decode '+ name +' from ABI: 0x'+ param.rawValue); + } + + var length = (new BN(hex, 16)).toNumber() * 2; return '0x' + param.dynamicPart().substr(64, length); }; @@ -228,23 +240,30 @@ var formatOutputDynamicBytes = function (param) { */ var formatOutputString = function (param) { var hex = param.dynamicPart().slice(0, 64); - if(hex) { - var length = (new BN(hex, 16)).toNumber() * 2; - return length ? utils.hexToUtf8('0x'+ param.dynamicPart().substr(64, length).replace(/^0x/i, '')) : ''; - } else { + + if(!hex) { throw new Error('ERROR: The returned value is not a convertible string:'+ hex); } + + var length = (new BN(hex, 16)).toNumber() * 2; + return length ? utils.hexToUtf8('0x'+ param.dynamicPart().substr(64, length).replace(/^0x/i, '')) : ''; }; /** * Should be used to format output address * * @method formatOutputAddress - * @param {Object} param right-aligned input bytes + * @param {SolidityParam} param right-aligned input bytes + * @param {String} name type name * @returns {String} address */ -var formatOutputAddress = function (param) { +var formatOutputAddress = function (param, name) { var value = param.staticPart(); + + if (!value) { + throw new Error('Couldn\'t decode '+ name +' from ABI: 0x'+ param.rawValue); + } + return utils.toChecksumAddress("0x" + value.slice(value.length - 40, value.length)); }; diff --git a/packages/web3-providers-ws/src/index.js b/packages/web3-providers-ws/src/index.js index 29fe4ce6a43..0f2a4e1b62a 100644 --- a/packages/web3-providers-ws/src/index.js +++ b/packages/web3-providers-ws/src/index.js @@ -216,6 +216,7 @@ WebsocketProvider.prototype.send = function (payload, callback) { } else { console.error('no error callback'); } + callback(new Error('connection not open')); return; } diff --git a/test/batch.js b/test/batch.js index 313f2922cc2..187a5dda1ad 100644 --- a/test/batch.js +++ b/test/batch.js @@ -237,6 +237,47 @@ describe('lib/web3/batch', function () { provider.injectBatchResults([result, result2], true); // injects error batch.execute(); }); + + it('should execute batch request with provider that supports sendAsync', function (done) { + + var provider = new FakeIpcProvider(); + var web3 = new Web3(provider); + + provider.sendAsync = provider.send + provider.send = () => { throw new Error('send was called instead of sendAsync') } + var result = '0x126'; + var resultVal = '294'; + var result2 = '0x127'; + var result2Val = '295'; + provider.injectBatchResults([result, result2]); + + var counter = 0; + var callback = function (err, r) { + counter++; + assert.deepEqual(r, resultVal); + }; + + var callback2 = function (err, r) { + assert.equal(counter, 1); + assert.deepEqual(r, result2Val); + done(); + }; + + provider.injectValidation(function (payload) { + var first = payload[0]; + var second = payload[1]; + + assert.equal(first.method, 'eth_getBalance'); + assert.deepEqual(first.params, ['0x0000000000000000000000000000000000000000', 'latest']); + assert.equal(second.method, 'eth_getBalance'); + assert.deepEqual(second.params, ['0x0000000000000000000000000000000000000005', 'latest']); + }); + + var batch = new web3.BatchRequest(); + batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); + batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000005', 'latest', callback2)); + batch.execute(); + }); + }); }); - diff --git a/test/eth.abi.decodeParameters.js b/test/eth.abi.decodeParameters.js index 34de205e682..56a1238ad72 100644 --- a/test/eth.abi.decodeParameters.js +++ b/test/eth.abi.decodeParameters.js @@ -25,6 +25,27 @@ var tests = [{ myNumber: '234', "__length__": 2 } +},{ + params: [['string'], '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'], + result: {'0': "", "__length__": 1} +},{ + params: [['int256'], '0x0000000000000000000000000000000000000000000000000000000000000000'], + result: {'0': "0", "__length__": 1} +},{ + params: [['uint256'], '0x0000000000000000000000000000000000000000000000000000000000000000'], + result: {'0': "0", "__length__": 1} +},{ + params: [['bytes'], '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'], + result: {'0': null, "__length__": 1} +},{ + params: [['address'], '0x0000000000000000000000000000000000000000000000000000000000000000'], + result: {'0': "0x0000000000000000000000000000000000000000", "__length__": 1} +},{ + params: [['bytes32'], '0x0000000000000000000000000000000000000000000000000000000000000000'], + result: {'0': "0x0000000000000000000000000000000000000000000000000000000000000000", "__length__": 1} +},{ + params: [['bool'], '0x0000000000000000000000000000000000000000000000000000000000000000'], + result: {'0': false, "__length__": 1} }]; describe('decodeParameters', function () { @@ -34,3 +55,38 @@ describe('decodeParameters', function () { }); }); }); + + +var failures = [{ + params: [['string', 'uint256'], '0x'] +},{ + params: [[{ + type: 'string', + name: 'myString' + },{ + type: 'uint256', + name: 'myNumber' + }], '0x'] +},{ + params: [['string'], '0x'] +},{ + params: [['int256'], '0x'] +},{ + params: [['uint256'], '0x'] +},{ + params: [['bytes'], '0x'] +},{ + params: [['address'], '0x'] +},{ + params: [['bytes32'], '0x'] +},{ + params: [['bool'], '0x'] +}]; + +describe('decodeParameters', function () { + failures.forEach(function (test) { + it('should not convert '+test.params[1]+' to '+test.params[0], function () { + assert.throws(_ => {web3.eth.abi.decodeParameters.apply(web3.eth.abi, test.params)}); + }); + }); +});