From 283bf3e5610dd5ebeb6128392869a8aae4c6c79e Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 2 Jun 2016 12:29:25 -0700 Subject: [PATCH] fix spv. clean up pool. --- lib/bcoin/fullnode.js | 32 +++++++++---- lib/bcoin/pool.js | 103 +++++++----------------------------------- lib/bcoin/spvnode.js | 42 +++++++++++++---- lib/bcoin/walletdb.js | 27 +++++++++++ 4 files changed, 99 insertions(+), 105 deletions(-) diff --git a/lib/bcoin/fullnode.js b/lib/bcoin/fullnode.js index 87b74131..877bd5f8 100644 --- a/lib/bcoin/fullnode.js +++ b/lib/bcoin/fullnode.js @@ -216,10 +216,25 @@ Fullnode.prototype._init = function _init() { self.wallet = wallet; - load(); + next(); }); }); }, + function(next) { + var i; + self.walletdb.getUnconfirmed(function(err, txs) { + if (err) + return callback(err); + + if (txs.length > 0) + bcoin.debug('Rebroadcasting %d transactions.', txs.length); + + for (i = 0; i < txs.length; i++) + self.pool.broadcast(txs[i]); + + next(); + }); + }, this.http.open.bind(this.http) ], load); }; @@ -355,24 +370,18 @@ Fullnode.prototype.createWallet = function createWallet(options, callback) { bcoin.debug('Loaded wallet with id=%s address=%s', wallet.id, wallet.getAddress()); - self.pool.addWallet(wallet, function(err) { - if (err) - return callback(err); - - return callback(null, wallet); - }); + return callback(null, wallet); }); }; /** * Retrieve a wallet from the wallet database. * @param {String} id - Wallet ID. - * @param {String?} passphrase - Wallet key passphrase. * @param {Function} callback - Returns [Error, {@link Wallet}]. */ -Fullnode.prototype.getWallet = function getWallet(id, passphrase, callback) { - return this.walletdb.get(id, passphrase, callback); +Fullnode.prototype.getWallet = function getWallet(id, callback) { + return this.walletdb.get(id, callback); }; /** @@ -382,6 +391,9 @@ Fullnode.prototype.getWallet = function getWallet(id, passphrase, callback) { */ Fullnode.prototype.scanWallet = function scanWallet(wallet, callback) { + if (!this.chain.db.options.indexTX || !this.chain.db.options.indexAddress) + return callback(new Error('Addresses not indexed.')); + wallet.scan(this.getTXByAddress.bind(this), callback); }; diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 5d645c67..9af0b7c8 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -1037,11 +1037,6 @@ Pool.prototype._createPeer = function _createPeer(options) { if (!host.hasNetwork()) continue; - if (self.options.headers) { - if (!host.hasHeaders()) - continue; - } - if (self.options.spv) { if (!host.hasBloom()) continue; @@ -1295,18 +1290,16 @@ Pool.prototype._removePeer = function _removePeer(peer) { }; /** - * Watch a piece of data (filterload, SPV-only). + * Watch a an address hash (filterload, SPV-only). * @param {Buffer|Hash} data + * @param {String?} enc */ -Pool.prototype.watch = function watch(data) { - if (Buffer.isBuffer(data)) - data = data.toString('hex'); +Pool.prototype.watch = function watch(data, enc) { + var key = data; - if (data instanceof bcoin.wallet) { - this.watchWallet(data); - return; - } + if (Buffer.isBuffer(key)) + key = key.toString('hex'); if (this.watchMap[data]) { this.watchMap[data]++; @@ -1315,19 +1308,22 @@ Pool.prototype.watch = function watch(data) { this.watchMap[data] = 1; - this.spvFilter.add(data, 'hex'); + this.spvFilter.add(data, enc); this.updateWatch(); }; /** - * Unwatch a piece of data (filterload, SPV-only). + * Unwatch an address hash (filterload, SPV-only). * @param {Buffer|Hash} data + * @param {String?} enc */ -Pool.prototype.unwatch = function unwatch(data) { - if (Buffer.isBuffer(data)) - data = data.toString('hex'); +Pool.prototype.unwatch = function unwatch(data, enc) { + var key = data; + + if (Buffer.isBuffer(key)) + key = key.toString('hex'); if (!this.watchMap[data]) return; @@ -1370,56 +1366,13 @@ Pool.prototype.updateWatch = function updateWatch() { }); }; -/** - * Add a wallet to bloom filter (SPV-only). Resend pending transactions. - * @param {Wallet} wallet - * @param {Function} callback - */ - -Pool.prototype.addWallet = function addWallet(wallet, callback) { - var self = this; - var i; - - callback = utils.asyncify(callback); - - if (this.options.spv) - this.watchWallet(wallet); - - wallet.getUnconfirmed(function(err, txs) { - if (err) - return callback(err); - - for (i = 0; i < txs.length; i++) - self.broadcast(txs[i]); - - if (!self.options.spv) - return callback(); - - self.searchWallet(wallet, callback); - }); -}; - -/** - * Remove a wallet from the bloom filter (SPV-only). - * @param {Wallet} wallet - */ - -Pool.prototype.removeWallet = function removeWallet(wallet) { - if (!this.options.spv) - return; - - assert(this.loaded, 'Pool is not loaded.'); - - this.unwatchWallet(wallet); -}; - /** * Add an address to the bloom filter (SPV-only). * @param {Address|Base58Address} address */ Pool.prototype.watchAddress = function watchAddress(address) { - this.watch(bcoin.address.getHash(address)); + this.watch(bcoin.address.getHash(address), 'hex'); }; /** @@ -1428,29 +1381,7 @@ Pool.prototype.watchAddress = function watchAddress(address) { */ Pool.prototype.unwatchAddress = function unwatchAddress(address) { - this.unwatch(bcoin.address.getHash(address)); -}; - -/** - * Add a wallet to the bloom filter (SPV-only). - * @param {Base58Address} address - */ - -Pool.prototype.watchWallet = function watchWallet(wallet) { - Object.keys(wallet.addressMap).forEach(function(address) { - this.watch(address); - }, this); -}; - -/** - * Remove a wallet from the bloom filter (SPV-only). - * @param {Base58Address} address - */ - -Pool.prototype.unwatchWallet = function unwatchWallet(wallet) { - Object.keys(wallet.addressMap).forEach(function(address) { - this.unwatch(address); - }, this); + this.unwatch(bcoin.address.getHash(address), 'hex'); }; /** @@ -1460,7 +1391,7 @@ Pool.prototype.unwatchWallet = function unwatchWallet(wallet) { * @param {Function} callback */ -Pool.prototype.searchWallet = function(wallet, callback) { +Pool.prototype.resetWallet = function resetWallet(wallet, callback) { var self = this; assert(this.loaded, 'Pool is not loaded.'); diff --git a/lib/bcoin/spvnode.js b/lib/bcoin/spvnode.js index 03b09297..e50951e7 100644 --- a/lib/bcoin/spvnode.js +++ b/lib/bcoin/spvnode.js @@ -156,6 +156,36 @@ SPVNode.prototype._init = function _init() { }); }); }, + function(next) { + var i; + self.walletdb.getUnconfirmed(function(err, txs) { + if (err) + return callback(err); + + if (txs.length > 0) + bcoin.debug('Rebroadcasting %d transactions.', txs.length); + + for (i = 0; i < txs.length; i++) + self.pool.broadcast(txs[i]); + + next(); + }); + }, + function(next) { + var i; + self.walletdb.getAddresses(function(err, hashes) { + if (err) + return callback(err); + + if (hashes.length > 0) + bcoin.debug('Adding %d addresses to filter.', hashes.length); + + for (i = 0; i < hashes.length; i++) + self.pool.watch(hashes[i], 'hex'); + + next(); + }); + }, this.http.open.bind(this.http) ], load); }; @@ -266,24 +296,18 @@ SPVNode.prototype.createWallet = function createWallet(options, callback) { bcoin.debug('Loaded wallet with id=%s address=%s', wallet.id, wallet.getAddress()); - self.pool.addWallet(wallet, function(err) { - if (err) - return callback(err); - - return callback(null, wallet); - }); + return callback(null, wallet); }); }; /** * Retrieve a wallet from the wallet database. * @param {String} id - Wallet ID. - * @param {String?} passphrase - Wallet key passphrase. * @param {Function} callback - Returns [Error, {@link Wallet}]. */ -SPVNode.prototype.getWallet = function getWallet(id, passphrase, callback) { - return this.walletdb.get(id, passphrase, callback); +SPVNode.prototype.getWallet = function getWallet(id, callback) { + return this.walletdb.get(id, callback); }; /* diff --git a/lib/bcoin/walletdb.js b/lib/bcoin/walletdb.js index 4d0d36e8..11434f02 100644 --- a/lib/bcoin/walletdb.js +++ b/lib/bcoin/walletdb.js @@ -739,6 +739,33 @@ WalletDB.prototype.getAddress = function getAddress(address, callback) { this.db.fetch('W/' + address, parsePaths, callback); }; +/** + * Get all address hashes. + * @param {WalletId} id + * @param {Function} callback + */ + +WalletDB.prototype.getAddresses = function getAddresses(id, callback) { + if (!callback) { + callback = id; + id = null; + } + + this.db.iterate({ + gte: 'W', + lte: 'W~', + values: true, + parse: function(value, key) { + var paths = parsePaths(value); + + if (id && !paths[id]) + return; + + return key.split('/')[1]; + } + }, callback); +}; + /** * Get the corresponding path for an address hash. * @param {WalletID} id