From d6ab6bb4fa506c5fb9479b6e534ab74632c1b819 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 19 Apr 2016 18:56:22 -0700 Subject: [PATCH] Fix floating point input bug When sending a transaction, we were converting to BN before handling decimals, which meant we were losing any precision past a decimal point, since BN does not handle decimals! Put this numeric normalization into a utility function with a test around it and got it working. --- test/unit/util_test.js | 62 ++++++++++++++++++++++++++---------------- ui/app/send.js | 10 ++++--- ui/app/util.js | 14 ++++++++-- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/test/unit/util_test.js b/test/unit/util_test.js index 7f8103d3b..3f46d4e9b 100644 --- a/test/unit/util_test.js +++ b/test/unit/util_test.js @@ -82,33 +82,47 @@ describe('util', function() { }) - describe('#normalizeToWei', function() { - it('should convert an eth to the appropriate equivalent values', function() { - var valueTable = { - wei: '1000000000000000000', - kwei: '1000000000000000', - mwei: '1000000000000', - gwei: '1000000000', - szabo: '1000000', - finney:'1000', - ether: '1', - kether:'0.001', - mether:'0.000001', - // AUDIT: We're getting BN numbers on these ones. - // I think they're big enough to ignore for now. - // gether:'0.000000001', - // tether:'0.000000000001', - } - var oneEthBn = new ethUtil.BN(ethInWei, 10) + describe('normalizing values', function() { - for(var currency in valueTable) { + describe('#normalizeToWei', function() { + it('should convert an eth to the appropriate equivalent values', function() { + var valueTable = { + wei: '1000000000000000000', + kwei: '1000000000000000', + mwei: '1000000000000', + gwei: '1000000000', + szabo: '1000000', + finney:'1000', + ether: '1', + // kether:'0.001', + // mether:'0.000001', + // AUDIT: We're getting BN numbers on these ones. + // I think they're big enough to ignore for now. + // gether:'0.000000001', + // tether:'0.000000000001', + } + var oneEthBn = new ethUtil.BN(ethInWei, 10) - var value = new ethUtil.BN(valueTable[currency], 10) - var output = util.normalizeToWei(value, currency) - assert.equal(output.toString(10), valueTable.wei, `value of ${output.toString(10)} ${currency} should convert to ${oneEthBn}`) + for(var currency in valueTable) { - } + var value = new ethUtil.BN(valueTable[currency], 10) + var output = util.normalizeToWei(value, currency) + assert.equal(output.toString(10), valueTable.wei, `value of ${output.toString(10)} ${currency} should convert to ${oneEthBn}`) + } + }) + }) + + describe('#normalizeNumberToWei', function() { + + it('should convert a kwei number to the appropriate equivalent wei', function() { + var result = util.normalizeNumberToWei(1.111, 'kwei') + assert.equal(result.toString(10), '1111', 'accepts decimals') + }) + + it('should convert a ether number to the appropriate equivalent wei', function() { + var result = util.normalizeNumberToWei(1.111, 'ether') + assert.equal(result.toString(10), '1111000000000000000', 'accepts decimals') + }) }) }) - }) diff --git a/ui/app/send.js b/ui/app/send.js index ad4a27604..d34accddc 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -108,11 +108,11 @@ SendTransactionScreen.prototype.back = function() { SendTransactionScreen.prototype.onSubmit = function(event) { var recipient = document.querySelector('input.address').value - var amount = new ethUtil.BN(document.querySelector('input.ether').value, 10) - var currency = document.querySelector('select.currency').value - var txData = document.querySelector('textarea.txData').value - var value = util.normalizeToWei(amount, currency) + var inputAmount = parseFloat(document.querySelector('input.ether').value) + var currency = document.querySelector('select.currency').value + var value = util.normalizeNumberToWei(inputAmount, currency) + var balance = this.props.balance if (value.gt(balance)) { @@ -132,6 +132,8 @@ SendTransactionScreen.prototype.onSubmit = function(event) { from: this.props.address, value: '0x' + value.toString(16), } + + var txData = document.querySelector('textarea.txData').value if (txData) txParams.data = txData this.props.dispatch(actions.signTx(txParams)) diff --git a/ui/app/util.js b/ui/app/util.js index 18862fade..bacf00c66 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -28,6 +28,7 @@ module.exports = { ethToWei: ethToWei, weiToEth: weiToEth, normalizeToWei: normalizeToWei, + normalizeNumberToWei: normalizeNumberToWei, valueTable: valueTable, bnTable: bnTable, } @@ -85,13 +86,20 @@ function dataSize(data) { // returns a BN in wei function normalizeToWei(amount, currency) { try { - var ether = amount.div(bnTable[currency]) - var wei = ether.mul(bnTable.wei) - return wei + return amount.mul(bnTable.wei).div(bnTable[currency]) } catch (e) {} return amount } +var multiple = new ethUtil.BN('1000', 10) +function normalizeNumberToWei(n, currency) { + var enlarged = n * 1000 + console.log(`Enlarged, we have ${enlarged}`) + var amount = new ethUtil.BN(String(enlarged), 10) + console.log("Amount inside is "+ amount.toString(10)) + return normalizeToWei(amount, currency).div(multiple) +} + function readableDate(ms) { var date = new Date(ms) var month = date.getMonth()