Skip to content

Commit e72083f

Browse files
authored
Merge branch 'master' into filter-fixes-moar
2 parents ff5e874 + ca0dff0 commit e72083f

21 files changed

+397
-260
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Current Master
44

5+
- Fix bug that could mis-render token balances when very small. (Not actually included in 3.9.9)
6+
7+
## 3.10.3 2017-9-21
8+
59
- Fix bug where metamask-dapp connections are lost on rpc error
610
- Fix bug that would sometimes display transactions as failed that could be successfully mined.
711

app/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "MetaMask",
33
"short_name": "Metamask",
4-
"version": "3.10.2",
4+
"version": "3.10.3",
55
"manifest_version": 2,
66
"author": "https://metamask.io",
77
"description": "Ethereum Browser Extension",

app/scripts/controllers/balance.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
const ObservableStore = require('obs-store')
2+
const PendingBalanceCalculator = require('../lib/pending-balance-calculator')
3+
const BN = require('ethereumjs-util').BN
4+
5+
class BalanceController {
6+
7+
constructor (opts = {}) {
8+
const { address, accountTracker, txController, blockTracker } = opts
9+
this.address = address
10+
this.accountTracker = accountTracker
11+
this.txController = txController
12+
this.blockTracker = blockTracker
13+
14+
const initState = {
15+
ethBalance: undefined,
16+
}
17+
this.store = new ObservableStore(initState)
18+
19+
this.balanceCalc = new PendingBalanceCalculator({
20+
getBalance: () => this._getBalance(),
21+
getPendingTransactions: this._getPendingTransactions.bind(this),
22+
})
23+
24+
this._registerUpdates()
25+
}
26+
27+
async updateBalance () {
28+
const balance = await this.balanceCalc.getBalance()
29+
this.store.updateState({
30+
ethBalance: balance,
31+
})
32+
}
33+
34+
_registerUpdates () {
35+
const update = this.updateBalance.bind(this)
36+
this.txController.on('submitted', update)
37+
this.txController.on('confirmed', update)
38+
this.txController.on('failed', update)
39+
this.accountTracker.store.subscribe(update)
40+
this.blockTracker.on('block', update)
41+
}
42+
43+
async _getBalance () {
44+
const { accounts } = this.accountTracker.store.getState()
45+
const entry = accounts[this.address]
46+
const balance = entry.balance
47+
return balance ? new BN(balance.substring(2), 16) : undefined
48+
}
49+
50+
async _getPendingTransactions () {
51+
const pending = this.txController.getFilteredTxList({
52+
from: this.address,
53+
status: 'submitted',
54+
err: undefined,
55+
})
56+
return pending
57+
}
58+
59+
}
60+
61+
module.exports = BalanceController
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const ObservableStore = require('obs-store')
2+
const extend = require('xtend')
3+
const BalanceController = require('./balance')
4+
5+
class ComputedbalancesController {
6+
7+
constructor (opts = {}) {
8+
const { accountTracker, txController, blockTracker } = opts
9+
this.accountTracker = accountTracker
10+
this.txController = txController
11+
this.blockTracker = blockTracker
12+
13+
const initState = extend({
14+
computedBalances: {},
15+
}, opts.initState)
16+
this.store = new ObservableStore(initState)
17+
this.balances = {}
18+
19+
this._initBalanceUpdating()
20+
}
21+
22+
updateAllBalances () {
23+
for (let address in this.accountTracker.store.getState().accounts) {
24+
this.balances[address].updateBalance()
25+
}
26+
}
27+
28+
_initBalanceUpdating () {
29+
const store = this.accountTracker.store.getState()
30+
this.addAnyAccountsFromStore(store)
31+
this.accountTracker.store.subscribe(this.addAnyAccountsFromStore.bind(this))
32+
}
33+
34+
addAnyAccountsFromStore(store) {
35+
const balances = store.accounts
36+
37+
for (let address in balances) {
38+
this.trackAddressIfNotAlready(address)
39+
}
40+
}
41+
42+
trackAddressIfNotAlready (address) {
43+
const state = this.store.getState()
44+
if (!(address in state.computedBalances)) {
45+
this.trackAddress(address)
46+
}
47+
}
48+
49+
trackAddress (address) {
50+
let updater = new BalanceController({
51+
address,
52+
accountTracker: this.accountTracker,
53+
txController: this.txController,
54+
blockTracker: this.blockTracker,
55+
})
56+
updater.store.subscribe((accountBalance) => {
57+
let newState = this.store.getState()
58+
newState.computedBalances[address] = accountBalance
59+
this.store.updateState(newState)
60+
})
61+
this.balances[address] = updater
62+
updater.updateBalance()
63+
}
64+
}
65+
66+
module.exports = ComputedbalancesController

