Extend block latency display (#7100)
* Add events & extrinsics to block latency * Adjust * Expand
This commit is contained in:
parent
f7bb4f4a18
commit
f9fa2d3b19
@ -23,27 +23,33 @@ interface ChartContents {
|
||||
|
||||
interface ChartInfo {
|
||||
blockLast: number;
|
||||
blocks: ChartContents;
|
||||
events: ChartContents;
|
||||
extrinsics: ChartContents;
|
||||
times: ChartContents;
|
||||
}
|
||||
|
||||
const COLORS_TIMES = ['#8c2200', '#acacac'];
|
||||
// const COLORS_EVENTS = ['#008c22', '#acacac'];
|
||||
// const COLORS_TXS = ['#00228c', '#acacac'];
|
||||
const COLORS_TIMES = ['#8c8c00', '#acacac'];
|
||||
const COLORS_BLOCKS = ['#008c8c', '#acacac'];
|
||||
const COLORS_EVENTS = ['#00448c', '#8c0044', '#acacac'];
|
||||
const COLORS_TXS = ['#448c00', '#acacac'];
|
||||
const OPTIONS = {
|
||||
animation: {
|
||||
duration: 0
|
||||
},
|
||||
aspectRatio: 5,
|
||||
aspectRatio: 6,
|
||||
maintainAspectRatio: true
|
||||
};
|
||||
|
||||
function getPoints (details: Detail[], timeAvg: number): ChartInfo {
|
||||
const events: ChartContents = {
|
||||
const blocks: ChartContents = {
|
||||
labels: [],
|
||||
values: [[], []]
|
||||
};
|
||||
const events: ChartContents = {
|
||||
labels: [],
|
||||
values: [[], [], []]
|
||||
};
|
||||
const extrinsics: ChartContents = {
|
||||
labels: [],
|
||||
values: [[], []]
|
||||
@ -53,30 +59,39 @@ function getPoints (details: Detail[], timeAvg: number): ChartInfo {
|
||||
values: [[], []]
|
||||
};
|
||||
|
||||
const eventAvg = details.reduce((a, { countEvents }) => a + countEvents, 0);
|
||||
const txAvg = details.reduce((a, { countExtrinsics }) => a + countExtrinsics, 0);
|
||||
const eventTotal = details.reduce((a, { events: { count } }) => a + count, 0);
|
||||
const txTotal = details.reduce((a, { extrinsics: { count } }) => a + count, 0);
|
||||
const blockTotal = details.reduce((a, { block: { bytes } }) => a + bytes, 0);
|
||||
|
||||
for (let i = 0; i < details.length; i++) {
|
||||
events.labels.push(formatNumber(details[i].blockNumber));
|
||||
events.values[0].push(details[i].countEvents);
|
||||
events.values[1].push((eventAvg - details[i].countEvents) / (details.length - 1));
|
||||
const blockNumber = formatNumber(details[i].block.number);
|
||||
|
||||
extrinsics.labels.push(formatNumber(details[i].blockNumber));
|
||||
extrinsics.values[0].push(details[i].countExtrinsics);
|
||||
extrinsics.values[1].push((txAvg - details[i].countExtrinsics) / (details.length - 1));
|
||||
blocks.labels.push(blockNumber);
|
||||
blocks.values[0].push(details[i].block.bytes);
|
||||
blocks.values[1].push((blockTotal - details[i].block.bytes) / (details.length - 1));
|
||||
|
||||
events.labels.push(blockNumber);
|
||||
events.values[0].push(details[i].events.count);
|
||||
events.values[1].push(details[i].events.system);
|
||||
events.values[2].push((eventTotal - details[i].events.count) / (details.length - 1));
|
||||
|
||||
extrinsics.labels.push(blockNumber);
|
||||
extrinsics.values[0].push(details[i].extrinsics.count);
|
||||
extrinsics.values[1].push((txTotal - details[i].extrinsics.count) / (details.length - 1));
|
||||
}
|
||||
|
||||
const filtered = details.filter(({ delay }) => delay);
|
||||
const avgBase = timeAvg * filtered.length;
|
||||
|
||||
for (let i = 0; i < filtered.length; i++) {
|
||||
times.labels.push(formatNumber(filtered[i].blockNumber));
|
||||
times.labels.push(formatNumber(filtered[i].block.number));
|
||||
times.values[0].push(filtered[i].delay / 1000);
|
||||
times.values[1].push((avgBase - filtered[i].delay) / (filtered.length - 1) / 1000);
|
||||
}
|
||||
|
||||
return {
|
||||
blockLast: times.values[0][times.values[0].length - 1],
|
||||
blocks,
|
||||
events,
|
||||
extrinsics,
|
||||
times
|
||||
@ -91,14 +106,15 @@ function Latency ({ className }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { details, stdDev, timeAvg, timeMax, timeMin } = useLatency();
|
||||
|
||||
const { blockLast, /* events, extrinsics, */ times } = useMemo(
|
||||
const { blockLast, blocks, events, extrinsics, times } = useMemo(
|
||||
() => getPoints(details, timeAvg),
|
||||
[details, timeAvg]
|
||||
);
|
||||
|
||||
const { /* eventsLegend, extrinsicsLegend, */ timesLegend } = useMemo(
|
||||
const { blocksLegend, eventsLegend, extrinsicsLegend, timesLegend } = useMemo(
|
||||
() => ({
|
||||
eventsLegend: [t<string>('events'), t<string>('average')],
|
||||
blocksLegend: [t<string>('bytes'), t<string>('average')],
|
||||
eventsLegend: [t<string>('events'), t<string>('system'), t<string>('average')],
|
||||
extrinsicsLegend: [t<string>('extrinsics'), t<string>('average')],
|
||||
timesLegend: [t<string>('blocktime'), t<string>('average')]
|
||||
}), [t]
|
||||
@ -138,14 +154,14 @@ function Latency ({ className }: Props): React.ReactElement<Props> | null {
|
||||
values={times.values}
|
||||
/>
|
||||
</div>
|
||||
{/* <div className='container'>
|
||||
<h1>{t<string>('events (last {{num}} blocks)', { replace: { num: events.labels.length } })}</h1>
|
||||
<div className='container'>
|
||||
<h1>{t<string>('blocksize (last {{num}} blocks)', { replace: { num: blocks.labels.length } })}</h1>
|
||||
<Chart.Line
|
||||
colors={COLORS_EVENTS}
|
||||
labels={events.labels}
|
||||
legends={eventsLegend}
|
||||
colors={COLORS_BLOCKS}
|
||||
labels={blocks.labels}
|
||||
legends={blocksLegend}
|
||||
options={OPTIONS}
|
||||
values={events.values}
|
||||
values={blocks.values}
|
||||
/>
|
||||
</div>
|
||||
<div className='container'>
|
||||
@ -157,7 +173,17 @@ function Latency ({ className }: Props): React.ReactElement<Props> | null {
|
||||
options={OPTIONS}
|
||||
values={extrinsics.values}
|
||||
/>
|
||||
</div> */}
|
||||
</div>
|
||||
<div className='container'>
|
||||
<h1>{t<string>('events (last {{num}} blocks)', { replace: { num: events.labels.length } })}</h1>
|
||||
<Chart.Line
|
||||
colors={COLORS_EVENTS}
|
||||
labels={events.labels}
|
||||
legends={eventsLegend}
|
||||
options={OPTIONS}
|
||||
values={events.values}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -4,10 +4,19 @@
|
||||
import type { Hash } from '@polkadot/types/interfaces';
|
||||
|
||||
export interface Detail {
|
||||
blockNumber: number;
|
||||
countEvents: number;
|
||||
countExtrinsics: number;
|
||||
block: {
|
||||
bytes: number;
|
||||
number: number;
|
||||
};
|
||||
delay: number;
|
||||
events: {
|
||||
count: number;
|
||||
system: number;
|
||||
};
|
||||
extrinsics: {
|
||||
bytes: number;
|
||||
count: number;
|
||||
};
|
||||
now: number;
|
||||
parentHash: Hash;
|
||||
}
|
||||
|
||||
@ -30,17 +30,17 @@ function getSetter ({ extrinsics }: Block): GenericExtrinsic | undefined {
|
||||
|
||||
function calcDelay (details: Detail[]): Detail[] {
|
||||
const filtered = details
|
||||
.sort((a, b) => a.blockNumber - b.blockNumber)
|
||||
.filter(({ blockNumber }, index) =>
|
||||
.sort((a, b) => a.block.number - b.block.number)
|
||||
.filter(({ block }, index) =>
|
||||
index === 0 ||
|
||||
blockNumber > details[index - 1].blockNumber
|
||||
block.number > details[index - 1].block.number
|
||||
);
|
||||
|
||||
for (let i = 0; i < filtered.length - 1; i++) {
|
||||
const a = filtered[i];
|
||||
const b = filtered[i + 1];
|
||||
|
||||
if ((b.blockNumber - a.blockNumber) === 1 && b.delay === 0) {
|
||||
if ((b.block.number - a.block.number) === 1 && b.delay === 0) {
|
||||
b.delay = b.now - a.now;
|
||||
}
|
||||
}
|
||||
@ -58,10 +58,19 @@ function addBlock (prev: Detail[], { block, events }: SignedBlockExtended): Deta
|
||||
return [
|
||||
...prev,
|
||||
{
|
||||
blockNumber: block.header.number.toNumber(),
|
||||
countEvents: events.length,
|
||||
countExtrinsics: block.extrinsics.length,
|
||||
block: {
|
||||
bytes: block.encodedLength,
|
||||
number: block.header.number.toNumber()
|
||||
},
|
||||
delay: 0,
|
||||
events: {
|
||||
count: events.length,
|
||||
system: events.filter(({ phase }) => !phase.isApplyExtrinsic).length
|
||||
},
|
||||
extrinsics: {
|
||||
bytes: block.extrinsics.reduce((a, x) => a + x.encodedLength, 0),
|
||||
count: block.extrinsics.length
|
||||
},
|
||||
now: (setter.args[0] as u32).toNumber(),
|
||||
parentHash: block.header.parentHash
|
||||
}
|
||||
@ -95,7 +104,7 @@ async function getPrev (api: ApiPromise, { block: { header } }: SignedBlockExten
|
||||
return getBlocks(api, blockNumbers);
|
||||
}
|
||||
|
||||
async function getNext (api: ApiPromise, { blockNumber: start }: Detail, { blockNumber: end }: Detail): Promise<SignedBlockExtended[]> {
|
||||
async function getNext (api: ApiPromise, { block: { number: start } }: Detail, { block: { number: end } }: Detail): Promise<SignedBlockExtended[]> {
|
||||
const blockNumbers: number[] = [];
|
||||
|
||||
for (let n = start + 1; n < end; n++) {
|
||||
@ -134,9 +143,9 @@ export default function useLatency (): Result {
|
||||
return;
|
||||
}
|
||||
|
||||
const lastIndex = details.findIndex(({ blockNumber }, index) =>
|
||||
const lastIndex = details.findIndex(({ block }, index) =>
|
||||
index !== (details.length - 1) &&
|
||||
(details[index + 1].blockNumber - blockNumber) > 1
|
||||
(details[index + 1].block.number - block.number) > 1
|
||||
);
|
||||
|
||||
if (lastIndex === -1) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user