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 { useTimeToUpgrade } from './use-time-to-upgrade';
|
||||
import {
|
||||
ERR_NO_TIME_UNITS,
|
||||
parseDuration,
|
||||
useTimeToUpgrade,
|
||||
} from './use-time-to-upgrade';
|
||||
|
||||
jest.mock('./__generated__/BlockStatistics', () => ({
|
||||
...jest.requireActual('./__generated__/BlockStatistics'),
|
||||
@ -8,7 +12,7 @@ jest.mock('./__generated__/BlockStatistics', () => ({
|
||||
data: {
|
||||
statistics: {
|
||||
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 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 [avg, setAvg] = useState<number | undefined>(undefined);
|
||||
const { data, startPolling, stopPolling, error } = useBlockStatisticsQuery({
|
||||
@ -28,7 +74,11 @@ const useAverageBlockDuration = (polls = DEFAULT_POLLS) => {
|
||||
|
||||
useEffect(() => {
|
||||
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) {
|
||||
const averageBlockDuration = sum(durations) / durations.length; // ms
|
||||
|
Loading…
Reference in New Issue
Block a user