From be04ccb9b8b498a0cbde4fe5d465e1649bee1db5 Mon Sep 17 00:00:00 2001 From: fboucquez Date: Thu, 29 Jul 2021 14:55:35 -0300 Subject: [PATCH 1/3] fix: custom preset cached on target fix: --preset bootstrap is not the default anymore. --- CHANGELOG.md | 5 +- README.md | 4 +- docs/config.md | 17 ++-- docs/pack.md | 21 ++-- docs/start.md | 16 ++-- src/commands/config.ts | 25 ++--- src/commands/pack.ts | 14 ++- src/commands/start.ts | 5 +- src/commands/updateVotingKeys.ts | 28 +++--- src/commands/wizard.ts | 15 +-- src/model/ConfigPreset.ts | 1 + src/service/ConfigLoader.ts | 69 +++++++------ src/service/ConfigService.ts | 2 +- src/service/VotingService.ts | 4 +- test/commands/config.test.ts | 4 +- test/override-currency-preset.yml | 1 + test/service/ConfigLoader.test.ts | 112 +++++++++++++++++++++- test/service/ConfigService.test.ts | 12 ++- test/unit-test-profiles/custom_preset.yml | 8 ++ 19 files changed, 247 insertions(+), 116 deletions(-) create mode 100644 test/unit-test-profiles/custom_preset.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index e42d783ad..162604241 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,15 @@ The changelog format is based on [Keep a Changelog](https://keepachangelog.com/e ## [1.1.2] - NEXT -**Milestone**: Mainnet(1.0.3.0) +**Milestone**: Mainnet(1.0.3.1) | Package | Version | Link | | ---------------- | ------- | ------------------------------------------------------------------ | | Symbol Bootstrap | v1.1.2 | [symbol-bootstrap](https://www.npmjs.com/package/symbol-bootstrap) | +- The `bootstrap` preset is not the default anymore. The name must be provided via --preset or as a custom preset field. +- A 'safe' custom preset is cached in the target folder. It's not required when upgrading the node without a configuration change. + ## [1.1.1] - Nov-16-2021 **Milestone**: Mainnet(1.0.3.1) diff --git a/README.md b/README.md index afa184e94..4bf26b0d2 100644 --- a/README.md +++ b/README.md @@ -66,9 +66,9 @@ Properties in each file override the previous values (by object deep merge). ### Out-of-the-box presets: -- `-p bootstrap`: Default [preset](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/network.yml). It's a private network with 1 mongo database, 2 peers, 1 api and 1 rest gateway. Nemesis block is generated. +- `-p bootstrap`: A [preset](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/network.yml). It's a private network with 1 mongo database, 2 peers, 1 api and 1 rest gateway. Nemesis block is generated. - `-p bootstrap -a light`: A [light](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/assembly-light.yml) network. It's a version of bootstrap preset with 1 mongo database, 1 dual peer and 1 rest gateway. Great for faster light e2e automatic testing. Nemesis block is generated. -- `-p bootstrap -a full`: A [full](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/assembly-full.yml) network. The default bootstrap preset plus 1 wallet, 1 explorer and 1 faucet. Great for demonstration purposes. Nemesis block is generated. +- `-p bootstrap -a full`: A [full](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/assembly-full.yml) network. The bootstrap preset plus 1 wallet, 1 explorer and 1 faucet. Great for demonstration purposes. Nemesis block is generated. - `-p testnet -a peer`: A [harvesting](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/assembly-peer.yml) peer node that connects to the current public [testnet](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/network.yml). [Nemesis block](https://github.com/nemtech/symbol-bootstrap/tree/main/presets/testnet/seed/00000) is copied over. - `-p testnet -a api`: A [api](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/assembly-api.yml) peer node that connects to the current public [testnet](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/network.yml) running its own mongo database and rest gateway. [Nemesis block](https://github.com/nemtech/symbol-bootstrap/tree/main/presets/testnet/seed/00000) is copied over. - `-p testnet -a dual`: A [dual](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/assembly-dual.yml) haversting peer node that connects to the current public [testnet](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/network.yml) running its own mongo database and rest gateway. [Nemesis block](https://github.com/nemtech/symbol-bootstrap/tree/main/presets/testnet/seed/00000) is copied over. diff --git a/docs/config.md b/docs/config.md index fe9aa5bcb..4d6ba53ec 100644 --- a/docs/config.md +++ b/docs/config.md @@ -14,17 +14,19 @@ USAGE $ symbol-bootstrap config OPTIONS - -a, --assembly=assembly The assembly, example "dual" for testnet. If not provided, the value is - resolved from the target/preset.yml file. + -a, --assembly=assembly The assembly that define the node(s) layout. It can be provided via custom + preset or cli parameter. If not provided, the value is resolved from the + target/preset.yml file. - -c, --customPreset=customPreset External preset file. Values in this file will override the provided presets + -c, --customPreset=customPreset External preset file. Values in this file will override the provided + presets. -h, --help It shows the help of this command. - -p, --preset=(bootstrap|testnet|mainnet) The network preset, can be provided via custom preset or cli parameter. If - not provided, the value is resolved from the target/preset.yml file. + -p, --preset=(bootstrap|testnet|mainnet) The network preset. It can be provided via custom preset or cli parameter. + If not provided, the value is resolved from the target/preset.yml file. - -r, --reset It resets the configuration generating a new one + -r, --reset It resets the configuration generating a new one. -t, --target=target [default: target] The target folder where the symbol-bootstrap network is generated @@ -46,8 +48,7 @@ OPTIONS --upgrade It regenerates the configuration reusing the previous keys. Use this flag when upgrading the version of bootstrap to keep your node up to date without - dropping the local data. The original preset (-t), assembly (-a), and custom - preset (-a) must be used. Backup the target folder before upgrading. + dropping the local data. Backup the target folder before upgrading. EXAMPLES $ symbol-bootstrap config -p bootstrap diff --git a/docs/pack.md b/docs/pack.md index 0423ad967..1dda18172 100644 --- a/docs/pack.md +++ b/docs/pack.md @@ -14,17 +14,19 @@ USAGE $ symbol-bootstrap pack OPTIONS - -a, --assembly=assembly (required) The assembly, example "dual" for testnet. + -a, --assembly=assembly The assembly that define the node(s) layout. It can be provided via custom + preset or cli parameter. If not provided, the value is resolved from the + target/preset.yml file. - -c, --customPreset=customPreset (required) External preset file. Values in this file will override the - provided presets + -c, --customPreset=customPreset External preset file. Values in this file will override the provided + presets. -h, --help It shows the help of this command. - -p, --preset=(bootstrap|testnet|mainnet) (required) The network preset, can be provided via custom preset or cli - parameter. + -p, --preset=(bootstrap|testnet|mainnet) The network preset. It can be provided via custom preset or cli parameter. + If not provided, the value is resolved from the target/preset.yml file. - -r, --reset It resets the configuration generating a new one + -r, --reset It resets the configuration generating a new one. -t, --target=target [default: target] The target folder where the symbol-bootstrap network is generated @@ -48,15 +50,14 @@ OPTIONS --upgrade It regenerates the configuration reusing the previous keys. Use this flag when upgrading the version of bootstrap to keep your node up to date without - dropping the local data. The original preset (-t), assembly (-a), and custom - preset (-a) must be used. Backup the target folder before upgrading. + dropping the local data. Backup the target folder before upgrading. EXAMPLES $ symbol-bootstrap pack - $ symbol-bootstrap pack -p bootstrap -c custom-preset.yml + $ symbol-bootstrap pack -c custom-preset.yml $ symbol-bootstrap pack -p testnet -a dual -c custom-preset.yml $ symbol-bootstrap pack -p mainnet -a dual --password 1234 -c custom-preset.yml - $ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap pack -p mainnet -a dual -c custom-preset.yml + $ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap pack -c custom-preset.yml ``` _See code: [src/commands/pack.ts](https://github.com/nemtech/symbol-bootstrap/blob/v1.1.2/src/commands/pack.ts)_ diff --git a/docs/start.md b/docs/start.md index f26e75bab..e99118d98 100644 --- a/docs/start.md +++ b/docs/start.md @@ -15,13 +15,14 @@ USAGE OPTIONS -a, --assembly=assembly - The assembly, example "dual" for testnet. If not provided, the value is resolved from the target/preset.yml file. + The assembly that define the node(s) layout. It can be provided via custom preset or cli parameter. If not provided, + the value is resolved from the target/preset.yml file. -b, --build If provided, docker-compose will run with -b (--build) -c, --customPreset=customPreset - External preset file. Values in this file will override the provided presets + External preset file. Values in this file will override the provided presets. -d, --detached If provided, docker-compose will run with -d (--detached) and this command will wait unit server is running before @@ -31,11 +32,11 @@ OPTIONS It shows the help of this command. -p, --preset=(bootstrap|testnet|mainnet) - The network preset, can be provided via custom preset or cli parameter. If not provided, the value is resolved from - the target/preset.yml file. + The network preset. It can be provided via custom preset or cli parameter. If not provided, the value is resolved + from the target/preset.yml file. -r, --reset - It resets the configuration generating a new one + It resets the configuration generating a new one. -t, --target=target [default: target] The target folder where the symbol-bootstrap network is generated @@ -79,11 +80,10 @@ OPTIONS --upgrade It regenerates the configuration reusing the previous keys. Use this flag when upgrading the version of bootstrap to - keep your node up to date without dropping the local data. The original preset (-t), assembly (-a), and custom - preset (-a) must be used. Backup the target folder before upgrading. + keep your node up to date without dropping the local data. Backup the target folder before upgrading. EXAMPLES - $ symbol-bootstrap start + $ symbol-bootstrap start -p bootstrap $ symbol-bootstrap start -p bootstrap $ symbol-bootstrap start -p testnet -a dual $ symbol-bootstrap start -p testnet -a dual --password 1234 diff --git a/src/commands/config.ts b/src/commands/config.ts index 97a6fcfd2..e9e279273 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -25,40 +25,33 @@ export default class Config extends Command { `$ symbol-bootstrap config -p testnet -a dual --password 1234`, `$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap config -p testnet -a dual`, ]; - //@typescript-eslint/explicit-module-boundary-types - static resolveFlags = (required: boolean) => ({ + + static flags = { help: CommandUtils.helpFlag, target: CommandUtils.targetFlag, password: CommandUtils.passwordFlag, noPassword: CommandUtils.noPasswordFlag, preset: flags.enum({ char: 'p', - description: `The network preset, can be provided via custom preset or cli parameter. ${ - required ? '' : 'If not provided, the value is resolved from the target/preset.yml file.' - }`, + description: `The network preset. It can be provided via custom preset or cli parameter. If not provided, the value is resolved from the target/preset.yml file.`, options: Object.keys(Preset).map((v) => v as Preset), - required: required, }), assembly: flags.string({ char: 'a', - description: `The assembly, example "dual" for testnet. ${ - required ? '' : 'If not provided, the value is resolved from the target/preset.yml file.' - }`, - required: required, + description: `The assembly that define the node(s) layout. It can be provided via custom preset or cli parameter. If not provided, the value is resolved from the target/preset.yml file.`, }), customPreset: flags.string({ char: 'c', - description: `External preset file. Values in this file will override the provided presets`, - required: required, + description: `External preset file. Values in this file will override the provided presets.`, }), reset: flags.boolean({ char: 'r', - description: 'It resets the configuration generating a new one', + description: 'It resets the configuration generating a new one.', default: ConfigService.defaultParams.reset, }), upgrade: flags.boolean({ - description: `It regenerates the configuration reusing the previous keys. Use this flag when upgrading the version of bootstrap to keep your node up to date without dropping the local data. The original preset (-t), assembly (-a), and custom preset (-a) must be used. Backup the target folder before upgrading.`, + description: `It regenerates the configuration reusing the previous keys. Use this flag when upgrading the version of bootstrap to keep your node up to date without dropping the local data. Backup the target folder before upgrading.`, default: ConfigService.defaultParams.reset, }), @@ -72,9 +65,7 @@ export default class Config extends Command { description: `User used to run docker images when creating configuration files like certificates or nemesis block. "${BootstrapUtils.CURRENT_USER}" means the current user.`, default: BootstrapUtils.CURRENT_USER, }), - }); - - static flags = Config.resolveFlags(false); + }; public async run(): Promise { const { flags } = this.parse(Config); diff --git a/src/commands/pack.ts b/src/commands/pack.ts index dc74821eb..47c02ce1a 100644 --- a/src/commands/pack.ts +++ b/src/commands/pack.ts @@ -28,16 +28,16 @@ export default class Pack extends Command { static examples = [ `$ symbol-bootstrap pack`, - `$ symbol-bootstrap pack -p bootstrap -c custom-preset.yml`, + `$ symbol-bootstrap pack -c custom-preset.yml`, `$ symbol-bootstrap pack -p testnet -a dual -c custom-preset.yml`, `$ symbol-bootstrap pack -p mainnet -a dual --password 1234 -c custom-preset.yml`, - `$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap pack -p mainnet -a dual -c custom-preset.yml`, + `$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap pack -c custom-preset.yml`, ]; static flags = { ...Compose.flags, ...Clean.flags, - ...Config.resolveFlags(true), + ...Config.flags, ready: flags.boolean({ description: 'If --ready is provided, the command will not ask offline confirmation.', }), @@ -46,9 +46,7 @@ export default class Pack extends Command { public async run(): Promise { const { flags } = this.parse(Pack); BootstrapUtils.showBanner(); - const preset = flags.preset; - const assembly = flags.assembly; - const targetZip = join(dirname(flags.target), `${preset}-${assembly || 'default'}-node.zip`); + const targetZip = join(dirname(flags.target), `symbol-node.zip`); if (existsSync(targetZip)) { throw new Error( @@ -112,7 +110,7 @@ export default class Pack extends Command { await ZipUtils.zip(targetZip, zipItems); await BootstrapUtils.deleteFile(noPrivateKeyTempFile); console.log(); - console.log(`Zip file ${targetZip} has been created. You can unzip it in your node's machine and run:`); - console.log(`$ symbol-bootstrap start -p ${preset}${assembly ? ` -a ${assembly}` : ''} -c ${configOnlyCustomPresetFileName}`); + console.log(`You can unzip it in your node's machine and run:`); + console.log(`$ symbol-bootstrap start`); } } diff --git a/src/commands/start.ts b/src/commands/start.ts index 4d9301303..edae71266 100644 --- a/src/commands/start.ts +++ b/src/commands/start.ts @@ -15,8 +15,7 @@ */ import { Command } from '@oclif/command'; -import { BootstrapService, BootstrapUtils } from '../service'; -import { CommandUtils } from '../service/CommandUtils'; +import { BootstrapService, BootstrapUtils, CommandUtils } from '../service'; import Clean from './clean'; import Compose from './compose'; import Config from './config'; @@ -26,7 +25,7 @@ export default class Start extends Command { static description = 'Single command that aggregates config, compose and run in one line!'; static examples = [ - `$ symbol-bootstrap start`, + `$ symbol-bootstrap start -p bootstrap`, `$ symbol-bootstrap start -p bootstrap`, `$ symbol-bootstrap start -p testnet -a dual`, `$ symbol-bootstrap start -p testnet -a dual --password 1234`, diff --git a/src/commands/updateVotingKeys.ts b/src/commands/updateVotingKeys.ts index 57e1696c9..dd61f9c4e 100644 --- a/src/commands/updateVotingKeys.ts +++ b/src/commands/updateVotingKeys.ts @@ -15,11 +15,9 @@ */ import { Command, flags } from '@oclif/command'; -import { join } from 'path'; import { LogType } from '../logger'; import Logger from '../logger/Logger'; import LoggerFactory from '../logger/LoggerFactory'; -import { ConfigPreset } from '../model'; import { BootstrapUtils, CommandUtils, ConfigLoader, CryptoUtils, RemoteNodeService, VotingService } from '../service'; const logger: Logger = LoggerFactory.getLogger(LogType.System); @@ -57,16 +55,24 @@ When a new voting file is created, Bootstrap will advise running the \`link\` co const target = flags.target; const configLoader = new ConfigLoader(); const addressesLocation = configLoader.getGeneratedAddressLocation(target); - const existingPreset = configLoader.loadExistingPresetData(target, password); - const preset = existingPreset.preset; - if (!preset) { - throw new Error(`Network preset could not be resolved!`); - } - // Adds new shared/network properties to the existing preset. This is for upgrades.. - const sharedPreset = BootstrapUtils.loadYaml(join(BootstrapUtils.ROOT_FOLDER, 'presets', 'shared.yml'), false); - const networkPreset = BootstrapUtils.loadYaml(join(BootstrapUtils.ROOT_FOLDER, 'presets', preset, 'network.yml'), false); - const presetData = configLoader.mergePresets(sharedPreset, networkPreset, existingPreset) as ConfigPreset; + const loadPresetData = () => { + try { + const oldPresetData = configLoader.loadExistingPresetData(target, password); + return configLoader.createPresetData({ + password: password, + oldPresetData, + }); + } catch (e) { + throw new Error( + `Node's preset cannot be loaded. Have you provided the right --target? If you have, please rerun the 'config' command with --upgrade. Error: ${ + e.message || 'unknown' + }`, + ); + } + }; + + const presetData = loadPresetData(); const addresses = configLoader.loadExistingAddresses(target, password); const privateKeySecurityMode = CryptoUtils.getPrivateKeySecurityMode(presetData.privateKeySecurityMode); diff --git a/src/commands/wizard.ts b/src/commands/wizard.ts index 2f8c9ebb8..dd2961743 100644 --- a/src/commands/wizard.ts +++ b/src/commands/wizard.ts @@ -118,7 +118,7 @@ export default class Wizard extends Command { if (network == Network.localNetwork) { console.log('For a local network, just run: '); console.log(''); - console.log(`$ symbol-bootstrap start -b ${preset}${assembly ? ` -a ${assembly}` : ''}`); + console.log(`$ symbol-bootstrap start -b ${preset} -a ${assembly}`); return; } @@ -258,20 +258,13 @@ export default class Wizard extends Command { console.log(); console.log(`Once you have finished the custom preset customization, You can use the 'start' to run the node in this machine:`); console.log(); - console.log( - `$ symbol-bootstrap start -p ${network} -a ${assembly} -c ${customPresetFile} ${ - target !== defaultParams.target ? `-t ${target}` : '' - }`, - ); + const targetParam = target !== defaultParams.target ? `-t ${target}` : ''; + console.log(`$ symbol-bootstrap start -c ${customPresetFile} ${targetParam}`); console.log(); console.log(`Alternatively, to create a zip file that can be deployed in your node machine you can use the 'pack' command:`); console.log(); - console.log( - `$ symbol-bootstrap pack -p ${network} -a ${assembly} -c ${customPresetFile} ${ - target !== defaultParams.target ? `-t ${target}` : '' - }`, - ); + console.log(`$ symbol-bootstrap pack -c ${customPresetFile} ${targetParam}`); console.log(); console.log( `Once the target folder is created, Bootstrap will use the protected and encrypted addresses.yml, and preset.yml in inside the target folder.`, diff --git a/src/model/ConfigPreset.ts b/src/model/ConfigPreset.ts index b3b2e827c..ca6cec646 100644 --- a/src/model/ConfigPreset.ts +++ b/src/model/ConfigPreset.ts @@ -449,6 +449,7 @@ export interface ConfigPreset extends CommonConfigPreset { wallets?: WalletPreset[]; faucets?: FaucetPreset[]; httpsProxies?: HttpsProxyPreset[]; + customPresetCache?: CustomPreset; } export interface CustomPreset extends Partial { diff --git a/src/service/ConfigLoader.ts b/src/service/ConfigLoader.ts index 4d2bfe172..b01a86cc8 100644 --- a/src/service/ConfigLoader.ts +++ b/src/service/ConfigLoader.ts @@ -25,7 +25,6 @@ import { ConfigAccount, ConfigPreset, CustomPreset, - DeepPartial, MosaicAccounts, NodeAccount, NodePreset, @@ -41,7 +40,11 @@ const logger: Logger = LoggerFactory.getLogger(LogType.System); export class ConfigLoader { public static presetInfoLogged = false; - public async generateRandomConfiguration(oldAddresses: Addresses | undefined, presetData: ConfigPreset): Promise { + public async generateRandomConfiguration( + oldAddresses: Addresses | undefined, + oldPresetData: ConfigPreset | undefined, + presetData: ConfigPreset, + ): Promise { const networkType = presetData.networkType; const addresses: Addresses = { version: this.getAddressesMigration(presetData.networkType).length + 1, @@ -124,8 +127,12 @@ export class ConfigLoader { if (presetData.nemesis) { if (oldAddresses) { + if (!oldPresetData) { + throw new Error('oldPresetData must be defined when upgrading!'); + } // Nemesis configuration cannot be changed on upgrade. addresses.mosaics = oldAddresses.mosaics; + presetData.nemesis = oldPresetData.nemesis; } else { if (presetData.nemesis.mosaics) { const mosaics: MosaicAccounts[] = []; @@ -365,19 +372,18 @@ export class ConfigLoader { return BootstrapUtils.loadYaml(fileLocation, false); } - public mergePresets(object: ConfigPreset, ...otherArgs: (CustomPreset | undefined)[]): any { - const presets: (CustomPreset | undefined)[] = [object, ...otherArgs]; - const reversed = _.reverse(presets); - const inflation = reversed.find((p) => p?.inflation)?.inflation || {}; - const knownRestGateways = reversed.find((p) => p?.knownRestGateways)?.knownRestGateways || []; - const knownPeers = reversed.find((p) => p?.knownPeers)?.knownPeers || []; - const presetData = _.merge(object, ...otherArgs); - presetData.inflation = inflation; - presetData.knownRestGateways = knownRestGateways; - presetData.knownPeers = knownPeers; + public mergePresets(object: T | undefined, ...otherArgs: (CustomPreset | undefined)[]): T { + const presets = [object, ...otherArgs]; + const reversed = [...presets].reverse(); + const presetData = _.merge({}, ...presets); + const inflation = reversed.find((p) => !_.isEmpty(p?.inflation))?.inflation; + const knownRestGateways = reversed.find((p) => !_.isEmpty(p?.knownRestGateways))?.knownRestGateways; + const knownPeers = reversed.find((p) => !_.isEmpty(p?.knownPeers))?.knownPeers; + if (inflation) presetData.inflation = inflation; + if (knownRestGateways) presetData.knownRestGateways = knownRestGateways; + if (knownPeers) presetData.knownPeers = knownPeers; return presetData; } - public createPresetData(params: { password: Password; preset?: Preset; @@ -390,13 +396,12 @@ export class ConfigLoader { const customPresetObject = params.customPresetObject; const oldPresetData = params.oldPresetData; const customPresetFileObject = this.loadCustomPreset(customPreset, params.password); - const preset = - params.preset || - params.customPresetObject?.preset || - customPresetFileObject?.preset || - oldPresetData?.preset || - Preset.bootstrap; - + const preset = params.preset || params.customPresetObject?.preset || customPresetFileObject?.preset || oldPresetData?.preset; + if (!preset) { + throw new KnownError( + 'Preset value could not be resolved from target folder contents. Please provide the --preset parameter when running the config/start command.', + ); + } const assembly = params.assembly || params.customPresetObject?.assembly || customPresetFileObject?.assembly || params.oldPresetData?.assembly; @@ -404,12 +409,15 @@ export class ConfigLoader { const networkPreset = BootstrapUtils.loadYaml(join(BootstrapUtils.ROOT_FOLDER, 'presets', preset, 'network.yml'), false); const assemblyPreset = this.loadAssembly(preset, assembly); - const presetData = this.mergePresets(sharedPreset, networkPreset, assemblyPreset, customPresetFileObject, customPresetObject, { - preset, - }); + const providedCustomPreset = this.mergePresets(customPresetFileObject, customPresetObject); + const resolvedCustomPreset = _.isEmpty(providedCustomPreset) ? oldPresetData?.customPresetCache || {} : providedCustomPreset; + + const presetData = this.mergePresets(sharedPreset, networkPreset, assemblyPreset, resolvedCustomPreset); if (presetData.assemblies && !assembly) { - throw new Error(`Preset ${preset} requires assembly (-a, --assembly option). Possible values are: ${presetData.assemblies}`); + throw new KnownError( + `Preset ${preset} requires assembly (-a, --assembly option). Possible values are: ${presetData.assemblies}. Please provide the --assembly parameter when running the config/start command.`, + ); } if (!ConfigLoader.presetInfoLogged) { logger.info(`Generating config from preset '${preset}'`); @@ -421,23 +429,24 @@ export class ConfigLoader { } } ConfigLoader.presetInfoLogged = true; - const presetDataWithDynamicDefaults = { + const presetDataWithDynamicDefaults: ConfigPreset = { + ...presetData, version: 1, preset: preset, assembly: assembly || '', - ...presetData, nodes: this.dynamicDefaultNodeConfiguration(presetData.nodes), + customPresetCache: resolvedCustomPreset, }; - return _.merge(oldPresetData || {}, this.expandRepeat(presetDataWithDynamicDefaults)); + return this.expandRepeat(presetDataWithDynamicDefaults); } - public dynamicDefaultNodeConfiguration(nodes?: NodePreset[]): NodePreset[] { + public dynamicDefaultNodeConfiguration(nodes?: Partial[]): NodePreset[] { return _.map(nodes || [], (node) => { - return { ...this.getDefaultConfiguration(node), ...node }; + return { ...this.getDefaultConfiguration(node), ...node } as NodePreset; }); } - private getDefaultConfiguration(node: NodePreset): DeepPartial { + private getDefaultConfiguration(node: Partial): Partial { if (node.harvesting && node.api) { return { syncsource: true, diff --git a/src/service/ConfigService.ts b/src/service/ConfigService.ts index 3f1d6e510..939074d12 100644 --- a/src/service/ConfigService.ts +++ b/src/service/ConfigService.ts @@ -153,7 +153,7 @@ export class ConfigService { } const presetData: ConfigPreset = this.resolveCurrentPresetData(oldPresetData, password); - const addresses = await this.configLoader.generateRandomConfiguration(oldAddresses, presetData); + const addresses = await this.configLoader.generateRandomConfiguration(oldAddresses, oldPresetData, presetData); const privateKeySecurityMode = CryptoUtils.getPrivateKeySecurityMode(presetData.privateKeySecurityMode); await BootstrapUtils.mkdir(target); diff --git a/src/service/VotingService.ts b/src/service/VotingService.ts index d5aeb18c4..4abab50de 100644 --- a/src/service/VotingService.ts +++ b/src/service/VotingService.ts @@ -51,7 +51,9 @@ export class VotingService { const votingKeyDesiredFutureLifetime = presetData.votingKeyDesiredFutureLifetime; const votingKeyDesiredLifetime = presetData.votingKeyDesiredLifetime; if (votingKeyDesiredFutureLifetime > votingKeyDesiredLifetime) { - throw new Error('votingKeyDesiredFutureLifetime cannot be greater than votingKeyDesiredLifetime'); + throw new Error( + `votingKeyDesiredFutureLifetime (${votingKeyDesiredFutureLifetime}) cannot be greater than votingKeyDesiredLifetime (${votingKeyDesiredLifetime})`, + ); } await BootstrapUtils.mkdir(votingKeysFolder); const votingUtils = new VotingUtils(); diff --git a/test/commands/config.test.ts b/test/commands/config.test.ts index 3453dc3c7..f976da4c4 100644 --- a/test/commands/config.test.ts +++ b/test/commands/config.test.ts @@ -18,7 +18,7 @@ import { test } from '@oclif/test'; describe('config', () => { test.stdout() - .command(['config', '-r', '--password', '1111']) + .command(['config', '-p', 'bootstrap', '-r', '--password', '1111']) .it('runs config', (ctx) => { console.log(ctx.stdout); }); @@ -26,7 +26,7 @@ describe('config', () => { describe('config with opt in', () => { test.stdout() - .command(['config', '-r', '-c', './test/optin_preset.yml', '--noPassword']) + .command(['config', '-p', 'bootstrap', '-r', '-c', './test/optin_preset.yml', '--noPassword']) .it('runs config', (ctx) => { console.log(ctx.stdout); }); diff --git a/test/override-currency-preset.yml b/test/override-currency-preset.yml index b1a1fd5bc..a7621d3dd 100644 --- a/test/override-currency-preset.yml +++ b/test/override-currency-preset.yml @@ -1,3 +1,4 @@ +preset: bootstrap nemesis: mosaics: - accounts: 20 diff --git a/test/service/ConfigLoader.test.ts b/test/service/ConfigLoader.test.ts index fb0808c31..538f9e7d0 100644 --- a/test/service/ConfigLoader.test.ts +++ b/test/service/ConfigLoader.test.ts @@ -43,7 +43,9 @@ describe('ConfigLoader', () => { password: 'abc', }); } catch (e) { - expect(e.message).to.equal('Preset testnet requires assembly (-a, --assembly option). Possible values are: api, dual, peer'); + expect(e.message).to.equal( + 'Preset testnet requires assembly (-a, --assembly option). Possible values are: api, dual, peer. Please provide the --assembly parameter when running the config/start command.', + ); return; } expect(true).to.be.false; @@ -61,6 +63,114 @@ describe('ConfigLoader', () => { expect(presetData).to.not.be.undefined; }); + it('ConfigLoader custom maxUnlockedAccounts', async () => { + const configLoader = new ConfigLoaderMocked(); + const originalPresetData = await configLoader.createPresetData({ + preset: Preset.testnet, + assembly: 'dual', + customPreset: 'test/unit-test-profiles/custom_preset.yml', + customPresetObject: { + maxUnlockedAccounts: 30, + }, + password: 'abcd', + }); + expect(originalPresetData).to.not.be.undefined; + expect(originalPresetData.nodes![0].maxUnlockedAccounts).eq(undefined); + expect(originalPresetData.maxUnlockedAccounts).eq(30); + expect(originalPresetData.customPresetCache).deep.eq({ + maxUnlockedAccounts: 30, + nodes: [ + { + host: 'my-host.io', + mainPrivateKey: 'CA82E7ADAF7AB729A5462A1BD5AA78632390634904A64EB1BB22295E2E1A1BDD', + remotePrivateKey: 'EFE3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1', + transportPrivateKey: '6154154096354BC3DB522174ACD8BFE553893A0991BD5D105599846F17A3383B', + voting: true, + vrfPrivateKey: 'F3C24C153783B683E40FB2671493B54480370BF4E3AB8027D4BF1293E14EB9B8', + }, + ], + privateKeySecurityMode: 'PROMPT_MAIN', + }); + + const upgradedPresetData = await configLoader.createPresetData({ + oldPresetData: originalPresetData, + preset: Preset.testnet, + assembly: 'dual', + password: 'abcd', + }); + expect(upgradedPresetData).to.not.be.undefined; + expect(upgradedPresetData.nodes![0].maxUnlockedAccounts).eq(undefined); + expect(upgradedPresetData.maxUnlockedAccounts).eq(30); + expect(upgradedPresetData.customPresetCache).deep.eq({ + maxUnlockedAccounts: 30, + nodes: [ + { + host: 'my-host.io', + mainPrivateKey: 'CA82E7ADAF7AB729A5462A1BD5AA78632390634904A64EB1BB22295E2E1A1BDD', + remotePrivateKey: 'EFE3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1', + transportPrivateKey: '6154154096354BC3DB522174ACD8BFE553893A0991BD5D105599846F17A3383B', + voting: true, + vrfPrivateKey: 'F3C24C153783B683E40FB2671493B54480370BF4E3AB8027D4BF1293E14EB9B8', + }, + ], + privateKeySecurityMode: 'PROMPT_MAIN', + }); + + const upgradedPresetResetToDefaults = await configLoader.createPresetData({ + oldPresetData: originalPresetData, + preset: Preset.testnet, + customPresetObject: { + maxUnlockedAccounts: 15, + }, + assembly: 'dual', + password: 'abcd', + }); + expect(upgradedPresetResetToDefaults).to.not.be.undefined; + expect(upgradedPresetResetToDefaults.nodes![0].maxUnlockedAccounts).eq(undefined); + expect(upgradedPresetResetToDefaults.maxUnlockedAccounts).eq(15); + expect(upgradedPresetResetToDefaults.customPresetCache).deep.eq({ + maxUnlockedAccounts: 15, + }); + }); + + it('mergePreset', async () => { + const configLoader = new ConfigLoaderMocked(); + expect( + configLoader.mergePresets( + { maxUnlockedAccounts: 1, inflation: { a: 1, c: 1, d: 1 } }, + { maxUnlockedAccounts: 2 }, + { maxUnlockedAccounts: 3, inflation: { c: 2, d: 2, e: 2 } }, + { maxUnlockedAccounts: 4 }, + ), + ).deep.eq({ maxUnlockedAccounts: 4, inflation: { c: 2, d: 2, e: 2 } }); + }); + + it('mergePreset with node', async () => { + const configLoader = new ConfigLoaderMocked(); + const merged = configLoader.mergePresets( + { + maxUnlockedAccounts: 1, + inflation: { a: 1, c: 1, d: 1 }, + }, + { nodes: [{ maxUnlockedAccounts: 5, name: 'name1' }], knownRestGateways: ['r1', 'r2'] }, + { maxUnlockedAccounts: 3, inflation: { c: 2, d: 2, e: 2 }, knownRestGateways: ['r2', 'r3'] }, + { + maxUnlockedAccounts: 4, + nodes: [{ maxUnlockedAccounts: 3 }, { maxUnlockedAccounts: 4, name: 'nameB' }], + }, + ); + console.log(JSON.stringify(merged)); + expect(merged).deep.eq({ + maxUnlockedAccounts: 4, + inflation: { c: 2, d: 2, e: 2 }, + nodes: [ + { maxUnlockedAccounts: 3, name: 'name1' }, + { maxUnlockedAccounts: 4, name: 'nameB' }, + ], + knownRestGateways: ['r2', 'r3'], + }); + }); + it('ConfigLoader loadPresetData bootstrap custom', async () => { const configLoader = new ConfigLoaderMocked(); const presetData = await configLoader.createPresetData({ diff --git a/test/service/ConfigService.test.ts b/test/service/ConfigService.test.ts index 2bfa76519..a2bf7c7fe 100644 --- a/test/service/ConfigService.test.ts +++ b/test/service/ConfigService.test.ts @@ -19,16 +19,17 @@ import 'mocha'; import { ConfigService, CryptoUtils, Preset } from '../../src/service'; describe('ConfigService', () => { - it('ConfigService default run with optin_preset.yml', async () => { + it('ConfigService bootstrap run with optin_preset.yml', async () => { await new ConfigService({ ...ConfigService.defaultParams, reset: true, + preset: Preset.bootstrap, target: 'target/tests/ConfigService.test.optin', customPreset: './test/optin_preset.yml', }).run(); }); - it('ConfigService default run with override-currency-preset.yml', async () => { + it('ConfigService bootstrap in custom preset run with override-currency-preset.yml', async () => { await new ConfigService({ ...ConfigService.defaultParams, reset: true, @@ -61,16 +62,23 @@ describe('ConfigService', () => { const configResult = await new ConfigService({ ...ConfigService.defaultParams, reset: true, + password: '1111', target: 'target/tests/bootstrap', preset: Preset.bootstrap, }).run(); + expect(configResult.addresses.mosaics?.length).eq(2); + expect(configResult.addresses.mosaics?.[0]?.accounts.length).eq(5); + expect(configResult.addresses.mosaics?.[1]?.accounts.length).eq(2); + const configResultUpgrade = await new ConfigService({ ...ConfigService.defaultParams, upgrade: true, + password: '1111', target: 'target/tests/bootstrap', preset: Preset.bootstrap, }).run(); + expect(configResult.addresses).deep.eq(configResultUpgrade.addresses); expect(CryptoUtils.removePrivateKeys(configResultUpgrade.presetData)).deep.eq( CryptoUtils.removePrivateKeys(configResult.presetData), diff --git a/test/unit-test-profiles/custom_preset.yml b/test/unit-test-profiles/custom_preset.yml new file mode 100644 index 000000000..657309f1c --- /dev/null +++ b/test/unit-test-profiles/custom_preset.yml @@ -0,0 +1,8 @@ +privateKeySecurityMode: PROMPT_MAIN +nodes: + - voting: true + host: 'my-host.io' + mainPrivateKey: CA82E7ADAF7AB729A5462A1BD5AA78632390634904A64EB1BB22295E2E1A1BDD + transportPrivateKey: 6154154096354BC3DB522174ACD8BFE553893A0991BD5D105599846F17A3383B + remotePrivateKey: EFE3F0EF0AB368B8D7AC194D52A8CCFA2D5050B80B9C76E4D2F4D4BF2CD461C1 + vrfPrivateKey: F3C24C153783B683E40FB2671493B54480370BF4E3AB8027D4BF1293E14EB9B8 From 4fec3d252c05caafaf9771c3aab1bc05547bfde3 Mon Sep 17 00:00:00 2001 From: Fernando Date: Tue, 23 Nov 2021 21:02:48 -0300 Subject: [PATCH 2/3] feedback fixes --- README.md | 11 +++++++---- docs/config.md | 3 ++- docs/pack.md | 2 +- docs/start.md | 6 +++--- src/commands/config.ts | 3 ++- src/commands/pack.ts | 2 +- src/commands/start.ts | 2 +- src/commands/updateVotingKeys.ts | 33 +++++++++++++++----------------- src/service/ConfigLoader.ts | 1 - 9 files changed, 32 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 4bf26b0d2..5e5510922 100644 --- a/README.md +++ b/README.md @@ -64,14 +64,17 @@ Presets are defined at 4 levels from general to specific: Properties in each file override the previous values (by object deep merge). -### Out-of-the-box presets: +### Out-of-the-box presets and assemblies: -- `-p bootstrap`: A [preset](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/network.yml). It's a private network with 1 mongo database, 2 peers, 1 api and 1 rest gateway. Nemesis block is generated. -- `-p bootstrap -a light`: A [light](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/assembly-light.yml) network. It's a version of bootstrap preset with 1 mongo database, 1 dual peer and 1 rest gateway. Great for faster light e2e automatic testing. Nemesis block is generated. -- `-p bootstrap -a full`: A [full](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/assembly-full.yml) network. The bootstrap preset plus 1 wallet, 1 explorer and 1 faucet. Great for demonstration purposes. Nemesis block is generated. +- `-p bootstrap`: A [multinode](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/network.yml) local network. A network with 1 mongo database, 2 peers, 1 api and 1 rest gateway. Nemesis block is generated. +- `-p bootstrap -a light`: A [light](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/assembly-light.yml) local network. It's a version of bootstrap preset with 1 mongo database, 1 dual peer and 1 rest gateway. Great for faster light e2e automatic testing. Nemesis block is generated. +- `-p bootstrap -a full`: A [full](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/bootstrap/assembly-full.yml) local network. The bootstrap preset plus 1 wallet, 1 explorer and 1 faucet. Great for demonstration purposes. Nemesis block is generated. - `-p testnet -a peer`: A [harvesting](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/assembly-peer.yml) peer node that connects to the current public [testnet](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/network.yml). [Nemesis block](https://github.com/nemtech/symbol-bootstrap/tree/main/presets/testnet/seed/00000) is copied over. - `-p testnet -a api`: A [api](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/assembly-api.yml) peer node that connects to the current public [testnet](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/network.yml) running its own mongo database and rest gateway. [Nemesis block](https://github.com/nemtech/symbol-bootstrap/tree/main/presets/testnet/seed/00000) is copied over. - `-p testnet -a dual`: A [dual](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/assembly-dual.yml) haversting peer node that connects to the current public [testnet](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/testnet/network.yml) running its own mongo database and rest gateway. [Nemesis block](https://github.com/nemtech/symbol-bootstrap/tree/main/presets/testnet/seed/00000) is copied over. +- `-p mainnet -a peer`: A [harvesting](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/mainnet/assembly-peer.yml) peer node that connects to the current public [mainnet](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/mainnet/network.yml). [Nemesis block](https://github.com/nemtech/symbol-bootstrap/tree/main/presets/mainnet/seed/00000) is copied over. +- `-p mainnet -a api`: A [api](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/mainnet/assembly-api.yml) peer node that connects to the current public [mainnet](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/mainnet/network.yml) running its own mongo database and rest gateway. [Nemesis block](https://github.com/nemtech/symbol-bootstrap/tree/main/presets/mainnet/seed/00000) is copied over. +- `-p mainnet -a dual`: A [dual](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/mainnet/assembly-dual.yml) haversting peer node that connects to the current public [mainnet](https://github.com/nemtech/symbol-bootstrap/blob/main/presets/mainnet/network.yml) running its own mongo database and rest gateway. [Nemesis block](https://github.com/nemtech/symbol-bootstrap/tree/main/presets/mainnet/seed/00000) is copied over. ### Custom preset: diff --git a/docs/config.md b/docs/config.md index 4d6ba53ec..64694efd9 100644 --- a/docs/config.md +++ b/docs/config.md @@ -14,7 +14,7 @@ USAGE $ symbol-bootstrap config OPTIONS - -a, --assembly=assembly The assembly that define the node(s) layout. It can be provided via custom + -a, --assembly=assembly The assembly that defines the node(s) layout. It can be provided via custom preset or cli parameter. If not provided, the value is resolved from the target/preset.yml file. @@ -53,6 +53,7 @@ OPTIONS EXAMPLES $ symbol-bootstrap config -p bootstrap $ symbol-bootstrap config -p testnet -a dual --password 1234 + $ symbol-bootstrap config -p mainnet -a peer -c custom-preset.yml $ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap config -p testnet -a dual ``` diff --git a/docs/pack.md b/docs/pack.md index 1dda18172..b812bf962 100644 --- a/docs/pack.md +++ b/docs/pack.md @@ -14,7 +14,7 @@ USAGE $ symbol-bootstrap pack OPTIONS - -a, --assembly=assembly The assembly that define the node(s) layout. It can be provided via custom + -a, --assembly=assembly The assembly that defines the node(s) layout. It can be provided via custom preset or cli parameter. If not provided, the value is resolved from the target/preset.yml file. diff --git a/docs/start.md b/docs/start.md index e99118d98..eb430452a 100644 --- a/docs/start.md +++ b/docs/start.md @@ -15,8 +15,8 @@ USAGE OPTIONS -a, --assembly=assembly - The assembly that define the node(s) layout. It can be provided via custom preset or cli parameter. If not provided, - the value is resolved from the target/preset.yml file. + The assembly that defines the node(s) layout. It can be provided via custom preset or cli parameter. If not + provided, the value is resolved from the target/preset.yml file. -b, --build If provided, docker-compose will run with -b (--build) @@ -83,9 +83,9 @@ OPTIONS keep your node up to date without dropping the local data. Backup the target folder before upgrading. EXAMPLES - $ symbol-bootstrap start -p bootstrap $ symbol-bootstrap start -p bootstrap $ symbol-bootstrap start -p testnet -a dual + $ symbol-bootstrap start -p mainnet -a peer -c custom-preset.yml $ symbol-bootstrap start -p testnet -a dual --password 1234 $ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap start -p testnet -a dual ``` diff --git a/src/commands/config.ts b/src/commands/config.ts index e9e279273..9ce8d2607 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -23,6 +23,7 @@ export default class Config extends Command { static examples = [ `$ symbol-bootstrap config -p bootstrap`, `$ symbol-bootstrap config -p testnet -a dual --password 1234`, + `$ symbol-bootstrap config -p mainnet -a peer -c custom-preset.yml`, `$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap config -p testnet -a dual`, ]; @@ -38,7 +39,7 @@ export default class Config extends Command { }), assembly: flags.string({ char: 'a', - description: `The assembly that define the node(s) layout. It can be provided via custom preset or cli parameter. If not provided, the value is resolved from the target/preset.yml file.`, + description: `The assembly that defines the node(s) layout. It can be provided via custom preset or cli parameter. If not provided, the value is resolved from the target/preset.yml file.`, }), customPreset: flags.string({ char: 'c', diff --git a/src/commands/pack.ts b/src/commands/pack.ts index 47c02ce1a..03c1e5013 100644 --- a/src/commands/pack.ts +++ b/src/commands/pack.ts @@ -110,7 +110,7 @@ export default class Pack extends Command { await ZipUtils.zip(targetZip, zipItems); await BootstrapUtils.deleteFile(noPrivateKeyTempFile); console.log(); - console.log(`You can unzip it in your node's machine and run:`); + console.log(`Zip file ${targetZip} has been created. You can unzip it in your node's machine and run:`); console.log(`$ symbol-bootstrap start`); } } diff --git a/src/commands/start.ts b/src/commands/start.ts index edae71266..96cdf0769 100644 --- a/src/commands/start.ts +++ b/src/commands/start.ts @@ -25,9 +25,9 @@ export default class Start extends Command { static description = 'Single command that aggregates config, compose and run in one line!'; static examples = [ - `$ symbol-bootstrap start -p bootstrap`, `$ symbol-bootstrap start -p bootstrap`, `$ symbol-bootstrap start -p testnet -a dual`, + `$ symbol-bootstrap start -p mainnet -a peer -c custom-preset.yml`, `$ symbol-bootstrap start -p testnet -a dual --password 1234`, `$ echo "$MY_ENV_VAR_PASSWORD" | symbol-bootstrap start -p testnet -a dual`, ]; diff --git a/src/commands/updateVotingKeys.ts b/src/commands/updateVotingKeys.ts index dd61f9c4e..a9609d3f3 100644 --- a/src/commands/updateVotingKeys.ts +++ b/src/commands/updateVotingKeys.ts @@ -18,6 +18,7 @@ import { Command, flags } from '@oclif/command'; import { LogType } from '../logger'; import Logger from '../logger/Logger'; import LoggerFactory from '../logger/LoggerFactory'; +import { ConfigPreset } from '../model'; import { BootstrapUtils, CommandUtils, ConfigLoader, CryptoUtils, RemoteNodeService, VotingService } from '../service'; const logger: Logger = LoggerFactory.getLogger(LogType.System); @@ -55,24 +56,20 @@ When a new voting file is created, Bootstrap will advise running the \`link\` co const target = flags.target; const configLoader = new ConfigLoader(); const addressesLocation = configLoader.getGeneratedAddressLocation(target); - - const loadPresetData = () => { - try { - const oldPresetData = configLoader.loadExistingPresetData(target, password); - return configLoader.createPresetData({ - password: password, - oldPresetData, - }); - } catch (e) { - throw new Error( - `Node's preset cannot be loaded. Have you provided the right --target? If you have, please rerun the 'config' command with --upgrade. Error: ${ - e.message || 'unknown' - }`, - ); - } - }; - - const presetData = loadPresetData(); + let presetData: ConfigPreset; + try { + const oldPresetData = configLoader.loadExistingPresetData(target, password); + presetData = configLoader.createPresetData({ + password: password, + oldPresetData, + }); + } catch (e) { + throw new Error( + `Node's preset cannot be loaded. Have you provided the right --target? If you have, please rerun the 'config' command with --upgrade. Error: ${ + e.message || 'unknown' + }`, + ); + } const addresses = configLoader.loadExistingAddresses(target, password); const privateKeySecurityMode = CryptoUtils.getPrivateKeySecurityMode(presetData.privateKeySecurityMode); diff --git a/src/service/ConfigLoader.ts b/src/service/ConfigLoader.ts index b01a86cc8..788dfee5a 100644 --- a/src/service/ConfigLoader.ts +++ b/src/service/ConfigLoader.ts @@ -132,7 +132,6 @@ export class ConfigLoader { } // Nemesis configuration cannot be changed on upgrade. addresses.mosaics = oldAddresses.mosaics; - presetData.nemesis = oldPresetData.nemesis; } else { if (presetData.nemesis.mosaics) { const mosaics: MosaicAccounts[] = []; From 979051c5c6db1582c07824d28a606b49536998da Mon Sep 17 00:00:00 2001 From: Fernando Date: Wed, 24 Nov 2021 18:05:48 -0300 Subject: [PATCH 3/3] Rolledback change for unit test sanity. It will be changed next pr. --- src/service/ConfigLoader.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/service/ConfigLoader.ts b/src/service/ConfigLoader.ts index 788dfee5a..b01a86cc8 100644 --- a/src/service/ConfigLoader.ts +++ b/src/service/ConfigLoader.ts @@ -132,6 +132,7 @@ export class ConfigLoader { } // Nemesis configuration cannot be changed on upgrade. addresses.mosaics = oldAddresses.mosaics; + presetData.nemesis = oldPresetData.nemesis; } else { if (presetData.nemesis.mosaics) { const mosaics: MosaicAccounts[] = [];