diff --git a/.yarnrc.yml b/.yarnrc.yml index dd002648b03..c59f803d7db 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -16,6 +16,7 @@ npmAuditExcludePackages: - "@humanwhocodes/object-schema" # TODO: Update eslint - micromatch # TODO: remove when new micromatch will be released https://github.com/advisories/GHSA-952p-6rrq-rcjv - eslint # TODO: Update eslint https://github.com/dashpay/platform/issues/2212 + - elliptic # TODO: Remove when elliptic >6.5.7 released packageExtensions: "@dashevo/protobufjs@*": diff --git a/packages/dashmate/src/commands/group/status.js b/packages/dashmate/src/commands/group/status.js index d3edbd88001..f9c20f800f3 100644 --- a/packages/dashmate/src/commands/group/status.js +++ b/packages/dashmate/src/commands/group/status.js @@ -86,7 +86,7 @@ export default class GroupStatusCommand extends GroupBaseCommand { plain['Platform Status'] = colors.status(scope.platform.tenderdash.serviceStatus)(scope.platform.tenderdash.serviceStatus) || 'n/a'; } else { plain['Platform Status'] = colors.status(scope.platform.tenderdash.serviceStatus)(scope.platform.tenderdash.serviceStatus) || 'n/a'; - plain['Platform Version'] = scope.platform.tenderdash.version || 'n/a'; + plain['Platform Version'] = scope.platform.drive.version || 'n/a'; plain['Platform Block Height'] = scope.platform.tenderdash.latestBlockHeight || 'n/a'; plain['Platform Peers'] = scope.platform.tenderdash.peers || 'n/a'; plain['Platform Network'] = scope.platform.tenderdash.network || 'n/a'; diff --git a/packages/dashmate/src/commands/status/index.js b/packages/dashmate/src/commands/status/index.js index c22269ccdc8..defeb7b80d2 100644 --- a/packages/dashmate/src/commands/status/index.js +++ b/packages/dashmate/src/commands/status/index.js @@ -116,7 +116,7 @@ export default class StatusCommand extends ConfigBaseCommand { plain['Platform Status'] = colors.status(platformStatus)(platformStatus) || 'n/a'; if (platform.tenderdash.serviceStatus === ServiceStatusEnum.up) { - plain['Platform Version'] = platform.tenderdash.version || 'n/a'; + plain['Platform Version'] = platform.drive.version || 'n/a'; plain['Platform Block Height'] = platform.tenderdash.latestBlockHeight || 'n/a'; plain['Platform Peers'] = platform.tenderdash.peers || 'n/a'; plain['Platform Network'] = platform.tenderdash.network || 'n/a'; diff --git a/packages/dashmate/src/commands/status/platform.js b/packages/dashmate/src/commands/status/platform.js index 2c0e401f18c..4f6eba5fbb3 100644 --- a/packages/dashmate/src/commands/status/platform.js +++ b/packages/dashmate/src/commands/status/platform.js @@ -32,7 +32,6 @@ export default class PlatformStatusCommand extends ConfigBaseCommand { flags, dockerCompose, createRpcClient, - getConnectionHost, config, getPlatformScope, ) { diff --git a/packages/dashmate/src/status/scopes/platform.js b/packages/dashmate/src/status/scopes/platform.js index 9943e35b108..04daa6070fa 100644 --- a/packages/dashmate/src/status/scopes/platform.js +++ b/packages/dashmate/src/status/scopes/platform.js @@ -159,6 +159,7 @@ export default function getPlatformScopeFactory( const info = { dockerStatus: null, serviceStatus: null, + version: null, }; try { @@ -192,6 +193,23 @@ export default function getPlatformScopeFactory( } } + try { + const driveVersionResult = await dockerCompose.execCommand( + config, + 'drive_abci', + 'drive-abci version', + ); + + info.version = driveVersionResult.out.trim(); + } catch (e) { + // Throw an error if it's not a Drive issue + if (!(e instanceof DockerComposeError + && e.dockerComposeExecutionResult + && e.dockerComposeExecutionResult.exitCode !== 0)) { + throw e; + } + } + return info; }; diff --git a/packages/dashmate/test/unit/status/scopes/platform.spec.js b/packages/dashmate/test/unit/status/scopes/platform.spec.js index b94f0da6365..fc8bc8bf1cb 100644 --- a/packages/dashmate/test/unit/status/scopes/platform.spec.js +++ b/packages/dashmate/test/unit/status/scopes/platform.spec.js @@ -1,5 +1,6 @@ import ContainerIsNotPresentError from '../../../../src/docker/errors/ContainerIsNotPresentError.js'; +import DockerComposeError from '../../../../src/docker/errors/DockerComposeError.js'; import providers from '../../../../src/status/providers.js'; import determineStatus from '../../../../src/status/determineStatus.js'; import getConfigMock from '../../../../src/test/mock/getConfigMock.js'; @@ -73,7 +74,8 @@ describe('getPlatformScopeFactory', () => { }, }); mockDockerCompose.isServiceRunning.returns(true); - mockDockerCompose.execCommand.returns({ exitCode: 0, out: '' }); + mockDockerCompose.execCommand.withArgs(config, 'drive_abci', 'drive-abci status').resolves({ exitCode: 0, out: '' }); + mockDockerCompose.execCommand.withArgs(config, 'drive_abci', 'drive-abci version').resolves({ exitCode: 0, out: '1.4.1' }); mockMNOWatchProvider.returns(Promise.resolve('OPEN')); const mockStatus = { @@ -121,6 +123,7 @@ describe('getPlatformScopeFactory', () => { drive: { dockerStatus: DockerStatusEnum.running, serviceStatus: ServiceStatusEnum.up, + version: '1.4.1', }, }; @@ -147,7 +150,7 @@ describe('getPlatformScopeFactory', () => { }, }); mockDockerCompose.isServiceRunning.returns(true); - mockDockerCompose.execCommand.returns({ exitCode: 0, out: '' }); + mockDockerCompose.execCommand.withArgs(config, 'drive_abci', 'drive-abci version').resolves({ exitCode: 0, out: '1.4.1' }); mockMNOWatchProvider.returns(Promise.resolve('OPEN')); const mockStatus = { @@ -195,6 +198,7 @@ describe('getPlatformScopeFactory', () => { drive: { dockerStatus: DockerStatusEnum.running, serviceStatus: ServiceStatusEnum.up, + version: '1.4.1', }, }; @@ -212,7 +216,6 @@ describe('getPlatformScopeFactory', () => { it('should return empty scope if error during request to core', async () => { mockRpcClient.mnsync.withArgs('status').throws(new Error()); - mockDockerCompose.execCommand.returns({ exitCode: 0, out: '' }); mockDockerCompose.isServiceRunning.returns(true); mockDetermineDockerStatus.withArgs(mockDockerCompose, config, 'drive_tenderdash') .returns(DockerStatusEnum.running); @@ -268,7 +271,7 @@ describe('getPlatformScopeFactory', () => { }, }, }); - mockDockerCompose.execCommand.returns({ exitCode: 1, out: '' }); + mockDockerCompose.execCommand.withArgs(config, 'drive_abci', 'drive-abci version').resolves({ exitCode: 0, out: '1.4.1' }); mockMNOWatchProvider.returns(Promise.resolve('OPEN')); const expectedScope = { @@ -300,6 +303,7 @@ describe('getPlatformScopeFactory', () => { drive: { dockerStatus: DockerStatusEnum.running, serviceStatus: ServiceStatusEnum.wait_for_core, + version: '1.4.1', }, }; @@ -324,7 +328,7 @@ describe('getPlatformScopeFactory', () => { .returns(DockerStatusEnum.running); mockDetermineDockerStatus.withArgs(mockDockerCompose, config, 'drive_abci') .returns(DockerStatusEnum.running); - mockDockerCompose.execCommand.returns({ exitCode: 0, out: '' }); + mockDockerCompose.execCommand.withArgs(config, 'drive_abci', 'drive-abci version').resolves({ exitCode: 0, out: '1.4.1' }); mockMNOWatchProvider.returns(Promise.resolve('OPEN')); const expectedScope = { @@ -356,6 +360,7 @@ describe('getPlatformScopeFactory', () => { drive: { dockerStatus: DockerStatusEnum.running, serviceStatus: ServiceStatusEnum.up, + version: '1.4.1', }, }; @@ -380,8 +385,11 @@ describe('getPlatformScopeFactory', () => { .returns(DockerStatusEnum.running); mockDetermineDockerStatus.withArgs(mockDockerCompose, config, 'drive_abci') .throws(new ContainerIsNotPresentError('drive_abci')); - mockDockerCompose.execCommand.returns({ exitCode: 0, out: '' }); mockMNOWatchProvider.returns(Promise.resolve('OPEN')); + const error = new DockerComposeError({ + exitCode: 1, + }); + mockDockerCompose.execCommand.withArgs(config, 'drive_abci', 'drive-abci version').rejects(error); const mockStatus = { node_info: { @@ -434,6 +442,7 @@ describe('getPlatformScopeFactory', () => { drive: { dockerStatus: DockerStatusEnum.not_started, serviceStatus: ServiceStatusEnum.stopped, + version: null, }, }; @@ -454,7 +463,8 @@ describe('getPlatformScopeFactory', () => { mockDockerCompose.isServiceRunning .withArgs(config, 'drive_tenderdash') .returns(true); - mockDockerCompose.execCommand.returns({ exitCode: 0, out: '' }); + mockDockerCompose.execCommand.withArgs(config, 'drive_abci', 'drive-abci status').resolves({ exitCode: 0, out: '' }); + mockDockerCompose.execCommand.withArgs(config, 'drive_abci', 'drive-abci version').resolves({ exitCode: 0, out: '1.4.1' }); mockDetermineDockerStatus.returns(DockerStatusEnum.running); mockMNOWatchProvider.returns(Promise.resolve('OPEN')); mockFetch.returns(Promise.reject(new Error('FetchError'))); @@ -488,6 +498,7 @@ describe('getPlatformScopeFactory', () => { drive: { dockerStatus: DockerStatusEnum.running, serviceStatus: ServiceStatusEnum.up, + version: '1.4.1', }, }; diff --git a/packages/rs-drive-abci/src/main.rs b/packages/rs-drive-abci/src/main.rs index a76fffd1c79..a8ae1adccdc 100644 --- a/packages/rs-drive-abci/src/main.rs +++ b/packages/rs-drive-abci/src/main.rs @@ -59,6 +59,10 @@ enum Commands { /// by creating `.fsck` file in database directory (`DB_PATH`). #[command()] Verify, + + /// Print current software version + #[command()] + Version, } /// Server that accepts connections from Tenderdash, and @@ -148,6 +152,7 @@ impl Cli { Commands::Config => dump_config(&config)?, Commands::Status => runtime.block_on(check_status(&config))?, Commands::Verify => verify_grovedb(&config.db_path, true)?, + Commands::Version => print_version(), }; Ok(()) @@ -220,16 +225,11 @@ fn main() -> Result<(), ExitCode> { runtime.spawn(handle_signals(cancel.clone(), loggers)); - let result = match cli.run(&runtime, config, cancel) { - Ok(()) => { - tracing::debug!("shutdown complete"); - Ok(()) - } - Err(e) => { - tracing::error!(error = e, "drive-abci failed: {e}"); - Err(ExitCode::FAILURE) - } - }; + let result = cli.run(&runtime, config, cancel).map_err(|e| { + tracing::error!(error = e, "drive-abci failed: {e}"); + + ExitCode::FAILURE + }); drop(runtime_guard); runtime.shutdown_timeout(Duration::from_millis(SHUTDOWN_TIMEOUT_MILIS)); @@ -387,6 +387,11 @@ fn verify_grovedb(db_path: &PathBuf, force: bool) -> Result<(), String> { } } +/// Print current software version. +fn print_version() { + println!("{}", env!("CARGO_PKG_VERSION")); +} + fn load_config(path: &Option) -> PlatformConfig { if let Some(path) = path { if let Err(e) = dotenvy::from_path(path) {