diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | app/scripts/controllers/transactions.js | 1 | ||||
-rw-r--r-- | app/scripts/lib/pending-tx-tracker.js | 10 | ||||
-rw-r--r-- | app/scripts/lib/tx-gas-utils.js | 2 | ||||
-rw-r--r-- | app/scripts/notice-controller.js | 2 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | test/unit/pending-tx-test.js | 63 | ||||
-rw-r--r-- | test/unit/util_test.js | 12 | ||||
-rw-r--r-- | ui/app/app.js | 11 | ||||
-rw-r--r-- | ui/app/send.js | 18 | ||||
-rw-r--r-- | ui/app/util.js | 3 |
11 files changed, 106 insertions, 20 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bda40c8b..dc96203be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - Throw an error if a application tries to submit a tx whose value is a decimal, and inform that it should be in wei. - Fix bug that prevented updating custom token details. +- No longer mark long-pending transactions as failed, since we now have button to retry with higher gas. +- Fix rounding error when specifying an ether amount that has too much precision. ## 3.13.3 2017-12-14 diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index f95b5e39a..7c7efb84d 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -59,7 +59,6 @@ module.exports = class TransactionController extends EventEmitter { this.pendingTxTracker = new PendingTransactionTracker({ provider: this.provider, nonceTracker: this.nonceTracker, - retryTimePeriod: 86400000, // Retry 3500 blocks, or about 1 day. publishTransaction: (rawTx) => this.query.sendRawTransaction(rawTx), getPendingTransactions: this.txStateManager.getPendingTransactions.bind(this.txStateManager), getCompletedTransactions: this.txStateManager.getConfirmedTransactions.bind(this.txStateManager), diff --git a/app/scripts/lib/pending-tx-tracker.js b/app/scripts/lib/pending-tx-tracker.js index dc6e526fd..e8869e6b8 100644 --- a/app/scripts/lib/pending-tx-tracker.js +++ b/app/scripts/lib/pending-tx-tracker.js @@ -23,7 +23,6 @@ module.exports = class PendingTransactionTracker extends EventEmitter { this.query = new EthQuery(config.provider) this.nonceTracker = config.nonceTracker // default is one day - this.retryTimePeriod = config.retryTimePeriod || 86400000 this.getPendingTransactions = config.getPendingTransactions this.getCompletedTransactions = config.getCompletedTransactions this.publishTransaction = config.publishTransaction @@ -106,12 +105,6 @@ module.exports = class PendingTransactionTracker extends EventEmitter { this.emit('tx:block-update', txMeta, latestBlockNumber) } - if (Date.now() > txMeta.time + this.retryTimePeriod) { - const hours = (this.retryTimePeriod / 3.6e+6).toFixed(1) - const err = new Error(`Gave up submitting after ${hours} hours.`) - return this.emit('tx:failed', txMeta.id, err) - } - const firstRetryBlockNumber = txMeta.firstRetryBlockNumber || latestBlockNumber const txBlockDistance = Number.parseInt(latestBlockNumber, 16) - Number.parseInt(firstRetryBlockNumber, 16) @@ -185,7 +178,8 @@ module.exports = class PendingTransactionTracker extends EventEmitter { } async _checkIfNonceIsTaken (txMeta) { - const completed = this.getCompletedTransactions() + const address = txMeta.txParams.from + const completed = this.getCompletedTransactions(address) const sameNonce = completed.filter((otherMeta) => { return otherMeta.txParams.nonce === txMeta.txParams.nonce }) diff --git a/app/scripts/lib/tx-gas-utils.js b/app/scripts/lib/tx-gas-utils.js index bc891fc07..ccf8bb1b1 100644 --- a/app/scripts/lib/tx-gas-utils.js +++ b/app/scripts/lib/tx-gas-utils.js @@ -26,7 +26,7 @@ module.exports = class txProvideUtil { err.message.includes('Transaction execution error.') || err.message.includes('gas required exceeds allowance or always failing transaction') ) - if ( simulationFailed ) { + if (simulationFailed) { txMeta.simulationFails = true return txMeta } diff --git a/app/scripts/notice-controller.js b/app/scripts/notice-controller.js index db2b8c4f4..14a63eae7 100644 --- a/app/scripts/notice-controller.js +++ b/app/scripts/notice-controller.js @@ -77,7 +77,7 @@ module.exports = class NoticeController extends EventEmitter { return uniqBy(oldNotices.concat(newNotices), 'id') } - _filterNotices(notices) { + _filterNotices (notices) { return notices.filter((newNotice) => { if ('version' in newNotice) { const satisfied = semver.satisfies(this.version, newNotice.version) diff --git a/package.json b/package.json index 7184e3ea8..871ed204e 100644 --- a/package.json +++ b/package.json @@ -217,7 +217,7 @@ "testem": "^1.10.3", "uglifyify": "^4.0.2", "vinyl-buffer": "^1.0.0", - "vinyl-source-stream": "^1.1.0", + "vinyl-source-stream": "^2.0.0", "watchify": "^3.9.0" }, "engines": { diff --git a/test/unit/pending-tx-test.js b/test/unit/pending-tx-test.js index 393601a57..bd47299cf 100644 --- a/test/unit/pending-tx-test.js +++ b/test/unit/pending-tx-test.js @@ -328,7 +328,7 @@ describe('PendingTransactionTracker', function () { it('should publish the transaction if the number of blocks since last retry exceeds the last set limit', function (done) { const enoughBalance = '0x100000' const mockLatestBlockNumber = '0x11' - + pendingTxTracker._resubmitTx(txMetaToTestExponentialBackoff, mockLatestBlockNumber) .then(() => done()) .catch((err) => { @@ -338,5 +338,64 @@ describe('PendingTransactionTracker', function () { assert.equal(pendingTxTracker.publishTransaction.callCount, 1, 'Should call publish transaction') }) - }) + }) + + describe('#_checkIfNonceIsTaken', function () { + beforeEach ( function () { + let confirmedTxList = [{ + id: 1, + hash: '0x0593ee121b92e10d63150ad08b4b8f9c7857d1bd160195ee648fb9a0f8d00eeb', + status: 'confirmed', + txParams: { + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + nonce: '0x1', + value: '0xfffff', + }, + rawTx: '0xf86c808504a817c800827b0d940c62bb85faa3311a998d3aba8098c1235c564966880de0b6b3a7640000802aa08ff665feb887a25d4099e40e11f0fef93ee9608f404bd3f853dd9e84ed3317a6a02ec9d3d1d6e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d', + }, { + id: 2, + hash: '0x0593ee121b92e10d63150ad08b4b8f9c7857d1bd160195ee648fb9a0f8d00eeb', + status: 'confirmed', + txParams: { + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + nonce: '0x2', + value: '0xfffff', + }, + rawTx: '0xf86c808504a817c800827b0d940c62bb85faa3311a998d3aba8098c1235c564966880de0b6b3a7640000802aa08ff665feb887a25d4099e40e11f0fef93ee9608f404bd3f853dd9e84ed3317a6a02ec9d3d1d6e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d', + }] + pendingTxTracker.getCompletedTransactions = (address) => { + if (!address) throw new Error('unless behavior has changed #_checkIfNonceIsTaken needs a filtered list of transactions to see if the nonce is taken') + return confirmedTxList + } + }) + + it('should return false if nonce has not been taken', function (done) { + pendingTxTracker._checkIfNonceIsTaken({ + txParams: { + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + nonce: '0x3', + value: '0xfffff', + }, + }) + .then((taken) => { + assert.ok(!taken) + done() + }) + .catch(done) + }) + + it('should return true if nonce has been taken', function (done) { + pendingTxTracker._checkIfNonceIsTaken({ + txParams: { + from: '0x1678a085c290ebd122dc42cba69373b5953b831d', + nonce: '0x2', + value: '0xfffff', + }, + }).then((taken) => { + assert.ok(taken) + done() + }) + .catch(done) + }) + }) }) diff --git a/test/unit/util_test.js b/test/unit/util_test.js index 3a8b6bdfd..59048975a 100644 --- a/test/unit/util_test.js +++ b/test/unit/util_test.js @@ -201,6 +201,18 @@ describe('util', function () { var output = util.normalizeEthStringToWei(input) assert.equal(output.toString(10), ethInWei) }) + + it('should account for overflow numbers gracefully by dropping extra precision.', function () { + var input = '1.11111111111111111111' + var output = util.normalizeEthStringToWei(input) + assert.equal(output.toString(10), '1111111111111111111') + }) + + it('should not truncate very exact wei values that do not have extra precision.', function () { + var input = '1.100000000000000001' + var output = util.normalizeEthStringToWei(input) + assert.equal(output.toString(10), '1100000000000000001') + }) }) describe('#normalizeNumberToWei', function () { diff --git a/ui/app/app.js b/ui/app/app.js index bd0ccb0a2..bc198b482 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -460,11 +460,6 @@ App.prototype.renderPrimary = function () { }) } - if (props.seedWords) { - log.debug('rendering seed words') - return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'}) - } - // show initialize screen if (!props.isInitialized || props.forgottenPassword) { // show current view @@ -499,6 +494,12 @@ App.prototype.renderPrimary = function () { } } + // show seed words screen + if (props.seedWords) { + log.debug('rendering seed words') + return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'}) + } + // show current view switch (props.currentView.name) { diff --git a/ui/app/send.js b/ui/app/send.js index e59c1130e..09c9e03d4 100644 --- a/ui/app/send.js +++ b/ui/app/send.js @@ -247,10 +247,26 @@ SendTransactionScreen.prototype.onSubmit = function () { const recipient = state.recipient || document.querySelector('input[name="address"]').value.replace(/^[.\s]+|[.\s]+$/g, '') const nickname = state.nickname || ' ' const input = document.querySelector('input[name="amount"]').value + const parts = input.split('') + + let message + + if (isNaN(input) || input === '') { + message = 'Invalid ether value.' + return this.props.dispatch(actions.displayWarning(message)) + } + + if (parts[1]) { + var decimal = parts[1] + if (decimal.length > 18) { + message = 'Ether amount is too precise.' + return this.props.dispatch(actions.displayWarning(message)) + } + } + const value = util.normalizeEthStringToWei(input) const txData = document.querySelector('input[name="txData"]').value const balance = this.props.balance - let message if (value.gt(balance)) { message = 'Insufficient funds.' diff --git a/ui/app/util.js b/ui/app/util.js index 3f8b4dcc3..293f4228c 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -193,6 +193,9 @@ function normalizeEthStringToWei (str) { while (decimal.length < 18) { decimal += '0' } + if (decimal.length > 18) { + decimal = decimal.slice(0, 18) + } const decimalBN = new ethUtil.BN(decimal, 10) eth = eth.add(decimalBN) } |