Skip to content

Migrations: Add in progress data to migration #925

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

**When upgrading to this version of hsd, you must pass `--chain-migrate=4`
and `--wallet-migrate=6` when you run it for the first time.**

### Wallet Changes

#### Wallet HTTP API
Expand Down
85 changes: 51 additions & 34 deletions lib/blockchain/migrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ const CoinView = require('../coins/coinview');
const UndoCoins = require('../coins/undocoins');
const layout = require('./layout');
const AbstractMigration = require('../migrations/migration');
const migrator = require('../migrations/migrator');
const {
Migrator,
oldLayout,
types
} = require('../migrations/migrator');
} = migrator;

/** @typedef {import('../types').Hash} Hash */
/** @typedef {ReturnType<bdb.DB['batch']>} Batch */
/** @typedef {import('../migrations/migrator').types} MigrationType */
/** @typedef {migrator.types} MigrationType */
/** @typedef {migrator.MigrationContext} MigrationContext */

/**
* Switch to new migrations layout.
Expand Down Expand Up @@ -59,14 +61,14 @@ class MigrateMigrations extends AbstractMigration {
/**
* Actual migration
* @param {Batch} b
* @param {MigrationContext} ctx
* @returns {Promise}
*/

async migrate(b) {
async migrate(b, ctx) {
this.logger.info('Migrating migrations..');

const oldLayout = this.layout.oldLayout;
const newLayout = this.layout.newLayout;
let nextMigration = 1;
const skipped = [];

Expand All @@ -90,33 +92,9 @@ class MigrateMigrations extends AbstractMigration {

this.db.writeVersion(b, 2);

const rawState = this.encodeMigrationState(nextMigration, skipped);
b.put(newLayout.M.encode(), rawState);
}

/**
* @param {Number} nextMigration
* @param {Number[]} skipped
* @returns {Buffer}
*/

encodeMigrationState(nextMigration, skipped) {
let size = 4;
size += encoding.sizeVarint(nextMigration);
size += encoding.sizeVarint(skipped.length);

for (const id of skipped)
size += encoding.sizeVarint(id);

const bw = bio.write(size);
bw.writeU32(0);
bw.writeVarint(nextMigration);
bw.writeVarint(skipped.length);

for (const id of skipped)
bw.writeVarint(id);

return bw.render();
ctx.state.version = 0;
ctx.state.skipped = skipped;
ctx.state.nextMigration = nextMigration;
}

static info() {
Expand Down Expand Up @@ -555,6 +533,45 @@ class MigrateTreeState extends AbstractMigration {
}
}

class MigrateMigrationStateV1 extends AbstractMigration {
/**
* Create migration migration state
* @constructor
* @param {ChainMigratorOptions} options
*/

constructor(options) {
super(options);

this.options = options;
this.logger = options.logger.context('chain-migration-migration-state-v1');
this.db = options.db;
this.ldb = options.ldb;
this.network = options.network;
}

async check() {
return types.MIGRATE;
}

/**
* @param {Batch} b
* @param {MigrationContext} ctx
* @returns {Promise}
*/

async migrate(b, ctx) {
ctx.state.version = 1;
}

static info() {
return {
name: 'Migrate Migration State',
description: 'Migrate migration state to v1'
};
}
}

/**
* Chain Migrator
* @alias module:blockchain.ChainMigrator
Expand All @@ -572,8 +589,6 @@ class ChainMigrator extends Migrator {
this.logger = this.options.logger.context('chain-migrations');
this.flagError = 'Restart with `hsd --chain-migrate='
+ this.lastMigration + '`';

this._migrationsToRun = null;
}

/**
Expand Down Expand Up @@ -695,13 +710,15 @@ ChainMigrator.migrations = {
0: MigrateMigrations,
1: MigrateChainState,
2: MigrateBlockStore,
3: MigrateTreeState
3: MigrateTreeState,
4: MigrateMigrationStateV1
};

// Expose migrations
ChainMigrator.MigrateChainState = MigrateChainState;
ChainMigrator.MigrateMigrations = MigrateMigrations;
ChainMigrator.MigrateBlockStore = MigrateBlockStore;
ChainMigrator.MigrateTreeState = MigrateTreeState;
ChainMigrator.MigrateMigrationStateV1 = MigrateMigrationStateV1;

module.exports = ChainMigrator;
4 changes: 3 additions & 1 deletion lib/migrations/migration.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/** @typedef {import('bdb').DB} DB */
/** @typedef {ReturnType<DB['batch']>} Batch */
/** @typedef {import('./migrator').types} MigrationType */
/** @typedef {import('./migrator').MigrationContext} MigrationContext */

/**
* Abstract class for single migration.
Expand Down Expand Up @@ -37,10 +38,11 @@ class AbstractMigration {
/**
* Run the actual migration
* @param {Batch} b
* @param {MigrationContext} ctx
* @returns {Promise}
*/

async migrate(b) {
async migrate(b, ctx) {
throw new Error('Abstract method.');
}

Expand Down
Loading