diff --git a/src/index.ts b/src/index.ts index 34a69472..09387e82 100644 --- a/src/index.ts +++ b/src/index.ts @@ -179,8 +179,8 @@ class LiskMigrator extends Command { // User specified custom config file const configV3: ApplicationConfigV3 = customConfigPath - ? await getConfig(liskCoreV3DataPath, customConfigPath) - : await getConfig(liskCoreV3DataPath); + ? await getConfig(this, liskCoreV3DataPath, networkIdentifier, customConfigPath) + : await getConfig(this, liskCoreV3DataPath, networkIdentifier); await setTokenIDLskByNetID(networkIdentifier); await setPrevSnapshotBlockHeightByNetID(networkIdentifier); diff --git a/src/utils/config.ts b/src/utils/config.ts index 36262a41..6f2bfbd9 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -14,7 +14,8 @@ /* eslint-disable no-param-reassign */ import * as fs from 'fs-extra'; import cli from 'cli-ux'; -import { existsSync, readdirSync, mkdirSync, writeFileSync } from 'fs'; +import { Command } from '@oclif/command'; +import { existsSync, mkdirSync, writeFileSync } from 'fs'; import { join, resolve } from 'path'; import { validator } from '@liskhq/lisk-validator'; import { ApplicationConfig, applicationConfigSchema } from 'lisk-framework'; @@ -39,7 +40,13 @@ const LOG_LEVEL_PRIORITY = Object.freeze({ TRACE: 5, }) as Record; -export const isBinaryBuild = (corePath: string): boolean => existsSync(join(corePath, '.build')); +export const getNetworkByNetworkID = (_networkID: string): string | Error => { + const networkInfo = NETWORK_CONSTANT[_networkID]; + if (!networkInfo) { + throw new Error('Migrator running against unidentified network. Cannot proceed.'); + } + return networkInfo.name; +}; export const getLogLevel = (loggerConfig: LoggerConfig): string => { const highestLogPriority = Math.max( @@ -47,20 +54,31 @@ export const getLogLevel = (loggerConfig: LoggerConfig): string => { LOG_LEVEL_PRIORITY[String(loggerConfig.consoleLogLevel).toUpperCase()], ); - const [logLevel] = Object.entries(LOG_LEVEL_PRIORITY).find( - ([, v]) => v === highestLogPriority, - ) as [string, number]; + try { + const [logLevel] = Object.entries(LOG_LEVEL_PRIORITY).find( + ([, v]) => v === highestLogPriority, + ) as [string, number]; - return logLevel.toLowerCase(); + return logLevel.toLowerCase(); + } catch (err) { + return 'info'; + } }; export const getConfig = async ( + _this: Command, corePath: string, + _networkID: string, customConfigPath?: string, ): Promise => { - const [network] = readdirSync(`${corePath}/config`); + let network: string | Error = 'mainnet'; + try { + network = getNetworkByNetworkID(_networkID); + } catch (err) { + _this.error(err as Error); + } - const dataDirConfigPath = `${corePath}/config/${network}/config.json`; + const dataDirConfigPath = join(corePath, 'config', network as string, 'config.json'); const dataDirConfig = await fs.readJSON(dataDirConfigPath); const customConfig = customConfigPath @@ -94,27 +112,27 @@ export const migrateUserConfig = async ( cli.action.start('Starting migration of custom config properties.'); // Assign default version if not available - if (!configV4.system.version) { + if (!configV4.system?.version) { cli.action.start(`Setting config property 'system.version' to: ${DEFAULT_VERSION}.`); configV4.system.version = DEFAULT_VERSION; cli.action.stop(); } - if (configV3.rootPath) { + if (configV3?.rootPath) { cli.action.start(`Setting config property 'system.dataPath' to: ${configV3.rootPath}.`); configV4.system.dataPath = configV3.rootPath; cli.action.stop(); } - if (configV3.logger) { + if (configV3?.logger) { const logLevel = getLogLevel(configV3.logger); cli.action.start(`Setting config property 'system.logLevel' to: ${logLevel}.`); configV4.system.logLevel = logLevel; cli.action.stop(); } - if (configV3.transactionPool) { - if (configV3.transactionPool.maxTransactions) { + if (configV3?.transactionPool) { + if (configV3?.transactionPool?.maxTransactions) { cli.action.start( `Setting config property 'transactionPool.maxTransactions' to: ${configV3.transactionPool.maxTransactions}.`, ); @@ -123,7 +141,7 @@ export const migrateUserConfig = async ( cli.action.stop(); } - if (configV3.transactionPool.maxTransactionsPerAccount) { + if (configV3?.transactionPool?.maxTransactionsPerAccount) { cli.action.start( `Setting config property 'transactionPool.maxTransactionsPerAccount' to: ${configV3.transactionPool.maxTransactionsPerAccount}.`, ); @@ -132,7 +150,7 @@ export const migrateUserConfig = async ( cli.action.stop(); } - if (configV3.transactionPool.transactionExpiryTime) { + if (configV3?.transactionPool?.transactionExpiryTime) { cli.action.start( `Setting config property 'transactionPool.transactionExpiryTime' to: ${configV3.transactionPool.transactionExpiryTime}.`, ); @@ -141,7 +159,7 @@ export const migrateUserConfig = async ( cli.action.stop(); } - if (configV3.transactionPool.minEntranceFeePriority) { + if (configV3?.transactionPool?.minEntranceFeePriority) { cli.action.start( `Setting config property 'transactionPool.minEntranceFeePriority' to: ${configV3.transactionPool.minEntranceFeePriority}.`, ); @@ -150,7 +168,7 @@ export const migrateUserConfig = async ( cli.action.stop(); } - if (configV3.transactionPool.minReplacementFeeDifference) { + if (configV3?.transactionPool?.minReplacementFeeDifference) { cli.action.start( `Setting config property 'transactionPool.minReplacementFeeDifference' to: ${configV3.transactionPool.minReplacementFeeDifference}.`, ); @@ -160,26 +178,26 @@ export const migrateUserConfig = async ( } } - if (configV3.rpc?.mode) { + if (configV3?.rpc?.mode) { cli.action.start(`Setting config property 'rpc.modes' to: ${configV3.rpc.mode}.`); configV4.rpc.modes = [configV3.rpc.mode]; cli.action.stop(); } - if (configV3.network) { - if (configV3.network.port) { + if (configV3?.network) { + if (configV3?.network?.port) { cli.action.start(`Setting config property 'network.port' to: ${configV3.network.port}.`); configV4.network.port = configV3.network.port; cli.action.stop(); } - if (configV3.network.hostIp) { + if (configV3?.network?.hostIp) { cli.action.start(`Setting config property 'network.host' to: ${configV3.network.hostIp}.`); configV4.network.host = configV3.network.hostIp; cli.action.stop(); } - if (configV3.network.maxOutboundConnections) { + if (configV3?.network?.maxOutboundConnections) { cli.action.start( `Setting config property 'network.maxOutboundConnections' to: ${configV3.network.maxOutboundConnections}.`, ); @@ -187,7 +205,7 @@ export const migrateUserConfig = async ( cli.action.stop(); } - if (configV3.network.maxInboundConnections) { + if (configV3?.network?.maxInboundConnections) { cli.action.start( `Setting config property 'network.maxInboundConnections' to: ${configV3.network.maxInboundConnections}.`, ); @@ -195,7 +213,7 @@ export const migrateUserConfig = async ( cli.action.stop(); } - if (configV3.network.wsMaxPayload) { + if (configV3?.network?.wsMaxPayload) { cli.action.start( `Setting config property 'network.wsMaxPayload' to: ${configV3.network.wsMaxPayload}.`, ); @@ -203,7 +221,7 @@ export const migrateUserConfig = async ( cli.action.stop(); } - if (configV3.network.advertiseAddress) { + if (configV3?.network?.advertiseAddress) { cli.action.start( `Setting config property 'network.advertiseAddress' to: ${configV3.network.advertiseAddress}.`, ); @@ -220,7 +238,7 @@ export const migrateUserConfig = async ( (NUMBER_ACTIVE_VALIDATORS + NUMBER_STANDBY_VALIDATORS); cli.action.stop(); - if (configV4.modules.pos && !configV4.modules.pos.maxBFTWeightCap) { + if (configV4.modules?.pos && !configV4.modules?.pos?.maxBFTWeightCap) { cli.action.start( `Setting config property 'modules.pos.maxBFTWeightCap' to: ${MAX_BFT_WEIGHT_CAP}.`, ); diff --git a/src/utils/genesis_block.ts b/src/utils/genesis_block.ts index aa3473ad..d09b99f1 100644 --- a/src/utils/genesis_block.ts +++ b/src/utils/genesis_block.ts @@ -20,12 +20,14 @@ import { GenesisAssetEntry } from '../types'; import { execAsync } from './process'; import { copyFile, createTarball } from './fs'; +/* eslint-disable func-names, @typescript-eslint/no-explicit-any */ (BigInt.prototype as any).toJSON = function () { return this.toString(); }; (Buffer.prototype as any).toJSON = function () { return this.toString('hex'); }; +/* eslint-enable func-names, @typescript-eslint/no-explicit-any */ export const createChecksum = async (filePath: string): Promise => { const fileStream = fs.createReadStream(filePath); diff --git a/test/unit/utils/config.spec.ts b/test/unit/utils/config.spec.ts index 6e92807e..c5b3fad0 100644 --- a/test/unit/utils/config.spec.ts +++ b/test/unit/utils/config.spec.ts @@ -15,7 +15,9 @@ import * as fs from 'fs-extra'; import { resolve, join } from 'path'; import { ApplicationConfig } from 'lisk-framework'; import { configV3, configV4 } from '../fixtures/config'; +import { NETWORK_CONSTANT } from '../../../src/constants'; import { + getNetworkByNetworkID, migrateUserConfig, validateConfig, writeConfig, @@ -58,6 +60,21 @@ describe('Migrate user configuration', () => { }); }); +describe('Test networkIdentifier method', () => { + it('should determine network correctly by networkIdentifier', async () => { + Object.keys(NETWORK_CONSTANT).forEach(networkID => { + const network = getNetworkByNetworkID(networkID); + expect(network).toBe(NETWORK_CONSTANT[networkID].name); + }); + }); + + it('should throw error with unknown networkIdentifier', async () => { + expect(() => getNetworkByNetworkID('unknown network identifier')).toThrow( + 'Migrator running against unidentified network. Cannot proceed.', + ); + }); +}); + describe('Test resolveConfigPathByNetworkID method', () => { it('should resolve config filePath when called by valid networkID', async () => { const expectedConfigPath = resolve(`${__dirname}../../../../config/testnet/config.json`);