aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md8
-rw-r--r--app/manifest.json2
-rw-r--r--app/scripts/contentscript.js11
-rw-r--r--app/scripts/controllers/network.js27
-rw-r--r--app/scripts/controllers/transactions.js2
-rw-r--r--app/scripts/keyring-controller.js2
-rw-r--r--app/scripts/lib/account-tracker.js4
-rw-r--r--app/scripts/lib/events-proxy.js31
-rw-r--r--app/scripts/metamask-controller.js4
-rw-r--r--app/scripts/migrations/_multi-keyring.js2
-rw-r--r--package.json10
-rw-r--r--test/unit/keyring-controller-test.js164
-rw-r--r--test/unit/network-contoller-test.js3
13 files changed, 71 insertions, 199 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f04136d78..3ad9888fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,15 @@
## Current Master
+## 3.10.5 2017-9-27
+
+- Fix block gas limit estimation.
+
+## 3.10.4 2017-9-27
+
- Fix bug that could mis-render token balances when very small. (Not actually included in 3.9.9)
+- Fix memory leak warning.
+- Fix bug where new event filters would not include historical events.
## 3.10.3 2017-9-21
diff --git a/app/manifest.json b/app/manifest.json
index fd07f15a9..4d02cd334 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "MetaMask",
"short_name": "Metamask",
- "version": "3.10.3",
+ "version": "3.10.5",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "Ethereum Browser Extension",
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index 90a0f1f22..b4708189e 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -42,16 +42,21 @@ function setupStreams () {
name: 'contentscript',
target: 'inpage',
})
- pageStream.on('error', console.error)
const pluginPort = extension.runtime.connect({ name: 'contentscript' })
const pluginStream = new PortStream(pluginPort)
- pluginStream.on('error', console.error)
// forward communication plugin->inpage
- pageStream.pipe(pluginStream).pipe(pageStream)
+ pump(
+ pageStream,
+ pluginStream,
+ pageStream,
+ (err) => logStreamDisconnectWarning('MetaMask Contentscript Forwarding', err)
+ )
// setup local multistream channels
const mux = new ObjectMultiplex()
+ mux.setMaxListeners(25)
+
pump(
mux,
pageStream,
diff --git a/app/scripts/controllers/network.js b/app/scripts/controllers/network.js
index 0a3e5e26b..dc9978043 100644
--- a/app/scripts/controllers/network.js
+++ b/app/scripts/controllers/network.js
@@ -4,6 +4,7 @@ const ObservableStore = require('obs-store')
const ComposedStore = require('obs-store/lib/composed')
const extend = require('xtend')
const EthQuery = require('eth-query')
+const createEventEmitterProxy = require('../lib/events-proxy.js')
const RPC_ADDRESS_LIST = require('../config.js').network
const DEFAULT_RPC = RPC_ADDRESS_LIST['rinkeby']
@@ -31,16 +32,8 @@ module.exports = class NetworkController extends EventEmitter {
initializeProvider (opts, providerContructor = MetaMaskProvider) {
this.providerInit = opts
this._provider = providerContructor(opts)
- this._proxy = new Proxy(this._provider, {
- get: (obj, name) => {
- if (name === 'on') return this._on.bind(this)
- return this._provider[name]
- },
- set: (obj, name, value) => {
- this._provider[name] = value
- return value
- },
- })
+ this._proxy = createEventEmitterProxy(this._provider)
+ this.provider._blockTracker = createEventEmitterProxy(this._provider._blockTracker)
this.provider.on('block', this._logBlock.bind(this))
this.provider.on('error', this.verifyNetwork.bind(this))
this.ethQuery = new EthQuery(this.provider)
@@ -55,11 +48,11 @@ module.exports = class NetworkController extends EventEmitter {
this._provider.removeAllListeners()
this._provider.stop()
- this.provider = MetaMaskProvider(newInit)
+ this._provider = MetaMaskProvider(newInit)
// apply the listners created by other controllers
- Object.keys(this._providerListeners).forEach((key) => {
- this._providerListeners[key].forEach((handler) => this._provider.addListener(key, handler))
- })
+ const blockTrackerHandlers = this.provider._blockTracker.proxyEventHandlers
+ this.provider.setTarget(this._provider)
+ this.provider._blockTracker = createEventEmitterProxy(this._provider._blockTracker, blockTrackerHandlers)
this.emit('networkDidChange')
}
@@ -121,10 +114,4 @@ module.exports = class NetworkController extends EventEmitter {
log.info(`BLOCK CHANGED: #${block.number.toString('hex')} 0x${block.hash.toString('hex')}`)
this.verifyNetwork()
}
-
- _on (event, handler) {
- if (!this._providerListeners[event]) this._providerListeners[event] = []
- this._providerListeners[event].push(handler)
- this._provider.on(event, handler)
- }
}
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index 3cd107031..4f5c94675 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -81,7 +81,7 @@ module.exports = class TransactionController extends EventEmitter {
this.txStateManager.updateTx(txMeta)
})
- this.blockTracker.on('rawBlock', this.pendingTxTracker.checkForTxInBlock.bind(this.pendingTxTracker))
+ this.blockTracker.on('block', this.pendingTxTracker.checkForTxInBlock.bind(this.pendingTxTracker))
// this is a little messy but until ethstore has been either
// removed or redone this is to guard against the race condition
// where accountTracker hasent been populated by the results yet
diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js
index 34e008ec4..1a1904621 100644
--- a/app/scripts/keyring-controller.js
+++ b/app/scripts/keyring-controller.js
@@ -568,7 +568,7 @@ class KeyringController extends EventEmitter {
clearKeyrings () {
let accounts
try {
- accounts = Object.keys(this.accountTracker.getState())
+ accounts = Object.keys(this.accountTracker.store.getState())
} catch (e) {
accounts = []
}
diff --git a/app/scripts/lib/account-tracker.js b/app/scripts/lib/account-tracker.js
index e2892b1ce..07fc32b10 100644
--- a/app/scripts/lib/account-tracker.js
+++ b/app/scripts/lib/account-tracker.js
@@ -11,6 +11,7 @@ const async = require('async')
const EthQuery = require('eth-query')
const ObservableStore = require('obs-store')
const EventEmitter = require('events').EventEmitter
+const ethUtil = require('ethereumjs-util')
function noop () {}
@@ -59,8 +60,9 @@ class AccountTracker extends EventEmitter {
_updateForBlock (block) {
const blockNumber = '0x' + block.number.toString('hex')
this._currentBlockNumber = blockNumber
+ const currentBlockGasLimit = ethUtil.addHexPrefix(block.gasLimit.toString())
- this.store.updateState({ currentBlockGasLimit: `0x${block.gasLimit.toString('hex')}` })
+ this.store.updateState({ currentBlockGasLimit })
async.parallel([
this._updateAccounts.bind(this),
diff --git a/app/scripts/lib/events-proxy.js b/app/scripts/lib/events-proxy.js
new file mode 100644
index 000000000..d1199a278
--- /dev/null
+++ b/app/scripts/lib/events-proxy.js
@@ -0,0 +1,31 @@
+module.exports = function createEventEmitterProxy(eventEmitter, listeners) {
+ let target = eventEmitter
+ const eventHandlers = listeners || {}
+ const proxy = new Proxy({}, {
+ get: (obj, name) => {
+ // intercept listeners
+ if (name === 'on') return addListener
+ if (name === 'setTarget') return setTarget
+ if (name === 'proxyEventHandlers') return eventHandlers
+ return target[name]
+ },
+ set: (obj, name, value) => {
+ target[name] = value
+ return true
+ },
+ })
+ function setTarget (eventEmitter) {
+ target = eventEmitter
+ // migrate listeners
+ Object.keys(eventHandlers).forEach((name) => {
+ eventHandlers[name].forEach((handler) => target.on(name, handler))
+ })
+ }
+ function addListener (name, handler) {
+ if (!eventHandlers[name]) eventHandlers[name] = []
+ eventHandlers[name].push(handler)
+ target.on(name, handler)
+ }
+ if (listeners) proxy.setTarget(eventEmitter)
+ return proxy
+} \ No newline at end of file
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 0f850b7f5..dc39ad13e 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -14,7 +14,7 @@ const createOriginMiddleware = require('./lib/createOriginMiddleware')
const createLoggerMiddleware = require('./lib/createLoggerMiddleware')
const createProviderMiddleware = require('./lib/createProviderMiddleware')
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
-const KeyringController = require('./keyring-controller')
+const KeyringController = require('eth-keyring-controller')
const NetworkController = require('./controllers/network')
const PreferencesController = require('./controllers/preferences')
const CurrencyController = require('./controllers/currency')
@@ -82,7 +82,7 @@ module.exports = class MetamaskController extends EventEmitter {
// rpc provider
this.provider = this.initializeProvider()
- this.blockTracker = this.provider
+ this.blockTracker = this.provider._blockTracker
// eth data query tools
this.ethQuery = new EthQuery(this.provider)
diff --git a/app/scripts/migrations/_multi-keyring.js b/app/scripts/migrations/_multi-keyring.js
index 253aa3d9d..7a4578ea7 100644
--- a/app/scripts/migrations/_multi-keyring.js
+++ b/app/scripts/migrations/_multi-keyring.js
@@ -10,7 +10,7 @@ which we dont have access to at the time of this writing.
const ObservableStore = require('obs-store')
const ConfigManager = require('../../app/scripts/lib/config-manager')
const IdentityStoreMigrator = require('../../app/scripts/lib/idStore-migrator')
-const KeyringController = require('../../app/scripts/lib/keyring-controller')
+const KeyringController = require('eth-keyring-controller')
const password = 'obviously not correct'
diff --git a/package.json b/package.json
index 182ae9900..c160cbfde 100644
--- a/package.json
+++ b/package.json
@@ -53,10 +53,8 @@
"async": "^2.5.0",
"await-semaphore": "^0.1.1",
"babel-runtime": "^6.23.0",
- "bip39": "^2.2.0",
"bluebird": "^3.5.0",
"bn.js": "^4.11.7",
- "browser-passworder": "^2.0.3",
"browserify-derequire": "^0.9.4",
"client-sw-ready-event": "^3.3.0",
"clone": "^2.1.1",
@@ -69,9 +67,11 @@
"end-of-stream": "^1.1.0",
"ensnare": "^1.0.0",
"eth-bin-to-ops": "^1.0.1",
+ "eth-block-tracker": "^2.2.0",
"eth-contract-metadata": "^1.1.4",
"eth-hd-keyring": "^1.1.1",
- "eth-json-rpc-filters": "^1.1.0",
+ "eth-json-rpc-filters": "^1.2.1",
+ "eth-keyring-controller": "^1.0.1",
"eth-phishing-detect": "^1.1.4",
"eth-query": "^2.1.2",
"eth-sig-util": "^1.2.2",
@@ -80,6 +80,7 @@
"ethereumjs-tx": "^1.3.0",
"ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
"ethereumjs-wallet": "^0.6.0",
+ "ethjs-contract": "^0.1.9",
"ethjs-ens": "^2.0.0",
"ethjs-query": "^0.2.9",
"express": "^4.14.0",
@@ -90,6 +91,7 @@
"gulp": "github:gulpjs/gulp#4.0",
"gulp-eslint": "^4.0.0",
"hat": "0.0.3",
+ "human-standard-token-abi": "^1.0.2",
"idb-global": "^2.1.0",
"identicon.js": "^2.3.1",
"iframe": "^1.0.0",
@@ -138,7 +140,7 @@
"valid-url": "^1.0.9",
"vreme": "^3.0.2",
"web3": "^0.20.1",
- "web3-provider-engine": "^13.2.9",
+ "web3-provider-engine": "^13.2.12",
"web3-stream-provider": "^3.0.1",
"xtend": "^4.0.1"
},
diff --git a/test/unit/keyring-controller-test.js b/test/unit/keyring-controller-test.js
deleted file mode 100644
index 135edf365..000000000
--- a/test/unit/keyring-controller-test.js
+++ /dev/null
@@ -1,164 +0,0 @@
-const assert = require('assert')
-const KeyringController = require('../../app/scripts/keyring-controller')
-const configManagerGen = require('../lib/mock-config-manager')
-const ethUtil = require('ethereumjs-util')
-const BN = ethUtil.BN
-const mockEncryptor = require('../lib/mock-encryptor')
-const sinon = require('sinon')
-
-describe('KeyringController', function () {
- let keyringController
- const password = 'password123'
- const seedWords = 'puzzle seed penalty soldier say clay field arctic metal hen cage runway'
- const addresses = ['eF35cA8EbB9669A35c31b5F6f249A9941a812AC1'.toLowerCase()]
- const accounts = []
- // let originalKeystore
-
- beforeEach(function (done) {
- this.sinon = sinon.sandbox.create()
- window.localStorage = {} // Hacking localStorage support into JSDom
-
- keyringController = new KeyringController({
- configManager: configManagerGen(),
- txManager: {
- getTxList: () => [],
- getUnapprovedTxList: () => [],
- },
- accountTracker: {
- addAccount (acct) { accounts.push(ethUtil.addHexPrefix(acct)) },
- },
- encryptor: mockEncryptor,
- })
-
- keyringController.createNewVaultAndKeychain(password)
- .then(function (newState) {
- newState
- done()
- })
- .catch((err) => {
- done(err)
- })
- })
-
- afterEach(function () {
- // Cleanup mocks
- this.sinon.restore()
- })
-
- describe('#createNewVaultAndKeychain', function () {
- this.timeout(10000)
-
- it('should set a vault on the configManager', function (done) {
- keyringController.store.updateState({ vault: null })
- assert(!keyringController.store.getState().vault, 'no previous vault')
- keyringController.createNewVaultAndKeychain(password)
- .then(() => {
- const vault = keyringController.store.getState().vault
- assert(vault, 'vault created')
- done()
- })
- .catch((reason) => {
- done(reason)
- })
- })
- })
-
- describe('#restoreKeyring', function () {
- it(`should pass a keyring's serialized data back to the correct type.`, function (done) {
- const mockSerialized = {
- type: 'HD Key Tree',
- data: {
- mnemonic: seedWords,
- numberOfAccounts: 1,
- },
- }
- const mock = this.sinon.mock(keyringController)
-
- mock.expects('getBalanceAndNickname')
- .exactly(1)
-
- keyringController.restoreKeyring(mockSerialized)
- .then((keyring) => {
- assert.equal(keyring.wallets.length, 1, 'one wallet restored')
- return keyring.getAccounts()
- })
- .then((accounts) => {
- assert.equal(accounts[0], addresses[0])
- mock.verify()
- done()
- })
- .catch((reason) => {
- done(reason)
- })
- })
- })
-
- describe('#createNickname', function () {
- it('should add the address to the identities hash', function () {
- const fakeAddress = '0x12345678'
- keyringController.createNickname(fakeAddress)
- const identities = keyringController.memStore.getState().identities
- const identity = identities[fakeAddress]
- assert.equal(identity.address, fakeAddress)
- })
- })
-
- describe('#saveAccountLabel', function () {
- it('sets the nickname', function (done) {
- const account = addresses[0]
- var nick = 'Test nickname'
- const identities = keyringController.memStore.getState().identities
- identities[ethUtil.addHexPrefix(account)] = {}
- keyringController.memStore.updateState({ identities })
- keyringController.saveAccountLabel(account, nick)
- .then((label) => {
- try {
- assert.equal(label, nick)
- const persisted = keyringController.store.getState().walletNicknames[account]
- assert.equal(persisted, nick)
- done()
- } catch (err) {
- done()
- }
- })
- .catch((reason) => {
- done(reason)
- })
- })
- })
-
- describe('#getAccounts', 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]) } },
- ]
-
- keyringController.getAccounts()
- .then((result) => {
- assert.deepEqual(result, [1, 2, 3, 4, 5, 6])
- done()
- })
- })
- })
-
- describe('#addGasBuffer', function () {
- it('adds 100k gas buffer to estimates', function () {
- const gas = '0x04ee59' // Actual estimated gas example
- const tooBigOutput = '0x80674f9' // Actual bad output
- const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16)
- const correctBuffer = new BN('100000', 10)
- const correct = bnGas.add(correctBuffer)
-
- // const tooBig = new BN(tooBigOutput, 16)
- const result = keyringController.addGasBuffer(gas)
- const bnResult = new BN(ethUtil.stripHexPrefix(result), 16)
-
- assert.equal(result.indexOf('0x'), 0, 'included hex prefix')
- assert(bnResult.gt(bnGas), 'Estimate increased in value.')
- assert.equal(bnResult.sub(bnGas).toString(10), '100000', 'added 100k gas')
- assert.equal(result, '0x' + correct.toString(16), 'Added the right amount')
- assert.notEqual(result, tooBigOutput, 'not that bad estimate')
- })
- })
-})
diff --git a/test/unit/network-contoller-test.js b/test/unit/network-contoller-test.js
index 87c2ee7a3..c1fdaf032 100644
--- a/test/unit/network-contoller-test.js
+++ b/test/unit/network-contoller-test.js
@@ -21,7 +21,7 @@ describe('# Network Controller', function () {
it('provider should be updatable without reassignment', function () {
networkController.initializeProvider(networkControllerProviderInit, dummyProviderConstructor)
const provider = networkController.provider
- networkController._provider = {test: true}
+ networkController.provider.setTarget({test: true, on: () => {}})
assert.ok(provider.test)
})
})
@@ -71,6 +71,7 @@ function dummyProviderConstructor() {
// provider
sendAsync: noop,
// block tracker
+ _blockTracker: {},
start: noop,
stop: noop,
on: noop,