fix(proposals): parsing block duration value (#4613)
This commit is contained in:
parent
3422b99491
commit
0fb8ee3abb
@ -1,5 +1,9 @@
|
|||||||
import { renderHook, waitFor } from '@testing-library/react';
|
import { renderHook, waitFor } from '@testing-library/react';
|
||||||
import { useTimeToUpgrade } from './use-time-to-upgrade';
|
import {
|
||||||
|
ERR_NO_TIME_UNITS,
|
||||||
|
parseDuration,
|
||||||
|
useTimeToUpgrade,
|
||||||
|
} from './use-time-to-upgrade';
|
||||||
|
|
||||||
jest.mock('./__generated__/BlockStatistics', () => ({
|
jest.mock('./__generated__/BlockStatistics', () => ({
|
||||||
...jest.requireActual('./__generated__/BlockStatistics'),
|
...jest.requireActual('./__generated__/BlockStatistics'),
|
||||||
@ -8,7 +12,7 @@ jest.mock('./__generated__/BlockStatistics', () => ({
|
|||||||
data: {
|
data: {
|
||||||
statistics: {
|
statistics: {
|
||||||
blockHeight: 1,
|
blockHeight: 1,
|
||||||
blockDuration: 500,
|
blockDuration: '500ms',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -30,3 +34,25 @@ describe('useTimeToUpgrade', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('parseDuration', () => {
|
||||||
|
it.each([
|
||||||
|
['1000000ns', 1],
|
||||||
|
['1000µs', 1],
|
||||||
|
['1ms', 1],
|
||||||
|
['1s', 1000],
|
||||||
|
['1m', 60 * 1000],
|
||||||
|
['1h', 60 * 60 * 1000],
|
||||||
|
// below test cases are from vega
|
||||||
|
['3.3s', 3300],
|
||||||
|
['4m5s', 4 * 60 * 1000 + 5 * 1000],
|
||||||
|
['4m5.001s', 4 * 60 * 1000 + 5001],
|
||||||
|
['5h6m7.001s', 5 * 60 * 60 * 1000 + 6 * 60 * 1000 + 7001],
|
||||||
|
['8m0.000000001s', 8 * 60 * 1000 + 1 / 1000000],
|
||||||
|
])('parses %s to %d milliseconds', (input, output) => {
|
||||||
|
expect(parseDuration(input)).toEqual(output);
|
||||||
|
});
|
||||||
|
it('throws an error when given corrupted data', () => {
|
||||||
|
expect(() => parseDuration('blah')).toThrow(ERR_NO_TIME_UNITS);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -7,6 +7,52 @@ const DEFAULT_POLLS = 10;
|
|||||||
const INTERVAL = 1000;
|
const INTERVAL = 1000;
|
||||||
const durations = [] as number[];
|
const durations = [] as number[];
|
||||||
|
|
||||||
|
export const ERR_NO_TIME_UNITS = new Error(
|
||||||
|
'could not parse block duration value - no time units detected'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses block duration value and output a number of milliseconds.
|
||||||
|
* @param input The block duration input from the API, e.g. 4m5.001s
|
||||||
|
* @returns A number of milliseconds
|
||||||
|
*/
|
||||||
|
export const parseDuration = (input: string) => {
|
||||||
|
// h -> 60*60*1000
|
||||||
|
// m -> 60*1000
|
||||||
|
// s -> 1000
|
||||||
|
// ms -> 1
|
||||||
|
// µs -> 1/1000
|
||||||
|
// ns -> 1/1000000
|
||||||
|
let H = 0;
|
||||||
|
let M = 0;
|
||||||
|
let S = 0;
|
||||||
|
const lessThanSecond = /^[0-9.]+[nµm]*s$/gu.test(input);
|
||||||
|
const exp = /(?<hours>[0-9.]+h)?(?<minutes>[0-9.]+m)?(?<seconds>[0-9.]+s)?/gu;
|
||||||
|
const m = exp.exec(input);
|
||||||
|
|
||||||
|
const hours = m?.groups?.['hours'];
|
||||||
|
const minutes = m?.groups?.['minutes'];
|
||||||
|
const seconds = lessThanSecond ? input : m?.groups?.['seconds'];
|
||||||
|
if (!lessThanSecond && !hours && !minutes && !seconds) {
|
||||||
|
throw ERR_NO_TIME_UNITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seconds) {
|
||||||
|
S = parseFloat(seconds);
|
||||||
|
if (seconds.includes('ns')) S /= 1000 * 1000;
|
||||||
|
else if (seconds.includes('µs')) S /= 1000;
|
||||||
|
else if (seconds.includes('ms')) S *= 1;
|
||||||
|
else if (seconds.includes('s')) S *= 1000;
|
||||||
|
}
|
||||||
|
if (minutes && !lessThanSecond) {
|
||||||
|
M = parseFloat(minutes) * 60 * 1000;
|
||||||
|
}
|
||||||
|
if (hours && !lessThanSecond) {
|
||||||
|
H = parseFloat(hours) * 60 * 60 * 1000;
|
||||||
|
}
|
||||||
|
return H + M + S;
|
||||||
|
};
|
||||||
|
|
||||||
const useAverageBlockDuration = (polls = DEFAULT_POLLS) => {
|
const useAverageBlockDuration = (polls = DEFAULT_POLLS) => {
|
||||||
const [avg, setAvg] = useState<number | undefined>(undefined);
|
const [avg, setAvg] = useState<number | undefined>(undefined);
|
||||||
const { data, startPolling, stopPolling, error } = useBlockStatisticsQuery({
|
const { data, startPolling, stopPolling, error } = useBlockStatisticsQuery({
|
||||||
@ -28,7 +74,11 @@ const useAverageBlockDuration = (polls = DEFAULT_POLLS) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (durations.length < polls && data) {
|
if (durations.length < polls && data) {
|
||||||
durations.push(parseFloat(data.statistics.blockDuration));
|
try {
|
||||||
|
durations.push(parseDuration(data.statistics.blockDuration)); // ms
|
||||||
|
} catch (err) {
|
||||||
|
// NOOP - do not add unparsed value to AVG
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (durations.length === polls) {
|
if (durations.length === polls) {
|
||||||
const averageBlockDuration = sum(durations) / durations.length; // ms
|
const averageBlockDuration = sum(durations) / durations.length; // ms
|
||||||
|
Loading…
Reference in New Issue
Block a user