From 3d447ded79c3f329cb1a0e8f1eec62b68e4fa2a5 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Thu, 30 Apr 2015 11:20:09 -0400 Subject: [PATCH] Update bn.js to 2.0.4 to handle 53 bit precision number input. --- lib/transaction/output.js | 8 +++-- lib/transaction/transaction.js | 14 ++++++-- lib/util/js.js | 4 +-- npm-shrinkwrap.json | 63 +++++++++++++-------------------- package.json | 4 +-- test/transaction/deserialize.js | 24 +++++++------ test/transaction/output.js | 8 ++--- test/util/js.js | 18 +++++----- 8 files changed, 73 insertions(+), 70 deletions(-) diff --git a/lib/transaction/output.js b/lib/transaction/output.js index 66385fc68..20823f353 100644 --- a/lib/transaction/output.js +++ b/lib/transaction/output.js @@ -48,12 +48,16 @@ Object.defineProperty(Output.prototype, 'satoshis', { this._satoshis = parseInt(num); this._satoshisBN = BN.fromNumber(this._satoshis); } else { + $.checkArgument( + JSUtil.isNaturalNumber(num), + 'Output satoshis is not a natural number' + ); this._satoshisBN = BN.fromNumber(num); this._satoshis = num; } $.checkState( - JSUtil.isPositiveInteger(this._satoshis), - 'Output satoshis is not a positive integer' + JSUtil.isNaturalNumber(this._satoshis), + 'Output satoshis is not a natural number' ); } }); diff --git a/lib/transaction/transaction.js b/lib/transaction/transaction.js index 1b1b9862e..d75d17ceb 100644 --- a/lib/transaction/transaction.js +++ b/lib/transaction/transaction.js @@ -60,6 +60,7 @@ function Transaction(serialized) { var CURRENT_VERSION = 1; var DEFAULT_NLOCKTIME = 0; +var MAX_SAFE_INTEGER = 0x1fffffffffffff; // Minimum amount for an output for it not to be considered a dust output Transaction.DUST_AMOUNT = 546; @@ -644,7 +645,7 @@ Transaction.prototype.getChangeOutput = function() { */ Transaction.prototype.to = function(address, amount) { $.checkArgument( - JSUtil.isPositiveInteger(amount), + JSUtil.isNaturalNumber(amount), 'Amount is expected to be a positive integer' ); this.addOutput(new Output({ @@ -990,7 +991,16 @@ Transaction.prototype.verify = function() { var valueoutbn = new BN(0); for (var i = 0; i < this.outputs.length; i++) { var txout = this.outputs[i]; - var valuebn = txout._satoshisBN; + + if (txout._satoshis > MAX_SAFE_INTEGER) { + return 'transaction txout ' + i + ' satoshis greater than max safe integer'; + } + + if (txout._satoshis !== txout._satoshisBN.toNumber()) { + return 'transaction txout ' + i + ' satoshis has corrupted value'; + } + + var valuebn = new BN(txout._satoshis, 10); if (valuebn.lt(BN.Zero)) { return 'transaction txout ' + i + ' negative'; } diff --git a/lib/util/js.js b/lib/util/js.js index 02fe4f4c7..c53e1e172 100644 --- a/lib/util/js.js +++ b/lib/util/js.js @@ -70,12 +70,12 @@ module.exports = { return target; }, /** - * Checks that a value is a positive integer + * Checks that a value is a natural number, a positive integer or zero. * * @param {*} value * @return {Boolean} */ - isPositiveInteger: function isPositiveInteger(value) { + isNaturalNumber: function isNaturalNumber(value) { return typeof value === 'number' && isFinite(value) && Math.floor(value) === value && diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 8c35dc91a..1818acf60 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,63 +1,48 @@ { "name": "bitcore", - "version": "0.9.0", + "version": "0.12.3", "dependencies": { "bn.js": { - "version": "0.16.1", - "from": "bn.js@0.16.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-0.16.1.tgz" + "version": "2.0.4", + "from": "bn.js@=2.0.4", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-2.0.4.tgz" }, "bs58": { "version": "2.0.0", - "from": "bs58@2.0.0", + "from": "bs58@=2.0.0", "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.0.tgz" }, "elliptic": { - "version": "0.16.0", - "from": "elliptic@0.16.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-0.16.0.tgz", + "version": "3.0.3", + "from": "elliptic@=3.0.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-3.0.3.tgz", "dependencies": { - "bn.js": { - "version": "0.16.1", - "from": "bn.js@0.16.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-0.16.1.tgz" - }, "brorand": { - "version": "1.0.1", - "from": "brorand@1.0.1", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.0.1.tgz" + "version": "1.0.5", + "from": "brorand@^1.0.1", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.0.5.tgz" }, "hash.js": { - "version": "0.3.2", - "from": "hash.js@0.3.2", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-0.3.2.tgz" - }, - "inherits": { - "version": "2.0.1", - "from": "inherits@^2.0.1" + "version": "1.0.2", + "from": "hash.js@^1.0.0", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.2.tgz" } } }, - "inherits": { - "version": "2.0.1", - "from": "inherits@2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, "hash.js": { "version": "0.3.2", - "from": "hash.js@0.3.2", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-0.3.2.tgz", - "dependencies": { - "inherits": { - "version": "2.0.1", - "from": "inherits@^2.0.1" - } - } + "from": "hash.js@=0.3.2", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-0.3.2.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@=2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "lodash": { - "version": "2.4.1", - "from": "lodash@=2.4.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz" + "version": "2.4.1", + "from": "lodash@=2.4.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz" }, "sha512": { "version": "0.0.1", diff --git a/package.json b/package.json index bebfdec6d..61ee6fc72 100644 --- a/package.json +++ b/package.json @@ -79,9 +79,9 @@ "request": "browser-request" }, "dependencies": { - "bn.js": "=0.16.1", + "bn.js": "=2.0.4", "bs58": "=2.0.0", - "elliptic": "=0.16.0", + "elliptic": "=3.0.3", "hash.js": "=0.3.2", "inherits": "=2.0.1", "lodash": "=2.4.1", diff --git a/test/transaction/deserialize.js b/test/transaction/deserialize.js index 28993d9b8..e9f43b8db 100644 --- a/test/transaction/deserialize.js +++ b/test/transaction/deserialize.js @@ -10,21 +10,25 @@ describe('Transaction deserialization', function() { describe('valid transaction test case', function() { var index = 0; vectors_valid.forEach(function(vector) { - if (vector.length > 1) { - var hexa = vector[1]; - Transaction(hexa).serialize(true).should.equal(hexa); - index++; - } + it('vector #' + index, function() { + if (vector.length > 1) { + var hexa = vector[1]; + Transaction(hexa).serialize(true).should.equal(hexa); + index++; + } + }); }); }); describe('invalid transaction test case', function() { var index = 0; vectors_invalid.forEach(function(vector) { - if (vector.length > 1) { - var hexa = vector[1]; - Transaction(hexa).serialize(true).should.equal(hexa); - index++; - } + it('invalid vector #' + index, function() { + if (vector.length > 1) { + var hexa = vector[1]; + Transaction(hexa).serialize(true).should.equal(hexa); + index++; + } + }); }); }); }); diff --git a/test/transaction/output.js b/test/transaction/output.js index fdade46ec..0ded9d5f8 100644 --- a/test/transaction/output.js +++ b/test/transaction/output.js @@ -45,7 +45,7 @@ describe('Output', function() { satoshis: -100, script: Script.empty() }); - }).should.throw('Output satoshis is not a positive integer'); + }).should.throw('Output satoshis is not a natural number'); }); it('1.1', function() { @@ -54,7 +54,7 @@ describe('Output', function() { satoshis: 1.1, script: Script.empty() }); - }).should.throw('Output satoshis is not a positive integer'); + }).should.throw('Output satoshis is not a natural number'); }); it('NaN', function() { @@ -63,7 +63,7 @@ describe('Output', function() { satoshis: NaN, script: Script.empty() }); - }).should.throw('Output satoshis is not a positive integer'); + }).should.throw('Output satoshis is not a natural number'); }); it('Infinity', function() { @@ -72,7 +72,7 @@ describe('Output', function() { satoshis: Infinity, script: Script.empty() }); - }).should.throw('Output satoshis is not a positive integer'); + }).should.throw('Output satoshis is not a natural number'); }); }); diff --git a/test/util/js.js b/test/util/js.js index 1e79d32cc..00070bcfb 100644 --- a/test/util/js.js +++ b/test/util/js.js @@ -32,44 +32,44 @@ describe('js utils', function() { }); - describe('isPositiveInteger', function() { + describe('isNaturalNumber', function() { it('false for float', function() { - var a = JSUtil.isPositiveInteger(0.1); + var a = JSUtil.isNaturalNumber(0.1); a.should.equal(false); }); it('false for string float', function() { - var a = JSUtil.isPositiveInteger('0.1'); + var a = JSUtil.isNaturalNumber('0.1'); a.should.equal(false); }); it('false for string integer', function() { - var a = JSUtil.isPositiveInteger('1'); + var a = JSUtil.isNaturalNumber('1'); a.should.equal(false); }); it('false for negative integer', function() { - var a = JSUtil.isPositiveInteger(-1); + var a = JSUtil.isNaturalNumber(-1); a.should.equal(false); }); it('false for negative integer string', function() { - var a = JSUtil.isPositiveInteger('-1'); + var a = JSUtil.isNaturalNumber('-1'); a.should.equal(false); }); it('false for infinity', function() { - var a = JSUtil.isPositiveInteger(Infinity); + var a = JSUtil.isNaturalNumber(Infinity); a.should.equal(false); }); it('false for NaN', function() { - var a = JSUtil.isPositiveInteger(NaN); + var a = JSUtil.isNaturalNumber(NaN); a.should.equal(false); }); it('true for positive integer', function() { - var a = JSUtil.isPositiveInteger(1000); + var a = JSUtil.isNaturalNumber(1000); a.should.equal(true); });