app/scripts/controllers/transactions.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ module.exports = class TransactionController extends EventEmitter {
2222
this.provider = opts.provider
2323
this.blockTracker = opts.blockTracker
2424
this.signEthTx = opts.signTransaction
25-
this.ethStore = opts.ethStore
25+
this.accountTracker = opts.accountTracker
2626

2727
this.nonceTracker = new NonceTracker({
2828
provider: this.provider,
@@ -52,7 +52,7 @@ module.exports = class TransactionController extends EventEmitter {
5252
provider: this.provider,
5353
nonceTracker: this.nonceTracker,
5454
getBalance: (address) => {
55-
const account = this.ethStore.getState().accounts[address]
55+
const account = this.accountTracker.getState().accounts[address]
5656
if (!account) return
5757
return account.balance
5858
},
@@ -73,7 +73,7 @@ module.exports = class TransactionController extends EventEmitter {
7373
this.blockTracker.on('block', this.pendingTxTracker.checkForTxInBlock.bind(this.pendingTxTracker))
7474
// this is a little messy but until ethstore has been either
7575
// removed or redone this is to guard against the race condition
76-
// where ethStore hasent been populated by the results yet
76+
// where accountTracker hasent been populated by the results yet
7777
this.blockTracker.once('latest', () => {
7878
this.blockTracker.on('latest', this.pendingTxTracker.resubmitPendingTxs.bind(this.pendingTxTracker))
7979
})
@@ -434,6 +434,7 @@ module.exports = class TransactionController extends EventEmitter {
434434
const txMeta = this.getTx(txId)
435435
txMeta.status = status
436436
this.emit(`${txMeta.id}:${status}`, txId)
437+
this.emit(`${status}`, txId)
437438
if (status === 'submitted' || status === 'rejected') {
438439
this.emit(`${txMeta.id}:finished`, txMeta)
439440
}

app/scripts/keyring-controller.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ class KeyringController extends EventEmitter {
3535
keyrings: [],
3636
identities: {},
3737
})
38-
this.ethStore = opts.ethStore
39-
this.encryptor = encryptor
38+
39+
this.accountTracker = opts.accountTracker
40+
this.encryptor = opts.encryptor || encryptor
4041
this.keyrings = []
4142
this.getNetwork = opts.getNetwork
4243
}
@@ -338,7 +339,7 @@ class KeyringController extends EventEmitter {
338339
//
339340
// Initializes the provided account array
340341
// Gives them numerically incremented nicknames,
341-
// and adds them to the ethStore for regular balance checking.
342+
// and adds them to the accountTracker for regular balance checking.
342343
setupAccounts (accounts) {
343344
return this.getAccounts()
344345
.then((loadedAccounts) => {
@@ -361,7 +362,7 @@ class KeyringController extends EventEmitter {
361362
throw new Error('Problem loading account.')
362363
}
363364
const address = normalizeAddress(account)
364-
this.ethStore.addAccount(address)
365+
this.accountTracker.addAccount(address)
365366
return this.createNickname(address)
366367
}
367368

@@ -567,12 +568,12 @@ class KeyringController extends EventEmitter {
567568
clearKeyrings () {
568569
let accounts
569570
try {
570-
accounts = Object.keys(this.ethStore.getState())
571+
accounts = Object.keys(this.accountTracker.getState())
571572
} catch (e) {
572573
accounts = []
573574
}
574575
accounts.forEach((address) => {
575-
this.ethStore.removeAccount(address)
576+
this.accountTracker.removeAccount(address)
576577
})
577578

578579
// clear keyrings from memory
Lines changed: 21 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Ethereum Store
1+
/* Account Tracker
22
*
33
* This module is responsible for tracking any number of accounts
44
* and caching their current balances & transaction counts.
@@ -10,19 +10,21 @@
1010
const async = require('async')
1111
const EthQuery = require('eth-query')
1212
const ObservableStore = require('obs-store')
13+
const EventEmitter = require('events').EventEmitter
1314
function noop () {}
1415

1516

16-
class EthereumStore extends ObservableStore {
17+
class AccountTracker extends EventEmitter {
1718

1819
constructor (opts = {}) {
19-
super({
20+
super()
21+
22+
const initState = {
2023
accounts: {},
21-
transactions: {},
22-
currentBlockNumber: '0',
23-
currentBlockHash: '',
2424
currentBlockGasLimit: '',
25-
})
25+
}
26+
this.store = new ObservableStore(initState)
27+
2628
this._provider = opts.provider
2729
this._query = new EthQuery(this._provider)
2830
this._blockTracker = opts.blockTracker
@@ -37,88 +39,52 @@ class EthereumStore extends ObservableStore {
3739
//
3840

3941
addAccount (address) {
40-
const accounts = this.getState().accounts
42+
const accounts = this.store.getState().accounts
4143
accounts[address] = {}
42-
this.updateState({ accounts })
44+
this.store.updateState({ accounts })
4345
if (!this._currentBlockNumber) return
4446
this._updateAccount(address)
4547
}
4648

4749
removeAccount (address) {
48-
const accounts = this.getState().accounts
50+
const accounts = this.store.getState().accounts
4951
delete accounts[address]
50-
this.updateState({ accounts })
51-
}
52-
53-
addTransaction (txHash) {
54-
const transactions = this.getState().transactions
55-
transactions[txHash] = {}
56-
this.updateState({ transactions })
57-
if (!this._currentBlockNumber) return
58-
this._updateTransaction(this._currentBlockNumber, txHash, noop)
59-
}
60-
61-
removeTransaction (txHash) {
62-
const transactions = this.getState().transactions
63-
delete transactions[txHash]
64-
this.updateState({ transactions })
52+
this.store.updateState({ accounts })
6553
}
6654

67-
6855
//
6956
// private
7057
//
7158

7259
_updateForBlock (block) {
7360
const blockNumber = '0x' + block.number.toString('hex')
7461
this._currentBlockNumber = blockNumber
75-
this.updateState({ currentBlockNumber: parseInt(blockNumber) })
76-
this.updateState({ currentBlockHash: `0x${block.hash.toString('hex')}`})
77-
this.updateState({ currentBlockGasLimit: `0x${block.gasLimit.toString('hex')}` })
62+
63+
this.store.updateState({ currentBlockGasLimit: `0x${block.gasLimit.toString('hex')}` })
64+
7865
async.parallel([
7966
this._updateAccounts.bind(this),
80-
this._updateTransactions.bind(this, blockNumber),
8167
], (err) => {
8268
if (err) return console.error(err)
83-
this.emit('block', this.getState())
69+
this.emit('block', this.store.getState())
8470
})
8571
}
8672

8773
_updateAccounts (cb = noop) {
88-
const accounts = this.getState().accounts
74+
const accounts = this.store.getState().accounts
8975
const addresses = Object.keys(accounts)
9076
async.each(addresses, this._updateAccount.bind(this), cb)
9177
}
9278

9379
_updateAccount (address, cb = noop) {
94-
const accounts = this.getState().accounts
9580
this._getAccount(address, (err, result) => {
9681
if (err) return cb(err)
9782
result.address = address
83+
const accounts = this.store.getState().accounts
9884
// only populate if the entry is still present
9985
if (accounts[address]) {
10086
accounts[address] = result
101-
this.updateState({ accounts })
102-
}
103-
cb(null, result)
104-
})
105-
}
106-
107-
_updateTransactions (block, cb = noop) {
108-
const transactions = this.getState().transactions
109-
const txHashes = Object.keys(transactions)
110-
async.each(txHashes, this._updateTransaction.bind(this, block), cb)
111-
}
112-
113-
_updateTransaction (block, txHash, cb = noop) {
114-
// would use the block here to determine how many confirmations the tx has
115-
const transactions = this.getState().transactions
116-
this._query.getTransaction(txHash, (err, result) => {
117-
if (err) return cb(err)
118-
// only populate if the entry is still present
119-
if (transactions[txHash]) {
120-
transactions[txHash] = result
121-
this.updateState({ transactions })
87+
this.store.updateState({ accounts })
12288
}
12389
cb(null, result)
12490
})
@@ -135,4 +101,4 @@ class EthereumStore extends ObservableStore {
135101

136102
}
137103

138-
module.exports = EthereumStore
104+
module.exports = AccountTracker

0 commit comments

Comments
 (0)