From 123d90aa016d3abe884f212dcabf6dab325d8fce Mon Sep 17 00:00:00 2001 From: Marcin Date: Thu, 13 Feb 2025 13:49:38 +0100 Subject: [PATCH 1/2] Fix for suspensions started in era >= 1000 (#142) Fix for azero.dev bug, which occurs for eras >= 1000. Is caused by invalid to number cast. `toHuman` casts numbers with more than 4 digits using comma thousands separator, e.g. `1008` era is cast as `1,008`, which then `toNumber` was not able to handle. It was clear that suspensions was not correctly parsed, ie without explicit types. Now it should be better. See backend structs: https://github.com/Cardinal-Cryptography/aleph-node/blob/release-14/primitives/src/lib.rs#L246-L262 This change is dedicated for Mainnet and Testnet release, so it is based on `release-11` branch. --- package.json | 4 +-- .../src/Suspensions/Suspensions.tsx | 30 ++++++++++++------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 75d306791add..e61ff24262ef 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,7 @@ "@polkadot/api-augment": "^13.2.1", "@polkadot/api-base": "^13.2.1", "@polkadot/api-contract": "^13.2.1", + "@polkadot/api-derive@npm:13.2.1": "patch:@polkadot/api-derive@npm%3A13.2.1#~/.yarn/patches/@polkadot-api-derive-npm-13.2.1-19d2cc1087.patch", "@polkadot/hw-ledger": "^13.1.1", "@polkadot/keyring": "^13.1.1", "@polkadot/networks": "^13.1.1", @@ -123,7 +124,6 @@ "@polkadot/x-textdecoder": "^13.1.1", "@polkadot/x-textencoder": "^13.1.1", "@polkadot/x-ws": "^13.1.1", - "typescript": "^5.3.3", - "@polkadot/api-derive@npm:13.2.1": "patch:@polkadot/api-derive@npm%3A13.2.1#~/.yarn/patches/@polkadot-api-derive-npm-13.2.1-19d2cc1087.patch" + "typescript": "^5.3.3" } } diff --git a/packages/page-staking/src/Suspensions/Suspensions.tsx b/packages/page-staking/src/Suspensions/Suspensions.tsx index 51ec685e222d..2bfefdbe29cc 100644 --- a/packages/page-staking/src/Suspensions/Suspensions.tsx +++ b/packages/page-staking/src/Suspensions/Suspensions.tsx @@ -1,7 +1,7 @@ // Copyright 2017-2025 @polkadot/app-staking authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { u64, Vec } from '@polkadot/types'; +import type { u8, u64, Vec } from '@polkadot/types'; import type { EventRecord, Hash } from '@polkadot/types/interfaces'; import type { Codec } from '@polkadot/types/types'; import type { u32 } from '@polkadot/types-codec'; @@ -16,6 +16,16 @@ import useErasStartSessionIndexLookup from '../Performance/useErasStartSessionIn type SuspensionReasons = [string, string, number][]; +interface BanReason { + insufficientUptime?: u32, + otherReason?: Vec, +} + +interface BanInfo { + reason: BanReason, + start: u32, +} + function parseEvents (events: EventRecord[]): SuspensionReasons { return events.filter(({ event }) => COMMITTEE_MANAGEMENT_NAMES.includes(event.section) && event.method === 'BanValidators') .map(({ event }) => { @@ -23,19 +33,17 @@ function parseEvents (events: EventRecord[]): SuspensionReasons { const reasons: SuspensionReasons = raw.map((value) => { const account = value[0].toString(); - const reasonAndEra = value[1].toHuman() as unknown as Record; + const banInfo = value[1].toJSON() as unknown as BanInfo; - const reasonTypeAndValue = reasonAndEra.reason as unknown as Record; - const reasonType = Object.keys(reasonTypeAndValue)[0]; - const reasonValue = Object.values(reasonTypeAndValue)[0]; - const era = Number(reasonAndEra.start.toString()); + const reason = banInfo.reason; + const era = Number(banInfo.start.toString()); - if (reasonType === 'OtherReason') { - return [account, reasonValue, era]; - } else if (reasonType === 'InsufficientUptime') { - return [account, 'Insufficient uptime in at least ' + reasonValue + ' sessions', era]; + if (reason.otherReason !== undefined) { + return [account, reason.otherReason.toString(), era]; + } else if (reason.insufficientUptime !== undefined) { + return [account, 'Insufficient uptime in at least ' + reason.insufficientUptime.toString() + ' sessions', era]; } else { - return [account, reasonType + ': ' + reasonValue, era]; + return [account, 'Unknown ban reason', era]; } }); From ecf57115a20cc1e716e9e5c96a3aa33bde1fac11 Mon Sep 17 00:00:00 2001 From: Marcin Date: Mon, 17 Feb 2025 12:28:30 +0100 Subject: [PATCH 2/2] linter --- packages/page-staking/src/Suspensions/Suspensions.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/page-staking/src/Suspensions/Suspensions.tsx b/packages/page-staking/src/Suspensions/Suspensions.tsx index 208d16d4555c..e7e3bf048ebf 100644 --- a/packages/page-staking/src/Suspensions/Suspensions.tsx +++ b/packages/page-staking/src/Suspensions/Suspensions.tsx @@ -1,7 +1,7 @@ // Copyright 2017-2025 @polkadot/app-staking authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type {u8, u16, Vec, u32} from '@polkadot/types'; +import type { u8, u16, u32, Vec } from '@polkadot/types'; import type { EraIndex, EventRecord, Hash, SessionIndex } from '@polkadot/types/interfaces'; import type { Perbill } from '@polkadot/types/interfaces/runtime'; import type { Codec } from '@polkadot/types/types'; @@ -56,7 +56,7 @@ function parseEvents (events: EventRecord[], productionBanConfigPeriod: number, address, era, suspensionLiftsInEra: era + productionBanConfigPeriod, - suspensionReason: reason.otherReason.toString(), + suspensionReason: reason.otherReason.toString() }; } else if (reason.insufficientProduction !== undefined) { return { @@ -70,7 +70,7 @@ function parseEvents (events: EventRecord[], productionBanConfigPeriod: number, address, era, suspensionLiftsInEra: era + finalizationBanConfigPeriod, - suspensionReason: `Insufficient finalization in at least ${reason.insufficientFinalization.toString} sessions` + suspensionReason: `Insufficient finalization in at least ${reason.insufficientFinalization.toString()} sessions` }; } else { return {