aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--app/scripts/controllers/transactions.js1
-rw-r--r--app/scripts/lib/pending-tx-tracker.js10
-rw-r--r--app/scripts/lib/tx-gas-utils.js2
-rw-r--r--app/scripts/notice-controller.js2
-rw-r--r--package.json2
-rw-r--r--test/unit/pending-tx-test.js63
-rw-r--r--test/unit/util_test.js12
-rw-r--r--ui/app/app.js11
-rw-r--r--ui/app/send.js18
-rw-r--r--ui/app/util.js3
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)
}