diff --git a/lib/model/addressmanager.js b/lib/model/addressmanager.js index bca94f6..48161d1 100644 --- a/lib/model/addressmanager.js +++ b/lib/model/addressmanager.js @@ -38,6 +38,15 @@ AddressManager.prototype._incrementIndex = function(isChange) { } }; +AddressManager.prototype.rewindIndex = function(isChange, n) { + n = _.isUndefined(n) ? 1 : n; + if (isChange) { + this.changeAddressIndex -= n; + } else { + this.receiveAddressIndex -= n; + } +}; + AddressManager.prototype.getCurrentAddressPath = function(isChange) { return 'm/' + this.copayerIndex + '/' + diff --git a/lib/server.js b/lib/server.js index cf9bc16..0125b63 100644 --- a/lib/server.js +++ b/lib/server.js @@ -432,9 +432,9 @@ WalletService.prototype.verifyMessageSignature = function(opts, cb) { WalletService.prototype._getBlockchainExplorer = function(provider, network) { if (!this.blockchainExplorer) { - var opts = {}; + var opts = {}; if (this.blockchainExplorerOpts && this.blockchainExplorerOpts[network]) { - opts = this.blockchainExplorerOpts[network]; + opts = this.blockchainExplorerOpts[network]; } opts.provider = provider; opts.network = network; @@ -1164,7 +1164,7 @@ WalletService.prototype.scan = function(opts, cb) { function deriveAddresses(size, derivator, cb) { async.mapSeries(_.range(size), function(i, next) { setTimeout(function() { - next(null, derivator()); + next(null, derivator.derive()); }, WalletService.scanConfig.DERIVATION_DELAY) }, cb); }; @@ -1184,10 +1184,14 @@ WalletService.prototype.scan = function(opts, cb) { deriveAddresses(WalletService.scanConfig.SCAN_WINDOW, derivator, function(err, addresses) { if (err) return next(err); networkName = networkName || Bitcore.Address(addresses[0].address).toObject().network; - allAddresses.push(addresses); checkActivity(_.pluck(addresses, 'address'), networkName, function(err, thereIsActivity) { if (err) return next(new Error('Could not fetch TX activity:' + err)); activity = thereIsActivity; + if (thereIsActivity) { + allAddresses.push(addresses); + } else { + derivator.rewind(WalletService.scanConfig.SCAN_WINDOW); + } next(); }); }); @@ -1208,10 +1212,16 @@ WalletService.prototype.scan = function(opts, cb) { var derivators = []; _.each([false, true], function(isChange) { - derivators.push(_.bind(wallet.createAddress, wallet, isChange)); + derivators.push({ + derive: _.bind(wallet.createAddress, wallet, isChange), + rewind: _.bind(wallet.addressManager.rewindIndex, wallet.addressManager, isChange), + }); if (opts.includeCopayerBranches) { _.each(wallet.copayers, function(copayer) { - derivators.push(_.bind(copayer.createAddress, copayer, wallet, isChange)); + derivators.push({ + derive: _.bind(copayer.createAddress, copayer, wallet, isChange), + rewind: _.bind(copayer.addressManager.rewindIndex, copayer.addressManager, isChange), + }); }); } }); diff --git a/test/integration/server.js b/test/integration/server.js index 4bc9621..9e3c728 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -2519,7 +2519,7 @@ describe('Wallet service', function() { }); }); - describe.only('#scan', function() { + describe('#scan', function() { var server, wallet; var scanConfigOld = WalletService.scanConfig; beforeEach(function(done) { @@ -2539,9 +2539,9 @@ describe('Wallet service', function() { it('should scan main addresses', function(done) { helpers.stubAddressActivity( - ['3K2VWMXheGZ4qG35DyGjA2dLeKfaSr534A', // 'm/2147483647/0/0' - '3NezgtNbuDzL2sFhnfxyVy8bHp4v6ud252', // 'm/2147483647/0/2' - '3CQ2hCMUu1SCPVPMpfCCuT3nAfHGiHV1o7', // 'm/2147483647/1/0' + ['3K2VWMXheGZ4qG35DyGjA2dLeKfaSr534A', // m/2147483647/0/0 + '3NezgtNbuDzL2sFhnfxyVy8bHp4v6ud252', // m/2147483647/0/2 + '3CQ2hCMUu1SCPVPMpfCCuT3nAfHGiHV1o7', // m/2147483647/1/0 ]); var expectedPaths = [ 'm/2147483647/0/0', @@ -2568,11 +2568,11 @@ describe('Wallet service', function() { }); it('should scan main addresses & copayer addresses', function(done) { helpers.stubAddressActivity( - ['3K2VWMXheGZ4qG35DyGjA2dLeKfaSr534A', // 'm/2147483647/0/0' - '3CQ2hCMUu1SCPVPMpfCCuT3nAfHGiHV1o7', // 'm/2147483647/1/0' - '3BYHznBmosYxUj1NWcjdFKX2tdsH7UT1YG', // 'm/0/0/1' - '3Eg1uPkGnwyU42bRiaDuo6Cu9bjjhoG7Sh', // 'm/1/1/0' - '3AYmZ63tMd2AHN8QLfu5D2nfRzCH66psWx', // 'm/1/0/0' + ['3K2VWMXheGZ4qG35DyGjA2dLeKfaSr534A', // m/2147483647/0/0 + '3CQ2hCMUu1SCPVPMpfCCuT3nAfHGiHV1o7', // m/2147483647/1/0 + '3BYHznBmosYxUj1NWcjdFKX2tdsH7UT1YG', // m/0/0/1 + '3Eg1uPkGnwyU42bRiaDuo6Cu9bjjhoG7Sh', // m/1/1/0 + '3AYmZ63tMd2AHN8QLfu5D2nfRzCH66psWx', // m/1/0/0 ]); var expectedPaths = [ 'm/2147483647/0/0', @@ -2664,7 +2664,11 @@ describe('Wallet service', function() { }); it('should start an asynchronous scan', function(done) { - helpers.stubAddressActivity(['3K2VWMXheGZ4qG35DyGjA2dLeKfaSr534A']); + helpers.stubAddressActivity([ + '3K2VWMXheGZ4qG35DyGjA2dLeKfaSr534A', // m/2147483647/0/0 + '3NezgtNbuDzL2sFhnfxyVy8bHp4v6ud252', // m/2147483647/0/2 + '3CQ2hCMUu1SCPVPMpfCCuT3nAfHGiHV1o7', // m/2147483647/1/1 + ]); var expectedPaths = [ 'm/2147483647/0/0', 'm/2147483647/0/1',