diff --git a/explorer/src/components/account/BlockHistoryCard.tsx b/explorer/src/components/account/BlockHistoryCard.tsx
index 606c0f8f71..d6371580db 100644
--- a/explorer/src/components/account/BlockHistoryCard.tsx
+++ b/explorer/src/components/account/BlockHistoryCard.tsx
@@ -6,32 +6,31 @@ import { Signature } from "components/common/Signature";
import { ErrorCard } from "components/common/ErrorCard";
import { LoadingCard } from "components/common/LoadingCard";
import { Slot } from "components/common/Slot";
+import { ClusterStatus, useCluster } from "providers/cluster";
export function BlockHistoryCard({ slot }: { slot: number }) {
const confirmedBlock = useBlock(slot);
const fetchBlock = useFetchBlock();
+ const { status } = useCluster();
const refresh = () => fetchBlock(slot);
+ // Fetch block on load
React.useEffect(() => {
- if (!confirmedBlock) refresh();
- }, [confirmedBlock, slot]); // eslint-disable-line react-hooks/exhaustive-deps
-
- if (!confirmedBlock) {
- return null;
- }
-
- if (confirmedBlock.data === undefined) {
- if (confirmedBlock.status === FetchStatus.Fetching) {
- return ;
- }
+ if (!confirmedBlock && status === ClusterStatus.Connected) refresh();
+ }, [slot, status]); // eslint-disable-line react-hooks/exhaustive-deps
+ if (!confirmedBlock || confirmedBlock.status === FetchStatus.Fetching) {
+ return ;
+ } else if (
+ confirmedBlock.data === undefined ||
+ confirmedBlock.status === FetchStatus.FetchFailed
+ ) {
return ;
+ } else if (confirmedBlock.data.block === undefined) {
+ return ;
}
- if (confirmedBlock.status === FetchStatus.FetchFailed) {
- return ;
- }
-
+ const block = confirmedBlock.data.block;
return (
<>
@@ -44,31 +43,31 @@ export function BlockHistoryCard({ slot }: { slot: number }) {
Slot |
-
+
|
Parent Slot |
-
+
|
Blockhash |
- {confirmedBlock.data.blockhash}
+ {block.blockhash}
|
Previous Blockhash |
- {confirmedBlock.data.previousBlockhash}
+ {block.previousBlockhash}
|
- {confirmedBlock.data.transactions.length === 0 ? (
+ {block.transactions.length === 0 ? (
) : (
@@ -85,7 +84,7 @@ export function BlockHistoryCard({ slot }: { slot: number }) {
- {confirmedBlock.data.transactions.map((tx, i) => {
+ {block.transactions.map((tx, i) => {
let statusText;
let statusClass;
let signature: React.ReactNode;
diff --git a/explorer/src/components/common/Slot.tsx b/explorer/src/components/common/Slot.tsx
index 1e1d680ad1..88da2025b3 100644
--- a/explorer/src/components/common/Slot.tsx
+++ b/explorer/src/components/common/Slot.tsx
@@ -1,5 +1,6 @@
import React, { useState } from "react";
import { Link } from "react-router-dom";
+import { clusterPath } from "utils/url";
type CopyState = "copy" | "copied";
type Props = {
@@ -30,7 +31,7 @@ export function Slot({ slot, link }: Props) {
return link ? (
{copyButton}
-
+
{slot.toLocaleString("en-US")}
diff --git a/explorer/src/providers/block.tsx b/explorer/src/providers/block.tsx
index c1bf178dc3..3890786dcd 100644
--- a/explorer/src/providers/block.tsx
+++ b/explorer/src/providers/block.tsx
@@ -15,8 +15,12 @@ export enum ActionType {
Clear,
}
-type State = Cache.State;
-type Dispatch = Cache.Dispatch;
+type Block = {
+ block?: ConfirmedBlock;
+};
+
+type State = Cache.State;
+type Dispatch = Cache.Dispatch;
const StateContext = React.createContext(undefined);
const DispatchContext = React.createContext(undefined);
@@ -25,7 +29,7 @@ type BlockProviderProps = { children: React.ReactNode };
export function BlockProvider({ children }: BlockProviderProps) {
const { url } = useCluster();
- const [state, dispatch] = Cache.useReducer(url);
+ const [state, dispatch] = Cache.useReducer(url);
React.useEffect(() => {
dispatch({ type: ActionType.Clear, url });
@@ -40,9 +44,7 @@ export function BlockProvider({ children }: BlockProviderProps) {
);
}
-export function useBlock(
- key: number
-): Cache.CacheEntry | undefined {
+export function useBlock(key: number): Cache.CacheEntry | undefined {
const context = React.useContext(StateContext);
if (!context) {
@@ -66,18 +68,23 @@ export async function fetchBlock(
});
let status: FetchStatus;
- let data: ConfirmedBlock | undefined;
+ let data: Block | undefined = undefined;
try {
const connection = new Connection(url, "max");
- data = await connection.getConfirmedBlock(Number(key));
+ data = { block: await connection.getConfirmedBlock(Number(key)) };
status = FetchStatus.Fetched;
- } catch (error) {
- console.log(error);
- if (cluster !== Cluster.Custom) {
- Sentry.captureException(error, { tags: { url } });
+ } catch (err) {
+ const error = err as Error;
+ if (error.message.includes("not found")) {
+ data = {} as Block;
+ status = FetchStatus.Fetched;
+ } else {
+ status = FetchStatus.FetchFailed;
+ if (cluster !== Cluster.Custom) {
+ Sentry.captureException(error, { tags: { url } });
+ }
}
- status = FetchStatus.FetchFailed;
}
dispatch({
@@ -90,14 +97,12 @@ export async function fetchBlock(
}
export function useFetchBlock() {
- const { cluster, url } = useCluster();
- const state = React.useContext(StateContext);
const dispatch = React.useContext(DispatchContext);
-
- if (!state || !dispatch) {
+ if (!dispatch) {
throw new Error(`useFetchBlock must be used within a BlockProvider`);
}
+ const { cluster, url } = useCluster();
return React.useCallback(
(key: number) => fetchBlock(dispatch, url, cluster, key),
[dispatch, cluster, url]