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 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/controllers/sidebar.js b/js/controllers/sidebar.js index e93bf27e2..ee356bb94 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(); @@ -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 f214625a6..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 || {}; @@ -86,19 +87,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); @@ -323,6 +311,12 @@ Wallet.prototype.updateTimestamp = function(ts) { this.store(); }; + +Wallet.prototype._onNoMessages = function() { + console.log('No messages at the server. Requesting sync'); //TODO + this.sendWalletReady(); +}; + Wallet.prototype._onData = function(senderId, data, ts) { preconditions.checkArgument(senderId); preconditions.checkArgument(data); @@ -330,22 +324,26 @@ Wallet.prototype._onData = function(senderId, data, ts) { preconditions.checkArgument(ts); preconditions.checkArgument(typeof ts === 'number'); - this.updateTimestamp(ts); + console.log('RECV', senderId, data); if (data.type !== 'walletId' && this.id !== data.walletId) { this.emit('corrupt', senderId); + this.updateTimestamp(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); @@ -365,11 +363,16 @@ Wallet.prototype._onData = function(senderId, data, ts) { case 'addressbook': this._onAddressBook(senderId, data); break; + // unused messages case 'disconnect': - this._onDisconnect(senderId, data); + //case 'an other unused message': break; + default: + throw new Error('unknown message type received: ' + data.type + ' from: ' + senderId) } + this.lastMessageFrom[senderId] = data.type; + this.updateTimestamp(ts); }; Wallet.prototype._onConnect = function(newCopayerId) { @@ -381,12 +384,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; }; @@ -445,6 +442,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(); @@ -647,8 +645,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', @@ -1751,15 +1748,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 cb7d078ee..675c39966 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.emit.bind(self, 'no messages')); + self.socket.on('connect', function() { self.socket.on('disconnect', function() { @@ -288,22 +290,12 @@ Network.prototype.start = function(opts, openCallback) { this._setupConnectionHandlers(openCallback); this.socket.emit('subscribe', pubkey); - 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', opts.lastTimestamp); - } - }, 500); + var fromTs = opts.lastTimestamp + 1; + var self = this; + self.socket.on('subscribed', function(m) { + self.socket.emit('sync', fromTs); + self.started = true; }); - - self.socket.emit('sync', opts.lastTimestamp); - self.started = true; }; Network.prototype.createSocket = function() { @@ -345,18 +337,21 @@ Network.prototype.send = function(dest, payload, cb) { dest = this.getCopayerIds(); payload.isBroadcast = 1; } + 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); + for (var ii in dest) { + var to = dest[ii]; + if (to == this.copayerId) + continue; + //console.log('SEND to: ' + to, this.copayerId, 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(); 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; - }); - });