scan addresses 1 by 1 and rewind to last used one

This commit is contained in:
Ivan Socolsky 2015-10-26 18:05:53 -03:00
parent a0f99f6660
commit 9ffcb7e470
3 changed files with 50 additions and 50 deletions

View File

@ -23,7 +23,7 @@ var _parseErr = function(err, res) {
log.warn('Insight error: ', err); log.warn('Insight error: ', err);
return "Insight Error"; return "Insight Error";
} }
log.warn("Insight " + res.request.href + " Returned Status: " + res.statusCode); log.warn("Insight " + res.request.href + " Returned Status: " + res.statusCode);
return "Error querying the blockchain"; return "Error querying the blockchain";
}; };
@ -45,7 +45,7 @@ Insight.prototype.getUnspentUtxos = function(addresses, cb) {
}; };
request(args, function(err, res, unspent) { request(args, function(err, res, unspent) {
if (err || res.statusCode !== 200) return cb(_parseErr(err,res)); if (err || res.statusCode !== 200) return cb(_parseErr(err, res));
return cb(null, unspent); return cb(null, unspent);
}); });
}; };
@ -64,7 +64,7 @@ Insight.prototype.broadcast = function(rawTx, cb) {
}; };
request(args, function(err, res, body) { request(args, function(err, res, body) {
if (err || res.statusCode !== 200) return cb(_parseErr(err,res)); if (err || res.statusCode !== 200) return cb(_parseErr(err, res));
return cb(null, body ? body.txid : null); return cb(null, body ? body.txid : null);
}); });
}; };
@ -77,9 +77,9 @@ Insight.prototype.getTransaction = function(txid, cb) {
}; };
request(args, function(err, res, tx) { request(args, function(err, res, tx) {
if (res && res.statusCode == 404 ) return cb(); if (res && res.statusCode == 404) return cb();
if (err || res.statusCode !== 200) if (err || res.statusCode !== 200)
return cb(_parseErr(err,res)); return cb(_parseErr(err, res));
return cb(null, tx); return cb(null, tx);
}); });
@ -100,7 +100,7 @@ Insight.prototype.getTransactions = function(addresses, from, to, cb) {
}; };
request(args, function(err, res, txs) { request(args, function(err, res, txs) {
if (err || res.statusCode !== 200) return cb(_parseErr(err,res)); if (err || res.statusCode !== 200) return cb(_parseErr(err, res));
if (_.isObject(txs) && txs.items) if (_.isObject(txs) && txs.items)
txs = txs.items; txs = txs.items;
@ -112,10 +112,20 @@ Insight.prototype.getTransactions = function(addresses, from, to, cb) {
}); });
}; };
Insight.prototype.getAddressActivity = function(addresses, cb) { Insight.prototype.getAddressActivity = function(address, cb) {
this.getTransactions(addresses, null, null, function(err, result) { var url = this.url + this.apiPrefix + '/addr/' + address;
if (err) return cb(err); var args = {
return cb(null, result && result.length > 0); method: 'GET',
url: url,
};
request(args, function(err, res, result) {
if (res && res.statusCode == 404) return cb();
if (err || res.statusCode !== 200)
return cb(_parseErr(err, res));
var nbTxs = result.unconfirmedTxApperances + result.txApperances;
return cb(null, nbTxs > 0);
}); });
}; };
@ -131,7 +141,7 @@ Insight.prototype.estimateFee = function(nbBlocks, cb) {
json: true, json: true,
}; };
request(args, function(err, res, body) { request(args, function(err, res, body) {
if (err || res.statusCode !== 200) return cb(_parseErr(err,res)); if (err || res.statusCode !== 200) return cb(_parseErr(err, res));
return cb(null, body); return cb(null, body);
}); });
}; };

View File

