mirror of
https://github.com/pezkuwichain/pezkuwi-sdk-ui.git
synced 2026-06-14 00:31:01 +00:00
d949863789
Comprehensive web interface for interacting with Pezkuwi blockchain. Features: - Blockchain explorer - Wallet management - Staking interface - Governance participation - Developer tools Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
152 lines
4.8 KiB
TypeScript
152 lines
4.8 KiB
TypeScript
// Copyright 2017-2026 @pezkuwi/app-broker authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import type { ChainBlockConstants, CoreWorkload, LegacyLease, RegionInfo, Reservation } from '@pezkuwi/react-hooks/types';
|
|
import type { CoreWorkloadType, CoreWorkplanType, InfoRow } from './types.js';
|
|
|
|
import { CoreTimeTypes } from '@pezkuwi/react-hooks/constants';
|
|
import { BN } from '@pezkuwi/util';
|
|
|
|
function formatDate (date: Date) {
|
|
const day = date.getDate();
|
|
const month = date.toLocaleString('default', { month: 'short' });
|
|
const year = date.getFullYear();
|
|
|
|
return `${day} ${month} ${year}`;
|
|
}
|
|
|
|
/**
|
|
* Calculation on the Relay chain
|
|
*
|
|
* blockTime = 6000 ms
|
|
* BlocksPerTimeslice = 80
|
|
* Default Region = 5040 timeslices
|
|
* TargetBlock = TargetTimeslice * BlocksPerTimeslice
|
|
* Block Time Difference = |TargetBlock - latest Block| * blockTime
|
|
*
|
|
* Estimate timestamp =
|
|
* if targetBlock is before the latestBlock
|
|
* now minus block time difference
|
|
* else
|
|
* now plus block time difference
|
|
*/
|
|
export const estimateTime = (
|
|
targetTimeslice: string | number,
|
|
latestBlock: number,
|
|
{ blocksPerTimeslice: blocksPerTs, blocktimeMs }: ChainBlockConstants = { blocksPerTimeslice: 80, blocktimeMs: 6000 }
|
|
): { timestamp: number, formattedDate: string } | null => {
|
|
if (!latestBlock || !targetTimeslice) {
|
|
console.error('Invalid input: one or more inputs are missing');
|
|
|
|
return null;
|
|
}
|
|
|
|
const now = new BN(Date.now());
|
|
|
|
try {
|
|
const blockTime = new BN(blocktimeMs); // Average block time in milliseconds (6 seconds)
|
|
const blocksPerTimeslice = new BN(blocksPerTs);
|
|
const targetBlock = new BN(Number(targetTimeslice)).mul(blocksPerTimeslice);
|
|
const latestBlockBN = new BN(latestBlock);
|
|
const blockDifference = targetBlock.sub(latestBlockBN);
|
|
const timeDifference = blockDifference.mul(blockTime);
|
|
const estTimestamp = now.add(timeDifference);
|
|
|
|
return {
|
|
formattedDate: formatDate(new Date(estTimestamp.toNumber())),
|
|
timestamp: estTimestamp.toNumber()
|
|
};
|
|
} catch (error) {
|
|
console.error('Error in calculation:', error);
|
|
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param data: CoreWorkloadType[]
|
|
* @param core: core number
|
|
* @param currentRegion
|
|
* @param timeslice
|
|
* @param param4
|
|
* @param regionLength
|
|
*/
|
|
export function formatRowInfo (
|
|
data: CoreWorkloadType[] | CoreWorkplanType[],
|
|
core: number,
|
|
regionOwnerInfo: RegionInfo | undefined,
|
|
currentTimeSlice: number,
|
|
currentRegion: { begin: number, beginDate: string, end: number, endDate: string },
|
|
regionLength: number,
|
|
coretimeRelayConstants: ChainBlockConstants = { blocksPerTimeslice: 0, blocktimeMs: 0 }
|
|
): InfoRow[] {
|
|
const blockNumberNow = currentTimeSlice * coretimeRelayConstants.blocksPerTimeslice;
|
|
|
|
return data.map((one: CoreWorkloadType | CoreWorkplanType) => {
|
|
const item: InfoRow = {
|
|
core,
|
|
maskBits: one?.info?.maskBits,
|
|
task: one?.info?.task,
|
|
type: one?.type
|
|
};
|
|
|
|
// For region-based types, use the provided dates
|
|
if ([CoreTimeTypes['Bulk Coretime'], CoreTimeTypes.Reservation, CoreTimeTypes['On Demand']].includes(one.type)) {
|
|
item.start = currentRegion.beginDate;
|
|
item.end = currentRegion.endDate;
|
|
item.startTimeslice = currentRegion.begin;
|
|
item.endBlock = currentRegion.end * coretimeRelayConstants.blocksPerTimeslice;
|
|
} else if (one.type === CoreTimeTypes.Lease) { // For lease type, calculate the end
|
|
const period = Math.floor(one.lastBlock / regionLength);
|
|
const endTs = period * regionLength;
|
|
const endEstimate = estimateTime(endTs, blockNumberNow, coretimeRelayConstants);
|
|
|
|
item.end = endEstimate?.formattedDate ?? null;
|
|
item.endBlock = endTs * coretimeRelayConstants.blocksPerTimeslice;
|
|
}
|
|
|
|
item.owner = regionOwnerInfo?.owner.toString();
|
|
|
|
return item;
|
|
});
|
|
}
|
|
|
|
export function getStats (totalCores: string | undefined, workloadInfos: CoreWorkload[] | undefined) {
|
|
if (!totalCores || !workloadInfos) {
|
|
return { idles: 0, pools: 0, tasks: 0 };
|
|
}
|
|
|
|
const { pools, tasks } = workloadInfos.reduce(
|
|
(acc, { info }) => {
|
|
if (info.isTask) {
|
|
acc.tasks += 1;
|
|
} else if (info.isPool) {
|
|
acc.pools += 1;
|
|
}
|
|
|
|
return acc;
|
|
},
|
|
{ pools: 0, tasks: 0 }
|
|
);
|
|
const idles = Number(totalCores) - (pools + tasks);
|
|
|
|
return { idles, pools, tasks };
|
|
}
|
|
|
|
export const createTaskMap = <T extends { task: string }>(items: T[]): Record<number, T> => {
|
|
return (items || []).reduce((acc, item) => {
|
|
acc[Number(item.task)] = item;
|
|
|
|
return acc;
|
|
}, {} as Record<number, T>);
|
|
};
|
|
|
|
export const getOccupancyType = (lease: LegacyLease | undefined, reservation: Reservation | undefined, isPool: boolean): CoreTimeTypes => {
|
|
if (isPool) {
|
|
return CoreTimeTypes['On Demand'];
|
|
}
|
|
|
|
return reservation ? CoreTimeTypes.Reservation : lease ? CoreTimeTypes.Lease : CoreTimeTypes['Bulk Coretime'];
|
|
};
|