diff --git a/lib/bcoin/chaindb.js b/lib/bcoin/chaindb.js index 345916eb..1a26f7b7 100644 --- a/lib/bcoin/chaindb.js +++ b/lib/bcoin/chaindb.js @@ -1131,6 +1131,65 @@ ChainDB.prototype.getCoins = function getCoins(hash, callback) { }, callback); }; +/** + * Scan the blockchain for transactions containing specified address hashes. + * @param {Hash} start - Block hash to start at. + * @param {Hash[]} hashes - Address hashes. + * @param {Function} iter - Iterator. Accepts ({@link TX}, {@link Function}). + * @param {Function} callback + */ + +ChainDB.prototype.scan = function scan(start, hashes, iter, callback) { + var self = this; + var hashMap = {}; + var total = 0; + var i; + + if (!start) + start = this.network.genesis.hash; + + for (i = 0; i < hashes.length; i++) + hashMap[hashes[i]] = true; + + this.logger.info('Rescanning from block %s.', utils.revHex(start)); + + (function next(err, hash) { + if (err) + return callback(err); + + if (!hash) { + self.logger.info('Finished scanning %d blocks.', total); + return callback(); + } + + total++; + + self.getFullBlock(hash, function(err, block) { + if (err) + return next(err); + + self.logger.info('Scanning block %s.', utils.revHex(hash)); + + utils.forEachSerial(block.txs, function(tx, next) { + var hashes = tx.getHashes('hex'); + var i, hash; + + for (i = 0; i < hashes.length; i++) { + hash = hashes[i]; + if (hashMap[hash]) + return iter(tx, next); + } + + next(); + }, function(err) { + if (err) + return next(err); + self.getNextHash(hash, next); + }); + }); + })(null, start); +}; + /** * Retrieve a transaction (not filled with coins). * @param {Hash} hash