diff --git a/lib/utils/asyncemitter.js b/lib/utils/asyncemitter.js index 39f241ea..8ece166b 100644 --- a/lib/utils/asyncemitter.js +++ b/lib/utils/asyncemitter.js @@ -187,8 +187,8 @@ AsyncEmitter.prototype.listeners = function listeners(type) { const result = []; - for (const listener of listeners) - result.push(listener.handler); + for (const {handler} of listeners) + result.push(handler); return result; }; @@ -215,10 +215,21 @@ AsyncEmitter.prototype.listenerCount = function listenerCount(type) { * @param {Function} handler */ -AsyncEmitter.prototype.listen = function listen(type, handler) { +AsyncEmitter.prototype.bind = function bind(type, handler) { return this.on(type, handler); }; +/** + * Emit event. + * @param {String} type + * @param {...Object} args + * @returns {Promise} + */ + +AsyncEmitter.prototype.fire = function fire() { + return this.emit.apply(this, arguments); +}; + /** * Add a listener. * @param {String} type @@ -236,24 +247,42 @@ AsyncEmitter.prototype.hook = function hook(type, handler) { * @returns {Promise} */ -AsyncEmitter.prototype.fire = function fire() { - return this.emit.apply(this, arguments); +AsyncEmitter.prototype.call = function call() { + return this.emitAsync.apply(this, arguments); }; /** * Emit an event synchronously. - * @method * @param {String} type * @param {...Object} args * @returns {Promise} */ AsyncEmitter.prototype.emit = function emit(type) { + try { + this._emit.apply(this, arguments); + } catch (e) { + if (type === 'error') + throw e; + + this._emit('error', e); + } +}; + +/** + * Emit an event synchronously. + * @private + * @param {String} type + * @param {...Object} args + * @returns {Promise} + */ + +AsyncEmitter.prototype._emit = function _emit(type) { assert(typeof type === 'string', '`type` must be a string.'); const listeners = this._events[type]; - if (!listeners || listeners.length === 0) { + if (!listeners) { if (type === 'error') { const error = arguments[1]; @@ -267,7 +296,9 @@ AsyncEmitter.prototype.emit = function emit(type) { return; } - let args; + assert(listeners.length > 0); + + let args = null; for (let i = 0; i < listeners.length; i++) { const listener = listeners[i]; @@ -311,12 +342,31 @@ AsyncEmitter.prototype.emit = function emit(type) { * @returns {Promise} */ -AsyncEmitter.prototype.call = async function call(type) { +AsyncEmitter.prototype.emitAsync = async function emitAsync(type) { + try { + await this._emitAsync.apply(this, arguments); + } catch (e) { + if (type === 'error') + throw e; + + await this._emitAsync('error', e); + } +}; + +/** + * Emit an event. Wait for promises to resolve. + * @private + * @param {String} type + * @param {...Object} args + * @returns {Promise} + */ + +AsyncEmitter.prototype._emitAsync = async function _emitAsync(type) { assert(typeof type === 'string', '`type` must be a string.'); const listeners = this._events[type]; - if (!listeners || listeners.length === 0) { + if (!listeners) { if (type === 'error') { const error = arguments[1]; @@ -330,7 +380,9 @@ AsyncEmitter.prototype.call = async function call(type) { return; } - let args; + assert(listeners.length > 0); + + let args = null; for (let i = 0; i < listeners.length; i++) { const listener = listeners[i]; @@ -366,29 +418,6 @@ AsyncEmitter.prototype.call = async function call(type) { } }; -/** - * Emit an event. Ignore rejections. - * @method - * @param {String} type - * @param {...Object} args - * @returns {Promise} - */ - -AsyncEmitter.prototype.tryCall = async function tryCall(type) { - try { - await this.call.apply(this, arguments); - } catch (e) { - if (type === 'error') - return; - - try { - await this.call('error', e); - } catch (e) { - ; - } - } -}; - /** * Event Listener * @constructor diff --git a/lib/utils/asyncobject.js b/lib/utils/asyncobject.js index 5c13eed9..a0fe11b1 100644 --- a/lib/utils/asyncobject.js +++ b/lib/utils/asyncobject.js @@ -157,7 +157,7 @@ AsyncObject.prototype._close = function _close(callback) { * @param {Function} handler */ -AsyncObject.prototype.listen = function listen(type, handler) { +AsyncObject.prototype.bind = function bind(type, handler) { return this.on(type, handler); }; diff --git a/lib/wallet/client.js b/lib/wallet/client.js index b1f8569b..c8205369 100644 --- a/lib/wallet/client.js +++ b/lib/wallet/client.js @@ -26,15 +26,15 @@ class WalletClient extends NodeClient { super(options); } - listen(event, handler) { + bind(event, handler) { const parser = parsers[event]; if (!parser) { - super.listen(event, handler); + super.bind(event, handler); return; } - super.listen(event, (...args) => { + super.bind(event, (...args) => { return handler(...parser(...args)); }); } diff --git a/lib/wallet/nodeclient.js b/lib/wallet/nodeclient.js index 61c237f2..d5a5ed2a 100644 --- a/lib/wallet/nodeclient.js +++ b/lib/wallet/nodeclient.js @@ -71,10 +71,9 @@ NodeClient.prototype._init = function _init() { * @returns {Promise} */ -NodeClient.prototype._open = function _open(options) { +NodeClient.prototype._open = async function _open(options) { this.listening = true; - this.emit('open'); - return Promise.resolve(); + setImmediate(() => this.emit('connect')); }; /** @@ -82,10 +81,9 @@ NodeClient.prototype._open = function _open(options) { * @returns {Promise} */ -NodeClient.prototype._close = function _close() { +NodeClient.prototype._close = async function _close() { this.listening = false; - this.emit('close'); - return Promise.resolve(); + setImmediate(() => this.emit('disconnect')); }; /** @@ -93,8 +91,8 @@ NodeClient.prototype._close = function _close() { * @returns {Promise} */ -NodeClient.prototype.getTip = function getTip() { - return Promise.resolve(this.node.chain.tip); +NodeClient.prototype.getTip = async function getTip() { + return this.node.chain.tip; }; /** @@ -121,9 +119,8 @@ NodeClient.prototype.getEntry = async function getEntry(hash) { * @returns {Promise} */ -NodeClient.prototype.send = function send(tx) { +NodeClient.prototype.send = async function send(tx) { this.node.relay(tx); - return Promise.resolve(); }; /** @@ -132,10 +129,9 @@ NodeClient.prototype.send = function send(tx) { * @returns {Promise} */ -NodeClient.prototype.setFilter = function setFilter(filter) { +NodeClient.prototype.setFilter = async function setFilter(filter) { this.filter = filter; this.node.pool.setFilter(filter); - return Promise.resolve(); }; /** @@ -144,9 +140,8 @@ NodeClient.prototype.setFilter = function setFilter(filter) { * @returns {Promise} */ -NodeClient.prototype.addFilter = function addFilter(data) { +NodeClient.prototype.addFilter = async function addFilter(data) { this.node.pool.queueFilterLoad(); - return Promise.resolve(); }; /** @@ -154,9 +149,8 @@ NodeClient.prototype.addFilter = function addFilter(data) { * @returns {Promise} */ -NodeClient.prototype.resetFilter = function resetFilter() { +NodeClient.prototype.resetFilter = async function resetFilter() { this.node.pool.queueFilterLoad(); - return Promise.resolve(); }; /** @@ -191,7 +185,7 @@ NodeClient.prototype.getHashes = async function getHashes(start = -1, end = -1) * @returns {Promise} */ -NodeClient.prototype.rescan = function rescan(start) { +NodeClient.prototype.rescan = async function rescan(start) { return this.node.chain.scan(start, this.filter, (entry, txs) => { return this.call('block rescan', entry, txs); }); diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 46a08f3c..4f9cf50f 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -194,7 +194,7 @@ Wallet.prototype.init = async function init(options) { this.logger.info('Wallet initialized (%s).', this.id); - await this.txdb.open(this); + return this.txdb.open(this); }; /** @@ -212,7 +212,7 @@ Wallet.prototype.open = async function open() { this.logger.info('Wallet opened (%s).', this.id); - await this.txdb.open(this); + return this.txdb.open(this); }; /** @@ -665,7 +665,7 @@ Wallet.prototype.ensureAccount = async function ensureAccount(options, passphras if (account) return account; - return await this.createAccount(options, passphrase); + return this.createAccount(options, passphrase); }; /** @@ -701,7 +701,7 @@ Wallet.prototype.getAccountHashes = async function getAccountHashes(acct) { if (index === -1) throw new Error('Account not found.'); - return await this.wdb.getAccountHashes(this.wid, index); + return this.wdb.getAccountHashes(this.wid, index); }; /** @@ -774,7 +774,7 @@ Wallet.prototype.getAccountName = async function getAccountName(index) { if (typeof index === 'string') return index; - return await this.wdb.getAccountName(this.wid, index); + return this.wdb.getAccountName(this.wid, index); }; /** @@ -789,7 +789,7 @@ Wallet.prototype.hasAccount = async function hasAccount(acct) { if (index === -1) return false; - return await this.db.hasAccount(this.wid, index); + return this.db.hasAccount(this.wid, index); }; /** @@ -912,7 +912,7 @@ Wallet.prototype.readPath = async function readPath(address) { Wallet.prototype.hasPath = async function hasPath(address) { const hash = Address.getHash(address, 'hex'); - return await this.wdb.hasPath(this.wid, hash); + return this.wdb.hasPath(this.wid, hash); }; /** @@ -923,20 +923,9 @@ Wallet.prototype.hasPath = async function hasPath(address) { Wallet.prototype.getPaths = async function getPaths(acct) { if (acct != null) - return await this.getAccountPaths(acct); + return this.getAccountPaths(acct); - const paths = await this.wdb.getWalletPaths(this.wid); - const result = []; - - for (const path of paths) { - path.name = await this.getAccountName(path.account); - - assert(path.name); - - result.push(path); - } - - return result; + return this.wdb.getWalletPaths(this.wid); }; /** @@ -1184,7 +1173,7 @@ Wallet.prototype.getAccountByAddress = async function getAccountByAddress(addres if (!path) return null; - return await this.getAccount(path.account); + return this.getAccount(path.account); }; /** @@ -1937,7 +1926,7 @@ Wallet.prototype.zap = async function zap(acct, age) { Wallet.prototype._zap = async function _zap(acct, age) { const account = await this.ensureIndex(acct); - return await this.txdb.zap(account, age); + return this.txdb.zap(account, age); }; /** @@ -2021,7 +2010,7 @@ Wallet.prototype.getHistory = async function getHistory(acct) { Wallet.prototype.getCoins = async function getCoins(acct) { const account = await this.ensureIndex(acct); - return await this.txdb.getCoins(account); + return this.txdb.getCoins(account); }; /** @@ -2032,7 +2021,7 @@ Wallet.prototype.getCoins = async function getCoins(acct) { Wallet.prototype.getCredits = async function getCredits(acct) { const account = await this.ensureIndex(acct); - return await this.txdb.getCredits(account); + return this.txdb.getCredits(account); }; /** @@ -2082,7 +2071,7 @@ Wallet.prototype.getSmartCoins = async function getSmartCoins(acct) { Wallet.prototype.getPending = async function getPending(acct) { const account = await this.ensureIndex(acct); - return await this.txdb.getPending(account); + return this.txdb.getPending(account); }; /** @@ -2093,7 +2082,7 @@ Wallet.prototype.getPending = async function getPending(acct) { Wallet.prototype.getBalance = async function getBalance(acct) { const account = await this.ensureIndex(acct); - return await this.txdb.getBalance(account); + return this.txdb.getBalance(account); }; /** @@ -2107,7 +2096,7 @@ Wallet.prototype.getBalance = async function getBalance(acct) { Wallet.prototype.getRange = async function getRange(acct, options) { const account = await this.ensureIndex(acct); - return await this.txdb.getRange(account, options); + return this.txdb.getRange(account, options); }; /** @@ -2119,7 +2108,7 @@ Wallet.prototype.getRange = async function getRange(acct, options) { Wallet.prototype.getLast = async function getLast(acct, limit) { const account = await this.ensureIndex(acct); - return await this.txdb.getLast(account, limit); + return this.txdb.getLast(account, limit); }; /** diff --git a/lib/wallet/walletdb.js b/lib/wallet/walletdb.js index 193b65c7..20dfd668 100644 --- a/lib/wallet/walletdb.js +++ b/lib/wallet/walletdb.js @@ -28,6 +28,7 @@ const Outpoint = require('../primitives/outpoint'); const layouts = require('./layout'); const records = require('./records'); const StaticWriter = require('../utils/staticwriter'); +const NullClient = require('./nullclient'); const layout = layouts.walletdb; const ChainState = records.ChainState; const BlockMeta = records.BlockMeta; @@ -53,7 +54,7 @@ function WalletDB(options) { this.network = this.options.network; this.logger = this.options.logger.context('wallet'); this.workers = this.options.workers; - this.client = this.options.client; + this.client = this.options.client || new NullClient(this); this.feeRate = this.options.feeRate; this.db = LDB(this.options); @@ -63,13 +64,17 @@ function WalletDB(options) { this.wallets = new Map(); this.depth = 0; this.rescanning = false; - this.bound = false; + // Wallet read lock. this.readLock = new MappedLock(); - this.writeLock = new Lock(); - this.txLock = new Lock(); - this.scanLock = new Lock(); + // Wallet write lock (creation and rename). + this.writeLock = new Lock(); + + // Lock for handling anything tx related. + this.txLock = new Lock(); + + // Address and outpoint filter. this.filter = new Bloom(); this._init(); @@ -104,6 +109,66 @@ WalletDB.prototype._init = function _init() { } this.filter = Bloom.fromRate(items, 0.001, flag); + this.bind(); +}; + +/** + * Bind to node events. + * @private + */ + +WalletDB.prototype.bind = function bind() { + this.client.on('error', (err) => { + this.emit('error', err); + }); + + this.client.on('connect', async () => { + try { + await this.syncNode(); + } catch (e) { + this.emit('error', e); + } + }); + + this.client.bind('block connect', async (entry, txs) => { + try { + await this.addBlock(entry, txs); + } catch (e) { + this.emit('error', e); + } + }); + + this.client.bind('block disconnect', async (entry) => { + try { + await this.removeBlock(entry); + } catch (e) { + this.emit('error', e); + } + }); + + this.client.hook('block rescan', async (entry, txs) => { + try { + await this.rescanBlock(entry, txs); + } catch (e) { + this.emit('error', e); + } + }); + + this.client.bind('tx', async (tx) => { + try { + await this.addTX(tx); + } catch (e) { + this.emit('error', e); + } + }); + + this.client.bind('chain reset', async (tip) => { + try { + await this.resetChain(tip); + } catch (e) { + this.emit('error', e); + } + }); }; /** @@ -121,7 +186,8 @@ WalletDB.prototype._open = async function _open() { if (this.options.wipeNoReally) await this.wipe(); - await this.load(); + await this.watch(); + await this.connect(); this.logger.info( 'WalletDB loaded (depth=%d, height=%d, start=%d).', @@ -159,182 +225,6 @@ WalletDB.prototype._close = async function _close() { await this.db.close(); }; -/** - * Load the walletdb. - * @returns {Promise} - */ - -WalletDB.prototype.load = async function load() { - const unlock = await this.txLock.lock(); - try { - await this.watch(); - await this.connect(); - await this.init(); - } finally { - unlock(); - } -}; - -/** - * Sync state with server on every connect. - * @returns {Promise} - */ - -WalletDB.prototype.syncNode = async function syncNode() { - const unlock = await this.txLock.lock(); - try { - this.logger.info('Resyncing from server...'); - await this.setFilter(); - await this.syncChain(); - await this.resend(); - } finally { - unlock(); - } -}; - -/** - * Bind to node events. - * @private - */ - -WalletDB.prototype.bind = function bind() { - if (!this.client) - return; - - if (this.bound) - return; - - this.bound = true; - - this.client.on('error', (err) => { - this.emit('error', err); - }); - - this.client.on('open', async () => { - try { - await this.syncNode(); - } catch (e) { - this.emit('error', e); - } - }); - - this.client.listen('block connect', async (entry, txs) => { - try { - await this.addBlock(entry, txs); - } catch (e) { - this.emit('error', e); - } - }); - - this.client.listen('block disconnect', async (entry) => { - try { - await this.removeBlock(entry); - } catch (e) { - this.emit('error', e); - } - }); - - this.client.hook('block rescan', async (entry, txs) => { - try { - await this.rescanBlock(entry, txs); - } catch (e) { - this.emit('error', e); - } - }); - - this.client.listen('tx', async (tx) => { - try { - await this.addTX(tx); - } catch (e) { - this.emit('error', e); - } - }); - - this.client.listen('chain reset', async (tip) => { - try { - await this.resetChain(tip); - } catch (e) { - this.emit('error', e); - } - }); -}; - -/** - * Connect to the node server (client required). - * @returns {Promise} - */ - -WalletDB.prototype.connect = async function connect() { - if (!this.client) - return; - - this.bind(); - - await this.client.open(); -}; - -/** - * Disconnect from node server (client required). - * @returns {Promise} - */ - -WalletDB.prototype.disconnect = async function disconnect() { - if (!this.client) - return; - - await this.client.close(); -}; - -/** - * Initialize and write initial sync state. - * @returns {Promise} - */ - -WalletDB.prototype.init = async function init() { - const cache = await this.getState(); - - if (cache) { - this.state = cache; - this.height = cache.height; - return; - } - - this.logger.info('Initializing database state from server.'); - - const b = this.db.batch(); - - let tip = null; - - if (this.client) { - const hashes = await this.client.getHashes(); - - for (let height = 0; height < hashes.length; height++) { - const hash = hashes[height]; - const meta = new BlockMeta(hash, height); - b.put(layout.h(height), meta.toHash()); - tip = meta; - } - } else { - tip = new BlockMeta(this.network.genesis.hash, 0); - b.put(layout.h(0), tip.toHash()); - } - - assert(tip); - - const state = this.state.clone(); - state.startHeight = tip.height; - state.startHash = tip.hash; - state.height = tip.height; - state.marked = false; - - b.put(layout.R, state.toRaw()); - - await b.write(); - - this.state = state; - this.height = state.height; -}; - /** * Watch addresses and outpoints. * @private @@ -379,6 +269,87 @@ WalletDB.prototype.watch = async function watch() { this.logger.info('Added %d outpoints to WalletDB filter.', outpoints); }; +/** + * Connect to the node server (client required). + * @returns {Promise} + */ + +WalletDB.prototype.connect = async function connect() { + return this.client.open(); +}; + +/** + * Disconnect from node server (client required). + * @returns {Promise} + */ + +WalletDB.prototype.disconnect = async function disconnect() { + return this.client.close(); +}; + +/** + * Sync state with server on every connect. + * @returns {Promise} + */ + +WalletDB.prototype.syncNode = async function syncNode() { + const unlock = await this.txLock.lock(); + try { + this.logger.info('Resyncing from server...'); + await this.syncState(); + await this.syncFilter(); + await this.syncChain(); + await this.resend(); + } finally { + unlock(); + } +}; + +/** + * Initialize and write initial sync state. + * @returns {Promise} + */ + +WalletDB.prototype.syncState = async function syncState() { + const cache = await this.getState(); + + if (cache) { + this.state = cache; + this.height = cache.height; + return; + } + + this.logger.info('Initializing database state from server.'); + + const b = this.db.batch(); + + let tip = null; + + const hashes = await this.client.getHashes(); + + for (let height = 0; height < hashes.length; height++) { + const hash = hashes[height]; + const meta = new BlockMeta(hash, height); + b.put(layout.h(height), meta.toHash()); + tip = meta; + } + + assert(tip); + + const state = this.state.clone(); + state.startHeight = tip.height; + state.startHash = tip.hash; + state.height = tip.height; + state.marked = false; + + b.put(layout.R, state.toRaw()); + + await b.write(); + + this.state = state; + this.height = state.height; +}; + /** * Connect and sync with the chain server. * @private @@ -386,11 +357,7 @@ WalletDB.prototype.watch = async function watch() { */ WalletDB.prototype.syncChain = async function syncChain() { - if (!this.client) - return; - let height = this.state.height; - let entry = null; this.logger.info('Syncing state from height %d.', height); @@ -398,17 +365,13 @@ WalletDB.prototype.syncChain = async function syncChain() { const tip = await this.getBlock(height); assert(tip); - entry = await this.client.getEntry(tip.hash); - - if (entry) + if (await this.client.getEntry(tip.hash)) break; assert(height !== 0); height -= 1; } - assert(entry); - await this.scan(height); }; @@ -420,9 +383,6 @@ WalletDB.prototype.syncChain = async function syncChain() { */ WalletDB.prototype.scan = async function scan(height) { - if (!this.client) - return; - if (height == null) height = this.state.startHeight; @@ -467,7 +427,7 @@ WalletDB.prototype.rescan = async function rescan(height) { */ WalletDB.prototype._rescan = async function _rescan(height) { - return await this.scan(height); + return this.scan(height); }; /** @@ -477,12 +437,7 @@ WalletDB.prototype._rescan = async function _rescan(height) { */ WalletDB.prototype.send = async function send(tx) { - if (!this.client) { - this.emit('send', tx); - return; - } - - await this.client.send(tx); + return this.client.send(tx); }; /** @@ -495,9 +450,6 @@ WalletDB.prototype.estimateFee = async function estimateFee(blocks) { if (this.feeRate > 0) return this.feeRate; - if (!this.client) - return this.network.feeRate; - const rate = await this.client.estimateFee(blocks); if (rate < this.network.feeRate) @@ -515,12 +467,7 @@ WalletDB.prototype.estimateFee = async function estimateFee(blocks) { * @returns {Promise} */ -WalletDB.prototype.setFilter = function setFilter() { - if (!this.client) { - this.emit('set filter', this.filter); - return Promise.resolve(); - } - +WalletDB.prototype.syncFilter = function syncFilter() { this.logger.info('Sending filter to server (%dmb).', this.filter.size / 8 / (1 << 20)); @@ -535,11 +482,6 @@ WalletDB.prototype.setFilter = function setFilter() { */ WalletDB.prototype.addFilter = function addFilter(data) { - if (!this.client) { - this.emit('add filter', data); - return Promise.resolve(); - } - return this.client.addFilter(data); }; @@ -550,11 +492,6 @@ WalletDB.prototype.addFilter = function addFilter(data) { */ WalletDB.prototype.resetFilter = function resetFilter() { - if (!this.client) { - this.emit('reset filter'); - return Promise.resolve(); - } - return this.client.resetFilter(); }; @@ -894,9 +831,7 @@ WalletDB.prototype.create = async function create(options) { */ WalletDB.prototype._create = async function _create(options) { - const exists = await this.has(options.id); - - if (exists) + if (await this.has(options.id)) throw new Error('WDB: Wallet already exists.'); const wallet = Wallet.fromOptions(this, options); @@ -937,7 +872,7 @@ WalletDB.prototype.ensure = async function ensure(options) { if (wallet) return wallet; - return await this.create(options); + return this.create(options); }; /** @@ -1196,6 +1131,8 @@ WalletDB.prototype.getWalletPaths = async function getWalletPaths(wid) { const path = Path.fromRaw(item.value); path.hash = hash; + path.name = await this.getAccountName(wid, path.account); + assert(path.name); paths.push(path); } @@ -1342,9 +1279,7 @@ WalletDB.prototype.resendPending = async function resendPending(wid) { txs.push(wtx.tx); } - const sorted = common.sortDeps(txs); - - for (const tx of sorted) + for (const tx of common.sortDeps(txs)) await this.send(tx); }; @@ -1415,7 +1350,7 @@ WalletDB.prototype.getState = async function getState() { * @returns {Promise} */ -WalletDB.prototype.syncTip = async function syncTip(tip) { +WalletDB.prototype.setTip = async function setTip(tip) { const b = this.db.batch(); const state = this.state.clone(); @@ -1722,7 +1657,7 @@ WalletDB.prototype.rollback = async function rollback(height) { assert(tip); await this.revert(tip.height); - await this.syncTip(tip); + await this.setTip(tip); }; /** @@ -1804,9 +1739,9 @@ WalletDB.prototype._addBlock = async function _addBlock(entry, txs) { } // Sync the state to the new tip. - await this.syncTip(tip); + await this.setTip(tip); - if (this.options.checkpoints) { + if (this.options.checkpoints && !this.state.marked) { if (tip.height <= this.network.lastCheckpoint) return 0; } @@ -1814,7 +1749,7 @@ WalletDB.prototype._addBlock = async function _addBlock(entry, txs) { let total = 0; for (const tx of txs) { - if (await this._insert(tx, tip)) + if (await this._addTX(tx, tip)) total += 1; } @@ -1872,7 +1807,7 @@ WalletDB.prototype._removeBlock = async function _removeBlock(entry) { const map = await this.getBlockMap(tip.height); if (!map) { - await this.syncTip(prev); + await this.setTip(prev); return 0; } @@ -1885,7 +1820,7 @@ WalletDB.prototype._removeBlock = async function _removeBlock(entry) { } // Sync the state to the previous tip. - await this.syncTip(prev); + await this.setTip(prev); this.logger.warning('Disconnected wallet block %s (tx=%d).', util.revHex(tip.hash), total); @@ -1931,7 +1866,7 @@ WalletDB.prototype.rescanBlock = async function rescanBlock(entry, txs) { WalletDB.prototype.addTX = async function addTX(tx) { const unlock = await this.txLock.lock(); try { - return await this._insert(tx); + return await this._addTX(tx); } finally { unlock(); } @@ -1945,7 +1880,7 @@ WalletDB.prototype.addTX = async function addTX(tx) { * @returns {Promise} */ -WalletDB.prototype._insert = async function _insert(tx, block) { +WalletDB.prototype._addTX = async function _addTX(tx, block) { const wids = await this.getWalletsByTX(tx); assert(!tx.mutable, 'WDB: Cannot add mutable TX.'); @@ -2055,10 +1990,8 @@ function WalletOptions(options) { */ WalletOptions.prototype.fromOptions = function fromOptions(options) { - if (options.network != null) { + if (options.network != null) this.network = Network.get(options.network); - this.port = this.network.rpcPort + 2; - } if (options.logger != null) { assert(typeof options.logger === 'object');