Skip to content

Commit

Permalink
Add Blockchain Info to Home Page (#14)
Browse files Browse the repository at this point in the history
* Fixed reward truncation entry

* Added a display of blockchain statistics to home page
  • Loading branch information
lucac-zilliqa authored Oct 20, 2023
1 parent be2d76c commit f497073
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useFinalizedSlotNumber, useSlotTimestamp } from "./useConsensus";
import Header from "./Header";
import RecentBlocks from "./execution/block/RecentBlocks";
import RecentDSBlocks from "./execution/block/RecentDSBlocks";
import ChainInfo from "./execution/ChainInfo";


const Home: FC = () => {
Expand All @@ -25,6 +26,9 @@ const Home: FC = () => {
return (
<>
<Header sourcifyPresent= {false} />
<div className="mx-1 my-1">
<ChainInfo />
</div>
<div className="grid grid-cols-5 gap-x-1 mx-1">
<span className="col-span-2">
<RecentDSBlocks />
Expand Down
27 changes: 27 additions & 0 deletions src/components/BCInfoToolTip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Menu } from "@headlessui/react";

type BCInfoToolTipProps = {
child: React.ReactNode,
};

const BCInfoToolTip: React.FC<BCInfoToolTipProps> = ({ child }) => {

return (
<Menu>
<span>
<Menu.Button className="rounded">
<FontAwesomeIcon icon={faInfoCircle} size="1x" />
</Menu.Button>
<Menu.Items className="absolute mt-2 flex min-w-max flex-col rounded-b border bg-white p-1 text-sm">
<div className="w-60 text-xs">
{ child }
</div>
</Menu.Items>
</span>
</Menu>
);
};

export default BCInfoToolTip;
17 changes: 17 additions & 0 deletions src/components/ChainInfoHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FC, memo } from "react";

type RecentNavBarProps = {
isLoading : boolean
};

const ChainInfoHeader: FC<RecentNavBarProps> = ({ isLoading }) => (
<div className="flex items-baseline justify-between py-3">
<div className="text-sm text-gray-500">
{isLoading
? "Waiting for blocks..."
: "Chain Info"}
</div>
</div>
);

export default memo(ChainInfoHeader);
21 changes: 21 additions & 0 deletions src/components/ChainInfoItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
type ChainInfoItemProps = {
title: React.ReactNode,
data: React.ReactNode,
};

const ChainInfoItem: React.FC<ChainInfoItemProps> = ({ title, data }) => {

return (
<span className="">
<span className="px-2 py-1 font-bold text-gray-500">
{title}
</span>
<br/>
<span className="px-2 py-1">
{data}
</span>
</span>
);
};

export default ChainInfoItem;
110 changes: 110 additions & 0 deletions src/execution/ChainInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { FC, useContext, memo } from "react";
import ContentFrame from "../components/ContentFrame";
import { RuntimeContext } from "../useRuntime";
import ChainInfoItem from "../components/ChainInfoItem";
import { PendingChainInfoResults } from "../search/PendingResults";
import ChainInfoHeader from "../components/ChainInfoHeader";
import { useBCInfoStateInfo, useLatestBlockChainInfo } from "../useLatestBlock";
import BCInfoToolTip from "../components/BCInfoToolTip";
import BlockLink from "../components/BlockLink";

const ChainInfo: FC = () => {
const { zilliqa } = useContext(RuntimeContext);

const latestBlockChainInfo = useLatestBlockChainInfo(zilliqa);

const BCInfo = useBCInfoStateInfo(latestBlockChainInfo);

// Return a table with rows containing the basic information of the most recent RECENT_SIZE blocks
return (
<ContentFrame isLoading={latestBlockChainInfo === undefined}>
<div className="pb-3">
<ChainInfoHeader isLoading={ latestBlockChainInfo === undefined }/>
{latestBlockChainInfo ?
<div className="grid grid-rows-3 grid-cols-4 items-baseline gap-x-1 border-t
border-b border-gray-200 bg-gray-100 text-sm">
<span>
<ChainInfoItem title="Current Tx Epoch:" data={latestBlockChainInfo.NumTxBlocks} />
</span>
<span>
<ChainInfoItem title="Number of Transactions:" data={latestBlockChainInfo.NumTransactions} />
</span>
<span>
<ChainInfoItem title="Peers:" data={latestBlockChainInfo.NumPeers} />
</span>
<span>
<ChainInfoItem title="Sharding Structure:" data={`[${latestBlockChainInfo.ShardingStructure.NumPeers.toString()}]`} />
</span>
<span>
<ChainInfoItem title="Current DS Epoch:" data={latestBlockChainInfo.CurrentDSEpoch} />
</span>
<span>
<ChainInfoItem title="DS Block Rate:" data={latestBlockChainInfo.DSBlockRate.toFixed(5)} />
</span>
<span>
<ChainInfoItem title="Tx Block Rate:" data={latestBlockChainInfo.TxBlockRate.toFixed(5)} />
</span>
<span>
<ChainInfoItem title="TPS:" data={latestBlockChainInfo.TransactionRate.toFixed(5)} />
</span>
<span>
<ChainInfoItem title="Number of Txns in DS Epoch:" data={latestBlockChainInfo.NumTxnsDSEpoch} />
</span>
<span>
<ChainInfoItem title="Number of Txns in Txn Epoch:" data={latestBlockChainInfo.NumTxnsTxEpoch} />
</span>
<span>
<ChainInfoItem title={
<span>
<BCInfoToolTip child={`This statistic is accurate from TxBlock ${BCInfo?.startTxBlock}. Requires user to stay on the Home Page`}/>
{' '}
Recent Max Observed TPS:
</span>}
data={
<span>
{BCInfo?.maxTPS.toFixed(5)}
{' '}
{BCInfo?.startTxBlock && <span className="text-xs">
<span className="text-gray-500">
(on TxBlock
{' '}
<BlockLink blockTag={BCInfo?.startTxBlock} />
)
</span>
</span>}
</span>
}/>
</span>
<span>
<ChainInfoItem title={
<span>
<BCInfoToolTip child={`This statistic is accurate from TxBlock ${BCInfo?.startTxBlock}. Requires user to stay on the Home Page`}/>
{' '}
Recent Max Observed Txn Count:
</span>}
data={
<span>
{BCInfo?.maxTxnCount}
{' '}
{BCInfo?.startTxBlock && <span className="text-xs">
<span className="text-gray-500">
(on TxBlock
{' '}
<BlockLink blockTag={BCInfo?.startTxBlock} />
)
</span>
</span>}
</span>
}/>
</span>
</div>
:

<PendingChainInfoResults />
}
</div>
</ContentFrame>
);
};

export default memo(ChainInfo);
2 changes: 1 addition & 1 deletion src/search/BlockItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const BlockItem: React.FC<BlockItemProps> = ({ block, feeDisplay}) => {
)}
{feeDisplay === FeeDisplay.GAS_PRICE && formatValue(block.gasUsed, 9)}
</span>
<span>
<span className="truncate">
<BlockReward block={block} />
</span>
<TimestampAge timestamp={block.timestamp}/>
Expand Down
8 changes: 8 additions & 0 deletions src/search/PendingResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,11 @@ export const PendingTransactionResults: React.FC = React.memo(() => (
</div>
));

