wdb-migration: fix and test coin selection progress recovery.
This commit is contained in:
parent
cd3dfeb943
commit
fb18da4dc6
2 changed files with 94 additions and 5 deletions
|
|
@ -1405,9 +1405,16 @@ class MigrateCoinSelection extends AbstractMigration {
|
|||
await this.decodeProgress(ctx.state.inProgressData);
|
||||
|
||||
for (const wid of wids) {
|
||||
if (wid < this.progress.wid)
|
||||
if (wid < this.progress.wid) {
|
||||
this.logger.debug(
|
||||
'Skipping wallet %d (%d/%d), already migrated.',
|
||||
wid, this.progress.wid, wids.length);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.logger.info(
|
||||
'Migrating wallet %d (%d/%d)',
|
||||
wid, this.progress.wid, wids.length);
|
||||
await this.migrateWallet(wid, ctx);
|
||||
}
|
||||
|
||||
|
|
@ -1473,7 +1480,7 @@ class MigrateCoinSelection extends AbstractMigration {
|
|||
this.progress.wid = wid;
|
||||
this.progress.account = account;
|
||||
this.progress.hash = hash;
|
||||
this.progress.index = index;
|
||||
this.progress.index = index + 1;
|
||||
|
||||
ctx.state.inProgressData = this.encodeProgress();
|
||||
ctx.writeState(parent.root());
|
||||
|
|
@ -1488,7 +1495,7 @@ class MigrateCoinSelection extends AbstractMigration {
|
|||
this.progress.hash = consensus.ZERO_HASH;
|
||||
this.progress.index = 0;
|
||||
ctx.state.inProgressData = this.encodeProgress();
|
||||
ctx.writeState(parent);
|
||||
ctx.writeState(parent.root());
|
||||
await parent.write();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1121,7 +1121,7 @@ describe('Wallet Migrations', function() {
|
|||
};
|
||||
|
||||
let walletDB, ldb;
|
||||
before(async () => {
|
||||
beforeEach(async () => {
|
||||
WalletMigrator.migrations = {};
|
||||
await fs.mkdirp(location);
|
||||
|
||||
|
|
@ -1133,7 +1133,7 @@ describe('Wallet Migrations', function() {
|
|||
await walletDB.close();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
afterEach(async () => {
|
||||
WalletMigrator.migrations = migrationsBAK;
|
||||
await rimraf(location);
|
||||
});
|
||||
|
|
@ -1164,5 +1164,87 @@ describe('Wallet Migrations', function() {
|
|||
|
||||
await walletDB.close();
|
||||
});
|
||||
|
||||
it('should resume the progress of migration if interrupted', async () => {
|
||||
// patch the db buckets to throw after each write.
|
||||
const patchDB = () => {
|
||||
// throw after each bucket write.
|
||||
const ldbBucket = walletDB.db.bucket;
|
||||
|
||||
walletDB.db.bucket = (prefix) => {
|
||||
const bucket = ldbBucket.call(ldb, prefix);
|
||||
const bucketBatch = bucket.batch;
|
||||
|
||||
bucket.batch = () => {
|
||||
const batch = bucketBatch.call(bucket);
|
||||
const originalWrite = batch.write;
|
||||
|
||||
batch.write = async () => {
|
||||
await originalWrite.call(batch);
|
||||
throw new Error('Interrupt migration');
|
||||
};
|
||||
|
||||
return batch;
|
||||
};
|
||||
|
||||
return bucket;
|
||||
};
|
||||
|
||||
return () => {
|
||||
walletDB.db.bucket = ldbBucket;
|
||||
};
|
||||
};
|
||||
|
||||
WalletMigrator.migrations = {
|
||||
0: class extends Migration {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
|
||||
this.batchSize = 10;
|
||||
}
|
||||
|
||||
async migrate(b, ctx) {
|
||||
const unpatch = patchDB();
|
||||
await super.migrate(b, ctx);
|
||||
unpatch();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
await walletDB.db.open();
|
||||
|
||||
const migrator = new WalletMigrator({
|
||||
walletMigrate: 0,
|
||||
walletDB: walletDB,
|
||||
dbVersion: 5
|
||||
});
|
||||
|
||||
let err;
|
||||
|
||||
do {
|
||||
try {
|
||||
await migrator.migrate();
|
||||
err = null;
|
||||
} catch (e) {
|
||||
if (e.message !== 'Interrupt migration')
|
||||
throw e;
|
||||
|
||||
err = e;
|
||||
}
|
||||
} while (err);
|
||||
|
||||
await checkEntries(ldb, {
|
||||
before: data.before,
|
||||
after: data.after,
|
||||
throw: true
|
||||
});
|
||||
|
||||
await checkExactEntries(ldb, data.prefixes, {
|
||||
after: data.after,
|
||||
throw: true
|
||||
});
|
||||
|
||||
await walletDB.db.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue