Skip to content

Commit

Permalink
wallet: separate open and connect. Add wallet-migrate-no-rescan option.
Browse files Browse the repository at this point in the history
  • Loading branch information
nodech committed Oct 20, 2023
1 parent f11615d commit b53d392
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 90 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,21 @@
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 API

- Add migration that recalculates txdb balances to fix any inconsistencies.
- WalletDB Now emits events for: `open`, `close`, `connect`, `disconnect`.
- WalletDB
- `open()` no longer calls `connect` and needs separate call `connect`.
- `open()` no longer calls scan, instead only rollbacks and waits for
sync to do the rescan.
- emits events for: `open`, `close`, `connect`, `disconnect`, `sync done`.
- HTTP Changes:
- All transaction creating endpoints now accept `hardFee` for specifying the
exact fee.
Expand Down
3 changes: 3 additions & 0 deletions lib/wallet/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class WalletNode extends Node {
wipeNoReally: this.config.bool('wipe-no-really'),
spv: this.config.bool('spv'),
walletMigrate: this.config.uint('migrate'),
migrateNoRescan: this.config.bool('migrate-no-rescan', false),
icannlockup: this.config.bool('icannlockup', false)
});

Expand Down Expand Up @@ -107,6 +108,7 @@ class WalletNode extends Node {
await this.openPlugins();

await this.http.open();
await this.wdb.connect();
await this.handleOpen();

this.logger.info('Wallet node is loaded.');
Expand All @@ -128,6 +130,7 @@ class WalletNode extends Node {

this.rpc.wallet = null;

await this.wdb.disconnect();
await this.wdb.close();
await this.handleClose();
}
Expand Down
3 changes: 3 additions & 0 deletions lib/wallet/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class Plugin extends EventEmitter {
wipeNoReally: this.config.bool('wipe-no-really'),
spv: node.spv,
walletMigrate: this.config.uint('migrate'),
migrateNoRescan: this.config.bool('migrate-no-rescan', false),
icannlockup: this.config.bool('icannlockup', false)
});

Expand Down Expand Up @@ -90,11 +91,13 @@ class Plugin extends EventEmitter {
await this.wdb.open();
this.rpc.wallet = this.wdb.primary;
await this.http.open();
await this.wdb.connect();
}

async close() {
await this.http.close();
this.rpc.wallet = null;
await this.wdb.disconnect();
await this.wdb.close();
}
}
Expand Down
62 changes: 47 additions & 15 deletions lib/wallet/walletdb.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,18 @@ class WalletDB extends EventEmitter {
this.name = 'wallet';
this.version = 2;

this.primary = null;
// chain state.
this.hasStateCache = false;
this.state = new ChainState();
this.confirming = false;
this.height = 0;

// wallets
this.primary = null;
this.wallets = new Map();
this.depth = 0;

// guards
this.confirming = false;
this.rescanning = false;
this.filterSent = false;

Expand Down Expand Up @@ -203,7 +209,7 @@ class WalletDB extends EventEmitter {
await this.wipe();

await this.watch();
await this.connect();
await this.loadState();

this.logger.info(
'WalletDB loaded (depth=%d, height=%d, start=%d).',
Expand All @@ -224,8 +230,13 @@ class WalletDB extends EventEmitter {
this.primary = wallet;

if (migrationResult.rescan) {
this.logger.info('Rescanning...');
await this.scan(0);
if (!this.options.migrateNoRescan) {
this.logger.info('Migration rollback...');
await this.rollback(0);
} else {
this.logger.warning(
'Migration rescan skipped, state may be incorrect.');
}
}

this.logger.info('WalletDB opened.');
Expand Down Expand Up @@ -275,7 +286,8 @@ class WalletDB extends EventEmitter {
*/

async close() {
await this.disconnect();
if (this.client.opened)
await this.disconnect();

for (const wallet of this.wallets.values()) {
await wallet.destroy();
Expand Down Expand Up @@ -375,7 +387,7 @@ class WalletDB extends EventEmitter {
const unlock = await this.txLock.lock();
try {
this.logger.info('Resyncing from server...');
await this.syncState();
await this.syncInitState();
await this.syncFilter();
await this.syncChain();
await this.resend();
Expand All @@ -385,18 +397,31 @@ class WalletDB extends EventEmitter {
}

/**
* Initialize and write initial sync state.
* Recover state from the cache.
* @returns {Promise}
*/

async syncState() {
async loadState() {
const cache = await this.getState();

if (cache) {
this.state = cache;
this.height = cache.height;
return undefined;
}
if (!cache)
return;

this.logger.info('Initialized chain state from the database.');
this.hasStateCache = true;
this.state = cache;
this.height = cache.height;
}

/**
* Initialize and write initial sync state.
* @returns {Promise}
*/

async syncInitState() {
// We have recovered from the cache.
if (this.hasStateCache)
return;

this.logger.info('Initializing database state from server.');

Expand Down Expand Up @@ -427,7 +452,7 @@ class WalletDB extends EventEmitter {
this.state = state;
this.height = state.height;

return undefined;
return;
}

/**
Expand Down Expand Up @@ -2192,6 +2217,7 @@ class WalletDB extends EventEmitter {
await iter.each(async (key, value) => {
const [height] = layout.b.decode(key);
const block = MapRecord.decode(value);
this.logger.info('Reverting block: %d', height);

for (const wid of block.wids) {
const wallet = await this.get(wid);
Expand Down Expand Up @@ -2501,6 +2527,7 @@ class WalletOptions {
this.spv = false;
this.wipeNoReally = false;
this.walletMigrate = -1;
this.migrateNoRescan = false;
this.icannlockup = false;

if (options)
Expand Down Expand Up @@ -2589,6 +2616,11 @@ class WalletOptions {
this.icannlockup = options.icannlockup;
}

if (options.migrateNoRescan != null) {
assert(typeof options.migrateNoRescan === 'boolean');
this.migrateNoRescan = options.migrateNoRescan;
}

return this;
}

Expand Down
6 changes: 6 additions & 0 deletions test/mempool-reorg-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const plugin = require('../lib/wallet/plugin');
const Coin = require('../lib/primitives/coin');
const Address = require('../lib/primitives/address');
const MTX = require('../lib/primitives/mtx');
const {forEvent} = require('./util/common');

const network = Network.get('regtest');
const {
Expand All @@ -25,8 +26,13 @@ describe('Mempool Covenant Reorg', function () {
let wallet, name;

before(async () => {
const wdb = node.require('walletdb').wdb;
const syncDone = forEvent(wdb, 'sync done');
await node.open();

wallet = node.get('walletdb').wdb.primary;

await syncDone;
});

after(async () => {
Expand Down
2 changes: 2 additions & 0 deletions test/wallet-auction-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ describe('Wallet Auction', function() {
await chain.open();
await miner.open();
await wdb.open();
await wdb.connect();

// Set up wallet
winner = await wdb.create();
Expand All @@ -81,6 +82,7 @@ describe('Wallet Auction', function() {
});

after(async () => {
await wdb.disconnect();
await wdb.close();
await miner.close();
await chain.close();
Expand Down
Loading

0 comments on commit b53d392

Please sign in to comment.