Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Commit

Permalink
🔨 Refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
sameersubudhi committed Oct 23, 2023
1 parent d069f97 commit 0e85fa4
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 73 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ module.exports = {
rules: {
'max-len': 'off', // Managed by prettier
'no-underscore-dangle': 'off', // Used for private variables and methods
'implicit-arrow-linebreak': 'off', // Prefered
'implicit-arrow-linebreak': 'off', // Preferred
'no-mixed-spaces-and-tabs': 'off', // Managed by prettier
'no-shadow': 'off',
'operator-linebreak': 'off',
'import/prefer-default-export': 'off',
'lines-between-class-members': 'off', // Off because typescript has members and methods
Expand All @@ -31,6 +32,7 @@ module.exports = {
'@typescript-eslint/no-unnecessary-boolean-literal-compare': ['error'],
'@typescript-eslint/no-unnecessary-qualifier': ['error'],
'@typescript-eslint/no-unnecessary-type-arguments': ['error'],
'@typescript-eslint/no-shadow': 'warn',
'@typescript-eslint/prefer-for-of': ['error'],
'@typescript-eslint/prefer-function-type': ['error'],
'@typescript-eslint/prefer-includes': ['error'],
Expand Down
11 changes: 6 additions & 5 deletions docs/migration.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Migration Guide

This section explains how to migrate a Lisk Core v3.0.4 (or later) node to Lisk Core v4.x using the Lisk Migrator.
This section explains how to migrate a Lisk Core v3.1.0 node to Lisk Core v4.0.0 using the Lisk Migrator.

The Lisk Migrator CLI tool will generate a new genesis (snapshot) block for Lisk Core v4.x.
The new genesis block is created based on a snapshot of the existing blockchain (running on Lisk Core v3.0.4+) at a pre-determined height.
The Lisk Migrator CLI tool will generate a new genesis (snapshot) block for Lisk Core v4.0.0.
The new genesis block is created based on a snapshot of the existing blockchain (running on Lisk Core v3.1.0) at a pre-determined height.

Lisk Migrator automatically exports the node's Forging Status information to the file named `forgingStatus.json` under the output directory. In case, Lisk Migrator is unable to save to the disk, as a fallback, the Forging Status information is logged to the standard output.
Lisk Migrator automatically exports the node's Forging Status information to the file named `forgingStatus.json` under the output directory.
In case, the Lisk Migrator is unable to save to the disk, as a fallback, the Forging Status information is logged to the standard output.

<!--
Expand Down Expand Up @@ -67,7 +68,7 @@ export PATH="$PATH:$HOME/lisk-migrator/bin"
**Check the announced snapshot height**

- For Mainnet: `TBD`
- For Testnet: `TBD`
- For Testnet: `20449414`

### Run Lisk Migrator

Expand Down
16 changes: 12 additions & 4 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,16 @@ export const LEGACY_DB_PATH = `${DEFAULT_LISK_CORE_PATH}/${DEFAULT_DATA_DIR}/leg
export const DEFAULT_VERSION = '0.1.0';
export const EVENT_NEW_BLOCK = 'app:block:new';

/* eslint-disable-next-line no-shadow */
export const enum ERROR_CODES {
GENESIS_BLOCK_CREATE = 0,
LISK_CORE_START = 1,
export const FILE_NAME = {
COMMANDS_TO_EXEC: 'commandsToExecute.txt',
FORGING_STATUS: 'forgingStatus.json',
};

export const enum ERROR_CODE {
DEFAULT = 0,
INVALID_CONFIG = 1,
GENESIS_BLOCK_CREATE = 2,
LISK_CORE_START = 3,
BACKUP_LEGACY_DATA_DIR = 4,
COPY_LEGACY_DB = 5,
}
4 changes: 2 additions & 2 deletions src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { Block } from '@liskhq/lisk-chain';
import { address } from '@liskhq/lisk-cryptography';
import { APIClient } from '@liskhq/lisk-api-client';
import { write } from './utils/fs';
import { EVENT_NEW_BLOCK } from './constants';
import { EVENT_NEW_BLOCK, FILE_NAME } from './constants';
import { ForgingStatus } from './types';

const { getLisk32AddressFromAddress } = address;
Expand All @@ -41,7 +41,7 @@ export const captureForgingStatusAtSnapshotHeight = (

if (finalForgingStatuses.length) {
try {
const forgingStatusJsonFilepath = resolve(outputDir, 'forgingStatus.json');
const forgingStatusJsonFilepath = resolve(outputDir, FILE_NAME.FORGING_STATUS);
await write(forgingStatusJsonFilepath, JSON.stringify(finalForgingStatuses, null, '\t'));
_this.log(`\nFinished exporting forging status to ${forgingStatusJsonFilepath}.`);
} catch (error) {
Expand Down
70 changes: 40 additions & 30 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import {
SNAPSHOT_DIR,
MIN_SUPPORTED_LISK_CORE_VERSION,
DEFAULT_LISK_CORE_PATH,
ERROR_CODES,
ERROR_CODE,
FILE_NAME,
} from './constants';
import { getAPIClient } from './client';
import {
Expand All @@ -53,11 +54,16 @@ import {
} from './utils/genesis_block';
import { CreateAsset } from './createAsset';
import { ApplicationConfigV3, NetworkConfigLocal, NodeInfo } from './types';
import { installLiskCore, startLiskCore, isLiskCoreV3Running } from './utils/node';
import {
installLiskCore,
startLiskCore,
isLiskCoreV3Running,
getLiskCoreStartCommand,
} from './utils/node';
import { resolveAbsolutePath, verifyOutputPath } from './utils/path';
import { execAsync } from './utils/process';
import { CustomError } from './utils/exception';
import { getCommandsToExecPostMigration, writeCommandsToExecute } from './utils/commands';
import { MigratorException } from './utils/exception';
import { writeCommandsToExec } from './utils/commands';

let configCoreV4: PartialApplicationConfig;
class LiskMigrator extends Command {
Expand Down Expand Up @@ -154,6 +160,7 @@ class LiskMigrator extends Command {

// Ensure the output directory is present
if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
const filePathCommandsToExec = `${outputDir}/${FILE_NAME.COMMANDS_TO_EXEC}`;

try {
// Asynchronously capture the node's Forging Status information at the snapshot height
Expand Down Expand Up @@ -239,7 +246,12 @@ class LiskMigrator extends Command {
const isValidConfig = await validateConfig(migratedConfigV4);
cli.action.stop();

if (!isValidConfig) throw new Error('Migrated user configuration is invalid.');
if (!isValidConfig) {
throw new MigratorException(
'Migrated user configuration is invalid.',
ERROR_CODE.INVALID_CONFIG,
);
}

cli.action.start(`Exporting user configuration to the path: ${outputDir}`);
await writeConfig(migratedConfigV4, outputDir);
Expand Down Expand Up @@ -310,16 +322,14 @@ class LiskMigrator extends Command {
"Lisk Core v3 still running. Please stop the node, type 'yes' to proceed and 'no' to exit. [yes/no]",
);
if (!isStopReconfirmed) {
throw new CustomError(
throw new Error(
`Cannot proceed with Lisk Core v4 auto-start. Please continue manually. In order to access legacy blockchain information posts-migration, please copy the contents of the ${snapshotDirPath} directory to 'data/legacy.db' under the Lisk Core v4 data directory (e.g: ${DEFAULT_LISK_CORE_PATH}/data/legacy.db/). Exiting!!!`,
ERROR_CODES.LISK_CORE_START,
);
} else if (numTriesLeft === 0 && isStopReconfirmed) {
const isCoreV3StillRunning = await isLiskCoreV3Running(liskCoreV3DataPath);
if (isCoreV3StillRunning) {
throw new CustomError(
throw new Error(
`Cannot auto-start Lisk Core v4 as Lisk Core v3 is still running. Please continue manually. In order to access legacy blockchain information posts-migration, please copy the contents of the ${snapshotDirPath} directory to 'data/legacy.db' under the Lisk Core v4 data directory (e.g: ${DEFAULT_LISK_CORE_PATH}/data/legacy.db/). Exiting!!!`,
ERROR_CODES.LISK_CORE_START,
);
}
}
Expand All @@ -345,16 +355,15 @@ class LiskMigrator extends Command {
);
}
} else {
throw new CustomError(
throw new Error(
`User did not confirm Lisk Core v3 node shutdown. Skipping the Lisk Core v4 auto-start process. Please continue manually. In order to access legacy blockchain information posts-migration, please copy the contents of the ${snapshotDirPath} directory to 'data/legacy.db' under the Lisk Core v4 data directory (e.g: ${DEFAULT_LISK_CORE_PATH}/data/legacy.db/). Exiting!!!`,
ERROR_CODES.LISK_CORE_START,
);
}
} catch (err) {
/* eslint-disable-next-line @typescript-eslint/restrict-template-expressions */
throw new CustomError(
`Failed to auto-start Lisk Core v4.\nError: ${(err as Error).message}`,
ERROR_CODES.LISK_CORE_START,
const errorMsg = `Failed to auto-start Lisk Core v4.\nError: ${(err as Error).message}`;
throw new MigratorException(
errorMsg,
err instanceof MigratorException ? err.code : ERROR_CODE.LISK_CORE_START,
);
}
} else {
Expand All @@ -365,40 +374,41 @@ class LiskMigrator extends Command {
}
} catch (error) {
const commandsToExecute: string[] = [];
const code = Number(`${(error as { message: string; code: number }).code}`);
const code = Number(`${(error as MigratorException).code}`);

const liskCoreStartCommand = `lisk core start--network ${networkConstant.name}`;
const basicStartCommand = `lisk-core start --network ${networkConstant.name}`;
const liskCoreStartCommand = getLiskCoreStartCommand() ?? basicStartCommand;

if (code === ERROR_CODES.GENESIS_BLOCK_CREATE) {
if (code === ERROR_CODE.GENESIS_BLOCK_CREATE) {
const genesisBlockCreateCommand = getGenesisBlockCreateCommand();
commandsToExecute.push(genesisBlockCreateCommand);
commandsToExecute.push(liskCoreStartCommand);
}

if (code === ERROR_CODES.LISK_CORE_START) {
if (code === ERROR_CODE.LISK_CORE_START) {
commandsToExecute.push(liskCoreStartCommand);
}

this.log(`Creating file with the list of commands to execute: ${filePathCommandsToExec}`);
await writeCommandsToExec(outputDir, commandsToExecute);
this.log(
`Creating file with the list of commands to execute: ${outputDir}/commandsToExecute.txt`,
);
await writeCommandsToExecute(
[...commandsToExecute, ...(await getCommandsToExecPostMigration(outputDir))],
outputDir,
`Successfully created file with the list of commands to execute: ${filePathCommandsToExec}`,
);
this.log(
`Successfully created file with the list of commands to execute: ${outputDir}/commandsToExecute.txt`,

this.error(
`Migrator could not finish execution successfully due to: ${
(error as Error).message
}\nPlease check the commands to be executed in the file: ${filePathCommandsToExec}`,
);
this.error(`${(error as Error).message}`);
}

this.log('Successfully finished migration. Exiting!!!');
this.log(
`Creating file with the list of commands to execute post migration: ${outputDir}/commandsToExecute.txt`,
`Creating file with the list of commands to execute post migration: ${filePathCommandsToExec}`,
);
await writeCommandsToExecute(await getCommandsToExecPostMigration(outputDir), outputDir);
await writeCommandsToExec(outputDir);
this.log(
`Successfully created file with the list of commands to execute post migration: ${outputDir}/commandsToExecute.txt`,
`Successfully created file with the list of commands to execute post migration: ${filePathCommandsToExec}`,
);

process.exit(0);
Expand Down
17 changes: 12 additions & 5 deletions src/utils/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import { resolve } from 'path';

import { read, write, exists } from './fs';
import { FILE_NAME } from '../constants';

export const getCommandsToExecPostMigration = async (outputDir: string) => {
const commandsToExecute = [];
Expand All @@ -24,7 +25,7 @@ export const getCommandsToExecPostMigration = async (outputDir: string) => {
);
commandsToExecute.push('lisk-core keys:import --file-path config/keys.json');

const forgingStatusJsonFilepath = resolve(outputDir, 'forgingStatus.json');
const forgingStatusJsonFilepath = resolve(outputDir, FILE_NAME.FORGING_STATUS);
if (await exists(forgingStatusJsonFilepath)) {
const forgingStatusString = (await read(forgingStatusJsonFilepath)) as string;
const forgingStatusJson = JSON.parse(forgingStatusString);
Expand Down Expand Up @@ -53,8 +54,14 @@ export const getCommandsToExecPostMigration = async (outputDir: string) => {
return commandsToExecute;
};

export const writeCommandsToExecute = async (commandsToExecute: string[], outputDir: string) => {
const commandsToExecuteFilepath = resolve(outputDir, 'commandsToExecute.txt');
const inputCommands = commandsToExecute.join('\n\n');
await write(commandsToExecuteFilepath, inputCommands);
export const writeCommandsToExec = async (outputDir: string, preCompletionCommands?: string[]) => {
const commandsToExecPreCompletion = preCompletionCommands ?? [];
const commandsToExecPostMigration = await getCommandsToExecPostMigration(outputDir);

const allCommandsToExec = [...commandsToExecPreCompletion, ...commandsToExecPostMigration].join(
'\n\n',
);

const commandsToExecuteFilepath = resolve(outputDir, FILE_NAME.COMMANDS_TO_EXEC);
await write(commandsToExecuteFilepath, allCommandsToExec);
};
6 changes: 4 additions & 2 deletions src/utils/exception.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
*
* Removal or modification of this copyright notice is prohibited.
*/
import { ERROR_CODE } from '../constants';

export class MigratorException extends Error {
public code: number = ERROR_CODE.DEFAULT;

export class CustomError extends Error {
public code: number;
public constructor(message: string, code: number) {
super(message);
this.code = code;
Expand Down
8 changes: 4 additions & 4 deletions src/utils/genesis_block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import * as fs from 'fs-extra';
import path from 'path';
import { Command } from '@oclif/command';
import { Block as BlockVersion3 } from '@liskhq/lisk-chain';
import { ERROR_CODES, SNAPSHOT_TIME_GAP } from '../constants';
import { ERROR_CODE, SNAPSHOT_TIME_GAP } from '../constants';
import { GenesisAssetEntry } from '../types';
import { execAsync } from './process';
import { copyFile, createTarball } from './fs';
import { CustomError } from './exception';
import { MigratorException } from './exception';

/* eslint-disable func-names, @typescript-eslint/no-explicit-any */
(BigInt.prototype as any).toJSON = function () {
Expand Down Expand Up @@ -72,9 +72,9 @@ export const createGenesisBlock = async (

await execAsync(genesisBlockCreateCommand);
} catch (error) {
throw new CustomError(
throw new MigratorException(
`Failed to create genesis block.\nError: ${(error as Error).message}`,
ERROR_CODES.GENESIS_BLOCK_CREATE,
ERROR_CODE.GENESIS_BLOCK_CREATE,
);
}
};
Expand Down
Loading

0 comments on commit 0e85fa4

Please sign in to comment.