wallet: client refactor.

This commit is contained in:
Christopher Jeffrey 2017-10-29 04:47:50 -07:00
parent aedbe27b6e
commit 771a4ef17f
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
6 changed files with 267 additions and 322 deletions

View File

@ -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

View File

@ -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);
};

View File

@ -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));
});
}

View File

@ -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);
});

View File

@ -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);
};
/**

View File

@ -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');