From ad4ebfdc3c22e3900e4475fab8d5d96c0068e1cc Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 28 Aug 2014 16:37:34 -0300 Subject: [PATCH 1/9] add resync to refresh button --- js/controllers/sidebar.js | 2 +- js/models/core/Wallet.js | 16 +--------------- js/models/network/Async.js | 5 ++++- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/js/controllers/sidebar.js b/js/controllers/sidebar.js index e93bf27e2..db34c12be 100644 --- a/js/controllers/sidebar.js +++ b/js/controllers/sidebar.js @@ -36,7 +36,7 @@ angular.module('copayApp.controllers').controller('SidebarController', function( $scope.refresh = function() { var w = $rootScope.wallet; - w.connectToAll(); + w.sendWalletReady(); if ($rootScope.addrInfos.length > 0) { controllerUtils.updateBalance(function() { $rootScope.$digest(); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index f214625a6..86ac1f3ae 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -86,19 +86,6 @@ Wallet.prototype.seedCopayer = function(pubKey) { this.seededCopayerId = pubKey; }; -// not being used now -Wallet.prototype.connectToAll = function() { - // not being used now - return; - - var all = this.publicKeyRing.getAllCopayerIds(); - this.network.connectToCopayers(all); - if (this.seededCopayerId) { - this.sendWalletReady(this.seededCopayerId); - this.seededCopayerId = null; - } -}; - Wallet.prototype._onIndexes = function(senderId, data) { this.log('RECV INDEXES:', data); var inIndexes = HDParams.fromList(data.indexes); @@ -647,8 +634,7 @@ Wallet.prototype.sendReject = function(ntxid) { Wallet.prototype.sendWalletReady = function(recipients) { - preconditions.checkArgument(recipients); - this.log('### SENDING WalletReady TO:', recipients); + this.log('### SENDING WalletReady TO:', recipients || 'All'); this.send(recipients, { type: 'walletReady', diff --git a/js/models/network/Async.js b/js/models/network/Async.js index cb7d078ee..e3075496c 100644 --- a/js/models/network/Async.js +++ b/js/models/network/Async.js @@ -345,13 +345,16 @@ Network.prototype.send = function(dest, payload, cb) { dest = this.getCopayerIds(); payload.isBroadcast = 1; } + console.log('SEND to: ' + to, payload); + if (typeof dest === 'string') dest = [dest]; var l = dest.length; var i = 0; - //console.log('sending ' + JSON.stringify(payload)); dest.forEach(function(to) { + + //console.log('\t to ' + to); var message = self.encode(to, payload); From 534a5f6349065320395ffa504cfe4827daffa95a Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 28 Aug 2014 18:05:29 -0300 Subject: [PATCH 2/9] update timestamp *after* processing messages --- js/models/core/Wallet.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 86ac1f3ae..3a31bc4e0 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -317,10 +317,10 @@ Wallet.prototype._onData = function(senderId, data, ts) { preconditions.checkArgument(ts); preconditions.checkArgument(typeof ts === 'number'); - this.updateTimestamp(ts); if (data.type !== 'walletId' && this.id !== data.walletId) { this.emit('corrupt', senderId); + this.updateTimestamp(ts); return; } @@ -356,6 +356,7 @@ Wallet.prototype._onData = function(senderId, data, ts) { this._onDisconnect(senderId, data); break; } + this.updateTimestamp(ts); }; From 9888bc9448dc9ba94c79a26495a6ac9665ae37ca Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 28 Aug 2014 18:43:04 -0300 Subject: [PATCH 3/9] handle no-messages --- js/models/core/Wallet.js | 10 +++++++++- js/models/network/Async.js | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 3a31bc4e0..7614f0fdc 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -310,6 +310,12 @@ Wallet.prototype.updateTimestamp = function(ts) { this.store(); }; + +Wallet.prototype._onNoMessages = function() { + console.log('No messages at the server. Requesting sync'); //TODO + this.sendWalletReady(senderId); +}; + Wallet.prototype._onData = function(senderId, data, ts) { preconditions.checkArgument(senderId); preconditions.checkArgument(data); @@ -355,9 +361,10 @@ Wallet.prototype._onData = function(senderId, data, ts) { case 'disconnect': this._onDisconnect(senderId, data); break; + default: + throw new Error('unknown message type received: '+ data.type + ' from: ' + senderId) } this.updateTimestamp(ts); - }; Wallet.prototype._onConnect = function(newCopayerId) { @@ -433,6 +440,7 @@ Wallet.prototype.netStart = function(callback) { net.removeAllListeners(); net.on('connect', self._onConnect.bind(self)); net.on('data', self._onData.bind(self)); + net.on('no messages', self._onNoMessages.bind(self)); var myId = self.getMyCopayerId(); var myIdPriv = self.getMyCopayerIdPriv(); diff --git a/js/models/network/Async.js b/js/models/network/Async.js index e3075496c..dc6fdbabc 100644 --- a/js/models/network/Async.js +++ b/js/models/network/Async.js @@ -220,6 +220,8 @@ Network.prototype._setupConnectionHandlers = function(cb) { }); self.socket.on('error', self._onError.bind(self)); + self.socket.on('no messages', self.bind(self, 'no messages')); + self.socket.on('connect', function() { self.socket.on('disconnect', function() { @@ -302,6 +304,7 @@ Network.prototype.start = function(opts, openCallback) { }, 500); }); + self.socket.emit('sync', opts.lastTimestamp); self.started = true; }; From 2809a145e215fb5dd47bb3153fd740146f148d3d Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 28 Aug 2014 18:43:20 -0300 Subject: [PATCH 4/9] prevent sending messages to self --- js/models/network/Async.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/models/network/Async.js b/js/models/network/Async.js index dc6fdbabc..18d9b4bc7 100644 --- a/js/models/network/Async.js +++ b/js/models/network/Async.js @@ -356,6 +356,8 @@ Network.prototype.send = function(dest, payload, cb) { var l = dest.length; var i = 0; dest.forEach(function(to) { + if (to === this.copayerId) + continue; //console.log('\t to ' + to); From 6aa959dcf51e2d053deb28abdcb05da67e8419ef Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 28 Aug 2014 18:58:43 -0300 Subject: [PATCH 5/9] rm disconnect message, rename disconnect fn --- js/controllers/sidebar.js | 6 +----- js/models/core/Wallet.js | 21 ++++++--------------- js/models/network/Async.js | 16 ++++++++-------- js/services/controllerUtils.js | 5 +---- 4 files changed, 16 insertions(+), 32 deletions(-) diff --git a/js/controllers/sidebar.js b/js/controllers/sidebar.js index db34c12be..ee356bb94 100644 --- a/js/controllers/sidebar.js +++ b/js/controllers/sidebar.js @@ -49,11 +49,7 @@ angular.module('copayApp.controllers').controller('SidebarController', function( }; function logout() { - var w = $rootScope.wallet; - if (w) { - w.disconnect(); - controllerUtils.logout(); - } + controllerUtils.logout(); } // ng-repeat defined number of times instead of repeating over array? diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 7614f0fdc..80b92ec5a 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -323,6 +323,7 @@ Wallet.prototype._onData = function(senderId, data, ts) { preconditions.checkArgument(ts); preconditions.checkArgument(typeof ts === 'number'); + //console.log('RECV', senderId, data); if (data.type !== 'walletId' && this.id !== data.walletId) { this.emit('corrupt', senderId); @@ -358,12 +359,13 @@ Wallet.prototype._onData = function(senderId, data, ts) { case 'addressbook': this._onAddressBook(senderId, data); break; + // unused messages case 'disconnect': - this._onDisconnect(senderId, data); break; default: throw new Error('unknown message type received: '+ data.type + ' from: ' + senderId) } + this.updateTimestamp(ts); }; @@ -376,12 +378,6 @@ Wallet.prototype._onConnect = function(newCopayerId) { this.emit('connect', peerID); }; -Wallet.prototype._onDisconnect = function(peerID) { - this.currentDelay = null; - this.emit('disconnect', peerID); -}; - - Wallet.prototype.getNetworkName = function() { return this.publicKeyRing.network.name; }; @@ -1746,15 +1742,10 @@ Wallet.prototype.indexDiscovery = function(start, change, copayerIndex, gap, cb) } -Wallet.prototype.disconnect = function() { - this.log('## DISCONNECTING'); +Wallet.prototype.close = function() { + this.log('## CLOSING'); this.lock.release(); - var self = this; - self.send(null, { - type: 'disconnect', - walletId: this.id, - }); - self.network.cleanUp(); + this.network.cleanUp(); }; Wallet.prototype.getNetwork = function() { diff --git a/js/models/network/Async.js b/js/models/network/Async.js index 18d9b4bc7..7e5395362 100644 --- a/js/models/network/Async.js +++ b/js/models/network/Async.js @@ -220,7 +220,7 @@ Network.prototype._setupConnectionHandlers = function(cb) { }); self.socket.on('error', self._onError.bind(self)); - self.socket.on('no messages', self.bind(self, 'no messages')); + self.socket.on('no messages', self.emit.bind(self, 'no messages')); self.socket.on('connect', function() { @@ -348,23 +348,23 @@ Network.prototype.send = function(dest, payload, cb) { dest = this.getCopayerIds(); payload.isBroadcast = 1; } - console.log('SEND to: ' + to, payload); if (typeof dest === 'string') dest = [dest]; var l = dest.length; var i = 0; - dest.forEach(function(to) { - if (to === this.copayerId) + for(var ii in dest){ + var to = dest[ii]; + if (to == this.copayerId) continue; + console.log('SEND to: ' + to, this.copayerId, payload); - //console.log('\t to ' + to); - var message = self.encode(to, payload); + var message = this.encode(to, payload); + this.socket.emit('message', message); + } - self.socket.emit('message', message); - }); if (typeof cb === 'function') cb(); }; diff --git a/js/services/controllerUtils.js b/js/services/controllerUtils.js index 197b53d11..16cfa5a6d 100644 --- a/js/services/controllerUtils.js +++ b/js/services/controllerUtils.js @@ -22,7 +22,7 @@ angular.module('copayApp.services') root.logout = function() { if ($rootScope.wallet) - $rootScope.wallet.disconnect(); + $rootScope.wallet.close(); Socket.removeAllListeners(); @@ -179,9 +179,6 @@ angular.module('copayApp.services') } $rootScope.$digest(); }); - w.on('disconnect', function(peerID) { - $rootScope.$digest(); - }); w.on('close', root.onErrorDigest); w.on('locked', root.onErrorDigest.bind(this)); w.netStart(); From 00e1668f8691c902ffa57dd8fe4ed195b5f9b9a0 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 28 Aug 2014 18:59:44 -0300 Subject: [PATCH 6/9] prevent syncing the same message twice --- js/models/network/Async.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/models/network/Async.js b/js/models/network/Async.js index 7e5395362..23fbfb4db 100644 --- a/js/models/network/Async.js +++ b/js/models/network/Async.js @@ -299,7 +299,7 @@ Network.prototype.start = function(opts, openCallback) { if (tries++ > 5) { self.emit('serverError'); } else { - self.socket.emit('sync', opts.lastTimestamp); + self.socket.emit('sync', opts.lastTimestamp + 1); } }, 500); }); From e0b04401c9512eb001a0300488d898ac7e10b09c Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 28 Aug 2014 19:00:11 -0300 Subject: [PATCH 7/9] better filter for vim --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1cf673978..7c9c458c7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ lib-cov *.out *.pid *.gz -*.swp +*.sw* *.sig tags pids From 2c354525eac2aa43b5e4b7b412ef985e0d2565c1 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 28 Aug 2014 19:19:28 -0300 Subject: [PATCH 8/9] test passing --- js/controllers/more.js | 1 - js/models/core/Wallet.js | 20 +++++++++++++------- js/models/network/Async.js | 10 +++++----- test/mocks/FakeWallet.js | 3 +-- test/test.Wallet.js | 16 ---------------- 5 files changed, 19 insertions(+), 31 deletions(-) diff --git a/js/controllers/more.js b/js/controllers/more.js index d0cee706b..87c76ebec 100644 --- a/js/controllers/more.js +++ b/js/controllers/more.js @@ -16,7 +16,6 @@ angular.module('copayApp.controllers').controller('MoreController', $scope.deleteWallet = function() { var w = $rootScope.wallet; - w.disconnect(); walletFactory.delete(w.id, function() { controllerUtils.logout(); }); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 80b92ec5a..7e1c14c83 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -53,6 +53,7 @@ function Wallet(opts) { this.addressBook = opts.addressBook || {}; this.publicKey = this.privateKey.publicHex; this.lastTimestamp = opts.lastTimestamp || undefined; + this.lastMessageFrom = {}; this.paymentRequests = opts.paymentRequests || {}; @@ -313,7 +314,7 @@ Wallet.prototype.updateTimestamp = function(ts) { Wallet.prototype._onNoMessages = function() { console.log('No messages at the server. Requesting sync'); //TODO - this.sendWalletReady(senderId); + this.sendWalletReady(); }; Wallet.prototype._onData = function(senderId, data, ts) { @@ -323,7 +324,7 @@ Wallet.prototype._onData = function(senderId, data, ts) { preconditions.checkArgument(ts); preconditions.checkArgument(typeof ts === 'number'); - //console.log('RECV', senderId, data); + console.log('RECV', senderId, data); if (data.type !== 'walletId' && this.id !== data.walletId) { this.emit('corrupt', senderId); @@ -331,15 +332,18 @@ Wallet.prototype._onData = function(senderId, data, ts) { return; } + switch (data.type) { // This handler is repeaded on WalletFactory (#join). TODO case 'walletId': this.sendWalletReady(senderId); break; case 'walletReady': - this.sendPublicKeyRing(senderId); - this.sendAddressBook(senderId); - this.sendAllTxProposals(senderId); // send old txps + if (this.lastMessageFrom[senderId] !== 'walletReady') { + this.sendPublicKeyRing(senderId); + this.sendAddressBook(senderId); + this.sendAllTxProposals(senderId); // send old txps + } break; case 'publicKeyRing': this._onPublicKeyRing(senderId, data); @@ -359,13 +363,15 @@ Wallet.prototype._onData = function(senderId, data, ts) { case 'addressbook': this._onAddressBook(senderId, data); break; - // unused messages + // unused messages case 'disconnect': + //case 'an other unused message': break; default: - throw new Error('unknown message type received: '+ data.type + ' from: ' + senderId) + throw new Error('unknown message type received: ' + data.type + ' from: ' + senderId) } + this.lastMessageFrom[senderId] = data.type; this.updateTimestamp(ts); }; diff --git a/js/models/network/Async.js b/js/models/network/Async.js index 23fbfb4db..86aa60876 100644 --- a/js/models/network/Async.js +++ b/js/models/network/Async.js @@ -290,6 +290,8 @@ Network.prototype.start = function(opts, openCallback) { this._setupConnectionHandlers(openCallback); this.socket.emit('subscribe', pubkey); + + var fromTs = opts.lastTimestamp + 1; var self = this, tries = 0; self.socket.on('insight-error', function(m) { @@ -299,13 +301,13 @@ Network.prototype.start = function(opts, openCallback) { if (tries++ > 5) { self.emit('serverError'); } else { - self.socket.emit('sync', opts.lastTimestamp + 1); + self.socket.emit('sync', fromTs); } }, 500); }); - self.socket.emit('sync', opts.lastTimestamp); + self.socket.emit('sync', fromTs); self.started = true; }; @@ -358,9 +360,7 @@ Network.prototype.send = function(dest, payload, cb) { var to = dest[ii]; if (to == this.copayerId) continue; - console.log('SEND to: ' + to, this.copayerId, payload); - - + //console.log('SEND to: ' + to, this.copayerId, payload); var message = this.encode(to, payload); this.socket.emit('message', message); } diff --git a/test/mocks/FakeWallet.js b/test/mocks/FakeWallet.js index b09cf8f4e..a9a90d073 100644 --- a/test/mocks/FakeWallet.js +++ b/test/mocks/FakeWallet.js @@ -102,8 +102,7 @@ FakeWallet.prototype.toEncryptedObj = function() { return this.enc; }; -FakeWallet.prototype.disconnect = function() { - this.disconnectCalled = 1; +FakeWallet.prototype.close = function() { }; // TODO a try catch was here diff --git a/test/test.Wallet.js b/test/test.Wallet.js index 6406f5bc5..e90ba751b 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -530,15 +530,6 @@ describe('Wallet model', function() { w._onConnect(newId); }); - it('handle disconnections', function(done) { - var w = createW(); - w.on('disconnect', function(id) { - id.should.equal(newId); - done(); - }); - w._onDisconnect(newId); - }); - it('should register new copayers correctly', function() { var w = createW(); var r = w.getRegisteredCopayerIds(); @@ -1429,11 +1420,4 @@ describe('Wallet model', function() { should.exist(n.networkNonce); }); - it('#disconnect', function() { - var w = cachedCreateW(); - var spy1 = sinon.spy(w, 'send'); - w.disconnect(); - spy1.calledOnce.should.be.true; - }); - }); From 02b8ceb35e8847af42feaec9a73707ecd8fd55af Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 28 Aug 2014 19:29:37 -0300 Subject: [PATCH 9/9] add subscribed event --- js/models/network/Async.js | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/js/models/network/Async.js b/js/models/network/Async.js index 86aa60876..675c39966 100644 --- a/js/models/network/Async.js +++ b/js/models/network/Async.js @@ -290,25 +290,12 @@ Network.prototype.start = function(opts, openCallback) { this._setupConnectionHandlers(openCallback); this.socket.emit('subscribe', pubkey); - var fromTs = opts.lastTimestamp + 1; - var self = this, - tries = 0; - self.socket.on('insight-error', function(m) { - - console.log('Retrying to sync...'); - setTimeout(function() { - if (tries++ > 5) { - self.emit('serverError'); - } else { - self.socket.emit('sync', fromTs); - } - }, 500); + var self = this; + self.socket.on('subscribed', function(m) { + self.socket.emit('sync', fromTs); + self.started = true; }); - - - self.socket.emit('sync', fromTs); - self.started = true; }; Network.prototype.createSocket = function() { @@ -356,9 +343,9 @@ Network.prototype.send = function(dest, payload, cb) { var l = dest.length; var i = 0; - for(var ii in dest){ + for (var ii in dest) { var to = dest[ii]; - if (to == this.copayerId) + if (to == this.copayerId) continue; //console.log('SEND to: ' + to, this.copayerId, payload); var message = this.encode(to, payload);