Skip to content

Commit

Permalink
wallet: add migration to regenerate missing change addresses. see #414,
Browse files Browse the repository at this point in the history
  • Loading branch information
chjj committed Mar 31, 2020
1 parent 5b1980f commit 4468e36
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lib/wallet/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class Wallet extends EventEmitter {
this.wid = 0;
this.id = null;
this.watchOnly = false;
this.fixedChange = false;
this.accountDepth = 0;
this.token = consensus.ZERO_HASH;
this.tokenDepth = 0;
Expand Down Expand Up @@ -4456,6 +4457,7 @@ class Wallet extends EventEmitter {
wid: this.wid,
id: this.id,
watchOnly: this.watchOnly,
fixedChange: this.fixedChange,
accountDepth: this.accountDepth,
token: this.token.toString('hex'),
tokenDepth: this.tokenDepth,
Expand Down Expand Up @@ -4502,6 +4504,9 @@ class Wallet extends EventEmitter {
if (this.watchOnly)
flags |= 1;

if (this.fixedChange)
flags |= 2;

bw.writeU8(flags);
bw.writeU32(this.accountDepth);
bw.writeBytes(this.token);
Expand All @@ -4523,6 +4528,7 @@ class Wallet extends EventEmitter {
const flags = br.readU8();

this.watchOnly = (flags & 1) !== 0;
this.fixedChange = (flags & 2) !== 0;
this.accountDepth = br.readU32();
this.token = br.readBytes(32);
this.tokenDepth = br.readU32();
Expand Down
45 changes: 45 additions & 0 deletions lib/wallet/walletdb.js
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,9 @@ class WalletDB extends EventEmitter {

this.register(wallet);

if (!wallet.fixedChange)
await this._migrateChange(wallet);

return wallet;
}

Expand Down Expand Up @@ -1087,6 +1090,7 @@ class WalletDB extends EventEmitter {
const wallet = Wallet.fromOptions(this, options);

wallet.wid = this.depth;
wallet.fixedChange = true;

await wallet.init(options, options.passphrase);

Expand Down Expand Up @@ -2270,6 +2274,47 @@ class WalletDB extends EventEmitter {

return this.rollback(entry.height);
}

/**
* Run change address migration.
* @param {Wallet} wallet
*/

async _migrateChange(wallet) {
const b = this.db.batch();

this.logger.info('Regenerating change addresses.');

let total = 0;

for (let i = 0; i < wallet.accountDepth; i++) {
const account = await wallet.getAccount(i);

for (let i = 0; i < account.changeDepth + account.lookahead; i++) {
const key = account.deriveChange(i);
const path = key.toPath();

if (!await this.hasPath(account.wid, path.hash)) {
await this.savePath(b, account.wid, path);
total += 1;
}
}
}

wallet.fixedChange = true;

this.save(b, wallet);

await b.write();

if (total > 0) {
this.logger.warning('Regenerated %d change addresses.', total);
this.logger.warning(
'Please rescan if you believe you have missing outputs.');
} else {
this.logger.info('All change addresses present.');
}
}
}

/**
Expand Down

0 comments on commit 4468e36

Please sign in to comment.