From a1c3c944cf534fff8bfb9560347a03ba2a2bda00 Mon Sep 17 00:00:00 2001 From: kumavis Date: Wed, 12 Oct 2016 12:35:55 -0700 Subject: [PATCH 1/3] dapp reload - fixed disconnect detection via polling --- app/scripts/contentscript.js | 20 ++++++++++++-------- app/scripts/inpage.js | 21 ++++++++++++++++----- app/scripts/lib/auto-reload.js | 22 +++++++++++----------- app/scripts/lib/inpage-provider.js | 17 ++++++++++------- app/scripts/lib/obj-multiplex.js | 8 ++++++-- app/scripts/lib/port-stream.js | 3 +-- package.json | 1 + 7 files changed, 57 insertions(+), 35 deletions(-) diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index b3a560c88..3ad145e3e 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -1,4 +1,5 @@ const LocalMessageDuplexStream = require('post-message-stream') +const PongStream = require('ping-pong-stream/pong') const PortStream = require('./lib/port-stream.js') const ObjectMultiplex = require('./lib/obj-multiplex') const extension = require('./lib/extension') @@ -51,17 +52,20 @@ function setupStreams(){ // forward communication plugin->inpage pageStream.pipe(pluginStream).pipe(pageStream) - // connect contentscript->inpage reload stream + // setup local multistream channels var mx = ObjectMultiplex() mx.on('error', console.error) - mx.pipe(pageStream) - var reloadStream = mx.createStream('reload') - reloadStream.on('error', console.error) + mx.pipe(pageStream).pipe(mx) + + // connect ping stream + var pongStream = new PongStream({ objectMode: true }) + pongStream.pipe(mx.createStream('pingpong')).pipe(pongStream) + + // ignore unused channels (handled by background) + mx.ignoreStream('provider') + mx.ignoreStream('publicConfig') + mx.ignoreStream('reload') - // if we lose connection with the plugin, trigger tab refresh - pluginStream.on('close', function () { - reloadStream.write({ method: 'reset' }) - }) } function shouldInjectWeb3(){ diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js index 28a1223ac..ef199946c 100644 --- a/app/scripts/inpage.js +++ b/app/scripts/inpage.js @@ -2,6 +2,8 @@ cleanContextForImports() require('web3/dist/web3.min.js') const LocalMessageDuplexStream = require('post-message-stream') +const PingStream = require('ping-pong-stream/ping') +const endOfStream = require('end-of-stream') const setupDappAutoReload = require('./lib/auto-reload.js') const MetamaskInpageProvider = require('./lib/inpage-provider.js') restoreContextAfterImports() @@ -29,13 +31,22 @@ web3.setProvider = function () { console.log('MetaMask - overrode web3.setProvider') } console.log('MetaMask - injected web3') +// export global web3, with usage-detection reload fn +var triggerReload = setupDappAutoReload(web3) -// -// export global web3 with auto dapp reload -// - +// listen for reset requests from metamask var reloadStream = inpageProvider.multiStream.createStream('reload') -setupDappAutoReload(web3, reloadStream) +reloadStream.once('data', triggerReload) + +// setup ping timeout autoreload +// LocalMessageDuplexStream does not self-close, so reload if pingStream fails +var pingChannel = inpageProvider.multiStream.createStream('pingpong') +var pingStream = new PingStream({ objectMode: true }) +// wait for first successful reponse +metamaskStream.once('data', function(){ + pingStream.pipe(pingChannel).pipe(pingStream) +}) +endOfStream(pingStream, triggerReload) // set web3 defaultAcount inpageProvider.publicConfigStore.subscribe(function (state) { diff --git a/app/scripts/lib/auto-reload.js b/app/scripts/lib/auto-reload.js index c4c8053f0..3c90905db 100644 --- a/app/scripts/lib/auto-reload.js +++ b/app/scripts/lib/auto-reload.js @@ -3,7 +3,7 @@ const ensnare = require('ensnare') module.exports = setupDappAutoReload -function setupDappAutoReload (web3, controlStream) { +function setupDappAutoReload (web3) { // export web3 as a global, checking for usage var pageIsUsingWeb3 = false var resetWasRequested = false @@ -16,19 +16,19 @@ function setupDappAutoReload (web3, controlStream) { global.web3 = web3 })) - // listen for reset requests from metamask - controlStream.once('data', function () { + return handleResetRequest + + function handleResetRequest() { resetWasRequested = true // ignore if web3 was not used if (!pageIsUsingWeb3) return // reload after short timeout - triggerReset() - }) - - // reload the page - function triggerReset () { - setTimeout(function () { - global.location.reload() - }, 500) + setTimeout(triggerReset, 500) } + } + +// reload the page +function triggerReset () { + global.location.reload() +} \ No newline at end of file diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js index bcde333d0..c6bfdb4da 100644 --- a/app/scripts/lib/inpage-provider.js +++ b/app/scripts/lib/inpage-provider.js @@ -1,6 +1,6 @@ const Streams = require('mississippi') -const ObjectMultiplex = require('./obj-multiplex') const StreamProvider = require('web3-stream-provider') +const ObjectMultiplex = require('./obj-multiplex') const RemoteStore = require('./remote-store.js').RemoteStore module.exports = MetamaskInpageProvider @@ -11,8 +11,9 @@ function MetamaskInpageProvider (connectionStream) { // setup connectionStream multiplexing var multiStream = ObjectMultiplex() Streams.pipe(connectionStream, multiStream, connectionStream, function (err) { - console.warn('MetamaskInpageProvider - lost connection to MetaMask') - if (err) throw err + let warningMsg = 'MetamaskInpageProvider - lost connection to MetaMask' + if (err) warningMsg += '\n' + err.stack + console.warn(warningMsg) }) self.multiStream = multiStream @@ -20,16 +21,18 @@ function MetamaskInpageProvider (connectionStream) { var publicConfigStore = remoteStoreWithLocalStorageCache('MetaMask-Config') var storeStream = publicConfigStore.createStream() Streams.pipe(storeStream, multiStream.createStream('publicConfig'), storeStream, function (err) { - console.warn('MetamaskInpageProvider - lost connection to MetaMask publicConfig') - if (err) throw err + let warningMsg = 'MetamaskInpageProvider - lost connection to MetaMask publicConfig' + if (err) warningMsg += '\n' + err.stack + console.warn(warningMsg) }) self.publicConfigStore = publicConfigStore // connect to async provider var asyncProvider = new StreamProvider() Streams.pipe(asyncProvider, multiStream.createStream('provider'), asyncProvider, function (err) { - console.warn('MetamaskInpageProvider - lost connection to MetaMask provider') - if (err) throw err + let warningMsg = 'MetamaskInpageProvider - lost connection to MetaMask provider' + if (err) warningMsg += '\n' + err.stack + console.warn(warningMsg) }) asyncProvider.on('error', console.error.bind(console)) self.asyncProvider = asyncProvider diff --git a/app/scripts/lib/obj-multiplex.js b/app/scripts/lib/obj-multiplex.js index f54ff7653..bd114c394 100644 --- a/app/scripts/lib/obj-multiplex.js +++ b/app/scripts/lib/obj-multiplex.js @@ -10,9 +10,9 @@ function ObjectMultiplex (opts) { var data = chunk.data var substream = mx.streams[name] if (!substream) { - console.warn('orphaned data for stream ' + name) + console.warn(`orphaned data for stream "${name}"`) } else { - substream.push(data) + if (substream.push) substream.push(data) } return cb() }) @@ -36,5 +36,9 @@ function ObjectMultiplex (opts) { } return substream } + // ignore streams (dont display orphaned data warning) + mx.ignoreStream = function (name) { + mx.streams[name] = true + } return mx } diff --git a/app/scripts/lib/port-stream.js b/app/scripts/lib/port-stream.js index 6f59d4485..6f4ccc6ab 100644 --- a/app/scripts/lib/port-stream.js +++ b/app/scripts/lib/port-stream.js @@ -53,8 +53,7 @@ PortDuplexStream.prototype._write = function (msg, encoding, cb) { } cb() } catch (err) { - console.error(err) - // this.emit('error', err) + // console.error(err) cb(new Error('PortDuplexStream - disconnected')) } } diff --git a/package.json b/package.json index 273117f8a..ea67eee75 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "mississippi": "^1.2.0", "multiplex": "^6.7.0", "once": "^1.3.3", + "ping-pong-stream": "^1.0.0", "pojo-migrator": "^2.1.0", "polyfill-crypto.getrandomvalues": "^1.0.0", "post-message-stream": "^1.0.0", From 3954ed2a7e28fd57f4705bbff30cb248c2d02392 Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 12 Oct 2016 13:04:21 -0700 Subject: [PATCH 2/3] Fix misnamed variable. --- app/scripts/metamask-controller.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 550531d6e..700d3f2ec 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -280,9 +280,11 @@ module.exports = class MetamaskController { checkTOSChange () { try { const storedHash = this.configManager.getTOSHash() || 0 - if (storedHash !== global.newTOSHash) { + console.log('storedHash is: ', storedHash) + console.log('global.TOS_HASH is: ', global.TOS_HASH) + if (storedHash !== global.TOS_HASH) { this.resetDisclaimer() - this.setTOSHash(global.newTOSHash) + this.setTOSHash(global.TOS_HASH) } } catch (e) { console.error('Error in checking TOS change.') From d750daed5ca0eccd741708e03a770b9f6c7ac36c Mon Sep 17 00:00:00 2001 From: Kevin Serrano Date: Wed, 12 Oct 2016 13:05:15 -0700 Subject: [PATCH 3/3] Remove logs. --- app/scripts/metamask-controller.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 700d3f2ec..65c5ba58b 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -280,8 +280,6 @@ module.exports = class MetamaskController { checkTOSChange () { try { const storedHash = this.configManager.getTOSHash() || 0 - console.log('storedHash is: ', storedHash) - console.log('global.TOS_HASH is: ', global.TOS_HASH) if (storedHash !== global.TOS_HASH) { this.resetDisclaimer() this.setTOSHash(global.TOS_HASH)