From 576fb26c1558e7e639f28bed07da72d662a5039e Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 29 Mar 2017 11:08:15 -0400 Subject: [PATCH 01/16] Add missing migration. --- app/scripts/migrations/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index a3dd48c17..019b4d13d 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -22,4 +22,5 @@ module.exports = [ require('./009'), require('./010'), require('./011'), + require('./012'), ] From cb34eda6c6e320297c8616248e7e57a6926a24a6 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 29 Mar 2017 11:51:04 -0400 Subject: [PATCH 02/16] Fix potential formatting issues for seed word display. --- ui/app/css/index.css | 1 - ui/app/keychains/hd/create-vault-complete.js | 11 ++++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ui/app/css/index.css b/ui/app/css/index.css index de8ae0e92..033502f5a 100644 --- a/ui/app/css/index.css +++ b/ui/app/css/index.css @@ -148,7 +148,6 @@ h2.page-subtitle { } textarea.twelve-word-phrase { - margin-top: 20px; padding: 12px; width: 300px; height: 140px; diff --git a/ui/app/keychains/hd/create-vault-complete.js b/ui/app/keychains/hd/create-vault-complete.js index 7272ebdbd..5230797ad 100644 --- a/ui/app/keychains/hd/create-vault-complete.js +++ b/ui/app/keychains/hd/create-vault-complete.js @@ -45,12 +45,17 @@ CreateVaultCompleteScreen.prototype.render = function () { 'Vault Created', ]), - h('span.error', { // Error for the right red + h('div', { style: { - padding: '12px 20px 0px 20px', + width: '360px', + height: '78px', + fontSize: '1em', + marginTop: '10px', textAlign: 'center', }, - }, 'These 12 words can restore all of your MetaMask accounts for this vault.\nSave them somewhere safe and secret.'), + }, [ + h('span.error', 'These 12 words can restore all of your MetaMask accounts for this vault.\nSave them somewhere safe and secret.'), + ]), h('textarea.twelve-word-phrase', { readOnly: true, From 610ec2bdf5841c8275073992e67c59fb47faa48c Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Mar 2017 10:40:57 -0700 Subject: [PATCH 03/16] Fix popup behavior for Firefox Firefox does not support the `focused` parameter when opening a new window, and we don't actually require it for Chrome either, new popups are at the foreground by default already. --- app/scripts/lib/extension.js | 5 ++++- app/scripts/lib/notifications.js | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/scripts/lib/extension.js b/app/scripts/lib/extension.js index 4b670490f..6f8b5d800 100644 --- a/app/scripts/lib/extension.js +++ b/app/scripts/lib/extension.js @@ -11,4 +11,7 @@ */ const Extension = require('./extension-instance') -module.exports = new Extension() +const instance = new Extension() +window.METAMASK_EXTENSION = instance +module.exports = instance + diff --git a/app/scripts/lib/notifications.js b/app/scripts/lib/notifications.js index 3db1ac6b5..33914846c 100644 --- a/app/scripts/lib/notifications.js +++ b/app/scripts/lib/notifications.js @@ -22,10 +22,12 @@ function show () { extension.windows.create({ url: 'notification.html', type: 'popup', - focused: true, width, height, }) + .catch((reason) => { + log.error("failed to create poupup", reason) + }) } }) } From daf22168b63d70669cf0bce17a17e0648aca584f Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Mar 2017 10:42:02 -0700 Subject: [PATCH 04/16] Bump changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e27f5c04..0a54cf886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Current Master +- Popup new transactions in Firefox. + ## 3.5.2 2017-3-28 - Fix bug where gas estimate totals were sometimes wrong. From 98dd684524fde7548442830fe01e1f3e24a6e67d Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Mar 2017 10:42:43 -0700 Subject: [PATCH 05/16] Linted --- app/scripts/lib/notifications.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/lib/notifications.js b/app/scripts/lib/notifications.js index 33914846c..0ec01f3a7 100644 --- a/app/scripts/lib/notifications.js +++ b/app/scripts/lib/notifications.js @@ -26,7 +26,7 @@ function show () { height, }) .catch((reason) => { - log.error("failed to create poupup", reason) + log.error('failed to create poupup', reason) }) } }) From f0a2b4d1b0ad0b87e8101850790d4ee30fa6116f Mon Sep 17 00:00:00 2001 From: kumavis Date: Wed, 29 Mar 2017 12:36:23 -0700 Subject: [PATCH 06/16] deps - bump provider-engine uses fetch instead of xhr, fixes a race condition in cache subp --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 488e7e90d..9e04bc6f7 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "valid-url": "^1.0.9", "vreme": "^3.0.2", "web3": "0.18.2", - "web3-provider-engine": "^10.0.1", + "web3-provider-engine": "^11.0.2", "web3-stream-provider": "^2.0.6", "xtend": "^4.0.1" }, From 8ade8bdf32933ea9449d06aa6a1fc71c10b461c4 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Wed, 29 Mar 2017 13:35:51 -0700 Subject: [PATCH 07/16] Fix currency checking for firefox By adding cryptonator to our permitted CORS hosts. Fixes #1285. Will probably trigger additional permissions requests to our users. --- app/manifest.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/manifest.json b/app/manifest.json index 75e72c295..a3242149b 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -57,7 +57,8 @@ "permissions": [ "storage", "clipboardWrite", - "http://localhost:8545/" + "http://localhost:8545/", + "https://www.cryptonator.com/" ], "web_accessible_resources": [ "scripts/inpage.js" From ff49e5e5cf3aadf63dbdf6570407c23e1ae6cdb9 Mon Sep 17 00:00:00 2001 From: kumavis Date: Wed, 29 Mar 2017 23:21:31 -0700 Subject: [PATCH 08/16] tx-utils - gas buffer ceiling at 90% of block gas limit --- app/scripts/lib/tx-utils.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index 72df53631..e8e23f8b5 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -63,14 +63,15 @@ module.exports = class txProviderUtils { addGasBuffer (initialGasLimitHex, blockGasLimitHex) { const initialGasLimitBn = hexToBn(initialGasLimitHex) const blockGasLimitBn = hexToBn(blockGasLimitHex) + const upperGasLimitBn = blockGasLimitBn.muln(0.9) const bufferedGasLimitBn = initialGasLimitBn.muln(1.5) // if initialGasLimit is above blockGasLimit, dont modify it - if (initialGasLimitBn.gt(blockGasLimitBn)) return bnToHex(initialGasLimitBn) + if (initialGasLimitBn.gt(upperGasLimitBn)) return bnToHex(initialGasLimitBn) // if bufferedGasLimit is below blockGasLimit, use bufferedGasLimit - if (bufferedGasLimitBn.lt(blockGasLimitBn)) return bnToHex(bufferedGasLimitBn) + if (bufferedGasLimitBn.lt(upperGasLimitBn)) return bnToHex(bufferedGasLimitBn) // otherwise use blockGasLimit - return bnToHex(blockGasLimitBn) + return bnToHex(upperGasLimitBn) } fillInTxParams (txParams, cb) { From 16b5f4a210cd496b9160efbfa5e2cc44ae0c8f5c Mon Sep 17 00:00:00 2001 From: kumavis Date: Wed, 29 Mar 2017 23:59:42 -0700 Subject: [PATCH 09/16] tests - tx-utils gasBuffer calc - fix bug and user easier numbers --- test/unit/tx-utils-test.js | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js index e57b25e83..8b4d2f059 100644 --- a/test/unit/tx-utils-test.js +++ b/test/unit/tx-utils-test.js @@ -14,8 +14,8 @@ describe('txUtils', function() { describe('addGasBuffer', function() { it('multiplies by 1.5, when within block gas limit', function() { - // naive estimatedGas: 0x123fad (~1.2 mil) - const inputHex = '0x123fad' + // naive estimatedGas: 0x16e360 (1.5 mil) + const inputHex = '0x16e360' // dummy gas limit: 0x3d4c52 (4 mil) const blockGasLimitHex = '0x3d4c52' const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) @@ -26,8 +26,8 @@ describe('txUtils', function() { }) it('uses original estimatedGas, when above block gas limit', function() { - // naive estimatedGas: 0x123fad (~1.2 mil) - const inputHex = '0x123fad' + // naive estimatedGas: 0x16e360 (1.5 mil) + const inputHex = '0x16e360' // dummy gas limit: 0x0f4240 (1 mil) const blockGasLimitHex = '0x0f4240' const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) @@ -37,16 +37,18 @@ describe('txUtils', function() { assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value') }) - it('buffers up to block gas limit', function() { - // naive estimatedGas: 0x123fad (~1.2 mil) - const inputHex = '0x1e8480' + it('buffers up to reccomend gas limit reccomended ceiling', function() { + // naive estimatedGas: 0x16e360 (1.5 mil) + const inputHex = '0x16e360' // dummy gas limit: 0x1e8480 (2 mil) const blockGasLimitHex = '0x1e8480' + const blockGasLimitBn = hexToBn(blockGasLimitHex) + const ceilGasLimitBn = blockGasLimitBn.muln(0.9) const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex) - const inputBn = hexToBn(inputHex) - const outputBn = hexToBn(output) - const expectedBn = hexToBn(blockGasLimitHex) - assert(outputBn.eq(expectedBn), 'returns the block gas limit value') + // const inputBn = hexToBn(inputHex) + // const outputBn = hexToBn(output) + const expectedHex = bnToHex(ceilGasLimitBn) + assert.equal(output, expectedHex, 'returns the gas limit reccomended ceiling value') }) }) }) @@ -55,4 +57,8 @@ describe('txUtils', function() { function hexToBn(inputHex) { return new BN(ethUtil.stripHexPrefix(inputHex), 16) +} + +function bnToHex(inputBn) { + return ethUtil.addHexPrefix(inputBn.toString(16)) } \ No newline at end of file From 1dce352523a1f79f052ef79c707d9bc44787b706 Mon Sep 17 00:00:00 2001 From: kumavis Date: Thu, 30 Mar 2017 14:23:23 -0700 Subject: [PATCH 10/16] tx-manager - add eip155 support --- app/scripts/transaction-manager.js | 20 +++++-- test/unit/tx-manager-test.js | 89 +++++++++++++++++++----------- test/unit/tx-utils-test.js | 17 ++++++ 3 files changed, 91 insertions(+), 35 deletions(-) diff --git a/app/scripts/transaction-manager.js b/app/scripts/transaction-manager.js index a70159680..d7051b2cb 100644 --- a/app/scripts/transaction-manager.js +++ b/app/scripts/transaction-manager.js @@ -205,11 +205,23 @@ module.exports = class TransactionManager extends EventEmitter { }) } + getChainId() { + const networkState = this.networkStore.getState() + const getChainId = parseInt(networkState.network) + if (Number.isNaN(getChainId)) { + return 0 + } else { + return getChainId + } + } + signTransaction (txId, cb) { - let txMeta = this.getTx(txId) - let txParams = txMeta.txParams - let fromAddress = txParams.from - let ethTx = this.txProviderUtils.buildEthTxFromParams(txParams) + const txMeta = this.getTx(txId) + const txParams = txMeta.txParams + const fromAddress = txParams.from + // add network/chain id + txParams.chainId = this.getChainId() + const ethTx = this.txProviderUtils.buildEthTxFromParams(txParams) this.signEthTx(ethTx, fromAddress).then(() => { this.setTxStatusSigned(txMeta.id) cb(null, ethUtil.bufferToHex(ethTx.serialize())) diff --git a/test/unit/tx-manager-test.js b/test/unit/tx-manager-test.js index d4bffdd9b..20f89a226 100644 --- a/test/unit/tx-manager-test.js +++ b/test/unit/tx-manager-test.js @@ -1,19 +1,30 @@ -const assert = require('assert') +// const assert = require('assert') +const assert = require('chai').assert const extend = require('xtend') const EventEmitter = require('events') +const ethUtil = require('ethereumjs-util') +const EthTx = require('ethereumjs-tx') const ObservableStore = require('obs-store') const STORAGE_KEY = 'metamask-persistance-key' const TransactionManager = require('../../app/scripts/transaction-manager') const noop = () => true +const currentNetworkId = 42 +const otherNetworkId = 36 +const privKey = new Buffer('8718b9618a37d1fc78c436511fc6df3c8258d3250635bba617f33003270ec03e', 'hex') describe('Transaction Manager', function() { let txManager beforeEach(function() { txManager = new TransactionManager({ - networkStore: new ObservableStore({ network: 'unit test' }), + networkStore: new ObservableStore({ network: currentNetworkId }), txHistoryLimit: 10, blockTracker: new EventEmitter(), + signTransaction: (ethTx) => new Promise((resolve) => { + ethTx.sign(privKey) + const result = ethTx.serialize() + resolve() + }) }) }) @@ -27,7 +38,6 @@ describe('Transaction Manager', function() { }) }) - it('returns error for negative values', function() { var sample = { value: '-0x01' @@ -51,7 +61,7 @@ describe('Transaction Manager', function() { describe('#addTx', function() { it('adds a tx returned in getTxList', function() { - var tx = { id: 1, status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} } + var tx = { id: 1, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} } txManager.addTx(tx, noop) var result = txManager.getTxList() assert.ok(Array.isArray(result)) @@ -60,8 +70,8 @@ describe('Transaction Manager', function() { }) it('does not override txs from other networks', function() { - var tx = { id: 1, status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} } - var tx2 = { id: 2, status: 'confirmed', metamaskNetworkId: 'another net', txParams: {} } + var tx = { id: 1, status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} } + var tx2 = { id: 2, status: 'confirmed', metamaskNetworkId: otherNetworkId, txParams: {} } txManager.addTx(tx, noop) txManager.addTx(tx2, noop) var result = txManager.getFullTxList() @@ -73,7 +83,7 @@ describe('Transaction Manager', function() { it('cuts off early txs beyond a limit', function() { const limit = txManager.txHistoryLimit for (let i = 0; i < limit + 1; i++) { - let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} } + let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} } txManager.addTx(tx, noop) } var result = txManager.getTxList() @@ -84,7 +94,7 @@ describe('Transaction Manager', function() { it('cuts off early txs beyond a limit whether or not it is confirmed or rejected', function() { const limit = txManager.txHistoryLimit for (let i = 0; i < limit + 1; i++) { - let tx = { id: i, time: new Date(), status: 'rejected', metamaskNetworkId: 'unit test', txParams: {} } + let tx = { id: i, time: new Date(), status: 'rejected', metamaskNetworkId: currentNetworkId, txParams: {} } txManager.addTx(tx, noop) } var result = txManager.getTxList() @@ -93,11 +103,11 @@ describe('Transaction Manager', function() { }) it('cuts off early txs beyond a limit but does not cut unapproved txs', function() { - var unconfirmedTx = { id: 0, time: new Date(), status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} } + var unconfirmedTx = { id: 0, time: new Date(), status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } txManager.addTx(unconfirmedTx, noop) const limit = txManager.txHistoryLimit for (let i = 1; i < limit + 1; i++) { - let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} } + let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} } txManager.addTx(tx, noop) } var result = txManager.getTxList() @@ -110,7 +120,7 @@ describe('Transaction Manager', function() { describe('#setTxStatusSigned', function() { it('sets the tx status to signed', function() { - var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} } + var tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } txManager.addTx(tx, noop) txManager.setTxStatusSigned(1) var result = txManager.getTxList() @@ -121,7 +131,7 @@ describe('Transaction Manager', function() { it('should emit a signed event to signal the exciton of callback', (done) => { this.timeout(10000) - var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} } + var tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } let noop = function () { assert(true, 'event listener has been triggered and noop executed') done() @@ -134,7 +144,7 @@ describe('Transaction Manager', function() { describe('#setTxStatusRejected', function() { it('sets the tx status to rejected', function() { - var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} } + var tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } txManager.addTx(tx) txManager.setTxStatusRejected(1) var result = txManager.getTxList() @@ -145,7 +155,7 @@ describe('Transaction Manager', function() { it('should emit a rejected event to signal the exciton of callback', (done) => { this.timeout(10000) - var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} } + var tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } txManager.addTx(tx) let noop = function (err, txId) { assert(true, 'event listener has been triggered and noop executed') @@ -159,9 +169,9 @@ describe('Transaction Manager', function() { describe('#updateTx', function() { it('replaces the tx with the same id', function() { - txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }, noop) - txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} }, noop) - txManager.updateTx({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: 'unit test', txParams: {} }) + txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + txManager.updateTx({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: currentNetworkId, txParams: {} }) var result = txManager.getTx('1') assert.equal(result.hash, 'foo') }) @@ -169,8 +179,8 @@ describe('Transaction Manager', function() { describe('#getUnapprovedTxList', function() { it('returns unapproved txs in a hash', function() { - txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }, noop) - txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} }, noop) + txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) let result = txManager.getUnapprovedTxList() assert.equal(typeof result, 'object') assert.equal(result['1'].status, 'unapproved') @@ -180,8 +190,8 @@ describe('Transaction Manager', function() { describe('#getTx', function() { it('returns a tx with the requested id', function() { - txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }, noop) - txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} }, noop) + txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) assert.equal(txManager.getTx('1').status, 'unapproved') assert.equal(txManager.getTx('2').status, 'confirmed') }) @@ -190,16 +200,16 @@ describe('Transaction Manager', function() { describe('#getFilteredTxList', function() { it('returns a tx with the requested data', function() { let txMetas = [ - { id: 0, status: 'unapproved', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: 'unit test' }, - { id: 1, status: 'unapproved', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: 'unit test' }, - { id: 2, status: 'unapproved', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: 'unit test' }, - { id: 3, status: 'unapproved', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: 'unit test' }, - { id: 4, status: 'unapproved', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: 'unit test' }, - { id: 5, status: 'confirmed', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: 'unit test' }, - { id: 6, status: 'confirmed', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: 'unit test' }, - { id: 7, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: 'unit test' }, - { id: 8, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: 'unit test' }, - { id: 9, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: 'unit test' }, + { id: 0, status: 'unapproved', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: currentNetworkId }, + { id: 1, status: 'unapproved', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: currentNetworkId }, + { id: 2, status: 'unapproved', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: currentNetworkId }, + { id: 3, status: 'unapproved', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: currentNetworkId }, + { id: 4, status: 'unapproved', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: currentNetworkId }, + { id: 5, status: 'confirmed', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: currentNetworkId }, + { id: 6, status: 'confirmed', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: currentNetworkId }, + { id: 7, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: currentNetworkId }, + { id: 8, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: currentNetworkId }, + { id: 9, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: currentNetworkId }, ] txMetas.forEach((txMeta) => txManager.addTx(txMeta, noop)) let filterParams @@ -219,4 +229,21 @@ describe('Transaction Manager', function() { }) }) + + describe('#sign replay-protected tx', function() { + it('prepares a tx with the chainId set', function() { + txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) + txManager.signTransaction('1', (err, rawTx) => { + if (err) return assert.fail('it should not fail') + const ethTx = new EthTx(ethUtil.toBuffer(rawTx)) + console.log('------------------------------------------') + console.log('ethTx.getChainId(), currentNetworkId') + console.log(ethTx.getChainId(), currentNetworkId) + assert.equal(ethTx.getChainId(), currentNetworkId) + }) + }) + }) + + + }) diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js index 8b4d2f059..93e9e4134 100644 --- a/test/unit/tx-utils-test.js +++ b/test/unit/tx-utils-test.js @@ -12,6 +12,23 @@ describe('txUtils', function() { txUtils = new TxUtils() }) + describe('chain Id', function() { + it('prepares a transaction with the provided chainId', function() { + const txParams = { + to: '0x70ad465e0bab6504002ad58c744ed89c7da38524', + from: '0x69ad465e0bab6504002ad58c744ed89c7da38525', + value: '0x0', + gas: '0x7b0c', + gasPrice: '0x199c82cc00', + data: '0x', + nonce: '0x3', + chainId: 42, + } + const ethTx = txUtils.buildEthTxFromParams(txParams) + assert.equal(ethTx.getChainId(), 42, 'chainId is set from tx params') + }) + }) + describe('addGasBuffer', function() { it('multiplies by 1.5, when within block gas limit', function() { // naive estimatedGas: 0x16e360 (1.5 mil) From e95ae43c8f0e40742540844984861a06f26999c6 Mon Sep 17 00:00:00 2001 From: kumavis Date: Thu, 30 Mar 2017 14:43:56 -0700 Subject: [PATCH 11/16] tests - unit - fail on unhandled promise rejection --- package.json | 1 + test/helper.js | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 9e04bc6f7..70da129d2 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "async": "^1.5.2", "async-q": "^0.3.1", "bip39": "^2.2.0", + "bluebird": "^3.5.0", "browser-passworder": "^2.0.3", "browserify-derequire": "^0.9.4", "clone": "^1.0.2", diff --git a/test/helper.js b/test/helper.js index a01ea1e53..dd22d80b4 100644 --- a/test/helper.js +++ b/test/helper.js @@ -1,11 +1,52 @@ +// disallow promises from swallowing errors +enableFailureOnUnhandledPromiseRejection() + +// logging util var log = require('loglevel') log.setDefaultLevel(5) +global.log = log +// +// polyfills +// + +// dom require('jsdom-global')() + +// localStorage window.localStorage = {} -if (!('crypto' in window)) { window.crypto = {} } -window.crypto.getRandomValues = require('polyfill-crypto.getrandomvalues') +// crypto.getRandomValues +if (!window.crypto) window.crypto = {} +if (!window.crypto.getRandomValues) window.crypto.getRandomValues = require('polyfill-crypto.getrandomvalues') -window.log = log -global.log = log + + +function enableFailureOnUnhandledPromiseRejection() { + // overwrite node's promise with the stricter Bluebird promise + global.Promise = require('bluebird') + + // rethrow unhandledRejections + if (typeof process !== 'undefined') { + process.on('unhandledRejection', function (reason) { + throw reason; + }); + } else if (typeof window !== 'undefined') { + // 2016-02-01: No browsers support this natively, however bluebird, when.js, + // and probably other libraries do. + if (typeof window.addEventListener === 'function') { + window.addEventListener('unhandledrejection', function (evt) { + throw evt.detail.reason; + }); + } else { + var oldOHR = window.onunhandledrejection; + window.onunhandledrejection = function (evt) { + if (typeof oldOHR === 'function') oldOHR.apply(this, arguments); + throw evt.detail.reason; + }; + } + } else if (typeof console !== 'undefined' && + typeof (console.error || console.log) === 'function') { + (console.error || console.log)('Unhandled rejections will be ignored!'); + } +} \ No newline at end of file From 8ae37ae80de38728c8c878ab24249450a570e97a Mon Sep 17 00:00:00 2001 From: kumavis Date: Thu, 30 Mar 2017 14:49:39 -0700 Subject: [PATCH 12/16] tests - helper - add note --- test/helper.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/test/helper.js b/test/helper.js index dd22d80b4..aaac7580e 100644 --- a/test/helper.js +++ b/test/helper.js @@ -26,27 +26,29 @@ function enableFailureOnUnhandledPromiseRejection() { // overwrite node's promise with the stricter Bluebird promise global.Promise = require('bluebird') + // modified from https://github.com/mochajs/mocha/issues/1926#issuecomment-180842722 + // rethrow unhandledRejections if (typeof process !== 'undefined') { process.on('unhandledRejection', function (reason) { - throw reason; - }); + throw reason + }) } else if (typeof window !== 'undefined') { // 2016-02-01: No browsers support this natively, however bluebird, when.js, // and probably other libraries do. if (typeof window.addEventListener === 'function') { window.addEventListener('unhandledrejection', function (evt) { - throw evt.detail.reason; - }); + throw evt.detail.reason + }) } else { - var oldOHR = window.onunhandledrejection; + var oldOHR = window.onunhandledrejection window.onunhandledrejection = function (evt) { - if (typeof oldOHR === 'function') oldOHR.apply(this, arguments); - throw evt.detail.reason; - }; + if (typeof oldOHR === 'function') oldOHR.apply(this, arguments) + throw evt.detail.reason + } } } else if (typeof console !== 'undefined' && typeof (console.error || console.log) === 'function') { - (console.error || console.log)('Unhandled rejections will be ignored!'); + (console.error || console.log)('Unhandled rejections will be ignored!') } } \ No newline at end of file From 1079c20c8329610f124713a1b1dae2dfe9c99ba0 Mon Sep 17 00:00:00 2001 From: kumavis Date: Thu, 30 Mar 2017 14:50:01 -0700 Subject: [PATCH 13/16] meta - package.json - rename npm test scripts --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 70da129d2..7dfe21f24 100644 --- a/package.json +++ b/package.json @@ -5,20 +5,20 @@ "private": true, "scripts": { "start": "npm run dev", - "lint": "gulp lint", - "buildCiUnits": "node test/integration/index.js", "dev": "gulp dev --debug", "disc": "gulp disc --debug", "dist": "gulp dist --disableLiveReload", - "test": "npm run lint && npm run fastTest && npm run ci", - "fastTest": "METAMASK_ENV=test mocha --require test/helper.js --recursive \"test/unit/**/*.js\"", + "test": "npm run lint && npm run test-unit && npm run test-integration", + "test-unit": "METAMASK_ENV=test mocha --require test/helper.js --recursive \"test/unit/**/*.js\"", + "test-integration": "npm run buildMock && npm run buildCiUnits && testem ci -P 2", + "lint": "gulp lint", + "buildCiUnits": "node test/integration/index.js", "watch": "mocha watch --recursive \"test/unit/**/*.js\"", "genStates": "node development/genStates.js", "ui": "npm run genStates && beefy ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", "mock": "beefy mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", "buildMock": "npm run genStates && browserify ./mock-dev.js -o ./development/bundle.js", "testem": "npm run buildMock && testem", - "ci": "npm run buildMock && npm run buildCiUnits && testem ci -P 2", "announce": "node development/announcer.js", "generateNotice": "node notices/notice-generator.js", "deleteNotice": "node notices/notice-delete.js" From 47ea5452414ef4c126ff6c6ccb40615f852f8bed Mon Sep 17 00:00:00 2001 From: kumavis Date: Thu, 30 Mar 2017 15:43:01 -0700 Subject: [PATCH 14/16] tests - add missing done --- test/unit/keyring-controller-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/keyring-controller-test.js b/test/unit/keyring-controller-test.js index aae4cdfd6..efd0a3546 100644 --- a/test/unit/keyring-controller-test.js +++ b/test/unit/keyring-controller-test.js @@ -135,7 +135,7 @@ describe('KeyringController', function() { }) describe('#getAccounts', function() { - it('returns the result of getAccounts for each keyring', function() { + it('returns the result of getAccounts for each keyring', function(done) { keyringController.keyrings = [ { getAccounts() { return Promise.resolve([1,2,3]) } }, { getAccounts() { return Promise.resolve([4,5,6]) } }, From 12918e18942a72223d7d97334934c31442e51caf Mon Sep 17 00:00:00 2001 From: kumavis Date: Thu, 30 Mar 2017 16:06:27 -0700 Subject: [PATCH 15/16] tests - tx-manager - fix assert and clean formatting --- package.json | 2 +- test/unit/tx-manager-test.js | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 9e04bc6f7..ba6a81da9 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "eth-query": "^1.0.3", "eth-sig-util": "^1.1.1", "eth-simple-keyring": "^1.1.1", - "ethereumjs-tx": "^1.0.0", + "ethereumjs-tx": "^1.2.5", "ethereumjs-util": "ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9", "ethereumjs-wallet": "^0.6.0", "ethjs-ens": "^1.0.2", diff --git a/test/unit/tx-manager-test.js b/test/unit/tx-manager-test.js index 20f89a226..21e94357b 100644 --- a/test/unit/tx-manager-test.js +++ b/test/unit/tx-manager-test.js @@ -1,5 +1,4 @@ -// const assert = require('assert') -const assert = require('chai').assert +const assert = require('assert') const extend = require('xtend') const EventEmitter = require('events') const ethUtil = require('ethereumjs-util') @@ -22,7 +21,6 @@ describe('Transaction Manager', function() { blockTracker: new EventEmitter(), signTransaction: (ethTx) => new Promise((resolve) => { ethTx.sign(privKey) - const result = ethTx.serialize() resolve() }) }) @@ -229,21 +227,15 @@ describe('Transaction Manager', function() { }) }) - describe('#sign replay-protected tx', function() { it('prepares a tx with the chainId set', function() { txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) txManager.signTransaction('1', (err, rawTx) => { if (err) return assert.fail('it should not fail') const ethTx = new EthTx(ethUtil.toBuffer(rawTx)) - console.log('------------------------------------------') - console.log('ethTx.getChainId(), currentNetworkId') - console.log(ethTx.getChainId(), currentNetworkId) assert.equal(ethTx.getChainId(), currentNetworkId) }) }) }) - - }) From 965c806a45bfc52f66de38a727a87dcde25f5607 Mon Sep 17 00:00:00 2001 From: kumavis Date: Thu, 30 Mar 2017 19:26:01 -0700 Subject: [PATCH 16/16] test - fix notice-controller test --- test/unit/notice-controller-test.js | 33 ++++++++++++++++------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/test/unit/notice-controller-test.js b/test/unit/notice-controller-test.js index 73fdb2f2e..ea37108bb 100644 --- a/test/unit/notice-controller-test.js +++ b/test/unit/notice-controller-test.js @@ -11,8 +11,6 @@ describe('notice-controller', function() { beforeEach(function() { // simple localStorage polyfill - window.localStorage = {} - if (window.localStorage.clear) window.localStorage.clear() let configManager = configManagerGen() noticeController = new NoticeController({ configManager: configManager, @@ -21,7 +19,7 @@ describe('notice-controller', function() { describe('notices', function() { describe('#getNoticesList', function() { - it('should return an empty array when new', function() { + it('should return an empty array when new', function(done) { var testList = [{ id:0, read:false, @@ -29,11 +27,12 @@ describe('notice-controller', function() { }] var result = noticeController.getNoticesList() assert.equal(result.length, 0) + done() }) }) describe('#setNoticesList', function() { - it('should set data appropriately', function () { + it('should set data appropriately', function (done) { var testList = [{ id:0, read:false, @@ -42,11 +41,12 @@ describe('notice-controller', function() { noticeController.setNoticesList(testList) var testListId = noticeController.getNoticesList()[0].id assert.equal(testListId, 0) + done() }) }) describe('#updateNoticeslist', function() { - it('should integrate the latest changes from the source', function() { + it('should integrate the latest changes from the source', function(done) { var testList = [{ id:55, read:false, @@ -57,26 +57,26 @@ describe('notice-controller', function() { var newList = noticeController.getNoticesList() assert.ok(newList[0].id === 55) assert.ok(newList[1]) + done() }) }) - it('should not overwrite any existing fields', function () { + it('should not overwrite any existing fields', function (done) { var testList = [{ id:0, read:false, title:"Futuristic Notice" }] noticeController.setNoticesList(testList) - noticeController.updateNoticesList().then(() => { - var newList = noticeController.getNoticesList() - assert.equal(newList[0].id, 0) - assert.equal(newList[0].title, "Futuristic Notice") - assert.equal(newList.length, 1) - }) + var newList = noticeController.getNoticesList() + assert.equal(newList[0].id, 0) + assert.equal(newList[0].title, "Futuristic Notice") + assert.equal(newList.length, 1) + done() }) }) describe('#markNoticeRead', function () { - it('should mark a notice as read', function () { + it('should mark a notice as read', function (done) { var testList = [{ id:0, read:false, @@ -86,11 +86,12 @@ describe('notice-controller', function() { noticeController.markNoticeRead(testList[0]) var newList = noticeController.getNoticesList() assert.ok(newList[0].read) + done() }) }) describe('#getLatestUnreadNotice', function () { - it('should retrieve the latest unread notice', function () { + it('should retrieve the latest unread notice', function (done) { var testList = [ {id:0,read:true,title:"Past Notice"}, {id:1,read:false,title:"Current Notice"}, @@ -99,8 +100,9 @@ describe('notice-controller', function() { noticeController.setNoticesList(testList) var latestUnread = noticeController.getLatestUnreadNotice() assert.equal(latestUnread.id, 2) + done() }) - it('should return undefined if no unread notices exist.', function () { + it('should return undefined if no unread notices exist.', function (done) { var testList = [ {id:0,read:true,title:"Past Notice"}, {id:1,read:true,title:"Current Notice"}, @@ -109,6 +111,7 @@ describe('notice-controller', function() { noticeController.setNoticesList(testList) var latestUnread = noticeController.getLatestUnreadNotice() assert.ok(!latestUnread) + done() }) }) })