Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dashmate): status command shows tenderdash error before activation #2028

Merged
merged 7 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions packages/dashmate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ In some cases, you must also additionally reset platform data:
```bash
$ dashmate stop
$ npm install -g dashmate
$ dashmate reset --platform-only --hard
$ dashmate reset --platform --hard
$ dashmate update
$ dashmate setup
$ dashmate start
Expand Down Expand Up @@ -283,14 +283,18 @@ The `reset` command removes all data corresponding to the specified config and a

```
USAGE
$ dashmate reset [-v] [--config <value>] [-h] [-f] [-p]
$ dashmate reset [--config <value>] [-v] [-h] [-f] [-p] [--keep-data]

FLAGS
-f, --force skip running services check
-h, --hard reset config as well as data
-p, --platform-only reset platform data only
-v, --verbose use verbose mode for output
--config=<value> configuration name to use
-f, --force skip running services check
-h, --hard reset config as well as services and data
-p, --platform reset platform services and data only
-v, --verbose use verbose mode for output
--config=<value> configuration name to use
--keep-data keep data

DESCRIPTION
Reset node data
```

To reset a node:
Expand Down Expand Up @@ -446,7 +450,7 @@ USAGE

FLAGS
-f, --force reset even running node
-p, --platform-only reset platform data only
-p, --platform reset platform data only
-v, --verbose use verbose mode for output
--group=<value> group name to use
--hard reset config as well as data
Expand Down
4 changes: 4 additions & 0 deletions packages/dashmate/src/commands/status/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default class PlatformStatusCommand extends ConfigBaseCommand {
flags,
dockerCompose,
createRpcClient,
getConnectionHost,
config,
getPlatformScope,
) {
Expand All @@ -57,6 +58,7 @@ export default class PlatformStatusCommand extends ConfigBaseCommand {

if (flags.format === OUTPUT_FORMATS.PLAIN) {
const {
platformActivation,
httpService,
httpPort,
httpPortState,
Expand All @@ -68,6 +70,8 @@ export default class PlatformStatusCommand extends ConfigBaseCommand {
drive,
} = scope;

plain['Platform Activation'] = platformActivation ? colors.platformActivation(platformActivation)(platformActivation) : 'n/a';

plain['HTTP service'] = httpService || 'n/a';
plain['HTTP port'] = `${httpPort} ${httpPortState ? colors.portState(httpPortState)(httpPortState) : ''}`;
plain['P2P service'] = p2pService || 'n/a';
Expand Down
2 changes: 2 additions & 0 deletions packages/dashmate/src/status/colors.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default {
return chalk.green;
case ServiceStatusEnum.syncing:
case ServiceStatusEnum.wait_for_core:
case ServiceStatusEnum.wait_for_activation:
return chalk.yellow;
default:
return chalk.red;
Expand Down Expand Up @@ -73,4 +74,5 @@ export default {
}
return chalk.red;
},
platformActivation: (string) => (string.startsWith('Activated') ? chalk.green : chalk.yellow),
};
7 changes: 6 additions & 1 deletion packages/dashmate/src/status/determineStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,14 @@ export default {
* Determine platform ServiceStatus based on DockerStatusEnum and core readiness
* @param dockerStatus {DockerStatusEnum}
* @param coreIsSynced {boolean}
* @param mnRRSoftFork {object}
* @returns {ServiceStatusEnum}
*/
platform: (dockerStatus, coreIsSynced) => {
platform: (dockerStatus, coreIsSynced, mnRRSoftFork) => {
if (coreIsSynced && !mnRRSoftFork.active) {
return ServiceStatusEnum.wait_for_activation;
}

if (dockerStatus === DockerStatusEnum.running) {
return coreIsSynced ? ServiceStatusEnum.up : ServiceStatusEnum.wait_for_core;
}
Expand Down
1 change: 1 addition & 0 deletions packages/dashmate/src/status/enums/serviceStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export const ServiceStatusEnum = {
up: 'up',
syncing: 'syncing',
wait_for_core: 'wait_for_core',
wait_for_activation: 'wait_for_activation',
error: 'error',
};
72 changes: 51 additions & 21 deletions packages/dashmate/src/status/scopes/platform.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import prettyMs from 'pretty-ms';
import providers from '../providers.js';
import { DockerStatusEnum } from '../enums/dockerStatus.js';
import { ServiceStatusEnum } from '../enums/serviceStatus.js';
Expand All @@ -15,24 +16,35 @@ export default function getPlatformScopeFactory(
createRpcClient,
getConnectionHost,
) {
async function getMNSync(config) {
async function getCoreInfo(config) {
const rpcClient = createRpcClient({
port: config.get('core.rpc.port'),
user: 'dashmate',
pass: config.get('core.rpc.users.dashmate.password'),
host: await getConnectionHost(config, 'core', 'core.rpc.host'),
});

const [mnSync, blockchainInfo] = await Promise.all([
rpcClient.mnsync('status'),
rpcClient.getBlockchainInfo(),
]);

const {
result: {
softforks: { mn_rr: mnRR },
},
} = blockchainInfo;

const {
result: {
IsSynced: isSynced,
},
} = await rpcClient.mnsync('status');
} = mnSync;

return isSynced;
return { isSynced, mnRRSoftFork: mnRR };
}

async function getTenderdashInfo(config, isCoreSynced) {
async function getTenderdashInfo(config, isCoreSynced, mnRRSoftFork) {
const info = {
p2pPortState: null,
httpPortState: null,
Expand Down Expand Up @@ -63,7 +75,7 @@ export default function getPlatformScopeFactory(
}

const dockerStatus = await determineStatus.docker(dockerCompose, config, 'drive_tenderdash');
const serviceStatus = determineStatus.platform(dockerStatus, isCoreSynced);
const serviceStatus = determineStatus.platform(dockerStatus, isCoreSynced, mnRRSoftFork);

info.dockerStatus = dockerStatus;
info.serviceStatus = serviceStatus;
Expand Down Expand Up @@ -142,15 +154,15 @@ export default function getPlatformScopeFactory(
return info;
}

const getDriveInfo = async (config, isCoreSynced) => {
const getDriveInfo = async (config, isCoreSynced, mnRRSoftFork) => {
const info = {
dockerStatus: null,
serviceStatus: null,
};

try {
info.dockerStatus = await determineStatus.docker(dockerCompose, config, 'drive_abci');
info.serviceStatus = determineStatus.platform(info.dockerStatus, isCoreSynced);
info.serviceStatus = determineStatus.platform(info.dockerStatus, isCoreSynced, mnRRSoftFork);

if (info.serviceStatus === ServiceStatusEnum.up) {
const driveEchoResult = await dockerCompose.execCommand(
Expand Down Expand Up @@ -194,6 +206,7 @@ export default function getPlatformScopeFactory(
const rpcService = `${rpcHost}:${rpcPort}`;

const scope = {
platformActivation: null,
coreIsSynced: null,
httpPort,
httpService,
Expand Down Expand Up @@ -233,11 +246,14 @@ export default function getPlatformScopeFactory(
}
}

let coreInfo;

try {
const coreIsSynced = await getMNSync(config);
scope.coreIsSynced = coreIsSynced;
coreInfo = await getCoreInfo(config);

if (!coreIsSynced) {
scope.coreIsSynced = coreInfo.isSynced;

if (!coreInfo.isSynced) {
if (process.env.DEBUG) {
// eslint-disable-next-line no-console
console.error('Platform status is not available until masternode state is \'READY\'');
Expand All @@ -250,20 +266,34 @@ export default function getPlatformScopeFactory(
}
}

const [tenderdash, drive] = await Promise.all([
getTenderdashInfo(config, scope.coreIsSynced),
getDriveInfo(config, scope.coreIsSynced),
]);
if (coreInfo) {
const { mnRRSoftFork } = coreInfo;

if (tenderdash) {
scope.tenderdash = tenderdash;
if (mnRRSoftFork.active) {
scope.platformActivation = `Activated (at height ${mnRRSoftFork.height})`;
} else {
const startTime = mnRRSoftFork.bip9.start_time;

scope.httpPortState = tenderdash.httpPortState;
scope.p2pPortState = tenderdash.p2pPortState;
}
const diff = (new Date().getTime() - startTime) / 1000;

scope.platformActivation = `Waiting for activation (approximately in ${prettyMs(diff, { compact: true })})`;
}

const [tenderdash, drive] = await Promise.all([
getTenderdashInfo(config, scope.coreIsSynced, coreInfo.mnRRSoftFork),
getDriveInfo(config, scope.coreIsSynced, coreInfo.mnRRSoftFork),
]);

if (drive) {
scope.drive = drive;
if (tenderdash) {
scope.tenderdash = tenderdash;

scope.httpPortState = tenderdash.httpPortState;
scope.p2pPortState = tenderdash.p2pPortState;
}

if (drive) {
scope.drive = drive;
}
}

return scope;
Expand Down
Loading
Loading