Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Fix generator enable/disable commands #7855

Merged
merged 12 commits into from
Dec 10, 2022
2 changes: 1 addition & 1 deletion commander/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
"@liskhq/lisk-chain": "^0.4.0-alpha.7",
"@liskhq/lisk-codec": "^0.3.0-alpha.5",
"@liskhq/lisk-cryptography": "^4.0.0-alpha.4",
"@liskhq/lisk-db": "0.3.0-debug.20-94522fbd51ec040e1040cdccd1b0572d805a2825",
"@liskhq/lisk-db": "0.3.0-debug.20-52ffbeac2c1b0b188e8df995a1dc6a1634426a27",
"@liskhq/lisk-passphrase": "^4.0.0-alpha.0",
"@liskhq/lisk-transactions": "^6.0.0-alpha.5",
"@liskhq/lisk-utils": "^0.3.0-alpha.1",
Expand Down
93 changes: 0 additions & 93 deletions commander/src/bootstrapping/commands/base_forging.ts

This file was deleted.

51 changes: 51 additions & 0 deletions commander/src/bootstrapping/commands/base_generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright © 2021 Lisk Foundation
*
* See the LICENSE file at the top-level directory of this distribution
* for licensing information.
*
* Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation,
* no part of this software, including this file, may be copied, modified,
* propagated, or distributed except according to the terms contained in the
* LICENSE file.
*
* Removal or modification of this copyright notice is prohibited.
*
*/

import * as inquirer from 'inquirer';
import { flagsWithParser } from '../../utils/flags';
import { BaseIPCClientCommand } from './base_ipc_client';

