Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lite mode support #55

Merged
merged 6 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions backend/src/client/parentchain/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ export const abi = [
name: 'SubnetBlockFinalized',
type: 'event',
},
{
inputs: [],
name: 'MODE',
outputs: [
{
internalType: 'string',
name: '',
type: 'string',
},
],
stateMutability: 'view',
type: 'function',
},
{
constant: true,
inputs: [
Expand Down
10 changes: 10 additions & 0 deletions backend/src/client/parentchain/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ export class ParentChainClient {
}
}

async mode(): Promise<string> {
try {
const result = await this.smartContractInstance.methods.MODE().call();
return result;
} catch (error) {
logger.error("Error while trying to fetch the mode in XDC mainnet", { message: error.message });
throw new HttpException(500, error.message ? error.message : 'Error while trying to fetch the mode in XDC parentchain');
}
}

/**
*
* @param committedSubnetBlockHash WARNING: This method only check against the block has that has already been committed, otherwise always 0
Expand Down
1 change: 1 addition & 0 deletions backend/src/controllers/account.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class RelayerController {
health: {
status: processingBacklog.isProcessing ? 'UP' : 'DOWN',
},
mode: processingBacklog.mode,
};
res.status(200).json(resp);
} catch (error) {
Expand Down
12 changes: 8 additions & 4 deletions backend/src/services/block.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,15 @@ export class BlockService {
}

// Returns the block num difference between what's mined in subnet and what's submitted to parent chain
public async getProcessingBacklog(): Promise<{ gap: number; isProcessing: boolean }> {
public async getProcessingBacklog(): Promise<{ gap: number; isProcessing: boolean; mode: string }> {
GalaxySciTech marked this conversation as resolved.
Show resolved Hide resolved
const [lastSubnetCommittedBlock, smartContractProcessingInfo] = await Promise.all([
this.getLastSubnetCommittedBlock(),
this.getSmartContractProcessingInfo(),
]);
return {
gap: lastSubnetCommittedBlock.number - smartContractProcessingInfo.processedUntil || -1,
isProcessing: smartContractProcessingInfo.isProcessing,
mode: smartContractProcessingInfo.mode,
};
}

Expand Down Expand Up @@ -206,16 +207,19 @@ export class BlockService {
};
}

private async getSmartContractProcessingInfo(): Promise<{ processedUntil: number; isProcessing: boolean }> {
private async getSmartContractProcessingInfo(): Promise<{ processedUntil: number; isProcessing: boolean; mode: string }> {
const { smartContractHeight, smartContractCommittedHash } = await this.getAndSetLastSubmittedBlockInfo();
const mode = await this.parentChainClient.mode();
const { timestamp } = await this.parentChainClient.getParentChainBlockBySubnetHash(smartContractCommittedHash);
let isProcessing = true;

const timeDiff = new Date().getTime() / 1000 - parseInt(timestamp.toString());
if (timeDiff > 60) isProcessing = false;

const isProcessing = (mode == 'full' && timeDiff < 120) || (mode == 'lite' && timeDiff < 1000);

return {
processedUntil: smartContractHeight,
isProcessing,
mode,
};
}

Expand Down
175 changes: 110 additions & 65 deletions frontend/src/components/info-cards/InfoCards.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import axios from 'axios';
import { useState } from 'react';
import { useLoaderData } from 'react-router-dom';
import axios from "axios";
import { useState } from "react";
import { useLoaderData } from "react-router-dom";

import {
BlocksInfoItem, MasterNode
} from '@/components/blocks-info/blocks-info-item/BlocksInfoItem';
import BlocksInfo from '@/components/blocks-info/BlocksInfo';
import Card from '@/components/card/Card';
import InfoList from '@/components/info-list/InfoList';
import { baseUrl } from '@/constants/urls';
import { Info, InfoListHealth } from '@/types/info';
import { HomeLoaderData } from '@/types/loaderData';
import { getSortedRecentBlocks, uniqReplaceByName } from '@/utils/blockHelper';
import { formatHash, formatMoney } from '@/utils/formatter';
BlocksInfoItem,
MasterNode,
} from "@/components/blocks-info/blocks-info-item/BlocksInfoItem";
import BlocksInfo from "@/components/blocks-info/BlocksInfo";
import Card from "@/components/card/Card";
import InfoList from "@/components/info-list/InfoList";
import { baseUrl } from "@/constants/urls";
import { Info, InfoListHealth } from "@/types/info";
import { HomeLoaderData } from "@/types/loaderData";
import { getSortedRecentBlocks, uniqReplaceByName } from "@/utils/blockHelper";
import { formatHash, formatMoney } from "@/utils/formatter";

interface InfoCardsProps {
nextFetchRecentBlocksIndex: number;
Expand All @@ -30,46 +31,59 @@ export default function InfoCards(props: InfoCardsProps) {
recentBlocks,
setRecentBlocks,
isLoadingRecentBlocks,
setIsLoadingRecentBlocks
setIsLoadingRecentBlocks,
} = props;
const loaderData = useLoaderData() as HomeLoaderData;

const [veryFirstSubnetBlock] = useState(loaderData.blocks?.blocks[0].number);
const [isFetchingMoreRecentBlocks, setIsLoadingMoreRecentBlocks] = useState(false);
const [isReachApiEndOfRecentBlocks, setIsReachApiEndOfRecentBlocks] = useState(false);
const [isFetchingMoreRecentBlocks, setIsLoadingMoreRecentBlocks] =
useState(false);
const [isReachApiEndOfRecentBlocks, setIsReachApiEndOfRecentBlocks] =
useState(false);

function getNetworkStatus(): InfoListHealth {
if (loaderData.network?.health.status === 'UP') {
return 'Normal';
if (loaderData.network?.health.status === "UP") {
return "Normal";
}

return 'Abnormal';
return "Abnormal";
}

function getRelayerStatus(): InfoListHealth {
if (loaderData.relayer?.health.status === 'UP') {
return 'Normal';
if (Number(loaderData.relayer?.account.balance) < 1) {
return "Low funds";
}
if (loaderData.relayer?.health.status === "UP") {
return "Normal";
}

return 'Abnormal';
return "Abnormal";
}

const mappedInfo: Info = getMappedInfo(loaderData, getNetworkStatus, getRelayerStatus);
const mappedInfo: Info = getMappedInfo(
loaderData,
getNetworkStatus,
getRelayerStatus
);

const masterNodes = loaderData.masterNodes?.nodes?.map<MasterNode>((v, i: number) => ({
...v,
type: 'master-node',
account: v.address,
number: i + 1
}));
const masterNodes = loaderData.masterNodes?.nodes?.map<MasterNode>(
(v, i: number) => ({
...v,
type: "master-node",
account: v.address,
number: i + 1,
})
);

const fetchMoreRecentBlocks = async () => {
if (!recentBlocks || !veryFirstSubnetBlock) {
return;
}

setIsLoadingMoreRecentBlocks(true);
const { data } = await axios.get<HomeLoaderData.Blocks>(`${baseUrl}/information/blocks?blockNumIndex=${nextFetchRecentBlocksIndex}`);
const { data } = await axios.get<HomeLoaderData.Blocks>(
`${baseUrl}/information/blocks?blockNumIndex=${nextFetchRecentBlocksIndex}`
);

const firstBlockNumber = data.blocks[0].number;

Expand All @@ -81,7 +95,10 @@ export default function InfoCards(props: InfoCardsProps) {

// concat data from api in the end of list since it would be the 'previous' data
setRecentBlocks((recentBlocks: BlocksInfoItem[]) => {
const newRecentBlocks = uniqReplaceByName(recentBlocks, getSortedRecentBlocks(data.blocks));
const newRecentBlocks = uniqReplaceByName(
recentBlocks,
getSortedRecentBlocks(data.blocks)
);
setIsLoadingMoreRecentBlocks(false);

// Reach API limit
Expand All @@ -95,31 +112,22 @@ export default function InfoCards(props: InfoCardsProps) {

return (
<>
<div className='grid lg:grid-cols-2 llg:grid-cols-3 gap-6'>
<Card className='max-w-[400px]'>
<InfoList
title='Network Info'
info={mappedInfo.network}
/>
<div className="grid lg:grid-cols-2 llg:grid-cols-3 gap-6">
<Card className="max-w-[400px]">
<InfoList title="Network Info" info={mappedInfo.network} />
</Card>
<Card className='max-w-[400px]'>
<InfoList
title='Relayer Info'
info={mappedInfo.relayer}
/>
<Card className="max-w-[400px]">
<InfoList title="Relayer Info" info={mappedInfo.relayer} />
</Card>
<Card className='max-w-[400px]'>
<InfoList
title='Master Nodes Info'
info={mappedInfo.masterNodes}
/>
<Card className="max-w-[400px]">
<InfoList title="Master Nodes Info" info={mappedInfo.masterNodes} />
</Card>
</div>

<div className='grid grid-cols-1 llg:grid-cols-2 gap-6'>
<Card className='max-w-[565px]'>
<div className="grid grid-cols-1 llg:grid-cols-2 gap-6">
<Card className="max-w-[565px]">
<BlocksInfo
title='Recent Blocks'
title="Recent Blocks"
data={recentBlocks}
setData={setRecentBlocks}
fetchMoreData={fetchMoreRecentBlocks}
Expand All @@ -130,47 +138,84 @@ export default function InfoCards(props: InfoCardsProps) {
enableInfinite
/>
</Card>
<Card className='max-w-[565px]'>
<BlocksInfo title='Master Nodes' data={masterNodes} />
<Card className="max-w-[565px]">
<BlocksInfo title="Master Nodes" data={masterNodes} />
</Card>
</div>
</>
);
}

function getMappedInfo(loaderData: HomeLoaderData, getNetworkStatus: () => InfoListHealth, getRelayerStatus: () => InfoListHealth): Info {
function getMappedInfo(
loaderData: HomeLoaderData,
getNetworkStatus: () => InfoListHealth,
getRelayerStatus: () => InfoListHealth
): Info {
const info: Info = {};

if (loaderData.network) {
info.network = {
health: getNetworkStatus(),
data: [
{ name: 'Block Time', value: `${Math.floor(loaderData.network.subnet.block.averageBlockTime * 100) / 100}s` },
{ name: 'TX Throughput', value: `${Math.round(loaderData.network.subnet.block.txThroughput * 100) / 100} txs/s` },
{ name: 'Checkpointed to', value: loaderData.network.parentChain.name },
]
{
name: "Block Time",
value: `${
Math.floor(loaderData.network.subnet.block.averageBlockTime * 100) /
100
}s`,
},
{
name: "TX Throughput",
value: `${
Math.round(loaderData.network.subnet.block.txThroughput * 100) / 100
} txs/s`,
},
{ name: "Checkpointed to", value: loaderData.network.parentChain.name },
],
};
}
if (loaderData.relayer) {
info.relayer = {
health: getRelayerStatus(),
data: [
{ name: 'Smart Contract', value: formatHash(loaderData.relayer.contractAddress) },
{ name: 'Backlog', value: `${loaderData.relayer.backlog} Subnet Headers` },
{ name: 'Remaining Balance', value: formatMoney(parseInt(loaderData.relayer.account.balance)) },
]
{
name: "Smart Contract",
value: `${formatHash(loaderData.relayer.contractAddress)}(mode : ${
loaderData.relayer.mode
})`,
},
{
name: "Backlog",
value: `${loaderData.relayer.backlog} Subnet Headers`,
},
{
name: "Remaining Balance",
value: formatMoney(parseInt(loaderData.relayer.account.balance))+" XDC",
},
],
};
}
if (loaderData.masterNodes) {
info.masterNodes = {
data: [
{ name: 'Current committee size', value: loaderData.masterNodes?.summary?.committee },
{ name: 'Activity(active / inactive)', value: `${loaderData.masterNodes?.summary?.activeNodes} / ${loaderData.masterNodes.summary.committee - loaderData.masterNodes?.summary?.activeNodes}` },
{ name: 'Number of standby nodes', value: loaderData.masterNodes?.summary?.inActiveNodes },
{
name: "Current committee size",
value: loaderData.masterNodes?.summary?.committee,
},
{
name: "Activity(active / inactive)",
value: `${loaderData.masterNodes?.summary?.activeNodes} / ${
loaderData.masterNodes.summary.committee -
loaderData.masterNodes?.summary?.activeNodes
}`,
},
{
name: "Number of standby nodes",
value: loaderData.masterNodes?.summary?.inActiveNodes,
},
],
};
}

return info;
}

11 changes: 9 additions & 2 deletions frontend/src/types/info.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ export namespace InfoListInfo {
}
}

export type InfoListHealth = 'Normal' | 'Abnormal';
export type InfoListHealth = "Normal" | "Abnormal" | "Low funds";

export type InfoNames = 'masterNodes' | 'relayer' | 'network' | 'parentChain' | 'transaction' | 'subnetBlock' | 'subnet';
export type InfoNames =
| "masterNodes"
| "relayer"
| "network"
| "parentChain"
| "transaction"
| "subnetBlock"
| "subnet";
1 change: 1 addition & 0 deletions frontend/src/types/loaderData.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export namespace HomeLoaderData {
details: string;
};
averageTXfee: number;
mode:string;
}

export interface Network {
Expand Down