From 529304c005318852b60bb93846a58d6eb3da2066 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 23 May 2017 01:56:10 -0400 Subject: [PATCH] Wrap the provider in a proxy --- app/scripts/controllers/network.js | 110 +++++++++++------------- app/scripts/controllers/transactions.js | 27 ++---- app/scripts/keyring-controller.js | 6 -- app/scripts/lib/config-manager.js | 5 +- app/scripts/metamask-controller.js | 42 ++------- 5 files changed, 64 insertions(+), 126 deletions(-) diff --git a/app/scripts/controllers/network.js b/app/scripts/controllers/network.js index 82eabb573..97c2ccbc2 100644 --- a/app/scripts/controllers/network.js +++ b/app/scripts/controllers/network.js @@ -3,21 +3,29 @@ const MetaMaskProvider = require('web3-provider-engine/zero.js') const ObservableStore = require('obs-store') const extend = require('xtend') const EthQuery = require('eth-query') -const MetamaskConfig = require('../config.js') - -const TESTNET_RPC = MetamaskConfig.network.testnet -const MAINNET_RPC = MetamaskConfig.network.mainnet -const MORDEN_RPC = MetamaskConfig.network.morden -const KOVAN_RPC = MetamaskConfig.network.kovan -const RINKEBY_RPC = MetamaskConfig.network.rinkeby +const RPC_ADDRESS_LIST = require('../config.js').network module.exports = class NetworkController extends EventEmitter { constructor (providerOpts) { super() this.networkStore = new ObservableStore({ network: 'loading' }) - providerOpts.provider.rpcTarget = this.getRpcAddressForType(providerOpts.provider.type) + providerOpts.provider.rpcTarget = this.getRpcAddressForType(providerOpts.provider.type, providerOpts.provider) this.providerStore = new ObservableStore(providerOpts) - this._claimed = 0 + this.store = new ObservableStore(extend(this.networkStore.getState(), this.providerStore.getState())) + + this._providerListners = {} + + this.networkStore.subscribe((state) => this.store.updateState(state)) + this.providerStore.subscribe((state) => this.store.updateState(state)) + this.on('networkSwitch', this.lookupNetwork) + } + + get provider () { + return this._proxy + } + + set provider (provider) { + this._provider = provider } getState () { @@ -29,28 +37,35 @@ module.exports = class NetworkController extends EventEmitter { initializeProvider (opts) { this.providerConfig = opts - this.provider = MetaMaskProvider(opts) + this._provider = MetaMaskProvider(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 + }, + }) + this.provider.on('block', this._logBlock.bind(this)) + this.provider.on('error', this.verifyNetwork.bind(this)) this.ethQuery = new EthQuery(this.provider) this.lookupNetwork() - return Promise.resolve(this.provider) + return this.provider } + switchNetwork (providerConfig) { - delete this.provider - delete this.ethQuery const newConfig = extend(this.providerConfig, providerConfig) this.providerConfig = newConfig + this.provider = MetaMaskProvider(newConfig) - this.ethQuery = new EthQuery(this.provider) - this.emit('networkSwitch', { - provider: this.provider, - ethQuery: this.ethQuery, - }, this.claim.bind(this)) + // apply the listners created by other controllers + Object.keys(this._providerListners).forEach((key) => { + this._providerListners[key].forEach((handler) => this._provider.addListener(key, handler)) + }) + this.emit('networkSwitch', this.provider) } - subscribe (cb) { - this.networkStore.subscribe(cb) - this.providerStore.subscribe(cb) - } verifyNetwork () { // Check network when restoring connectivity: @@ -74,7 +89,6 @@ module.exports = class NetworkController extends EventEmitter { this.ethQuery.sendAsync({ method: 'net_version' }, (err, network) => { if (err) return this.setNetworkState('loading') - log.info('web3.getNetwork returned ' + network) this.setNetworkState(network) }) @@ -102,51 +116,27 @@ module.exports = class NetworkController extends EventEmitter { this.switchNetwork({ rpcUrl: rpcTarget, }) - this.once('claimed', () => { - this.providerStore.updateState({provider: {type, rpcTarget}}) - console.log('CLAIMED') - this.lookupNetwork() - }) - - } - - useEtherscanProvider () { - this.setProviderType('etherscan') + this.providerStore.updateState({provider: {type, rpcTarget}}) } getProvider () { return this.providerStore.getState().provider } - getRpcAddressForType (type) { - const provider = this.getProvider() - switch (type) { - - case 'mainnet': - return MAINNET_RPC - - case 'testnet': - return TESTNET_RPC - - case 'morden': - return MORDEN_RPC - - case 'kovan': - return KOVAN_RPC - - case 'rinkeby': - return RINKEBY_RPC + getRpcAddressForType (type, provider = this.getProvider()) { + console.log(`#getRpcAddressForType: ${type}`) + if (type in RPC_ADDRESS_LIST) return RPC_ADDRESS_LIST[type] + return provider && provider.rpcTarget ? provider.rpcTarget : RPC_ADDRESS_LIST['rinkeby'] + } - default: - return provider && provider.rpcTarget ? provider.rpcTarget : TESTNET_RPC - } + _logBlock (block) { + log.info(`BLOCK CHANGED: #${block.number.toString('hex')} 0x${block.hash.toString('hex')}`) + this.verifyNetwork() } - claim () { - this._claimed += 1 - if (this._claimed === this.listenerCount('networkSwitch')) { - this.emit('claimed') - this._claimed = 0 - } + _on (event, handler) { + if (!this._providerListners[event]) this._providerListners[event] = [] + this._providerListners[event].push(handler) + this._provider.on(event, handler) } } diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index cfeeab6e6..b9bea2f1c 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -4,7 +4,6 @@ const extend = require('xtend') const Semaphore = require('semaphore') const ObservableStore = require('obs-store') const ethUtil = require('ethereumjs-util') -const EthQuery = require('eth-query') const TxProviderUtil = require('../lib/tx-utils') const createId = require('../lib/random-id') @@ -18,11 +17,13 @@ module.exports = class TransactionManager extends EventEmitter { this.networkStore = opts.networkStore || new ObservableStore({}) this.preferencesStore = opts.preferencesStore || new ObservableStore({}) this.txHistoryLimit = opts.txHistoryLimit - this.setupProviderAndEthQuery({ - provider: opts.provider, - blockTracker: opts.blockTracker, - ethQuery: opts.ethQuery, - }) + this.provider = opts.provider + this.blockTracker = opts.blockTracker + this.query = opts.ethQuery + this.txProviderUtils = new TxProviderUtil(this.query) + this.networkStore.subscribe((_) => this.blockTracker.on('block', this.checkForTxInBlock.bind(this))) + this.blockTracker.on('block', this.checkForTxInBlock.bind(this)) + this.signEthTx = opts.signTransaction this.nonceLock = Semaphore(1) @@ -41,20 +42,6 @@ module.exports = class TransactionManager extends EventEmitter { return this.networkStore.getState().network } - setupProviderAndEthQuery ({provider, blockTracker, ethQuery}) { - if (this.provider) { - delete this.provider - delete this.blockTracker - delete this.query - delete this.txProviderUtils - } - this.provider = provider - this.query = ethQuery - this.txProviderUtils = new TxProviderUtil(ethQuery) - blockTracker ? this.blockTracker = blockTracker : this.blockTracker = provider - this.blockTracker.on('block', this.checkForTxInBlock.bind(this)) - } - getSelectedAddress () { return this.preferencesStore.getState().selectedAddress } diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js index bb699ca8b..5b3c80e40 100644 --- a/app/scripts/keyring-controller.js +++ b/app/scripts/keyring-controller.js @@ -41,12 +41,6 @@ class KeyringController extends EventEmitter { this.getNetwork = opts.getNetwork } - setEthStore (ethStore) { - delete this.ethStore - this.ethStore = ethStore - return this.setupAccounts() - } - // Full Update // returns Promise( @object state ) // diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js index 6ca9bd9ea..fee8423fa 100644 --- a/app/scripts/lib/config-manager.js +++ b/app/scripts/lib/config-manager.js @@ -1,14 +1,13 @@ const ethUtil = require('ethereumjs-util') const normalize = require('eth-sig-util').normalize +const MetamaskConfig = require('../config.js') + -<<<<<<< HEAD -======= const MAINNET_RPC = MetamaskConfig.network.mainnet const ROPSTEN_RPC = MetamaskConfig.network.ropsten const KOVAN_RPC = MetamaskConfig.network.kovan const RINKEBY_RPC = MetamaskConfig.network.rinkeby ->>>>>>> master /* The config-manager is a convenience object * wrapping a pojo-migrator. * diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index b93f627bb..ef82da0d3 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -40,6 +40,7 @@ module.exports = class MetamaskController extends EventEmitter { this.store = new ObservableStore(initState) // network store + this.networkController = new NetworkController(initState.NetworkController) // config manager this.configManager = new ConfigManager({ @@ -60,12 +61,11 @@ module.exports = class MetamaskController extends EventEmitter { // rpc provider this.provider = this.initializeProvider() - this.provider.on('block', this.logBlock.bind(this)) - this.provider.on('error', this.networkController.verifyNetwork.bind(this.networkController)) // eth data query tools this.ethQuery = new EthQuery(this.provider) this.ethStore = new EthStore({ + network: this.networkController.networkStore, provider: this.provider, blockTracker: this.provider, }) @@ -111,32 +111,6 @@ module.exports = class MetamaskController extends EventEmitter { this.shapeshiftController = new ShapeShiftController({ initState: initState.ShapeShiftController, }) - this.networkController.on('networkSwitch', (providerUtil, claimed) => { - delete this.provider - delete this.ethQuery - delete this.ethStore - console.log('order:@? 1') - this.provider = providerUtil.provider - this.provider.on('block', this.logBlock.bind(this)) - this.provider.on('error', this.networkController.verifyNetwork.bind(this.networkController)) - - this.ethQuery = providerUtil.ethQuery - this.ethStore = new EthStore({ - provider: this.provider, - blockTracker: this.provider, - }) - this.provider.once('block', claimed) - }) - this.networkController.on('networkSwitch', (_, claimed) => { - console.log('order:@? 2') - this.txManager.setupProviderAndEthQuery({ - provider: this.provider, - blockTracker: this.provider, - ethQuery: this.ethQuery, - }) - this.keyringController.setEthStore(this.ethStore) - .then(claimed) - }) this.networkController.lookupNetwork() this.messageManager = new MessageManager() @@ -170,7 +144,7 @@ module.exports = class MetamaskController extends EventEmitter { }) // manual mem state subscriptions - this.networkController.subscribe(this.sendUpdate.bind(this)) + this.networkController.store.subscribe(this.sendUpdate.bind(this)) this.ethStore.subscribe(this.sendUpdate.bind(this)) this.txController.memStore.subscribe(this.sendUpdate.bind(this)) this.messageManager.memStore.subscribe(this.sendUpdate.bind(this)) @@ -188,7 +162,7 @@ module.exports = class MetamaskController extends EventEmitter { // initializeProvider () { - this.networkController.initializeProvider({ + return this.networkController.initializeProvider({ static: { eth_syncing: false, web3_clientVersion: `MetaMask/v${version}`, @@ -213,7 +187,6 @@ module.exports = class MetamaskController extends EventEmitter { // new style msg signing processPersonalMessage: this.newUnsignedPersonalMessage.bind(this), }) - return this.networkController.provider } initPublicConfigStore () { @@ -249,7 +222,7 @@ module.exports = class MetamaskController extends EventEmitter { { isInitialized, }, - this.networkController.getState(), + this.networkController.store.getState(), this.ethStore.getState(), this.txController.memStore.getState(), this.messageManager.memStore.getState(), @@ -284,7 +257,6 @@ module.exports = class MetamaskController extends EventEmitter { // etc getState: (cb) => cb(null, this.getState()), setProviderType: this.networkController.setProviderType.bind(this.networkController), - useEtherscanProvider: this.networkController.useEtherscanProvider.bind(this.networkController), setCurrentCurrency: this.setCurrentCurrency.bind(this), markAccountsFound: this.markAccountsFound.bind(this), // coinbase @@ -618,10 +590,6 @@ module.exports = class MetamaskController extends EventEmitter { // // Log blocks - logBlock (block) { - log.info(`BLOCK CHANGED: #${block.number.toString('hex')} 0x${block.hash.toString('hex')}`) - this.networkController.verifyNetwork() - } setCurrentCurrency (currencyCode, cb) { try {