Merge pull request #2845 from alextsg/NewUI-flat-4.0.5c

[NewUI] Merge master into NewUI-flat
feature/default_network_editable
Alexander Tseung 7 years ago committed by GitHub
commit dc9d8b24c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      CHANGELOG.md
  2. 3
      app/scripts/lib/pending-tx-tracker.js
  3. 13
      app/scripts/lib/tx-gas-utils.js
  4. 2
      app/scripts/notice-controller.js
  5. 18
      old-ui/app/send.js
  6. 2
      package.json
  7. 61
      test/unit/pending-tx-test.js
  8. 12
      test/unit/util_test.js
  9. 11
      ui/app/app.js
  10. 3
      ui/app/util.js

@ -2,8 +2,10 @@
## Current Master ## Current Master
- 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. - 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. - 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 ## 3.13.3 2017-12-14

@ -178,7 +178,8 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
} }
async _checkIfNonceIsTaken (txMeta) { async _checkIfNonceIsTaken (txMeta) {
const completed = this.getCompletedTransactions() const address = txMeta.txParams.from
const completed = this.getCompletedTransactions(address)
const sameNonce = completed.filter((otherMeta) => { const sameNonce = completed.filter((otherMeta) => {
return otherMeta.txParams.nonce === txMeta.txParams.nonce return otherMeta.txParams.nonce === txMeta.txParams.nonce
}) })

@ -26,7 +26,7 @@ module.exports = class txProvideUtil {
err.message.includes('Transaction execution error.') || err.message.includes('Transaction execution error.') ||
err.message.includes('gas required exceeds allowance or always failing transaction') err.message.includes('gas required exceeds allowance or always failing transaction')
) )
if ( simulationFailed ) { if (simulationFailed) {
txMeta.simulationFails = true txMeta.simulationFails = true
return txMeta return txMeta
} }
@ -81,8 +81,15 @@ module.exports = class txProvideUtil {
} }
async validateTxParams (txParams) { async validateTxParams (txParams) {
if (('value' in txParams) && txParams.value.indexOf('-') === 0) { if ('value' in txParams) {
throw new Error(`Invalid transaction value of ${txParams.value} not a positive number.`) const value = txParams.value.toString()
if (value.includes('-')) {
throw new Error(`Invalid transaction value of ${txParams.value} not a positive number.`)
}
if (value.includes('.')) {
throw new Error(`Invalid transaction value of ${txParams.value} number must be in wei`)
}
} }
} }
} }

@ -77,7 +77,7 @@ module.exports = class NoticeController extends EventEmitter {
return uniqBy(oldNotices.concat(newNotices), 'id') return uniqBy(oldNotices.concat(newNotices), 'id')
} }
_filterNotices(notices) { _filterNotices (notices) {
return notices.filter((newNotice) => { return notices.filter((newNotice) => {
if ('version' in newNotice) { if ('version' in newNotice) {
const satisfied = semver.satisfies(this.version, newNotice.version) const satisfied = semver.satisfies(this.version, newNotice.version)

@ -247,10 +247,26 @@ SendTransactionScreen.prototype.onSubmit = function () {
const recipient = state.recipient || document.querySelector('input[name="address"]').value.replace(/^[.\s]+|[.\s]+$/g, '') const recipient = state.recipient || document.querySelector('input[name="address"]').value.replace(/^[.\s]+|[.\s]+$/g, '')
const nickname = state.nickname || ' ' const nickname = state.nickname || ' '
const input = document.querySelector('input[name="amount"]').value 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 value = util.normalizeEthStringToWei(input)
const txData = document.querySelector('input[name="txData"]').value const txData = document.querySelector('input[name="txData"]').value
const balance = this.props.balance const balance = this.props.balance
let message
if (value.gt(balance)) { if (value.gt(balance)) {
message = 'Insufficient funds.' message = 'Insufficient funds.'

@ -239,7 +239,7 @@
"testem": "^1.10.3", "testem": "^1.10.3",
"uglifyify": "^4.0.2", "uglifyify": "^4.0.2",
"vinyl-buffer": "^1.0.0", "vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0", "vinyl-source-stream": "^2.0.0",
"watchify": "^3.9.0" "watchify": "^3.9.0"
}, },
"engines": { "engines": {

@ -339,5 +339,64 @@ describe('PendingTransactionTracker', function () {
assert.equal(pendingTxTracker.publishTransaction.callCount, 1, 'Should call publish transaction') 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)
})
})
}) })

@ -201,6 +201,18 @@ describe('util', function () {
var output = util.normalizeEthStringToWei(input) var output = util.normalizeEthStringToWei(input)
assert.equal(output.toString(10), ethInWei) 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 () { describe('#normalizeNumberToWei', function () {

@ -360,11 +360,6 @@ App.prototype.renderPrimary = function () {
}) })
} }
if (props.seedWords) {
log.debug('rendering seed words')
return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'})
}
// show initialize screen // show initialize screen
if (!props.isInitialized || props.forgottenPassword) { if (!props.isInitialized || props.forgottenPassword) {
// show current view // show current view
@ -389,6 +384,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 // show current view
switch (props.currentView.name) { switch (props.currentView.name) {

@ -211,6 +211,9 @@ function normalizeEthStringToWei (str) {
while (decimal.length < 18) { while (decimal.length < 18) {
decimal += '0' decimal += '0'
} }
if (decimal.length > 18) {
decimal = decimal.slice(0, 18)
}
const decimalBN = new ethUtil.BN(decimal, 10) const decimalBN = new ethUtil.BN(decimal, 10)
eth = eth.add(decimalBN) eth = eth.add(decimalBN)
} }

Loading…
Cancel
Save