diff --git a/packages/page-parachains/src/Overview/Parachains.tsx b/packages/page-parachains/src/Overview/Parachains.tsx index 59a3b2e310..45021d75ea 100644 --- a/packages/page-parachains/src/Overview/Parachains.tsx +++ b/packages/page-parachains/src/Overview/Parachains.tsx @@ -3,7 +3,7 @@ import type { ApiPromise } from '@polkadot/api'; import type { SignedBlockExtended } from '@polkadot/api-derive/types'; -import type { AccountId, CandidateReceipt, Event, ParaId, ParaValidatorIndex } from '@polkadot/types/interfaces'; +import type { AccountId, CandidateReceipt, CoreAssignment, Event, ParaId, ParaValidatorIndex } from '@polkadot/types/interfaces'; import type { IEvent } from '@polkadot/types/types'; import type { LeasePeriod, QueuedAction, ScheduledProposals } from '../types'; import type { EventMapInfo, ValidatorInfo } from './types'; @@ -33,12 +33,12 @@ interface LastEvents { lastTimeout: EventMap; } -type MultiResult = [AccountId[] | null, ParaValidatorIndex[][] | null, ParaValidatorIndex[] | null]; +type MultiResult = [AccountId[] | null, CoreAssignment[] | null, ParaValidatorIndex[][] | null, ParaValidatorIndex[] | null]; const EMPTY_EVENTS: LastEvents = { lastBacked: {}, lastIncluded: {}, lastTimeout: {} }; const optionsMulti = { - defaultValue: [null, null, null] as MultiResult + defaultValue: [null, null, null, null] as MultiResult }; function includeEntry (map: EventMap, event: Event, blockHash: string, blockNumber: BN): void { @@ -61,20 +61,28 @@ function extractScheduledIds (scheduled: ScheduledProposals[] = []): Record { - return activeIndices && validators && validatorGroups && ids && (ids.length <= validatorGroups.length) - ? ids.reduce((all: Record, id, index) => ({ - ...all, - [id.toString()]: validatorGroups[index] - .map((indexActive) => [indexActive, activeIndices[indexActive.toNumber()]]) - .filter(([, a]) => a) - .map(([indexActive, indexValidator]) => ({ - indexActive, - indexValidator, - validatorId: validators[indexValidator.toNumber()] - })) - }), {}) - : {}; +function mapValidators (startWith: Record, ids: ParaId[] | undefined, validators: AccountId[] | null, validatorGroups: ParaValidatorIndex[][] | null, activeIndices: ParaValidatorIndex[] | null, assignments: CoreAssignment[] | null): Record { + return assignments && activeIndices && validators && validatorGroups && ids + ? ids.reduce((all: Record, id) => { + const assignment = assignments.find(({ paraId }) => paraId.eq(id)); + + if (!assignment) { + return all; + } + + return { + ...all, + [id.toString()]: validatorGroups[assignment.groupIdx.toNumber()] + .map((indexActive) => [indexActive, activeIndices[indexActive.toNumber()]]) + .filter(([, a]) => a) + .map(([indexActive, indexValidator]) => ({ + indexActive, + indexValidator, + validatorId: validators[indexValidator.toNumber()] + })) + }; + }, { ...startWith }) + : startWith; } function extractEvents (api: ApiPromise, lastBlock: SignedBlockExtended, prev: LastEvents): LastEvents { @@ -147,13 +155,15 @@ function Parachains ({ actionsQueue, ids, leasePeriod, scheduled }: Props): Reac const bestNumber = useBestNumber(); const lastBlock = useCall(api.derive.chain.subscribeNewBlocks); const [{ lastBacked, lastIncluded, lastTimeout }, setLastEvents] = useState(EMPTY_EVENTS); - const [validators, validatorGroups, activeIndices] = useCallMulti([ + const [validators, assignments, validatorGroups, validatorIndices] = useCallMulti([ api.query.session.validators, + (api.query.parasScheduler || api.query.paraScheduler || api.query.scheduler)?.scheduled, (api.query.parasScheduler || api.query.paraScheduler || api.query.scheduler)?.validatorGroups, (api.query.parasShared || api.query.shared)?.activeValidatorIndices ], optionsMulti); const hrmp = useHrmp(); const hasLinksMap = useIsParasLinked(ids); + const [validatorMap, setValidatorMap] = useState>({}); const headerRef = useRef([ [t('parachains'), 'start', 2], @@ -174,11 +184,6 @@ function Parachains ({ actionsQueue, ids, leasePeriod, scheduled }: Props): Reac [scheduled] ); - const validatorMap = useMemo( - () => mapValidators(ids, validators, validatorGroups, activeIndices), - [activeIndices, ids, validators, validatorGroups] - ); - const knownIds = useMemo( () => extractIds(hasLinksMap, ids), [ids, hasLinksMap] @@ -195,6 +200,12 @@ function Parachains ({ actionsQueue, ids, leasePeriod, scheduled }: Props): Reac ); }, [api, lastBlock]); + useEffect((): void => { + setValidatorMap((prev) => + mapValidators(prev, ids, validators, validatorGroups, validatorIndices, assignments) + ); + }, [assignments, ids, validators, validatorGroups, validatorIndices]); + return ( ('There are no registered parachains')}