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): imported node is not starting #2009

Merged
merged 9 commits into from
Jul 29, 2024
7 changes: 4 additions & 3 deletions packages/dashmate/src/core/waitForCoreStart.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import wait from '../util/wait.js';
*
* @typedef {waitForCoreStart}
* @param {CoreService} coreService
* @param {number} [maxRetries=120] ~2 minutes
* @param {number} [delayMs=1000]
* @return {Promise<void>}
*/
export default async function waitForCoreStart(coreService) {
export default async function waitForCoreStart(coreService, maxRetries = 120, delayMs = 1000) {
let retries = 0;
let isReady = false;
const maxRetries = 120; // ~2 minutes

do {
try {
Expand All @@ -20,7 +21,7 @@ export default async function waitForCoreStart(coreService) {
isReady = true;
} catch (e) {
// just wait 1 second before next try
await wait(1000);
await wait(delayMs);
++retries;
}
} while (!isReady && retries < maxRetries);
Expand Down
4 changes: 2 additions & 2 deletions packages/dashmate/src/listr/tasks/reindexNodeTaskFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export default function reindexNodeTaskFactory(

ctx.coreService = new CoreService(config, rpcClient, container);

await waitForCoreStart(ctx.coreService);
await waitForCoreStart(ctx.coreService, 300, 2000);

// When Core is started remove reindex=1 from dashd.conf
// rendering service templates without additional variables
Expand All @@ -146,7 +146,7 @@ export default function reindexNodeTaskFactory(
await waitForCoreSync(ctx.coreService, (verificationProgress) => {
const { percent, blocks, headers } = verificationProgress;

observer.next(`${(percent * 100).toFixed(4)}%, ${blocks} / ${headers}`);
observer.next(`${(percent * 100).toFixed(1)}%, ${blocks} / ${headers}`);
});

await new Promise((res) => { setTimeout(res, 2000); });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Listr } from 'listr2';
import fs from 'fs';
import path from 'path';
import chalk from 'chalk';
import {
NETWORK_TESTNET,
} from '../../../../constants.js';
Expand Down Expand Up @@ -74,7 +75,11 @@ function validateCoreDataDirectoryPathFactory(config) {
* @param {generateEnvs} generateEnvs
* @return {importCoreDataTask}
*/
export default function importCoreDataTaskFactory(docker, dockerPull, generateEnvs) {
export default function importCoreDataTaskFactory(
docker,
dockerPull,
generateEnvs,
) {
/**
* @typedef {function} importCoreDataTask
* @returns {Listr}
Expand Down Expand Up @@ -135,6 +140,12 @@ export default function importCoreDataTaskFactory(docker, dockerPull, generateEn
// eslint-disable-next-line prefer-destructuring
ctx.importedExternalIp = configFileContent.match(/^externalip=([^ \n]+)/m)?.[1];

// We need to reindex Core if there weren't all required indexed enabled before
ctx.isReindexRequired = !configFileContent.match(/^txindex=1/)
|| !configFileContent.match(/^addressindex=1/)
|| !configFileContent.match(/^timestampindex=1/)
|| !configFileContent.match(/^spentindex=1/);

// Copy data directory to docker a volume

// Create a volume
Expand Down Expand Up @@ -193,11 +204,21 @@ export default function importCoreDataTaskFactory(docker, dockerPull, generateEn
throw new Error('Cannot copy data dir to volume');
}

// TODO: Wording needs to be updated
let header;
if (ctx.isReindexRequired) {
header = chalk` {bold You existing Core node doesn't have indexes required to run ${ctx.nodeTypeName}.
Reindex of the Core data will be needed after you finish the node setup.}

Please stop your existing Dash Core node before reindexing.
Also, disable any automatic startup services (e.g., cron, systemd) for the existing Dash Core installation.\n`;
} else {
header = ` Please stop your existing Dash Core node before starting the new dashmate-based
node ("dashmate start"). Also, disable any automatic startup services (e.g., cron, systemd) for the existing Dash Core installation.\n`;
}

await task.prompt({
type: 'confirm',
header: ` Please stop your existing Dash Core node before starting the new dashmate-based
node ("dashmate start"). Also, disable any automatic startup services (e.g., cron, systemd) for the existing Dash Core installation.\n`,
header,
message: 'Press any key to continue...',
default: ' ',
separator: () => '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,29 @@ export default function verifySystemRequirementsTaskFactory(docker, dockerCompos
}
}

let message = '';
if (ctx.isHP) {
message = `Dash Platform requires more resources than the current system provides.
Evonode rewards are paid based on block production, and resource-limited
nodes may not be able to produce blocks quickly enough to receive reward
payments. Upgrading system resources is recommended before proceeding.

{bold This node may not receive Dash Platform reward payments due to its resource limitations.}`;
} else {
message = `Limited system resources may impact the performance of the node.
The node might not provide required services to the network in time and will get PoSe banned.
PoSe banned node aren't receiving masternode rewards.
Upgrading system resources is recommended before proceeding.`;
}

if (warnings.length > 0) {
const warningsText = warnings.map((warning) => ` - ${warning}`).join('\n');

const header = chalk` Minimum requirements have not been met:

{red ${warningsText}}

Dash Platform requires more resources than the current system provides.
Evonode rewards are paid based on block production, and resource-limited
nodes may not be able to produce blocks quickly enough to receive reward
payments. Upgrading system resources is recommended before proceeding.

{bold This server may not receive Dash Platform reward payments due to its resource limitations.}\n`;
${message}\n`;

// This option is used for tests
if (ctx.acceptUnmetSystemRequirements) {
Expand All @@ -170,6 +180,9 @@ export default function verifySystemRequirementsTaskFactory(docker, dockerCompos

if (!proceed) {
throw new Error('System requirements have not been met');
} else {
// eslint-disable-next-line no-param-reassign
task.output = chalk`{yellow System requirements have not been met.}`;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import chalk from 'chalk';
import {
NODE_TYPE_MASTERNODE,
NODE_TYPE_FULLNODE,
PRESET_MAINNET,
} from '../../../constants.js';

import {
Expand Down Expand Up @@ -49,10 +48,8 @@ export default function setupRegularPresetTaskFactory(
{
title: 'Node type',
task: async (ctx, task) => {
let nodeTypeName;

if (!ctx.nodeType) {
nodeTypeName = await task.prompt([
ctx.nodeTypeName = await task.prompt([
{
type: 'select',
// Keep this order, because each item references the text in the previous item
Expand All @@ -75,16 +72,15 @@ export default function setupRegularPresetTaskFactory(
},
]);

ctx.nodeType = getNodeTypeByName(nodeTypeName);
ctx.isHP = isNodeTypeNameHighPerformance(nodeTypeName);
ctx.nodeType = getNodeTypeByName(ctx.nodeTypeName);
ctx.isHP = isNodeTypeNameHighPerformance(ctx.nodeTypeName);
} else {
nodeTypeName = getNodeTypeNameByType(ctx.nodeType);
ctx.nodeTypeName = getNodeTypeNameByType(ctx.nodeType);
}

ctx.config = defaultConfigs.get(ctx.preset);

// TODO: We need to change this and enable platform on mainnet
ctx.config.set('platform.enable', ctx.isHP && ctx.config.get('network') !== PRESET_MAINNET);
ctx.config.set('platform.enable', ctx.isHP);
ctx.config.set('core.masternode.enable', ctx.nodeType === NODE_TYPE_MASTERNODE);

if (ctx.config.get('core.masternode.enable')) {
Expand All @@ -99,7 +95,7 @@ export default function setupRegularPresetTaskFactory(
});

// eslint-disable-next-line no-param-reassign
task.output = ctx.nodeType ? ctx.nodeType : nodeTypeName;
task.output = ctx.nodeTypeName;
},
options: {
persistentOutput: true,
Expand All @@ -113,11 +109,11 @@ export default function setupRegularPresetTaskFactory(
task: async (ctx, task) => {
let header;
if (ctx.isHP) {
header = ` If your HP masternode is already registered, we will import your masternode
operator and platform node keys to configure an HP masternode. Please make
header = ` If your Evo masternode is already registered, we will import your masternode
operator and platform node keys to configure an Evo masternode. Please make
sure your IP address has not changed, otherwise you will need to create a
provider update service transaction.\n
If you are registering a new HP masternode, dashmate will provide more
If you are registering a new Evo masternode, dashmate will provide more
information and help you to generate the necessary keys.\n`;
} else {
header = ` If your masternode is already registered, we will import your masternode
Expand Down Expand Up @@ -158,11 +154,20 @@ export default function setupRegularPresetTaskFactory(
configFile.setConfig(ctx.config);
configFile.setDefaultConfigName(ctx.preset);

let startInstructions = '';
if (ctx.isReindexRequired) {
startInstructions = chalk`You existing Core node doesn't have indexes required to run ${ctx.nodeTypeName}
Please run {bold.cyanBright dashmate core reindex} to reindex your node.
The node will be started automatically after reindex is complete.`;
} else {
startInstructions = chalk`You can now run {bold.cyanBright dashmate start} to start your node, followed by
{bold.cyanBright dashmate status} for a node health status overview.`;
}

// eslint-disable-next-line no-param-reassign
task.output = chalk`Node configuration completed successfully!

You can now run {bold.cyanBright dashmate start} to start your node, followed by
{bold.cyanBright dashmate status} for a node health status overview.
${startInstructions}

Run {bold.cyanBright dashmate --help} or {bold.cyanBright dashmate <command> --help} for quick help on how
to use dashmate to manage your node.\n`;
Expand Down
5 changes: 0 additions & 5 deletions packages/dashmate/src/listr/tasks/startNodeTaskFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,6 @@ export default function startNodeTaskFactory(
* @return {Object}
*/
function startNodeTask(config) {
// Check external IP is set
if (config.get('core.masternode.enable')) {
config.get('externalIp', true);
}

const isMinerEnabled = config.get('core.miner.enable');

if (isMinerEnabled === true && config.get('network') !== NETWORK_LOCAL) {
Expand Down
Loading