export const PendingChainInfoResults: React.FC = React.memo(() => (
<div className="grid animate-pulse grid-cols-4 items-baseline gap-x-1 border-t border-gray-200 px-2 py-3 text-sm">
<div className="col-span-1 h-5 w-full rounded bg-gradient-to-r from-gray-100 to-transparent"></div>
<div className="col-span-1 h-5 w-full rounded bg-gradient-to-r from-gray-100 to-transparent"></div>
<div className="col-span-1 h-5 w-full rounded bg-gradient-to-r from-gray-100 to-transparent"></div>
<div className="col-span-1 h-5 w-full rounded bg-gradient-to-r from-gray-100 to-transparent"></div>
</div>
));
2 changes: 1 addition & 1 deletion src/search/RecentBlockItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const RecentBlockItem: React.FC<BlockItemProps> = ({ block, feeDisplay}) => {
)}
{feeDisplay === FeeDisplay.GAS_PRICE && formatValue(block.gasUsed, 9)}
</span>
<span>
<span className="truncate">
<BlockReward block={block} />
</span>
<TimestampAge timestamp={block.timestamp}/>
Expand Down
44 changes: 43 additions & 1 deletion src/useLatestBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Block } from "@ethersproject/abstract-provider";
import { JsonRpcProvider } from "@ethersproject/providers";
import { Zilliqa } from "@zilliqa-js/zilliqa";
import { BlockchainInfo } from '@zilliqa-js/core/dist/types/src/types'
import { useBlockChainInfo } from "./useZilliqaHooks";

const refreshRate = 30000 // In milliseconds

Expand Down Expand Up @@ -118,3 +117,46 @@ export const useLatestBlockChainInfo = (zilliqa?: Zilliqa)

return latestBlockChainInfo;
};

interface BCInfoState {
startTxBlock: number,
maxTPS: number,
maxTPSTxBlockNum: number,
maxTxnCount: number,
maxTxnCountTxBlockNum: number
}

export const useBCInfoStateInfo = (latestBlockChainInfo?: BlockchainInfo)
: BCInfoState | undefined => {

const [state, setState] = useState<BCInfoState>();

useEffect(() => {
setState((prevState: BCInfoState | undefined) => {
if(latestBlockChainInfo === undefined) return prevState;

if(prevState === undefined){
return {
startTxBlock: parseInt(latestBlockChainInfo.NumTxBlocks, 10) - 1,
maxTPS: latestBlockChainInfo.TransactionRate,
maxTPSTxBlockNum: parseInt(latestBlockChainInfo.NumTxBlocks, 10) - 1,
maxTxnCount: parseInt(latestBlockChainInfo.NumTxnsTxEpoch, 10),
maxTxnCountTxBlockNum: parseInt(latestBlockChainInfo.NumTxBlocks, 10) - 1,
};
};

const newState : BCInfoState = { ...prevState};
if (prevState.maxTPS <= latestBlockChainInfo.TransactionRate) {
newState.maxTPS = latestBlockChainInfo.TransactionRate
newState.maxTPSTxBlockNum = parseInt(latestBlockChainInfo.NumTxBlocks, 10) - 1
}
if (prevState.maxTxnCount <= parseInt(latestBlockChainInfo.NumTxnsTxEpoch, 10)) {
newState.maxTxnCount = parseInt(latestBlockChainInfo.NumTxnsTxEpoch, 10)
newState.maxTxnCountTxBlockNum = parseInt(latestBlockChainInfo.NumTxBlocks, 10) - 1
}
return newState
});
}, [latestBlockChainInfo]);

return state;
}

0 comments on commit f497073

Please sign in to comment.