From 1e7e9a2aa75eecb881631c343d6f7d3546e0f55f Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 19 Apr 2016 07:36:05 -0700 Subject: [PATCH] handle negative outputs. serialize int64 correctly. --- lib/bcoin/utils.js | 14 ++++++++++---- test/tx-test.js | 8 ++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/bcoin/utils.js b/lib/bcoin/utils.js index ea0be826..50b6282e 100644 --- a/lib/bcoin/utils.js +++ b/lib/bcoin/utils.js @@ -600,6 +600,7 @@ utils.assert = assert; utils.btc = utils.toBTC = function toBTC(satoshi, strict) { var m = new bn(10000000).mul(new bn(10)); + var neg = false; var lo; if (utils.isBTC(satoshi)) @@ -613,6 +614,11 @@ utils.toBTC = function toBTC(satoshi, strict) { if (!satoshi) throw new Error('Could not calculate BTC'); + if (satoshi.isNeg()) { + satoshi = satoshi.neg(); + neg = true; + } + lo = satoshi.mod(m); if (lo.cmpn(0) !== 0) { @@ -628,7 +634,7 @@ utils.toBTC = function toBTC(satoshi, strict) { if (lo === '.') lo += '0'; - return satoshi.div(m).toString(10) + lo; + return (neg ? '-' : '') + satoshi.div(m).toString(10) + lo; }; /** @@ -689,7 +695,7 @@ utils.isInt = function isInt(val) { */ utils.isFloat = function isFloat(val) { - return typeof val === 'string' && /^\d+\.\d+$/.test(val); + return typeof val === 'string' && /^-?\d+\.\d+$/.test(val); }; /** @@ -1980,7 +1986,7 @@ utils.write64 = function write64(dst, num, off) { if (num.cmpn(0) === 0) num = new bn(0); else - num = num.neg().notn(64).subn(1); + num = num.neg().notn(64).addn(1); } if (num.bitLength() > 64) @@ -2016,7 +2022,7 @@ utils.write64BE = function write64BE(dst, num, off) { if (num.cmpn(0) === 0) num = new bn(0); else - num = num.neg().notn(64).subn(1); + num = num.neg().notn(64).addn(1); } if (num.bitLength() > 64) diff --git a/test/tx-test.js b/test/tx-test.js index 7c498e6d..983a48f0 100644 --- a/test/tx-test.js +++ b/test/tx-test.js @@ -210,6 +210,14 @@ describe('TX', function() { }); return; } + if (comments === 'Negative output') { + it('should handle invalid tx (negative)' + suffix + ': ' + comments, function () { + clearCache(tx, nocache); + assert.ok(tx.verify(null, true, flags)); + assert.ok(!tx.isSane()); + }); + return; + } if (comments.indexOf('Coinbase') === 0) { it('should handle invalid coinbase' + suffix + ': ' + comments, function () { clearCache(tx, nocache);