@ -64,7 +64,7 @@ WalletService.BACKOFF_TIME = 2;
// Fund scanning parameters // Fund scanning parameters
WalletService.SCAN_CONFIG = { WalletService.SCAN_CONFIG = {
scanWindow: 20, maxGap: 20,
derivationDelay: 10, // in milliseconds derivationDelay: 10, // in milliseconds
}; };
@ -1878,43 +1878,35 @@ WalletService.prototype.scan = function(opts, cb) {
opts = opts || {}; opts = opts || {};
function deriveAddresses(size, derivator, cb) { function checkActivity(address, network, cb) {
async.mapSeries(_.range(size), function(i, next) { var bc = self._getBlockchainExplorer(network);
setTimeout(function() { bc.getAddressActivity(address, cb);
next(null, derivator.derive());
}, WalletService.SCAN_CONFIG.derivationDelay)
}, cb);
};
function checkActivity(addresses, networkName, cb) {
var bc = self._getBlockchainExplorer(networkName);
bc.getAddressActivity(addresses, cb);
}; };
function scanBranch(derivator, cb) { function scanBranch(derivator, cb) {
var activity = true; var inactiveCounter = 0;
var allAddresses = []; var allAddresses = [];
var networkName; var gap = WalletService.SCAN_CONFIG.maxGap;
async.whilst(function() {
return activity;
}, function(next) {
deriveAddresses(WalletService.SCAN_CONFIG.scanWindow, derivator, function(err, addresses) {
if (err) return next(err);
networkName = networkName || Bitcore.Address(addresses[0].address).toObject().network;
checkActivity(_.pluck(addresses, 'address'), networkName, function(err, thereIsActivity) {
if (err) return next(err);
activity = thereIsActivity; async.whilst(function() {
if (thereIsActivity) { return inactiveCounter < gap;
allAddresses.push(addresses); }, function(next) {
} else { var address = derivator.derive();
derivator.rewind(WalletService.SCAN_CONFIG.scanWindow); checkActivity(address.address, address.network, function(err, activity) {
} console.log('*** [server.js ln1895] address.path, activity:', address.path, activity); // TODO
next();
}); if (err) return next(err);
allAddresses.push(address);
inactiveCounter = activity ? 0 : inactiveCounter + 1;
console.log('*** [server.js ln1905] inactiveCounter:', inactiveCounter); // TODO
next();
}); });
}, function(err) { }, function(err) {
return cb(err, _.flatten(allAddresses)); derivator.rewind(gap);
return cb(err, _.dropRight(allAddresses, gap));
}); });
}; };

View File

@ -237,8 +237,8 @@ helpers.stubFeeLevels = function(levels) {
}; };
helpers.stubAddressActivity = function(activeAddresses) { helpers.stubAddressActivity = function(activeAddresses) {
blockchainExplorer.getAddressActivity = function(addresses, cb) { blockchainExplorer.getAddressActivity = function(address, cb) {
return cb(null, _.intersection(activeAddresses, addresses).length > 0); return cb(null, _.contains(activeAddresses, address));
}; };
}; };
@ -4771,7 +4771,7 @@ describe('Wallet service', function() {
describe('1-of-1 wallet (BIP44 & P2PKH)', function() { describe('1-of-1 wallet (BIP44 & P2PKH)', function() {
beforeEach(function(done) { beforeEach(function(done) {
this.timeout(5000); this.timeout(5000);
WalletService.SCAN_CONFIG.scanWindow = 2; WalletService.SCAN_CONFIG.maxGap = 2;
WalletService.SCAN_CONFIG.derivationDelay = 0; WalletService.SCAN_CONFIG.derivationDelay = 0;
helpers.createAndJoinWallet(1, 1, function(s, w) { helpers.createAndJoinWallet(1, 1, function(s, w) {
@ -4784,7 +4784,7 @@ describe('Wallet service', function() {
WalletService.SCAN_CONFIG = scanConfigOld; WalletService.SCAN_CONFIG = scanConfigOld;
}); });
it('should scan main addresses', function(done) { it.only('should scan main addresses', function(done) {
helpers.stubAddressActivity( helpers.stubAddressActivity(
['1L3z9LPd861FWQhf3vDn89Fnc9dkdBo2CG', // m/0/0 ['1L3z9LPd861FWQhf3vDn89Fnc9dkdBo2CG', // m/0/0
'1GdXraZ1gtoVAvBh49D4hK9xLm6SKgesoE', // m/0/2 '1GdXraZ1gtoVAvBh49D4hK9xLm6SKgesoE', // m/0/2
@ -4794,9 +4794,7 @@ describe('Wallet service', function() {
'm/0/0', 'm/0/0',
'm/0/1', 'm/0/1',
'm/0/2', 'm/0/2',
'm/0/3',
'm/1/0', 'm/1/0',
'm/1/1',
]; ];
server.scan({}, function(err) { server.scan({}, function(err) {
should.not.exist(err); should.not.exist(err);
@ -4810,7 +4808,7 @@ describe('Wallet service', function() {
_.difference(paths, expectedPaths).length.should.equal(0); _.difference(paths, expectedPaths).length.should.equal(0);
server.createAddress({}, function(err, address) { server.createAddress({}, function(err, address) {
should.not.exist(err); should.not.exist(err);
address.path.should.equal('m/0/4'); address.path.should.equal('m/0/3');
done(); done();
}); });
}); });