export abstract class BaseGeneratorCommand extends BaseIPCClientCommand {
static args = [
{
name: 'address',
required: true,
description: 'Address of an account in a lisk32 format.',
},
];

static flags = {
...BaseIPCClientCommand.flags,
password: flagsWithParser.password,
};

protected async getPassword(
parsedFlags: Awaited<ReturnType<typeof BaseGeneratorCommand.prototype.parse>>['flags'],
): Promise<string> {
if (parsedFlags.password) {
return parsedFlags.password as string;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const answers = await inquirer.prompt([
{
type: 'password',
message: 'Enter password to decrypt the encrypted passphrase: ',
name: 'password',
mask: '*',
},
]);
return (answers as { password: string }).password;
}
}
32 changes: 24 additions & 8 deletions commander/src/bootstrapping/commands/generator/disable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
*
*/

import { BaseForgingCommand } from '../base_forging';
import { BaseGeneratorCommand } from '../base_generator';

export abstract class DisableCommand extends BaseForgingCommand {
static description = 'Disable forging for given validator address.';
export abstract class DisableCommand extends BaseGeneratorCommand {
static description = 'Disable block generation for given validator address.';

static examples = [
'generator:disable lskycz7hvr8yfu74bcwxy2n4mopfmjancgdvxq8xz',
Expand All @@ -25,13 +25,29 @@ export abstract class DisableCommand extends BaseForgingCommand {
];

static flags = {
...BaseForgingCommand.flags,
...BaseGeneratorCommand.flags,
};

static args = [...BaseForgingCommand.args];
static args = [...BaseGeneratorCommand.args];

async init(): Promise<void> {
await super.init();
this.forging = false;
async run(): Promise<void> {
const { args, flags } = await this.parse(DisableCommand);
const { address } = args as { address: string };

const password = await this.getPassword(flags);

if (!this._client) {
this.error('APIClient is not initialized.');
}

await this._client.invoke('generator_updateStatus', {
address,
password,
enable: false,
height: 0,
maxHeightGenerated: 0,
maxHeightPrevoted: 0,
});
this.log('Disabled block generation');
bobanm marked this conversation as resolved.
Show resolved Hide resolved
}
}
109 changes: 80 additions & 29 deletions commander/src/bootstrapping/commands/generator/enable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,94 @@
*
*/

import { BaseForgingCommand } from '../base_forging';
import { Flags } from '@oclif/core';
import { BaseGeneratorCommand } from '../base_generator';

export abstract class EnableCommand extends BaseForgingCommand {
static description = 'Enable forging for given validator address.';
const isLessThanZero = (value: number | undefined | null): boolean =>
value === null || value === undefined || value < 0;
bobanm marked this conversation as resolved.
Show resolved Hide resolved

interface Status {
readonly address: string;
readonly height: number;
readonly maxHeightGenerated: number;
readonly maxHeightPrevoted: number;
}

export abstract class EnableCommand extends BaseGeneratorCommand {
static description = 'Enable block generation for given validator address.';

static examples = [
'generator:enable lsk24cd35u4jdq8szo3pnsqe5dsxwrnazyqqqg5eu 100 100 10',
'generator:enable lsk24cd35u4jdq8szo3pnsqe5dsxwrnazyqqqg5eu 100 100 10 --overwrite',
'generator:enable lsk24cd35u4jdq8szo3pnsqe5dsxwrnazyqqqg5eu 100 100 10 --data-path ./data',
'generator:enable lsk24cd35u4jdq8szo3pnsqe5dsxwrnazyqqqg5eu 100 100 10 --data-path ./data --password your_password',
'generator:enable lsk24cd35u4jdq8szo3pnsqe5dsxwrnazyqqqg5eu --use-status-value',
'generator:enable lsk24cd35u4jdq8szo3pnsqe5dsxwrnazyqqqg5eu --height=100 --max-height-generated=30 --max-height-prevoted=10',
'generator:enable lsk24cd35u4jdq8szo3pnsqe5dsxwrnazyqqqg5eu --height=100 --max-height-generated=30 --max-height-prevoted=10 --data-path ./data',
'generator:enable lsk24cd35u4jdq8szo3pnsqe5dsxwrnazyqqqg5eu --height=100 --max-height-generated=30 --max-height-prevoted=10 --data-path ./data --password your_password',
];

static flags = {
...BaseForgingCommand.flags,
...BaseGeneratorCommand.flags,
height: Flags.integer({
description: 'Last generated block height.',
}),
'max-height-generated': Flags.integer({
description: 'Validators largest previously generated height.',
}),
'max-height-prevoted': Flags.integer({
description: 'Validators largest prevoted height for a block.',
bobanm marked this conversation as resolved.
Show resolved Hide resolved
}),
'use-status-value': Flags.boolean({
description: 'Use status value from the connected node',
}),
};

static args = [
...BaseForgingCommand.args,
{
name: 'height',
required: true,
description: 'Last forged block height.',
},
{
name: 'maxHeightGenerated',
required: true,
description: 'Validators largest previously forged height.',
},
{
name: 'maxHeightPrevoted',
required: true,
description: 'Validators largest prevoted height for a block.',
},
];
static args = [...BaseGeneratorCommand.args];

async run(): Promise<void> {
const { args, flags } = await this.parse(EnableCommand);
const { address } = args as { address: string };
const { 'use-status-value': useStatusValue } = flags;

let {
height,
'max-height-generated': maxHeightGenerated,
'max-height-prevoted': maxHeightPrevoted,
} = flags;

if (
!useStatusValue &&
(isLessThanZero(height) ||
isLessThanZero(maxHeightGenerated) ||
isLessThanZero(maxHeightPrevoted))
) {
throw new Error(
'The maxHeightGenerated and maxHeightPrevoted parameter value must be greater than or equal to 0',
bobanm marked this conversation as resolved.
Show resolved Hide resolved
);
}

const password = await this.getPassword(flags);

if (!this._client) {
this.error('APIClient is not initialized.');
}

if (useStatusValue) {
const statusList = await this._client.invoke<{ status: Status[] }>('generator_getStatus');
const foundStatus = statusList.status.find(s => s.address === address);
if (!foundStatus) {
throw new Error(`Status for ${address} not found in the node.`);
}
height = foundStatus.height;
maxHeightGenerated = foundStatus.maxHeightGenerated;
maxHeightPrevoted = foundStatus.maxHeightPrevoted;
}

async init(): Promise<void> {
await super.init();
this.forging = true;
await this._client.invoke('generator_updateStatus', {
address,
password,
enable: true,
height: Number(height ?? 0),
maxHeightGenerated: Number(maxHeightGenerated ?? 0),
maxHeightPrevoted: Number(maxHeightPrevoted ?? 0),
});
this.log(`Enabled block generation for ${address}`);
}
}
4 changes: 2 additions & 2 deletions commander/src/bootstrapping/commands/generator/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ interface KeysWithInfo {
encrypted?: EncryptedMessageObject;
},
];
generatorInfo: [
generatorInfo?: [
{
address: string;
height: number;
Expand Down Expand Up @@ -88,7 +88,7 @@ export abstract class ImportCommand extends BaseIPCClientCommand {

const fileData = fs.readJSONSync(flags['file-path']) as unknown as KeysWithInfo;

for (const info of fileData.generatorInfo) {
for (const info of fileData.generatorInfo ?? []) {
await this._client.invoke('generator_setStatus', info);
}
}
Expand Down
Loading