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

CSUB-630: Add missing error handling to wizard, bond & validate #1195

Merged
merged 6 commits into from
Jul 19, 2023
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
4 changes: 2 additions & 2 deletions scripts/cc-cli/src/commands/balance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Command, OptionValues } from "commander";
import { newApi } from "../api";
import { getBalance, logBalance } from "../utils/balance";
import {
parseAddresOrExit,
parseAddressOrExit,
parseBoolean,
requiredInput,
} from "../utils/parsing";
Expand All @@ -20,7 +20,7 @@ async function balanceAction(options: OptionValues) {
const json = parseBoolean(options.json);
const { api } = await newApi(options.url);

const address = parseAddresOrExit(
const address = parseAddressOrExit(
requiredInput(
options.address,
"Failed to show balance: Must specify an address"
Expand Down
8 changes: 4 additions & 4 deletions scripts/cc-cli/src/commands/bond.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import {
import { BN } from "creditcoin-js";
import {
inputOrDefault,
parseAddresOrExit,
parseAddressOrExit,
parseAmountOrExit,
parseBoolean,
parseChoice,
parseChoiceOrExit,
requiredInput,
} from "../utils/parsing";

Expand Down Expand Up @@ -97,15 +97,15 @@ function parseOptions(options: OptionValues) {
);
checkAmount(amount);

const controller = parseAddresOrExit(
const controller = parseAddressOrExit(
requiredInput(
options.controller,
"Failed to bond: Must specify a controller address"
)
);

const rewardDestination = checkRewardDestination(
parseChoice(inputOrDefault(options.rewardDestination, "Staked"), [
parseChoiceOrExit(inputOrDefault(options.rewardDestination, "Staked"), [
"Staked",
"Stash",
"Controller",
Expand Down
4 changes: 2 additions & 2 deletions scripts/cc-cli/src/commands/distributeRewards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from "../utils/account";
import { requireEnoughFundsToSend, signSendAndWatch } from "../utils/tx";
import {
parseAddresOrExit,
parseAddressOrExit,
parseIntegerOrExit,
requiredInput,
} from "../utils/parsing";
Expand Down Expand Up @@ -45,7 +45,7 @@ async function distributeRewardsAction(options: OptionValues) {
}

function parseOptions(options: OptionValues) {
const validator = parseAddresOrExit(
const validator = parseAddressOrExit(
requiredInput(
options.validatorId,
"Failed to distribute rewards: Must specify a validator address"
Expand Down
4 changes: 2 additions & 2 deletions scripts/cc-cli/src/commands/send.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from "../utils/account";
import { requireEnoughFundsToSend, signSendAndWatch } from "../utils/tx";
import {
parseAddresOrExit,
parseAddressOrExit,
parseAmountOrExit,
parseBoolean,
requiredInput,
Expand Down Expand Up @@ -51,7 +51,7 @@ function parseOptions(options: OptionValues) {
requiredInput(options.amount, "Failed to send CTC: Must specify an amount")
);

const recipient = parseAddresOrExit(
const recipient = parseAddressOrExit(
requiredInput(options.to, "Failed to send CTC: Must specify a recipient")
);

Expand Down
4 changes: 2 additions & 2 deletions scripts/cc-cli/src/commands/status.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Command, OptionValues } from "commander";
import { newApi } from "../api";
import { getStatus, printValidatorStatus } from "../utils/status";
import { parseAddresOrExit, requiredInput } from "../utils/parsing";
import { parseAddressOrExit, requiredInput } from "../utils/parsing";

export function makeStatusCommand() {
const cmd = new Command("status");
Expand All @@ -15,7 +15,7 @@ async function statusAction(options: OptionValues) {
const { api } = await newApi(options.url);

// Check options
const address = parseAddresOrExit(
const address = parseAddressOrExit(
requiredInput(
options.address,
"Failed to show validator status: Must specify an address"
Expand Down
8 changes: 4 additions & 4 deletions scripts/cc-cli/src/commands/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { StakingPalletValidatorPrefs, validate } from "../utils/validate";
import {
inputOrDefault,
parseBoolean,
parsePercentAsPerbill,
parsePercentAsPerbillOrExit,
} from "../utils/parsing";

export function makeValidateCommand() {
Expand All @@ -26,13 +26,13 @@ export function makeValidateCommand() {
async function validateAction(options: OptionValues) {
const { api } = await newApi(options.url);

const controllerSeed = await getControllerSeedFromEnvOrPrompt();

// Default commission is 0%
const commission = parsePercentAsPerbill(
const commission = parsePercentAsPerbillOrExit(
inputOrDefault(options.commission, "0")
);

const controllerSeed = await getControllerSeedFromEnvOrPrompt();

const blocked = parseBoolean(options.blocked);

const preferences: StakingPalletValidatorPrefs = { commission, blocked };
Expand Down
8 changes: 4 additions & 4 deletions scripts/cc-cli/src/commands/wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import {
inputOrDefault,
parseAmountOrExit,
parseBoolean,
parseChoice,
parsePercentAsPerbill,
parseChoiceOrExit,
parsePercentAsPerbillOrExit,
requiredInput,
} from "../utils/parsing";

Expand Down Expand Up @@ -235,14 +235,14 @@ function parseOptions(options: OptionValues) {
}

const rewardDestination = checkRewardDestination(
parseChoice(inputOrDefault(options.rewardDestination, "Staked"), [
parseChoiceOrExit(inputOrDefault(options.rewardDestination, "Staked"), [
"Staked",
"Stash",
"Controller",
])
);

const commission = parsePercentAsPerbill(
pLabarta marked this conversation as resolved.
Show resolved Hide resolved
const commission = parsePercentAsPerbillOrExit(
inputOrDefault(options.commission, "0")
);

Expand Down
68 changes: 34 additions & 34 deletions scripts/cc-cli/src/test/parsing.test.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,62 @@
import {
parseAddress,
parseAmount,
parseAddressInternal,
parseAmountInternal,
parseBoolean,
parseChoice,
parseHexString,
parseInteger,
parsePercentAsPerbill,
parseChoiceInternal,
parseHexStringInternal,
parseIntegerInternal,
parsePercentAsPerbillInternal,
} from "../utils/parsing";

describe("parseAddress", () => {
test("with valid argument returns the same address", () => {
const substrateAddress = "5EACfEfYjfg5ZHpzp9uoMCR68UNGBUAu5AYjvZdM5aLYaojx";
const parsedAddress = parseAddress(substrateAddress);
const parsedAddress = parseAddressInternal(substrateAddress);
expect(parsedAddress).toBe(substrateAddress);
});

test("with invalid argument throws an error", () => {
// address is too short
const substrateAddress = "5EACfEfYjfg5ZHpzp9uoMCZdM5aLYaojx";
const parsedInvalid = () => parseAddress(substrateAddress);
const parsedInvalid = () => parseAddressInternal(substrateAddress);
expect(parsedInvalid).toThrowError(Error);
});
});

describe("parseAmount", () => {
test("with valid integer argument returns the same amount * 10^^18", () => {
const amount = "1";
const parsedAmount = parseAmount(amount);
const parsedAmount = parseAmountInternal(amount);
expect(parsedAmount.toString()).toBe("1000000000000000000");
});

test("with valid float argument returns the same amount * 10^^18", () => {
const amount = "0.4";
const parsedAmount = parseAmount(amount);
const parsedAmount = parseAmountInternal(amount);
expect(parsedAmount.toString()).toBe("400000000000000000");
});

test("with negative argument throws an error", () => {
const amount = "-1";
const parsedInvalid = () => parseAmount(amount);
const parsedInvalid = () => parseAmountInternal(amount);
expect(parsedInvalid).toThrowError(Error);
});

test("with argument containing decimal comma throws an error", () => {
const amount = "100,1";
const parsedInvalid = () => parseAmount(amount);
const parsedInvalid = () => parseAmountInternal(amount);
expect(parsedInvalid).toThrowError(Error);
});

test("with 0 as argument throws an error", () => {
const amount = "0";
const parsedInvalid = () => parseAmount(amount);
const parsedInvalid = () => parseAmountInternal(amount);
expect(parsedInvalid).toThrowError(Error);
});

test("with string argument throws an error", () => {
const amount = "abcdef";
const parsedInvalid = () => parseAmount(amount);
const parsedInvalid = () => parseAmountInternal(amount);
expect(parsedInvalid).toThrowError(Error);
});
});
Expand All @@ -65,21 +65,21 @@ describe("parseChoice", () => {
test("with valid argument returns the same choice", () => {
const choice = "Staked";
const choices = ["Staked", "Stash", "Controller"];
const parsedChoice = parseChoice(choice, choices);
const parsedChoice = parseChoiceInternal(choice, choices);
expect(parsedChoice).toBe(choice);
});

test("with valid mixed case argument returns choice in canonical format", () => {
const choice = "stAKed";
const choices = ["Staked", "Stash", "Controller"];
const parsedChoice = parseChoice(choice, choices);
const parsedChoice = parseChoiceInternal(choice, choices);
expect(parsedChoice).toBe("Staked");
});

test("with invalid argument throws an error", () => {
const choice = "Bonded";
const choices = ["Staked", "Stash", "Controller"];
const parsedInvalid = () => parseChoice(choice, choices);
const parsedInvalid = () => parseChoiceInternal(choice, choices);
expect(parsedInvalid).toThrowError(Error);
});
});
Expand All @@ -100,97 +100,97 @@ describe("parseBoolean", () => {

describe("parseInteger", () => {
test("with valid argument, 0, returns the same integer", () => {
const parsedInteger = parseInteger("0");
const parsedInteger = parseIntegerInternal("0");
expect(parsedInteger).toBe(0);
});

test("with valid argument, > 0, returns the same integer", () => {
const parsedInteger = parseInteger("1");
const parsedInteger = parseIntegerInternal("1");
expect(parsedInteger).toBe(1);
});

test("with valid argument, < 0, returns the same integer", () => {
const parsedInteger = parseInteger("-1");
const parsedInteger = parseIntegerInternal("-1");
expect(parsedInteger).toBe(-1);
});

test("with float argument throws an error", () => {
const parsedInvalid = () => parseInteger("0.1");
const parsedInvalid = () => parseIntegerInternal("0.1");
expect(parsedInvalid).toThrowError(Error);
});

test("with string argument throws an error", () => {
const integer = "abcdef";
const parsedInvalid = () => parseInteger(integer);
const parsedInvalid = () => parseIntegerInternal(integer);
expect(parsedInvalid).toThrowError(Error);
});
});

describe("parseHexString", () => {
test("with valid argument, lower case, returns the same hex string", () => {
const hexString = "0x1234567890abcdef";
const parsedHexString = parseHexString(hexString);
const parsedHexString = parseHexStringInternal(hexString);
expect(parsedHexString).toBe(hexString);
});

test("with valid argument, mixed case, returns the same hex string", () => {
const hexString = "0x1234567890AbCdeF";
const parsedHexString = parseHexString(hexString);
const parsedHexString = parseHexStringInternal(hexString);
expect(parsedHexString).toBe(hexString);
});

test("with invalid argument, missing 0x prefix, throws an error", () => {
const hexString = "1234567890abcdef";
const parsedInvalid = () => parseHexString(hexString);
const parsedInvalid = () => parseHexStringInternal(hexString);
expect(parsedInvalid).toThrowError(Error);
});

test("with invalid argument, contains invalid hex digits, throws an error", () => {
const parsedInvalid = () => parseHexString("0x123x==xZZZ");
const parsedInvalid = () => parseHexStringInternal("0x123x==xZZZ");
expect(parsedInvalid).toThrowError(Error);
});
});

describe("parsePercentAsPerbill", () => {
test("with valid argument, lower boundary, returns correct perbill", () => {
const parsedPerbill = parsePercentAsPerbill("0");
const parsedPerbill = parsePercentAsPerbillInternal("0");
expect(parsedPerbill).toBe(0);
});

test("with valid argument, upper boundary, returns correct perbill", () => {
const parsedPerbill = parsePercentAsPerbill("100");
const parsedPerbill = parsePercentAsPerbillInternal("100");
expect(parsedPerbill).toBe(1_000_000_000);
});

test("with valid argument, float value inside boundaries, returns correct perbill", () => {
const parsedPerbill = parsePercentAsPerbill("50.5");
const parsedPerbill = parsePercentAsPerbillInternal("50.5");
expect(parsedPerbill).toBe(505_000_000);
});

test("with invalid argument, float < lower boundary, throws an error", () => {
const parsedInvalid = () => parsePercentAsPerbill("-0.1");
const parsedInvalid = () => parsePercentAsPerbillInternal("-0.1");
expect(parsedInvalid).toThrowError(Error);
});

test("with invalid argument, int < lower boundary, throws an error", () => {
const parsedInvalid = () => parsePercentAsPerbill("-1");
const parsedInvalid = () => parsePercentAsPerbillInternal("-1");
expect(parsedInvalid).toThrowError(Error);
});

test("with invalid argument, float > upper boundary, throws an error", () => {
const perbill = "100.1";
const parsedInvalid = () => parsePercentAsPerbill(perbill);
const parsedInvalid = () => parsePercentAsPerbillInternal(perbill);
expect(parsedInvalid).toThrowError(Error);
});

test("with invalid argument, int > upper boundary, throws an error", () => {
const parsedInvalid = () => parsePercentAsPerbill("101");
const parsedInvalid = () => parsePercentAsPerbillInternal("101");
expect(parsedInvalid).toThrowError(Error);
});

test("with invalid argument, a string, throws an error", () => {
const perbill = "abcdef";
const parsedInvalid = () => parsePercentAsPerbill(perbill);
const parsedInvalid = () => parsePercentAsPerbillInternal(perbill);
expect(parsedInvalid).toThrowError(Error);
});
});
Loading
Loading