diff --git a/CHANGELOG.md b/CHANGELOG.md index 3300a92f0..0e95c8a59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,13 @@ you run it for the first time.** ### Wallet Changes: #### Configuration - Wallet now has option `wallet-migrate-no-rescan`/`migrate-no-rescan` if you -want to disable rescan when migration recommends it. It may result in the -incorrect txdb state, but can be useful if you know the issue does not affect -your wallet or is not critical. +- Wallet now has option `wallet-migrate-no-rescan`/`migrate-no-rescan` if you + want to disable rescan when migration recommends it. It may result in the + incorrect txdb state, but can be useful if you know the issue does not affect + your wallet or is not critical. +- Add `--wallet-preload-all` (or `--preload-all` for standalone wallet node) + that will open all wallets before starting other services (e.g. HTTP). + By default this is set to `false`. #### Wallet API diff --git a/lib/wallet/node.js b/lib/wallet/node.js index b91b92a76..818e4c00a 100644 --- a/lib/wallet/node.js +++ b/lib/wallet/node.js @@ -52,8 +52,9 @@ class WalletNode extends Node { wipeNoReally: this.config.bool('wipe-no-really'), spv: this.config.bool('spv'), walletMigrate: this.config.uint('migrate'), + icannlockup: this.config.bool('icannlockup', false), migrateNoRescan: this.config.bool('migrate-no-rescan', false), - icannlockup: this.config.bool('icannlockup', false) + preloadAll: this.config.bool('preload-all', false) }); this.rpc = new RPC(this); diff --git a/lib/wallet/plugin.js b/lib/wallet/plugin.js index 539789839..632026dbc 100644 --- a/lib/wallet/plugin.js +++ b/lib/wallet/plugin.js @@ -57,8 +57,9 @@ class Plugin extends EventEmitter { wipeNoReally: this.config.bool('wipe-no-really'), spv: node.spv, walletMigrate: this.config.uint('migrate'), + icannlockup: this.config.bool('icannlockup', false), migrateNoRescan: this.config.bool('migrate-no-rescan', false), - icannlockup: this.config.bool('icannlockup', false) + preloadAll: this.config.bool('preload-all', false) }); this.rpc = new RPC(this); diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 4e15acfd4..b9be5173c 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -199,9 +199,9 @@ class Wallet extends EventEmitter { const account = await this._createAccount(options, passphrase); assert(account); - this.logger.info('Wallet initialized (%s).', this.id); + await this.txdb.open(this); - return this.txdb.open(this); + this.logger.info('Wallet initialized (%s).', this.id); } /** @@ -215,9 +215,8 @@ class Wallet extends EventEmitter { if (!account) throw new Error('Default account not found.'); + await this.txdb.open(this); this.logger.info('Wallet opened (%s).', this.id); - - return this.txdb.open(this); } /** diff --git a/lib/wallet/walletdb.js b/lib/wallet/walletdb.js index e0736bd59..e0b5dd23c 100644 --- a/lib/wallet/walletdb.js +++ b/lib/wallet/walletdb.js @@ -208,11 +208,10 @@ class WalletDB extends EventEmitter { if (this.options.wipeNoReally) await this.wipe(); - await this.watch(); await this.loadState(); this.logger.info( - 'WalletDB loaded (depth=%d, height=%d, start=%d).', + 'WalletDB is loading (depth=%d, height=%d, start=%d).', this.depth, this.state.height, this.state.startHeight); @@ -239,6 +238,9 @@ class WalletDB extends EventEmitter { } } + await this.preloadAll(); + await this.watch(); + this.logger.info('WalletDB opened.'); this.emit('open'); } @@ -258,6 +260,22 @@ class WalletDB extends EventEmitter { b.put(layout.V.encode(), value); } + /** + * Preload all wallets. + * @returns {Promise} + */ + + async preloadAll() { + if (!this.options.preloadAll) + return; + + this.logger.info('Preloading all wallets...'); + const wallets = await this.getWallets(); + + for (const wname of wallets) + await this.get(wname); + } + /** * Verify network. * @returns {Promise} @@ -899,7 +917,7 @@ class WalletDB extends EventEmitter { /** * Map wallet id to wid. * @param {String|Number} id - * @returns {Promise} - Returns {Number}. + * @returns {Promise} */ async ensureWID(id) { @@ -915,7 +933,7 @@ class WalletDB extends EventEmitter { /** * Map wallet id to wid. * @param {String} id - * @returns {Promise} - Returns {Number}. + * @returns {Promise} */ async getWID(id) { @@ -932,7 +950,7 @@ class WalletDB extends EventEmitter { /** * Map wallet wid to id. * @param {Number} wid - * @returns {Promise} - Returns {String}. + * @returns {Promise} */ async getID(wid) { @@ -947,7 +965,7 @@ class WalletDB extends EventEmitter { /** * Get a wallet from the database, setup watcher. * @param {Number|String} id - * @returns {Promise} - Returns {@link Wallet}. + * @returns {Promise} */ async get(id) { @@ -969,7 +987,7 @@ class WalletDB extends EventEmitter { * Get a wallet from the database without a lock. * @private * @param {Number} wid - * @returns {Promise} - Returns {@link Wallet}. + * @returns {Promise} */ async _get(wid) { @@ -2527,8 +2545,9 @@ class WalletOptions { this.spv = false; this.wipeNoReally = false; this.walletMigrate = -1; - this.migrateNoRescan = false; this.icannlockup = false; + this.migrateNoRescan = false; + this.preloadAll = false; if (options) this.fromOptions(options); @@ -2621,6 +2640,11 @@ class WalletOptions { this.migrateNoRescan = options.migrateNoRescan; } + if (options.preloadAll != null) { + assert(typeof options.preloadAll === 'boolean'); + this.preloadAll = options.preloadAll; + } + return this; } @@ -2652,6 +2676,11 @@ function fromString(str) { return buf; } +/** + * @param {Buffer} buf + * @returns {String} + */ + function toString(buf) { assert(buf.length > 0); assert(buf[0] === buf.length - 1);