From bb76c50127992c1fc0369f40cbc0a43e95c1794c Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 31 Mar 2021 15:29:30 +0300 Subject: [PATCH] Hrmp message count (#4990) --- .../src/Overview/Parachain.tsx | 18 ++++++++--- .../src/Overview/Parachains.tsx | 32 +++++++++++++++++-- .../page-parachains/src/Overview/types.ts | 4 ++- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/packages/page-parachains/src/Overview/Parachain.tsx b/packages/page-parachains/src/Overview/Parachain.tsx index 7a1a18a211..9ecddb9268 100644 --- a/packages/page-parachains/src/Overview/Parachain.tsx +++ b/packages/page-parachains/src/Overview/Parachain.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { Option, Vec } from '@polkadot/types'; -import type { AccountId, BlockNumber, CandidatePendingAvailability, HeadData, Header, ParaId, ParaInfo, ParaLifecycle } from '@polkadot/types/interfaces'; +import type { AccountId, BlockNumber, CandidatePendingAvailability, HeadData, Header, HrmpChannel, HrmpChannelId, ParaId, ParaInfo, ParaLifecycle } from '@polkadot/types/interfaces'; import type { Codec } from '@polkadot/types/types'; import type { EventMapInfo, QueuedAction, ValidatorInfo } from './types'; @@ -12,7 +12,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { AddressMini, Expander, ParaLink } from '@polkadot/react-components'; import { useApi, useCall, useCallMulti, useParaApi } from '@polkadot/react-hooks'; import { BlockToTime } from '@polkadot/react-query'; -import { formatNumber } from '@polkadot/util'; +import { BN_ZERO, formatNumber } from '@polkadot/util'; import { useTranslation } from '../translate'; import { sliceHex } from '../util'; @@ -20,6 +20,8 @@ import Lifecycle from './Lifecycle'; interface Props { bestNumber?: BN; + channelDst?: [HrmpChannelId, HrmpChannel][]; + channelSrc?: [HrmpChannelId, HrmpChannel][]; className?: string; id: ParaId; isScheduled?: boolean; @@ -88,7 +90,7 @@ function renderAddresses (list?: AccountId[]): JSX.Element[] | undefined { )); } -function Parachain ({ bestNumber, className = '', id, lastBacked, lastInclusion, lastTimeout, nextAction, sessionValidators, validators }: Props): React.ReactElement { +function Parachain ({ bestNumber, channelDst, channelSrc, className = '', id, lastBacked, lastInclusion, lastTimeout, nextAction, sessionValidators, validators }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); const { api: paraApi } = useParaApi(id); @@ -107,6 +109,14 @@ function Parachain ({ bestNumber, className = '', id, lastBacked, lastInclusion, ], optionsMulti); const [nonBacked, setNonBacked] = useState([]); + const channelCounts = useMemo( + () => [ + channelDst ? channelDst.reduce((count, [, channel]) => count.iadd(channel.msgCount), new BN(0)) : BN_ZERO, + channelSrc ? channelSrc.reduce((count, [, channel]) => count.iadd(channel.msgCount), new BN(0)) : BN_ZERO + ], + [channelDst, channelSrc] + ); + const blockDelay = useMemo( () => bestNumber && ( lastInclusion @@ -198,7 +208,7 @@ function Parachain ({ bestNumber, className = '', id, lastBacked, lastInclusion, )} - {formatNumber(paraInfo.qUmp)} / {formatNumber(paraInfo.qDmp)} / {formatNumber(paraInfo.qHrmpE)} / {formatNumber(paraInfo.qHrmpI)} + {formatNumber(paraInfo.qUmp)} / {formatNumber(paraInfo.qDmp)} / {formatNumber(paraInfo.qHrmpE)} / {formatNumber(paraInfo.qHrmpI)} ({formatNumber(channelCounts[0])} / {formatNumber(channelCounts[1])}) ); diff --git a/packages/page-parachains/src/Overview/Parachains.tsx b/packages/page-parachains/src/Overview/Parachains.tsx index 7de50409da..04c71c80dc 100644 --- a/packages/page-parachains/src/Overview/Parachains.tsx +++ b/packages/page-parachains/src/Overview/Parachains.tsx @@ -3,10 +3,11 @@ 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 { Option, StorageKey } from '@polkadot/types'; +import type { AccountId, CandidateReceipt, Event, HrmpChannel, HrmpChannelId, ParaId, ParaValidatorIndex } from '@polkadot/types/interfaces'; import type { IEvent } from '@polkadot/types/types'; import type { ScheduledProposals } from '../types'; -import type { EventMapInfo, QueuedAction, ValidatorInfo } from './types'; +import type { ChannelMap, EventMapInfo, QueuedAction, ValidatorInfo } from './types'; import BN from 'bn.js'; import React, { useEffect, useMemo, useRef, useState } from 'react'; @@ -114,6 +115,29 @@ function extractEvents (api: ApiPromise, lastBlock: SignedBlockExtended, prev: L : prev; } +const optChannelKeys = { + transform: (keys: StorageKey<[HrmpChannelId]>[]): HrmpChannelId[] => + keys.map(({ args: [id] }) => id) +}; + +const optChannels = { + transform: ([[channelIds], channels]: [[HrmpChannelId[]], Option[]]): [ChannelMap, ChannelMap] => + channelIds + .map((id, index): [HrmpChannelId, Option] => [id, channels[index]]) + .filter(([, opt]) => opt.isSome) + .map(([id, opt]): [HrmpChannelId, HrmpChannel] => [id, opt.unwrap()]) + .reduce(([src, dst]: [ChannelMap, ChannelMap], [id, channel]): [ChannelMap, ChannelMap] => { + dst[id.receiver.toNumber()] ||= []; + src[id.sender.toNumber()] ||= []; + + dst[id.receiver.toNumber()].push([id, channel]); + src[id.sender.toNumber()].push([id, channel]); + + return [src, dst]; + }, [{}, {}]), + withParamsTransform: true +}; + function extractActions (actionsQueue: QueuedAction[], knownIds?: [ParaId, string][]): Record { return actionsQueue && knownIds ? knownIds.reduce((all: Record, [id, key]) => ({ @@ -134,6 +158,8 @@ function Parachains ({ actionsQueue, ids, scheduled }: Props): React.ReactElemen api.query.paraScheduler?.validatorGroups || api.query.scheduler?.validatorGroups, api.query.shared?.activeValidatorIndices ], optionsMulti); + const channelIds = useCall(api.query.hrmp?.hrmpChannels.keys, undefined, optChannelKeys); + const allChannels = useCall<[ChannelMap, ChannelMap]>(channelIds && api.query.hrmp.hrmpChannels.multi, [channelIds], optChannels); const headerRef = useRef([ [t('parachains'), 'start', 2], @@ -183,6 +209,8 @@ function Parachains ({ actionsQueue, ids, scheduled }: Props): React.ReactElemen {knownIds?.map(([id, key], index): React.ReactNode => ( ; export interface LeaseInfo { accountId: AccountId;