diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 94719700..4627a037 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -73,6 +73,9 @@ function Pool(options) { timeout: options.txTimeout || 60000 }; + // Added and watched wallets + this.wallets = []; + this.createConnection = options.createConnection; assert(this.createConnection); @@ -323,6 +326,12 @@ Pool.prototype._removePeer = function _removePeer(peer) { }; Pool.prototype.watch = function watch(id) { + if (id instanceof bcoin.wallet) { + this.watch(id.getAddress()); + this.watch(id.getPublicKey()); + return; + } + var hid = utils.toHex(id); if (this.watchMap[hid]) this.watchMap[hid]++; @@ -363,11 +372,52 @@ Pool.prototype.unwatch = function unwatch(id) { this.peers.block[i].updateWatch(); }; -Pool.prototype.search = function search(id, range) { +Pool.prototype.addWallet = function addWallet(w, defaultTs) { + if (this.wallets.indexOf(w) !== -1) + return false; + this.watch(w.getHash()); + this.watch(w.getPublicKey()); + + // Relay pending TXs + // NOTE: It is important to do it after search, because search could + // add TS to pending TXs, thus making them confirmed + w.pending().forEach(function(tx) { + this.sendTX(tx); + }, this); + + var self = this; var e = new EventEmitter(); + if (w.loaded) + search(w.lastTs); + else + w.once('load', function(lastTs) { search(w.lastTs) }); + + function search(ts) { + // Search for last week by default + if (!ts) + ts = defaultTs || ((+new Date / 1000) - 7 * 24 * 3600); + self.search(false, ts, e); + } + + return e; +} + +Pool.prototype.removeWallet = function removeWallet(w) { + var i = this.wallets.indexOf(w); + if (i == -1) + return; + this.wallets.splice(i, 1); + this.unwatch(w.getHash()); + this.unwatch(w.getPublicKey()); +} + +Pool.prototype.search = function search(id, range, e) { + e = e || new EventEmitter(); // Optional id argument - if (typeof id === 'object' && !Array.isArray(id) || + if (id !== null && + typeof id === 'object' && + !Array.isArray(id) || typeof id === 'number') { range = id; id = null; @@ -375,7 +425,9 @@ Pool.prototype.search = function search(id, range) { if (typeof id === 'string') id = utils.toArray(id, 'hex'); - if (range) + if (typeof range === 'number') + range = { start: range, end: null }; + else if (range) range = { start: range.start, end: range.end }; else range = { start: 0, end: 0 }; diff --git a/lib/bcoin/tx-pool.js b/lib/bcoin/tx-pool.js index 03ddaae5..a4334966 100644 --- a/lib/bcoin/tx-pool.js +++ b/lib/bcoin/tx-pool.js @@ -17,6 +17,7 @@ function TXPool(wallet) { this._unspent = {}; this._orphans = {}; this._lastTs = 0; + this._loaded = false; // Load TXs from storage this._init(); @@ -25,8 +26,10 @@ inherits(TXPool, EventEmitter); module.exports = TXPool; TXPool.prototype._init = function init() { - if (!this._storage) + if (!this._storage) { + this._loaded = true; return; + } var self = this; var s = this._storage.createReadStream({ @@ -41,6 +44,7 @@ TXPool.prototype._init = function init() { self.emit('error', err); }); s.on('end', function() { + self._loaded = true; self.emit('load', self._lastTs); }); }; diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index ab4dbc0f..29764e32 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -26,6 +26,8 @@ function Wallet(options, passphrase) { options.compressed : true; this.storage = options.storage; this.key = null; + this.loaded = false; + this.lastTs = 0; if (options.passphrase) { this.key = bcoin.ecdsa.genKeyPair({ @@ -51,6 +53,11 @@ inherits(Wallet, EventEmitter); module.exports = Wallet; Wallet.prototype._init = function init() { + if (this.tx.loaded) { + this.loaded = true; + return; + } + // Notify owners about new accepted transactions var self = this; var prevBalance = null; @@ -67,6 +74,8 @@ Wallet.prototype._init = function init() { }); this.tx.once('load', function(ts) { + self.loaded = true; + self.lastTs = ts; self.emit('load', ts); });