From 7c5ad7bdfa5c3a7431c3cf39be0c46925d260bf2 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 6 Dec 2016 13:42:05 -0300 Subject: [PATCH] update lastUsedOn --- lib/blockchainmonitor.js | 4 ++- lib/model/address.js | 5 ++- lib/storage.js | 42 ++++++++++++++++++++++++ test/integration/bcmonitor.js | 62 ++++++++++++++++++++++++++++++----- 4 files changed, 102 insertions(+), 11 deletions(-) diff --git a/lib/blockchainmonitor.js b/lib/blockchainmonitor.js index e2df13a..b0c0179 100644 --- a/lib/blockchainmonitor.js +++ b/lib/blockchainmonitor.js @@ -170,7 +170,9 @@ BlockchainMonitor.prototype._handleTxOuts = function(data) { walletId: walletId, }); self.storage.softResetTxHistoryCache(walletId, function() { - self._storeAndBroadcastNotification(notification, next); + self.storage.updateLastUsedOn(out.address, function() { + self._storeAndBroadcastNotification(notification, next); + }); }); }); }, function(err) { diff --git a/lib/model/address.js b/lib/model/address.js index 9b024ab..52d5675 100644 --- a/lib/model/address.js +++ b/lib/model/address.js @@ -11,10 +11,11 @@ function Address() {}; Address.create = function(opts) { opts = opts || {}; + var now = Math.floor(Date.now() / 1000); var x = new Address(); x.version = '1.0.0'; - x.createdOn = Math.floor(Date.now() / 1000); + x.createdOn = now; x.address = opts.address; x.walletId = opts.walletId; x.isChange = opts.isChange; @@ -23,6 +24,7 @@ Address.create = function(opts) { x.network = Bitcore.Address(x.address).toObject().network; x.type = opts.type || Constants.SCRIPT_TYPES.P2SH; x.hasActivity = undefined; + x.lastUsedOn = now; return x; }; @@ -39,6 +41,7 @@ Address.fromObj = function(obj) { x.publicKeys = obj.publicKeys; x.type = obj.type || Constants.SCRIPT_TYPES.P2SH; x.hasActivity = obj.hasActivity; + x.lastUsedOn = obj.lastUsedOn; return x; }; diff --git a/lib/storage.js b/lib/storage.js index a10013c..286efbc 100644 --- a/lib/storage.js +++ b/lib/storage.js @@ -59,6 +59,10 @@ Storage.prototype._createIndexes = function() { walletId: 1, createdOn: 1, }); + this.db.collection(collections.ADDRESSES).createIndex({ + walletId: 1, + lastUsedOn: 1, + }); this.db.collection(collections.ADDRESSES).createIndex({ address: 1, }); @@ -845,5 +849,43 @@ Storage.prototype._dump = function(cb, fn) { }); }; +Storage.prototype.updateLastUsedOn = function(address, cb) { + this.db.collection(collections.ADDRESSES).update({ + address: address, + }, { + $set: { + lastUsedOn: Math.floor(Date.now() / 1000), + }, + }, { + w: 1, + }, cb); +}; + + +Storage.prototype.fetchRecentAddresses = function(walletId, minUsedOn, cb) { + var self = this; + + this.db.collection(collections.ADDRESSES).find({ + walletId: walletId, + $or: [{ + lastUsedOn: { + $gte: minUsedOn, + } + }, { + lastUsedOn: null, + }], + }).toArray(function(err, result) { + if (err) return cb(err); + if (!result) return cb(); + var addresses = _.map(result, function(address) { + return Model.Address.fromObj(address); + }); + return cb(null, addresses); + }); +}; + + + + Storage.collections = collections; module.exports = Storage; diff --git a/test/integration/bcmonitor.js b/test/integration/bcmonitor.js index 8d4781e..a022f7d 100644 --- a/test/integration/bcmonitor.js +++ b/test/integration/bcmonitor.js @@ -42,7 +42,6 @@ describe('Blockchain monitor', function() { helpers.createAndJoinWallet(2, 3, function(s, w) { server = s; wallet = w; - var bcmonitor = new BlockchainMonitor(); bcmonitor.start({ lockOpts: {}, @@ -61,16 +60,21 @@ describe('Blockchain monitor', function() { }); it('should notify copayers of incoming txs', function(done) { - server.createAddress({}, function(err, address) { - should.not.exist(err); - var incoming = { - txid: '123', - vout: [{}], - }; - incoming.vout[0][address.address] = 1500; + var incoming = { + txid: '123', + vout: [{}], + }; + var address; + + server.createAddress({}, function(err, a) { + should.not.exist(err); + address = a.address; + + incoming.vout[0][address] = 1500; socket.handlers['tx'](incoming); + setTimeout(function() { server.getNotifications({}, function(err, notifications) { should.not.exist(err); @@ -80,11 +84,51 @@ describe('Blockchain monitor', function() { should.exist(notification); notification.walletId.should.equal(wallet.id); notification.data.txid.should.equal('123'); - notification.data.address.should.equal(address.address); + notification.data.address.should.equal(address); notification.data.amount.should.equal(1500); done(); }); }, 100); }); }); + + it('should update address lastUsedOn for incoming txs', function(done) { + + var incoming = { + txid: '123', + vout: [{}, {}], + }; + var address, address2; + var aLongTimeAgo = Date.now() - (1000 * 10 * 86400); + + var clock = sinon.useFakeTimers(aLongTimeAgo, 'Date'); + + server.createAddress({}, function(err, a) { + should.not.exist(err); + address = a.address; + + server.createAddress({}, function(err, a2) { + should.not.exist(err); + address2 = a2.address; + + clock.restore(); + + storage.fetchRecentAddresses(wallet.id, (Date.now() / 1000) - 100, function(err, addr) { + addr.length.should.equal(0); + + incoming.vout[0][address] = 1500; + incoming.vout[1][address2] = 150; + + socket.handlers['tx'](incoming); + + setTimeout(function() { + storage.fetchRecentAddresses(wallet.id, (Date.now() / 1000) - 100, function(err, addr) { + addr.length.should.equal(2); + done(); + }); + }, 50); + }); + }); + }); + }); });