From 0c83117683a4acce4d29229d7bb5ef40f76c5969 Mon Sep 17 00:00:00 2001 From: Pablo Labarta Date: Tue, 20 Jun 2023 17:53:07 -0300 Subject: [PATCH 1/6] add: canWithdraw to status --- scripts/cc-cli/src/utils/status.ts | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/scripts/cc-cli/src/utils/status.ts b/scripts/cc-cli/src/utils/status.ts index 080c88a9fa..6a5119842f 100644 --- a/scripts/cc-cli/src/utils/status.ts +++ b/scripts/cc-cli/src/utils/status.ts @@ -32,7 +32,7 @@ export async function getStatus(address: string, api: ApiPromise) { : undefined; const unlockingRes = res.stakingLedger.unlocking; - const currentEra = await api.query.staking.currentEra(); + const currentEra = (await api.query.staking.currentEra()).unwrap(); const unlocking = unlockingRes ? unlockingRes.filter((u: any) => u.era > currentEra) : []; @@ -41,6 +41,18 @@ export async function getStatus(address: string, api: ApiPromise) { ? readAmountFromHex(res.redeemable.toString()) : new BN(0); + const readyForWithdraw = res.stakingLedger.unlocking + .map((u: any) => { + const chunk: UnlockChunk = { + era: u.era.toNumber(), + value: u.value.toBn(), + }; + return chunk; + }) + .filter((u: UnlockChunk) => u.era < currentEra.toNumber()); + + const canWithdraw = readyForWithdraw.length > 0; + const nextUnbondingDate = unlocking.length > 0 ? unlocking[0].era.toNumber() : null; @@ -71,6 +83,8 @@ export async function getStatus(address: string, api: ApiPromise) { validating: validatorEntries.includes(address), waiting: waitingValidators.includes(address), active: activeValidators.includes(address), + canWithdraw, + readyForWithdraw, nextUnbondingDate, nextUnbondingAmount: nextUnbondingAmount ? nextUnbondingAmount : new BN(0), redeemable, @@ -87,6 +101,11 @@ export async function printValidatorStatus(status: Status, api: ApiPromise) { console.log("Waiting: ", status.waiting); console.log("Active: ", status.active); + console.log("Can withdraw: ", status.canWithdraw); + if (status.canWithdraw) { + console.log("Unlocking chunks: ", status.readyForWithdraw); + } + let nextUnlocking = "None"; if (status.nextUnbondingAmount && status.nextUnbondingAmount.eq(new BN(0))) { nextUnlocking = "None"; @@ -116,11 +135,18 @@ export interface Status { validating: boolean; waiting: boolean; active: boolean; + canWithdraw: boolean; + readyForWithdraw: UnlockChunk[]; nextUnbondingDate: Option; nextUnbondingAmount: Option; redeemable: Balance; } +interface UnlockChunk { + era: EraNumber; + value: Balance; +} + type Balance = BN; type EraNumber = number; From 69b7ca1976c09e1003a4671f0795e15225f18bb5 Mon Sep 17 00:00:00 2001 From: Pablo Labarta Date: Tue, 20 Jun 2023 18:54:40 -0300 Subject: [PATCH 2/6] add: reformat how unlocked chunks are printed --- scripts/cc-cli/src/utils/status.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/cc-cli/src/utils/status.ts b/scripts/cc-cli/src/utils/status.ts index 6a5119842f..2becebfb93 100644 --- a/scripts/cc-cli/src/utils/status.ts +++ b/scripts/cc-cli/src/utils/status.ts @@ -103,7 +103,12 @@ export async function printValidatorStatus(status: Status, api: ApiPromise) { console.log("Can withdraw: ", status.canWithdraw); if (status.canWithdraw) { - console.log("Unlocking chunks: ", status.readyForWithdraw); + console.log("Unlocked chunks: "); + status.readyForWithdraw.forEach((chunk) => { + console.log( + ` ${toCTCString(chunk.value)} unlocked since era ${chunk.era}` + ); + }); } let nextUnlocking = "None"; From 7856a1ec7054ca66dc8473b2cc52ee09d58fd542 Mon Sep 17 00:00:00 2001 From: Pablo Labarta Date: Tue, 20 Jun 2023 19:03:46 -0300 Subject: [PATCH 3/6] add: withdraw command checks unlocked funds --- scripts/cc-cli/src/commands/withdrawUnbonded.ts | 9 +++++++++ scripts/cc-cli/src/utils/status.ts | 10 ++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/cc-cli/src/commands/withdrawUnbonded.ts b/scripts/cc-cli/src/commands/withdrawUnbonded.ts index e7969e23fd..8533b15d28 100644 --- a/scripts/cc-cli/src/commands/withdrawUnbonded.ts +++ b/scripts/cc-cli/src/commands/withdrawUnbonded.ts @@ -1,5 +1,6 @@ import { Command, OptionValues } from "commander"; import { newApi } from "../api"; +import { getStatus, requireStatus } from "../utils/status"; import { getControllerSeedFromEnvOrPrompt, initKeyringPair, @@ -18,6 +19,14 @@ async function withdrawUnbondedAction(options: OptionValues) { const controllerSeed = await getControllerSeedFromEnvOrPrompt(); const controller = initKeyringPair(controllerSeed); + + let status = await getStatus(controller.address, api); + requireStatus( + status, + "canWithdraw", + "Cannot perform action, there are no unlocked funds to withdraw" + ); + const slashingSpans = await api.query.staking.slashingSpans( controller.address ); diff --git a/scripts/cc-cli/src/utils/status.ts b/scripts/cc-cli/src/utils/status.ts index 2becebfb93..c403445a69 100644 --- a/scripts/cc-cli/src/utils/status.ts +++ b/scripts/cc-cli/src/utils/status.ts @@ -124,10 +124,16 @@ export async function printValidatorStatus(status: Status, api: ApiPromise) { console.log(`Next unbonding chunk: ${nextUnlocking}`); } -export function requireStatus(status: Status, condition: keyof Status) { +export function requireStatus( + status: Status, + condition: keyof Status, + message?: string +) { if (!status[condition]) { console.error( - `Cannot perform action, validator is not ${condition.toString()}` + message + ? message + : `Cannot perform action, validator is not ${condition.toString()}` ); process.exit(1); } From e0a8672527ae19d614ff8ca362f781c959b9a56a Mon Sep 17 00:00:00 2001 From: Ada Anderson Date: Thu, 22 Jun 2023 10:44:17 -0400 Subject: [PATCH 4/6] Appease the linter --- scripts/cc-cli/src/commands/withdrawUnbonded.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cc-cli/src/commands/withdrawUnbonded.ts b/scripts/cc-cli/src/commands/withdrawUnbonded.ts index 8533b15d28..50b38a13c0 100644 --- a/scripts/cc-cli/src/commands/withdrawUnbonded.ts +++ b/scripts/cc-cli/src/commands/withdrawUnbonded.ts @@ -20,7 +20,7 @@ async function withdrawUnbondedAction(options: OptionValues) { const controllerSeed = await getControllerSeedFromEnvOrPrompt(); const controller = initKeyringPair(controllerSeed); - let status = await getStatus(controller.address, api); + const status = await getStatus(controller.address, api); requireStatus( status, "canWithdraw", From 7bb478a574171af16a9b98fb74d6f1618e9b5d2b Mon Sep 17 00:00:00 2001 From: Nathan Whitaker Date: Thu, 22 Jun 2023 11:35:32 -0700 Subject: [PATCH 5/6] Check stash status in withdrawUnbondedAction --- scripts/cc-cli/src/commands/withdrawUnbonded.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/cc-cli/src/commands/withdrawUnbonded.ts b/scripts/cc-cli/src/commands/withdrawUnbonded.ts index 50b38a13c0..ba78b266d4 100644 --- a/scripts/cc-cli/src/commands/withdrawUnbonded.ts +++ b/scripts/cc-cli/src/commands/withdrawUnbonded.ts @@ -9,7 +9,6 @@ import { export function makeWithdrawUnbondedCommand() { const cmd = new Command("withdraw-unbonded"); cmd.description("Withdraw unbonded funds from a stash account"); - cmd.option("-a, --amount [amount]", "Amount to withdraw"); cmd.action(withdrawUnbondedAction); return cmd; } @@ -20,7 +19,14 @@ async function withdrawUnbondedAction(options: OptionValues) { const controllerSeed = await getControllerSeedFromEnvOrPrompt(); const controller = initKeyringPair(controllerSeed); - const status = await getStatus(controller.address, api); + const controllerStatus = await getStatus(controller.address, api); + + if (!controllerStatus.stash) { + console.error(`Cannot withdraw, ${controller.address} is not staked`); + process.exit(1); + } + + const status = await getStatus(controllerStatus.stash, api); requireStatus( status, "canWithdraw", From f6bfe0ff77c13188085998b8d0253dfe5504d452 Mon Sep 17 00:00:00 2001 From: Ada Anderson Date: Thu, 22 Jun 2023 16:06:14 -0400 Subject: [PATCH 6/6] More detailed error message --- scripts/cc-cli/src/commands/withdrawUnbonded.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/cc-cli/src/commands/withdrawUnbonded.ts b/scripts/cc-cli/src/commands/withdrawUnbonded.ts index ba78b266d4..a1b72a624c 100644 --- a/scripts/cc-cli/src/commands/withdrawUnbonded.ts +++ b/scripts/cc-cli/src/commands/withdrawUnbonded.ts @@ -22,7 +22,9 @@ async function withdrawUnbondedAction(options: OptionValues) { const controllerStatus = await getStatus(controller.address, api); if (!controllerStatus.stash) { - console.error(`Cannot withdraw, ${controller.address} is not staked`); + console.error( + `Could not find stash account associated with the provided controller address: ${controller.address}. Please ensure the address is actually a controller.` + ); process.exit(1); }