Skip to content

Commit

Permalink
[block] Slight UX improvements on blocks (#1001)
Browse files Browse the repository at this point in the history
* [block] Slight UX improvements on blocks

- navigation between blocks
- counts of transactions

* [blocks] Move Block APIs to SDK v2
  • Loading branch information
gregnazario authored Jan 29, 2025
1 parent 3a58058 commit fc3c8ea
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 99 deletions.
17 changes: 7 additions & 10 deletions src/api/hooks/useGetBlock.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {Types} from "aptos";
import {useQuery} from "@tanstack/react-query";
import {getBlockByHeight, getBlockByVersion} from "../../api";
import {ResponseError} from "../../api/client";
import {useGlobalState} from "../../global-config/GlobalConfig";
import {getBlockByHeight, getBlockByVersion} from "../v2";
import {Block} from "@aptos-labs/ts-sdk";

export function useGetBlockByHeight({
height,
Expand All @@ -13,13 +13,12 @@ export function useGetBlockByHeight({
}) {
const [state] = useGlobalState();

const result = useQuery<Types.Block, ResponseError>({
return useQuery<Block, ResponseError>({
queryKey: ["block", height, state.network_value],
queryFn: () =>
getBlockByHeight({height, withTransactions}, state.aptos_client),
getBlockByHeight({height, withTransactions}, state.sdk_v2_client),
refetchInterval: 1200000,
});

return result;
}

export function useGetBlockByVersion({
Expand All @@ -31,11 +30,9 @@ export function useGetBlockByVersion({
}) {
const [state] = useGlobalState();

const result = useQuery<Types.Block, ResponseError>({
return useQuery<Block, ResponseError>({
queryKey: ["block", version, state.network_value],
queryFn: () =>
getBlockByVersion({version, withTransactions}, state.aptos_client),
getBlockByVersion({version, withTransactions}, state.sdk_v2_client),
});

return result;
}
46 changes: 30 additions & 16 deletions src/api/hooks/useGetMostRecentBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,45 @@ import {useQuery} from "@tanstack/react-query";
import {getLedgerInfo, getRecentBlocks} from "..";
import {Types} from "aptos";

export function useGetMostRecentBlocks(count: number) {
export function useGetMostRecentBlocks(
start: string | undefined,
count: number,
) {
const [state] = useGlobalState();
const [isLoading, setIsLoading] = useState<boolean>(true);
const [recentBlocks, setRecentBlocks] = useState<Types.Block[]>([]);

const {data: ledgerData} = useQuery({
const {isLoading: isLoadingLedgerData, data: ledgerData} = useQuery({
queryKey: ["ledgerInfo", state.network_value],
queryFn: () => getLedgerInfo(state.aptos_client),
});
const currentBlockHeight = ledgerData?.block_height;
const currentBlockHeight = parseInt(start ?? ledgerData?.block_height ?? "");

const {isLoading: isLoading, data: blocks} = useQuery({
queryKey: ["block", currentBlockHeight, state.network_value],
queryFn: async () => {
if (currentBlockHeight !== undefined) {
return getRecentBlocks(currentBlockHeight, count, state.aptos_client);
}
},
});

useEffect(() => {
if (currentBlockHeight !== undefined) {
const fetchData = async () => {
const blocks = await getRecentBlocks(
parseInt(currentBlockHeight),
count,
state.aptos_client,
);
setRecentBlocks(blocks);
setIsLoading(false);
};
fetchData();
if (
currentBlockHeight !== undefined &&
!isLoadingLedgerData &&
!isLoading &&
blocks
) {
setRecentBlocks(blocks);
}
}, [currentBlockHeight, state, count]);
}, [
currentBlockHeight,
state,
count,
isLoadingLedgerData,
isLoading,
blocks,
]);

return {recentBlocks, isLoading};
}
4 changes: 2 additions & 2 deletions src/api/hooks/useGetTPSByBlockHeight.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import moment from "moment";
import {useEffect, useState} from "react";
import {Types} from "aptos";
import {useGetBlockByHeight} from "./useGetBlock";
import {parseTimestamp} from "../../pages/utils";
import {Block} from "@aptos-labs/ts-sdk";

const TPS_FREQUENCY = 600; // calculate tps every 600 blocks

function calculateTps(startBlock: Types.Block, endBlock: Types.Block): number {
function calculateTps(startBlock: Block, endBlock: Block): number {
const startTransactionVersion = parseInt(startBlock.last_version);
const endTransactionVersion = parseInt(endBlock.last_version);

Expand Down
16 changes: 0 additions & 16 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,22 +195,6 @@ export function getTableItem(
return withResponseError(client.getTableItem(tableHandle, data));
}

export function getBlockByHeight(
requestParameters: {height: number; withTransactions: boolean},
client: AptosClient,
): Promise<Types.Block> {
const {height, withTransactions} = requestParameters;
return withResponseError(client.getBlockByHeight(height, withTransactions));
}

export function getBlockByVersion(
requestParameters: {version: number; withTransactions: boolean},
client: AptosClient,
): Promise<Types.Block> {
const {version, withTransactions} = requestParameters;
return withResponseError(client.getBlockByVersion(version, withTransactions));
}

export async function getRecentBlocks(
currentBlockHeight: number,
count: number,
Expand Down
42 changes: 42 additions & 0 deletions src/api/v2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {withResponseError} from "./client";
import {Aptos, Block} from "@aptos-labs/ts-sdk";

export function getBlockByHeight(
requestParameters: {height: number; withTransactions: boolean},
aptos: Aptos,
): Promise<Block> {
const {height, withTransactions} = requestParameters;
return withResponseError(
aptos.getBlockByHeight({blockHeight: height, options: {withTransactions}}),
);
}

export function getBlockByVersion(
requestParameters: {version: number; withTransactions: boolean},
aptos: Aptos,
): Promise<Block> {
const {version, withTransactions} = requestParameters;
return withResponseError(
aptos.getBlockByVersion({
ledgerVersion: version,
options: {withTransactions},
}),
);
}

export async function getRecentBlocks(
currentBlockHeight: bigint | number,
count: bigint | number,
aptos: Aptos,
): Promise<Block[]> {
const blockPromises = [];
// Don't await here, or they'll be in serial
for (let i = BigInt(0); i < BigInt(count); i++) {
const block = aptos.getBlockByHeight({
blockHeight: BigInt(currentBlockHeight) - i,
options: {withTransactions: false}, // Always false, or this will take forever
});
blockPromises.push(block);
}
return Promise.all(blockPromises);
}
6 changes: 3 additions & 3 deletions src/pages/Block/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from "react";
import {Types} from "aptos";
import {Box} from "@mui/material";
import OverviewTab from "./Tabs/OverviewTab";
import TransactionsTab from "./Tabs/TransactionsTab";
Expand All @@ -10,6 +9,7 @@ import StyledTabs from "../../components/StyledTabs";
import StyledTab from "../../components/StyledTab";
import {useParams} from "react-router-dom";
import {useNavigate} from "../../routing";
import {Block} from "@aptos-labs/ts-sdk";

const TAB_VALUES: TabValue[] = ["overview", "transactions"];

Expand Down Expand Up @@ -44,7 +44,7 @@ function getTabIcon(value: TabValue): JSX.Element {

type TabPanelProps = {
value: TabValue;
data: Types.Block;
data: Block;
};

function TabPanel({value, data}: TabPanelProps): JSX.Element {
Expand All @@ -53,7 +53,7 @@ function TabPanel({value, data}: TabPanelProps): JSX.Element {
}

type AccountTabsProps = {
data: Types.Block;
data: Block;
tabValues?: TabValue[];
};

Expand Down
103 changes: 61 additions & 42 deletions src/pages/Block/Tabs/OverviewTab.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import {Box} from "@mui/material";
import {Types} from "aptos";
import React from "react";
import HashButton, {HashType} from "../../../components/HashButton";
import ContentBox from "../../../components/IndividualPageContent/ContentBox";
import ContentRow from "../../../components/IndividualPageContent/ContentRow";
import TimestampValue from "../../../components/IndividualPageContent/ContentValue/TimestampValue";
import {Link} from "../../../routing";
import {getLearnMoreTooltip} from "../../Transaction/helpers";
import {
Block,
BlockMetadataTransactionResponse,
isBlockMetadataTransactionResponse,
TransactionResponse,
} from "@aptos-labs/ts-sdk";

function isBlockMetadataTransaction(
txn: Types.Transaction,
): txn is Types.Transaction_BlockMetadataTransaction {
return (
(txn as Types.Transaction_BlockMetadataTransaction).type ===
"block_metadata_transaction"
);
}

function VersionValue({data}: {data: Types.Block}) {
function VersionValue({data}: {data: Block}) {
const {first_version, last_version} = data;
return (
<>
Expand All @@ -33,16 +29,19 @@ function VersionValue({data}: {data: Types.Block}) {
}

function BlockMetadataRows({
block,
blockTxn,
}: {
blockTxn: Types.Transaction | undefined;
block: Block;
blockTxn: TransactionResponse | undefined;
}) {
if (!blockTxn) {
return null;
}

const txn = blockTxn as Types.Transaction_BlockMetadataTransaction;

const txn = blockTxn as BlockMetadataTransactionResponse;
const previousBlock = (BigInt(block.block_height) - 1n).toString();
const nextBlock = (BigInt(block.block_height) + 1n).toString();
return (
<>
<ContentRow
Expand All @@ -60,44 +59,64 @@ function BlockMetadataRows({
value={txn.round}
tooltip={getLearnMoreTooltip("round")}
/>
<ContentRow
title="Previous Block:"
value={
<Link to={`/block/${previousBlock}`} underline="none">
{previousBlock}
</Link>
}
tooltip={getLearnMoreTooltip("block")}
/>
<ContentRow
title="Next Block:"
value={
<Link to={`/block/${nextBlock}`} underline="none">
{nextBlock}
</Link>
}
tooltip={getLearnMoreTooltip("block")}
/>
</>
);
}

type OverviewTabProps = {
data: Types.Block;
data: Block;
};

export default function OverviewTab({data}: OverviewTabProps) {
const blockTxn: Types.Transaction | undefined = (
const blockTxn: TransactionResponse | undefined = (
data.transactions ?? []
).find(isBlockMetadataTransaction);
).find(isBlockMetadataTransactionResponse);

return (
<Box marginBottom={3}>
<ContentBox>
<ContentRow
title={"Block Height:"}
value={data.block_height}
tooltip={getLearnMoreTooltip("block_height")}
/>
<ContentRow
title={"Version:"}
value={<VersionValue data={data} />}
tooltip={getLearnMoreTooltip("version")}
/>
<ContentRow
title={"Timestamp:"}
value={
<TimestampValue
timestamp={data.block_timestamp}
ensureMilliSeconds
/>
}
tooltip={getLearnMoreTooltip("timestamp")}
/>
<BlockMetadataRows blockTxn={blockTxn} />
</ContentBox>
</Box>
blockTxn && (
<Box marginBottom={3}>
<ContentBox>
<ContentRow
title={"Block Height:"}
value={data.block_height}
tooltip={getLearnMoreTooltip("block_height")}
/>
<ContentRow
title={`Transactions (${BigInt(data.last_version) - BigInt(data.first_version) + 1n}):`}
value={<VersionValue data={data} />}
tooltip={getLearnMoreTooltip("version")}
/>
<ContentRow
title={"Timestamp:"}
value={
<TimestampValue
timestamp={data.block_timestamp}
ensureMilliSeconds
/>
}
tooltip={getLearnMoreTooltip("timestamp")}
/>
<BlockMetadataRows block={data} blockTxn={blockTxn} />
</ContentBox>
</Box>
)
);
}
9 changes: 6 additions & 3 deletions src/pages/Block/Tabs/TransactionsTab.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from "react";
import {Types} from "aptos";
import TransactionsTable from "../../Transactions/TransactionsTable";
import EmptyTabContent from "../../../components/IndividualPageContent/EmptyTabContent";
import {Block} from "@aptos-labs/ts-sdk";
import {Types} from "aptos";

type TransactionsTabProps = {
data: Types.Block;
data: Block;
};

export default function TransactionsTab({data}: TransactionsTabProps) {
Expand All @@ -13,5 +14,7 @@ export default function TransactionsTab({data}: TransactionsTabProps) {
return <EmptyTabContent />;
}

return <TransactionsTable transactions={transactions} />;
return (
<TransactionsTable transactions={transactions as Types.Transaction[]} />
);
}
Loading

0 comments on commit fc3c8ea

Please sign in to comment.