From 3de84c4ddf9b56ba19afb20c04f035d5bee6a6ac Mon Sep 17 00:00:00 2001 From: Ivan Shumkov Date: Fri, 28 Apr 2023 14:36:08 +0800 Subject: [PATCH 1/4] fix(dashmate): force reset fails with volume deletion --- packages/dashmate/docker-compose.platform.yml | 5 -- packages/dashmate/src/commands/group/reset.js | 64 +++++++------------ packages/dashmate/src/commands/reset.js | 12 +--- packages/dashmate/src/config/Config.js | 16 +++-- packages/dashmate/src/docker/DockerCompose.js | 4 +- .../src/listr/tasks/resetNodeTaskFactory.js | 47 +++++++++----- 6 files changed, 69 insertions(+), 79 deletions(-) diff --git a/packages/dashmate/docker-compose.platform.yml b/packages/dashmate/docker-compose.platform.yml index 5b150636c9d..bab9e14314a 100644 --- a/packages/dashmate/docker-compose.platform.yml +++ b/packages/dashmate/docker-compose.platform.yml @@ -4,8 +4,6 @@ services: drive_abci: image: ${PLATFORM_DRIVE_ABCI_DOCKER_IMAGE:?err} restart: unless-stopped - depends_on: - - core volumes: - drive_abci_data:/platform/packages/js-drive/db - ${PLATFORM_DRIVE_ABCI_LOG_PRETTY_DIRECTORY_PATH:?err}:/var/log/pretty @@ -58,7 +56,6 @@ services: restart: unless-stopped depends_on: - drive_tenderdash - - core environment: - API_JSON_RPC_PORT=3004 - API_GRPC_PORT=3005 @@ -81,8 +78,6 @@ services: dapi_tx_filter_stream: image: ${PLATFORM_DAPI_API_DOCKER_IMAGE:?err} restart: unless-stopped - depends_on: - - core environment: - TX_FILTER_STREAM_GRPC_PORT=3006 - DASHCORE_RPC_HOST=core diff --git a/packages/dashmate/src/commands/group/reset.js b/packages/dashmate/src/commands/group/reset.js index be782b9c0b2..02e3da75cd2 100644 --- a/packages/dashmate/src/commands/group/reset.js +++ b/packages/dashmate/src/commands/group/reset.js @@ -4,6 +4,7 @@ const { Flags } = require('@oclif/core'); const GroupBaseCommand = require('../../oclif/command/GroupBaseCommand'); const MuteOneLineError = require('../../oclif/errors/MuteOneLineError'); +const { PRESET_LOCAL } = require('../../constants'); class GroupResetCommand extends GroupBaseCommand { /** @@ -16,7 +17,6 @@ class GroupResetCommand extends GroupBaseCommand { * @param {configureTenderdashTask} configureTenderdashTask * @param {generateToAddressTask} generateToAddressTask * @param {ConfigFile} configFile - * @param {Object[]} systemConfigs * @return {Promise} */ async runWithDependencies( @@ -25,7 +25,7 @@ class GroupResetCommand extends GroupBaseCommand { verbose: isVerbose, hard: isHardReset, force: isForce, - 'platform-only': isPlatformOnlyReset, + platform: isPlatformOnlyReset, }, isSystemConfig, resetNodeTask, @@ -34,66 +34,48 @@ class GroupResetCommand extends GroupBaseCommand { configureTenderdashTask, generateToAddressTask, configFile, - systemConfigs, ) { const groupName = configGroup[0].get('group'); - if (isHardReset && !isSystemConfig(groupName)) { - throw new Error(`Cannot hard reset non-system config group "${configGroup[0].get('group')}"`); - } - - const baseConfig = systemConfigs.base; - const amount = 100; const tasks = new Listr( [ { title: `Reset ${groupName} nodes`, - task: () => new Listr(configGroup.map((config) => ({ - title: `Reset ${config.getName()} node`, - task: (ctx) => { - ctx.skipPlatformInitialization = true; - - config.set('platform.dpns', baseConfig.platform.dpns); - config.set('platform.dashpay', baseConfig.platform.dashpay); - config.set('platform.featureFlags', baseConfig.platform.featureFlags); - config.set('platform.masternodeRewardShares', baseConfig.platform.masternodeRewardShares); + task: () => { + const resetTasks = configGroup.map((config) => ({ + title: `Reset ${config.getName()} node`, + task: () => resetNodeTask(config), + })); - // TODO: Should stay the same - config.set('platform.drive.tenderdash.node.id', baseConfig.platform.drive.tenderdash.node.id); - config.set('platform.drive.tenderdash.node.key', baseConfig.platform.drive.tenderdash.node.key); - config.set('platform.drive.tenderdash.genesis', baseConfig.platform.drive.tenderdash.genesis); - - if (!ctx.isPlatformOnlyReset) { - config.set('core.masternode.operator.privateKey', baseConfig.core.masternode.operator.privateKey); - } - - return resetNodeTask(config); - }, - }))), + return new Listr(resetTasks); + }, }, { - enabled: (ctx) => ctx.isHardReset, + enabled: (ctx) => ctx.isHardReset && groupName === PRESET_LOCAL, title: 'Delete node configs', task: () => ( - configGroup.forEach((config) => configFile.removeConfig(config.getName())) + configGroup + .filter((config) => configFile.isConfigExists(config.getName())) + .forEach((config) => configFile.removeConfig(config.getName())) ), }, { - enabled: (ctx) => !ctx.isHardReset, - title: 'Configure Tenderdash nodes', - task: () => configureTenderdashTask(configGroup), - }, - { - enabled: (ctx) => !ctx.isHardReset && !ctx.isPlatformOnlyReset, + enabled: (ctx) => !ctx.isHardReset + && !ctx.isPlatformOnlyReset && groupName === PRESET_LOCAL, title: 'Configure Core nodes', task: () => configureCoreTask(configGroup), }, + { + enabled: (ctx) => !ctx.isHardReset && groupName === PRESET_LOCAL, + title: 'Configure Tenderdash nodes', + task: () => configureTenderdashTask(configGroup), + }, { // in case we don't need to register masternodes title: `Generate ${amount} dash to local wallet`, - enabled: (ctx) => !ctx.isHardReset, + enabled: (ctx) => !ctx.isHardReset && groupName === PRESET_LOCAL, skip: (ctx) => !!ctx.fundingPrivateKeyString, task: () => generateToAddressTask(configGroup[0], amount), }, @@ -135,9 +117,9 @@ GroupResetCommand.flags = { description: 'reset even running node', default: false, }), - 'platform-only': Flags.boolean({ + platform: Flags.boolean({ char: 'p', - description: 'reset platform data only', + description: 'reset platform services and data only', default: false, }), }; diff --git a/packages/dashmate/src/commands/reset.js b/packages/dashmate/src/commands/reset.js index c8a6eb8e33b..ab12bdd2825 100644 --- a/packages/dashmate/src/commands/reset.js +++ b/packages/dashmate/src/commands/reset.js @@ -22,20 +22,12 @@ class ResetCommand extends ConfigBaseCommand { verbose: isVerbose, hard: isHardReset, force: isForce, - 'platform-only': isPlatformOnlyReset, + platform: isPlatformOnlyReset, }, isSystemConfig, config, resetNodeTask, ) { - if (isHardReset && !isSystemConfig(config.getName())) { - throw new Error(`Cannot hard reset non-system config "${config.getName()}"`); - } - - if (!config.get('platform.enable') && isPlatformOnlyReset) { - throw new Error('Cannot reset platform only if platform services are not enabled in config'); - } - const tasks = new Listr([ { title: `Reset ${config.getName()} node`, @@ -71,7 +63,7 @@ ResetCommand.flags = { ...ConfigBaseCommand.flags, hard: Flags.boolean({ char: 'h', description: 'reset config as well as data', default: false }), force: Flags.boolean({ char: 'f', description: 'skip running services check', default: false }), - 'platform-only': Flags.boolean({ char: 'p', description: 'reset platform data only', default: false }), + platform: Flags.boolean({ char: 'p', description: 'reset platform services and data only', default: false }), verbose: Flags.boolean({ char: 'v', description: 'use verbose mode for output', default: false }), }; diff --git a/packages/dashmate/src/config/Config.js b/packages/dashmate/src/config/Config.js index 27d1cff55e0..07a440bc900 100644 --- a/packages/dashmate/src/config/Config.js +++ b/packages/dashmate/src/config/Config.js @@ -151,14 +151,20 @@ class Config { } /** - * + * @param {Object} [options={}] + * @param {boolean} [options.platformOnly=false] * @return {{CONFIG_NAME: string, COMPOSE_PROJECT_NAME: string}} */ - toEnvs() { - const dockerComposeFiles = ['docker-compose.yml']; + toEnvs(options = {}) { + const dockerComposeFiles = []; + + if (!options.platformOnly) { + // TODO: it should contain only the dashmate helper that must be ran always + dockerComposeFiles.push('docker-compose.yml'); - if (this.get('core.masternode.enable') === true) { - dockerComposeFiles.push('docker-compose.sentinel.yml'); + if (this.get('core.masternode.enable') === true) { + dockerComposeFiles.push('docker-compose.sentinel.yml'); + } } if (this.get('platform.enable')) { diff --git a/packages/dashmate/src/docker/DockerCompose.js b/packages/dashmate/src/docker/DockerCompose.js index 0303226bedf..6e56b1a5f45 100644 --- a/packages/dashmate/src/docker/DockerCompose.js +++ b/packages/dashmate/src/docker/DockerCompose.js @@ -235,7 +235,7 @@ class DockerCompose { * @param {Object} envs * @param {string} [filterServiceNames] * @param {boolean} returnServiceNames - * @return {string[]} + * @return {Promise} */ async getContainersList( envs, @@ -324,7 +324,7 @@ class DockerCompose { try { await dockerCompose.rm({ ...this.getOptions(envs), - commandOptions: ['--stop', '-v'], + commandOptions: ['--stop'], }, ...serviceNames); } catch (e) { throw new DockerComposeError(e); diff --git a/packages/dashmate/src/listr/tasks/resetNodeTaskFactory.js b/packages/dashmate/src/listr/tasks/resetNodeTaskFactory.js index 1e3b1dbb076..f970e66d397 100644 --- a/packages/dashmate/src/listr/tasks/resetNodeTaskFactory.js +++ b/packages/dashmate/src/listr/tasks/resetNodeTaskFactory.js @@ -6,6 +6,7 @@ const { Listr } = require('listr2'); * @param {startNodeTask} startNodeTask * @param {generateToAddressTask} generateToAddressTask * @param {systemConfigs} systemConfigs + * @param {ConfigFile} configFile * @return {resetNodeTask} */ function resetNodeTaskFactory( @@ -14,6 +15,7 @@ function resetNodeTaskFactory( startNodeTask, generateToAddressTask, systemConfigs, + configFile, ) { /** * @typedef {resetNodeTask} @@ -21,6 +23,13 @@ function resetNodeTaskFactory( */ function resetNodeTask(config) { return new Listr([ + { + task: (ctx) => { + if (!config.get('platform.enable') && ctx.isPlatformOnlyReset) { + throw new Error('Cannot reset platform only if platform services are not enabled in config'); + } + }, + }, { title: 'Check services are not running', skip: (ctx) => ctx.isForce, @@ -37,26 +46,27 @@ function resetNodeTaskFactory( }, { title: 'Remove platform services and associated data', - enabled: (ctx) => ctx.isPlatformOnlyReset && config.get('platform.enable'), + enabled: (ctx) => ctx.isPlatformOnlyReset, task: async () => { // Remove containers - const coreContainerNames = ['core', 'sentinel']; - const containerNames = await dockerCompose - .getContainersList(config.toEnvs(), undefined, true); - const platformContainerNames = containerNames - .filter((containerName) => !coreContainerNames.includes(containerName)); + const serviceNames = await dockerCompose + .getContainersList( + config.toEnvs({ platformOnly: true }), + undefined, + true, + ); - await dockerCompose.rm(config.toEnvs(), platformContainerNames); + await dockerCompose.rm(config.toEnvs(), serviceNames); // Remove volumes - const coreVolumeNames = ['core_data']; const { COMPOSE_PROJECT_NAME: composeProjectName } = config.toEnvs(); - const projectVolumeNames = await dockerCompose.getVolumeNames(config.toEnvs()); + const projectVolumeNames = await dockerCompose.getVolumeNames( + config.toEnvs({ platformOnly: true }), + ); await Promise.all( projectVolumeNames - .filter((volumeName) => !coreVolumeNames.includes(volumeName)) .map((volumeName) => `${composeProjectName}_${volumeName}`) .map(async (volumeName) => docker.getVolume(volumeName).remove()), ); @@ -66,14 +76,19 @@ function resetNodeTaskFactory( title: `Reset config ${config.getName()}`, enabled: (ctx) => ctx.isHardReset, task: (ctx) => { - const name = config.get('group') || config.getName(); + const baseConfigName = config.get('group') || config.getName(); - if (ctx.isPlatformOnlyReset) { - // TODO: This won't work for user created configs - const { platform: systemPlatformConfig } = systemConfigs[name]; - config.set('platform', systemPlatformConfig); + if (systemConfigs[baseConfigName]) { + // Reset config if has a base config + if (ctx.isPlatformOnlyReset) { + const { platform: systemPlatformConfig } = systemConfigs[baseConfigName]; + config.set('platform', systemPlatformConfig); + } else { + config.setOptions(systemConfigs[baseConfigName]); + } } else { - config.setOptions(systemConfigs[name]); + // Delete config if no base config + configFile.removeConfig(config.getName()); } }, }, From af6043fef486c2f6aeca949920e6f8e946face7f Mon Sep 17 00:00:00 2001 From: Ivan Shumkov Date: Fri, 28 Apr 2023 16:59:59 +0800 Subject: [PATCH 2/4] fix(dashmate): soft reset fails --- packages/dashmate/src/listr/tasks/resetNodeTaskFactory.js | 8 ++++++++ .../listr/tasks/setup/local/configureCoreTaskFactory.js | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/dashmate/src/listr/tasks/resetNodeTaskFactory.js b/packages/dashmate/src/listr/tasks/resetNodeTaskFactory.js index f970e66d397..c5b48d08cdd 100644 --- a/packages/dashmate/src/listr/tasks/resetNodeTaskFactory.js +++ b/packages/dashmate/src/listr/tasks/resetNodeTaskFactory.js @@ -72,6 +72,14 @@ function resetNodeTaskFactory( ); }, }, + { + title: 'Reset dashmate\'s ephemeral data', + task: (ctx) => { + if (!ctx.isPlatformOnlyReset) { + config.set('core.miner.mediantime', null); + } + }, + }, { title: `Reset config ${config.getName()}`, enabled: (ctx) => ctx.isHardReset, diff --git a/packages/dashmate/src/listr/tasks/setup/local/configureCoreTaskFactory.js b/packages/dashmate/src/listr/tasks/setup/local/configureCoreTaskFactory.js index ab5cd6b3cca..16f67fe5dba 100644 --- a/packages/dashmate/src/listr/tasks/setup/local/configureCoreTaskFactory.js +++ b/packages/dashmate/src/listr/tasks/setup/local/configureCoreTaskFactory.js @@ -162,13 +162,6 @@ function configureCoreTaskFactory( const subTasks = masternodeConfigs.map((config, index) => ({ title: `Register ${config.getName()} masternode`, - skip: () => { - if (config.get('core.masternode.operator.privateKey')) { - return `Masternode operator private key ('core.masternode.operator.privateKey') is already set in ${config.getName()} config`; - } - - return false; - }, task: () => new Listr([ { title: 'Generate a masternode operator key', From 03763e5cd2b188459b7254b2adc8b7355914d394 Mon Sep 17 00:00:00 2001 From: Ivan Shumkov Date: Fri, 28 Apr 2023 17:13:07 +0800 Subject: [PATCH 3/4] fix(dashmate): soft reset fails --- packages/dashmate/src/commands/group/reset.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/dashmate/src/commands/group/reset.js b/packages/dashmate/src/commands/group/reset.js index 02e3da75cd2..3e0a8e9b34d 100644 --- a/packages/dashmate/src/commands/group/reset.js +++ b/packages/dashmate/src/commands/group/reset.js @@ -72,13 +72,6 @@ class GroupResetCommand extends GroupBaseCommand { title: 'Configure Tenderdash nodes', task: () => configureTenderdashTask(configGroup), }, - { - // in case we don't need to register masternodes - title: `Generate ${amount} dash to local wallet`, - enabled: (ctx) => !ctx.isHardReset && groupName === PRESET_LOCAL, - skip: (ctx) => !!ctx.fundingPrivateKeyString, - task: () => generateToAddressTask(configGroup[0], amount), - }, ], { renderer: isVerbose ? 'verbose' : 'default', From ffb3af60db19ac224c9882ea685f4bbf78dce07d Mon Sep 17 00:00:00 2001 From: Ivan Shumkov Date: Fri, 28 Apr 2023 17:31:25 +0800 Subject: [PATCH 4/4] style: fix linter --- packages/dashmate/src/commands/group/reset.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/dashmate/src/commands/group/reset.js b/packages/dashmate/src/commands/group/reset.js index 3e0a8e9b34d..6ab225ea296 100644 --- a/packages/dashmate/src/commands/group/reset.js +++ b/packages/dashmate/src/commands/group/reset.js @@ -37,8 +37,6 @@ class GroupResetCommand extends GroupBaseCommand { ) { const groupName = configGroup[0].get('group'); - const amount = 100; - const tasks = new Listr( [ {