start scan

This commit is contained in:
Ivan Socolsky 2015-04-02 11:18:39 -03:00
parent f37ec60951
commit fe29fa107a
3 changed files with 154 additions and 64 deletions

View File

@ -25,6 +25,7 @@ Wallet.create = function(opts) {
x.m = opts.m;
x.n = opts.n;
x.status = 'pending';
x.scanning = false;
x.publicKeyRing = [];
x.addressIndex = 0;
x.copayers = [];
@ -44,6 +45,7 @@ Wallet.fromObj = function(obj) {
x.m = obj.m;
x.n = obj.n;
x.status = obj.status;
x.scanning = obj.scanning;
x.publicKeyRing = obj.publicKeyRing;
x.copayers = _.map(obj.copayers, function(copayer) {
return Copayer.fromObj(copayer);
@ -135,6 +137,10 @@ Wallet.prototype.isComplete = function() {
return this.status == 'complete';
};
Wallet.prototype.isScanning = function() {
return this.scanning;
};
Wallet.prototype.createAddress = function(isChange) {
$.checkState(this.isComplete());

View File

@ -1180,8 +1180,7 @@ WalletService.prototype.scan = function(opts, cb) {
Utils.runLocked(self.walletId, cb, function(cb) {
self.getWallet({}, function(err, wallet) {
if (err) return cb(err);
if (!wallet.isComplete())
return cb(new ClientError('Wallet is not complete'));
if (!wallet.isComplete()) return cb(new ClientError('Wallet is not complete'));
var derivators = [];
_.each([false, true], function(isChange) {
@ -1201,8 +1200,42 @@ WalletService.prototype.scan = function(opts, cb) {
}, cb);
});
});
};
/**
* Start a scan process.
*
* @param {Object} opts
* @param {Boolean} opts.includeCopayerBranches (defaults to false)
*/
WalletService.prototype.startScan = function(opts, cb) {
var self = this;
function scanFinished(err) {
var data = {};
if (err) {
data.result = 'error';
data.error = err;
} else {
data.result = 'success';
}
self._notify('ScanFinished', data);
};
Utils.runLocked(self.walletId, cb, function(cb) {
self.getWallet({}, function(err, wallet) {
if (err) return cb(err);
if (!wallet.isComplete()) return cb(new ClientError('Wallet is not complete'));
setTimeout(function() {
self.scan(opts, scanFinished);
}, 0);
return cb()
});
});
};
module.exports = WalletService;
module.exports.ClientError = ClientError;

View File

@ -2518,11 +2518,18 @@ describe('Wallet service', function() {
});
describe('#scan', function() {
var server, wallet;
var scanConfigOld = WalletService.scanConfig;
beforeEach(function() {
beforeEach(function(done) {
this.timeout(5000);
WalletService.scanConfig.SCAN_WINDOW = 2;
WalletService.scanConfig.DERIVATION_DELAY = 0;
helpers.createAndJoinWallet(1, 2, function(s, w) {
server = s;
wallet = w;
done();
});
});
afterEach(function() {
WalletService.scanConfig = scanConfigOld;
@ -2530,76 +2537,70 @@ describe('Wallet service', function() {
it('should scan main addresses', function(done) {
helpers.stubAddressActivity(['3K2VWMXheGZ4qG35DyGjA2dLeKfaSr534A']);
helpers.createAndJoinWallet(1, 2, function(server, wallet) {
var expectedPaths = [
'm/2147483647/0/0',
'm/2147483647/0/1',
'm/2147483647/0/2',
'm/2147483647/0/3',
'm/2147483647/1/0',
'm/2147483647/1/1',
];
server.scan({}, function(err) {
should.not.exist(err);
server.storage.fetchAddresses(wallet.id, function(err, addresses) {
should.exist(addresses);
addresses.length.should.equal(expectedPaths.length);
var paths = _.pluck(addresses, 'path');
_.difference(paths, expectedPaths).length.should.equal(0);
server.createAddress({}, function(err, address) {
should.not.exist(err);
address.path.should.equal('m/2147483647/0/4');
done();
});
})
});
var expectedPaths = [
'm/2147483647/0/0',
'm/2147483647/0/1',
'm/2147483647/0/2',
'm/2147483647/0/3',
'm/2147483647/1/0',
'm/2147483647/1/1',
];
server.scan({}, function(err) {
should.not.exist(err);
server.storage.fetchAddresses(wallet.id, function(err, addresses) {
should.exist(addresses);
addresses.length.should.equal(expectedPaths.length);
var paths = _.pluck(addresses, 'path');
_.difference(paths, expectedPaths).length.should.equal(0);
server.createAddress({}, function(err, address) {
should.not.exist(err);
address.path.should.equal('m/2147483647/0/4');
done();
});
})
});
});
it('should scan main addresses & copayer addresses', function(done) {
helpers.stubAddressActivity(['3K2VWMXheGZ4qG35DyGjA2dLeKfaSr534A']);
helpers.createAndJoinWallet(1, 2, function(server, wallet) {
var expectedPaths = [
'm/2147483647/0/0',
'm/2147483647/0/1',
'm/2147483647/0/2',
'm/2147483647/0/3',
'm/2147483647/1/0',
'm/2147483647/1/1',
'm/0/0/0',
'm/0/0/1',
'm/0/1/0',
'm/0/1/1',
'm/1/0/0',
'm/1/0/1',
'm/1/1/0',
'm/1/1/1',
];
server.scan({
includeCopayerBranches: true
}, function(err) {
should.not.exist(err);
server.storage.fetchAddresses(wallet.id, function(err, addresses) {
should.exist(addresses);
addresses.length.should.equal(expectedPaths.length);
var paths = _.pluck(addresses, 'path');
_.difference(paths, expectedPaths).length.should.equal(0);
done();
})
});
var expectedPaths = [
'm/2147483647/0/0',
'm/2147483647/0/1',
'm/2147483647/0/2',
'm/2147483647/0/3',
'm/2147483647/1/0',
'm/2147483647/1/1',
'm/0/0/0',
'm/0/0/1',
'm/0/1/0',
'm/0/1/1',
'm/1/0/0',
'm/1/0/1',
'm/1/1/0',
'm/1/1/1',
];
server.scan({
includeCopayerBranches: true
}, function(err) {
should.not.exist(err);
server.storage.fetchAddresses(wallet.id, function(err, addresses) {
should.exist(addresses);
addresses.length.should.equal(expectedPaths.length);
var paths = _.pluck(addresses, 'path');
_.difference(paths, expectedPaths).length.should.equal(0);
done();
})
});
});
it('should restore wallet balance', function(done) {
async.waterfall([
function(next) {
helpers.createAndJoinWallet(1, 2, function(server, wallet) {
helpers.stubUtxos(server, wallet, [1, 2, 3], function(utxos) {
should.exist(utxos);
helpers.stubAddressActivity(_.pluck(utxos, 'address'));
server.getBalance({}, function(err, balance) {
balance.totalAmount.should.equal(helpers.toSatoshi(6));
next(null, server, wallet);
});
helpers.stubUtxos(server, wallet, [1, 2, 3], function(utxos) {
should.exist(utxos);
helpers.stubAddressActivity(_.pluck(utxos, 'address'));
server.getBalance({}, function(err, balance) {
balance.totalAmount.should.equal(helpers.toSatoshi(6));
next(null, server, wallet);
});
});
},
@ -2834,6 +2835,56 @@ describe('Wallet service', function() {
});
});
});
describe('#startScan', function() {
var server, wallet;
var scanConfigOld = WalletService.scanConfig;
beforeEach(function(done) {
this.timeout(5000);
WalletService.scanConfig.SCAN_WINDOW = 2;
WalletService.scanConfig.DERIVATION_DELAY = 0;
helpers.createAndJoinWallet(1, 2, function(s, w) {
server = s;
wallet = w;
done();
});
});
afterEach(function() {
WalletService.scanConfig = scanConfigOld;
WalletService.onNotification(function() {});
});
it('should start an asynchronous scan', function(done) {
helpers.stubAddressActivity(['3K2VWMXheGZ4qG35DyGjA2dLeKfaSr534A']);
var expectedPaths = [
'm/2147483647/0/0',
'm/2147483647/0/1',
'm/2147483647/0/2',
'm/2147483647/0/3',
'm/2147483647/1/0',
'm/2147483647/1/1',
];
WalletService.onNotification(function(n) {
if (n.type == 'ScanFinished') {
server.storage.fetchAddresses(wallet.id, function(err, addresses) {
should.exist(addresses);
addresses.length.should.equal(expectedPaths.length);
var paths = _.pluck(addresses, 'path');
_.difference(paths, expectedPaths).length.should.equal(0);
server.createAddress({}, function(err, address) {
should.not.exist(err);
address.path.should.equal('m/2147483647/0/4');
done();
});
})
}
});
server.startScan({}, function(err) {
should.not.exist(err);
});
});
});
});