Show parachains last backed (#4446)

This commit is contained in:
Jaco Greeff 2021-01-18 16:56:10 +01:00 committed by GitHub
parent 2d87138a6b
commit 54681c57b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 31 deletions

View File

@ -20,7 +20,8 @@ interface Props {
className?: string;
id: ParaId;
isScheduled?: boolean;
lastInclusion?: [string, string];
lastBacked?: [string, string, BN];
lastInclusion?: [string, string, BN];
}
type QueryResult = [Option<HeadData>, Option<BlockNumber>, Vec<Codec>, Vec<Codec>, Vec<Codec>, Vec<Codec>, Option<BlockNumber>];
@ -35,7 +36,7 @@ interface QueryState {
watermark: BlockNumber | null;
}
const transformLast = {
const transformHeader = {
transform: (header: Header) => header.number.unwrap()
};
@ -62,12 +63,12 @@ const optionsMulti = {
})
};
function Parachain ({ bestNumber, className = '', id, isScheduled, lastInclusion }: Props): React.ReactElement<Props> {
function Parachain ({ bestNumber, className = '', id, isScheduled, lastBacked, lastInclusion }: Props): React.ReactElement<Props> {
const { api } = useApi();
const { api: paraApi, endpoints } = useParaApi(id);
const paraBest = useCall<BlockNumber>(paraApi?.derive.chain.bestNumber);
const paraIssu = useCall<Balance>(paraApi?.query.balances?.totalIssuance);
const lastRelayNumber = useCall<BN>(lastInclusion && api.rpc.chain.getHeader, [lastInclusion && lastInclusion[1]], transformLast);
const lastRelayNumber = useCall<BN>(lastInclusion && api.rpc.chain.getHeader, [lastInclusion && lastInclusion[1]], transformHeader);
const paraInfo = useCallMulti<QueryState>([
[api.query.paras.heads, id],
[api.query.paras.futureCodeUpgrades, id],
@ -112,6 +113,11 @@ function Parachain ({ bestNumber, className = '', id, isScheduled, lastInclusion
: paraInfo.watermark && formatNumber(paraInfo.watermark)
}
</td>
<td className='number'>
{lastBacked &&
<a href={`#/explorer/query/${lastBacked[0]}`}>{formatNumber(lastBacked[2])}</a>
}
</td>
<td className='number media--900'>{paraBest && <>{formatNumber(paraBest)}</>}</td>
<td className='number media--1100'>{paraIssu && <FormatBalance valueFormatted={paraIssu.toHuman()} />}</td>
<td className='number media--1300'>

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import type { SignedBlockExtended } from '@polkadot/api-derive/type';
import type { CandidateReceipt, ParaId } from '@polkadot/types/interfaces';
import type { CandidateReceipt, Event, ParaId } from '@polkadot/types/interfaces';
import type { ScheduledProposals } from '../types';
import BN from 'bn.js';
@ -19,48 +19,67 @@ interface Props {
scheduled?: ScheduledProposals[];
}
type EventMap = Record<string, [string, string, BN]>;
interface LastEvents {
lastBacked: EventMap;
lastIncluded: EventMap;
}
function includeEntry (map: EventMap, event: Event, blockHash: string, blockNumber: BN): void {
const { descriptor } = event.data[0] as CandidateReceipt;
map[descriptor.paraId.toString()] = [
blockHash,
descriptor.relayParent.toHex(),
blockNumber
];
}
function ParachainList ({ ids, scheduled }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const bestNumber = useCall<BN>(api.derive.chain.bestNumber);
const lastBlock = useCall<SignedBlockExtended>(api.derive.chain.subscribeNewBlocks);
const [lastIncluded, setLastIncluded] = useState<Record<string, [string, string]>>({});
const [{ lastBacked, lastIncluded }, setLastEvents] = useState<LastEvents>({ lastBacked: {}, lastIncluded: {} });
const scheduledIds = useMemo(
() => scheduled
? scheduled.reduce((all: Record<string, boolean>, { scheduledIds }: ScheduledProposals): Record<string, boolean> => {
return scheduledIds.reduce((all: Record<string, boolean>, id) => ({ ...all, [id.toString()]: true }), all);
}, {})
: {},
() => (scheduled || []).reduce((all: Record<string, boolean>, { scheduledIds }: ScheduledProposals): Record<string, boolean> => {
return scheduledIds.reduce((all: Record<string, boolean>, id) => ({ ...all, [id.toString()]: true }), all);
}, {}),
[scheduled]
);
useEffect((): void => {
lastBlock && setLastIncluded((prev) => {
const updated: Record<string, [string, string]> = {};
lastBlock && setLastEvents((prev) => {
const backed: Record<string, [string, string, BN]> = {};
const included: Record<string, [string, string, BN]> = {};
const blockNumber = lastBlock.block.header.number.unwrap();
const blockHash = lastBlock.block.header.hash.toHex();
let wasUpdated = false;
let wasIncluded = false;
let wasBacked = false;
lastBlock.events.forEach(({ event, phase }) => {
if (phase.isApplyExtrinsic && api.events.inclusion.CandidateBacked.is(event)) {
const { descriptor } = event.data[0] as CandidateReceipt;
updated[descriptor.paraId.toString()] = [
blockHash,
descriptor.relayParent.toHex()
];
wasUpdated = true;
if (phase.isApplyExtrinsic) {
if (api.events.inclusion.CandidateBacked.is(event)) {
includeEntry(backed, event, blockHash, blockNumber);
wasBacked = true;
} else if (api.events.inclusion.CandidateIncluded.is(event)) {
includeEntry(included, event, blockHash, blockNumber);
wasIncluded = true;
}
}
});
return wasUpdated
? Object.entries(prev).reduce((updated: Record<string, [string, string]>, [id, hashes]): Record<string, [string, string]> => {
if (!updated[id]) {
updated[id] = hashes;
}
return updated;
}, updated)
return wasBacked || wasIncluded
? {
lastBacked: wasBacked
? { ...prev.lastBacked, ...backed }
: prev.lastBacked,
lastIncluded: wasIncluded
? { ...prev.lastIncluded, ...included }
: prev.lastIncluded
}
: prev;
});
}, [api, lastBlock]);
@ -68,7 +87,8 @@ function ParachainList ({ ids, scheduled }: Props): React.ReactElement<Props> {
const headerRef = useRef([
[t('parachains'), 'start', 3],
[t('heads'), 'start'],
[t('relay parent'), undefined, 2],
[t('included (parent)'), undefined, 2],
[t('backed')],
[t('chain best'), 'media--900'],
[t('issuance'), 'media--1100'],
[t('upgrade'), 'media--1300'],
@ -86,6 +106,7 @@ function ParachainList ({ ids, scheduled }: Props): React.ReactElement<Props> {
id={id}
isScheduled={scheduledIds[id.toString()]}
key={id.toString()}
lastBacked={lastBacked[id.toString()]}
lastInclusion={lastIncluded[id.toString()]}
/>
))}