Skip to content

Commit cf4484d

Browse files
feat: Adding txn search to banks chart
1 parent f201e22 commit cf4484d

34 files changed

+1672
-214
lines changed

package-lock.json

Lines changed: 23 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"@types/luxon": "^3.4.2",
4141
"byte-size": "^9.0.0",
4242
"clsx": "^2.1.1",
43+
"cmdk": "^1.1.1",
4344
"events": "^3.3.0",
4445
"hammerjs": "^2.0.8",
4546
"immer": "^10.1.1",
@@ -69,7 +70,7 @@
6970
"@types/react-dom": "^18.3.0",
7071
"@vitejs/plugin-react": "^4.3.1",
7172
"eslint": "^9.11.1",
72-
"eslint-config-prettier": "^9.1.0",
73+
"eslint-config-prettier": "^10.1.8",
7374
"eslint-plugin-react": "^7.36.1",
7475
"eslint-plugin-react-hooks": "^5.1.0-rc-04bd67a4-20240924",
7576
"eslint-plugin-react-refresh": "^0.4.12",

src/api/entities.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ export const slotTransactionsSchema = z.object({
238238
txn_microblock_id: z.number().array(),
239239
txn_landed: z.boolean().array(),
240240
txn_signature: z.string().array(),
241+
txn_source_ipv4: z.string().array(),
242+
txn_source_tpu: z.string().array(),
241243
});
242244

243245
export const slotLevelSchema = z.enum([

src/app.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
--green-live: #3cff73;
1414

1515
font-variant-numeric: tabular-nums;
16+
17+
overflow: hidden;
1618
}
1719

1820
.rt-TooltipContent {

src/components/Card.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
import styles from "./card.module.css";
2-
import type { CSSProperties, PropsWithChildren } from "react";
2+
import type { PropsWithChildren, HTMLAttributes } from "react";
33

44
interface CardProps {
55
hideChildren?: boolean;
6-
style?: CSSProperties;
76
}
87

98
export default function Card({
109
children,
1110
hideChildren,
12-
style,
13-
}: PropsWithChildren<CardProps>) {
11+
...props
12+
}: PropsWithChildren<CardProps & HTMLAttributes<HTMLDivElement>>) {
1413
return (
15-
<div className={styles.card} style={style}>
14+
<div className={styles.card} {...props}>
1615
{!hideChildren && children}
1716
</div>
1817
);

src/consts.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const lamportsPerSol = 1_000_000_000;
99
export const defaultMaxComputeUnits = 50_000_000;
1010

1111
export const clusterIndicatorHeight = 5;
12+
export const slotNavHeight = 36.5;
1213

1314
export const headerHeight = 48;
1415
export const headerSpacing = 13;
@@ -28,3 +29,46 @@ export const slotNavWidth =
2829
export const narrowNavMedia = "(max-width: 768px)";
2930

3031
export const maxZIndex = 110;
32+
export const txnErrorCodeMap: Record<string, string> = {
33+
0: "Success", // The transaction successfully executed
34+
1: "Account In Use", // Includes a writable account that was already in use at the time this transaction was executed
35+
2: "Account Loaded Twice", // Lists at least one account pubkey more than once
36+
3: "Account Not Found", // Lists at least one account pubkey that was not found in the accounts database
37+
4: "Program Account Not Found", // Could not find or parse a listed program account
38+
5: "Insufficient Funds For Fee", // Lists a fee payer that does not have enough SOL to fund this transaction
39+
6: "Invalid Account For Fee", // Lists a fee payer that may not be used to pay transaction fees
40+
7: "Already Processed", // This transaction has been processed before (e.g. the transaction was sent twice)
41+
8: "Blockhash Not Found", // Provides a block hash of a recent block in the chain, b, that this validator has not seen yet, or that is so old it has been discarded
42+
9: "Instruction Error", // Includes an instruction that failed to process
43+
10: "Call Chain Too Deep", // Includes a cross program invocation (CPI) chain that exceeds the maximum depth allowed
44+
11: "Missing Signature For Fee", // Requires a fee but has no signature present
45+
12: "Invalid Account Index", // Contains an invalid account reference in one of its instructions
46+
13: "Signature Failure", // Includes a signature that did not pass verification
47+
14: "Invalid Program For Execution", // Includes a program that may not be used for executing transactions
48+
15: "Sanitize Failure", // Failed to parse a portion of the transaction payload
49+
16: "Cluster Maintenance", // Cluster is undergoing an active maintenance window
50+
17: "Account Borrow Outstanding", // Transaction processing left an account with an outstanding borrowed reference
51+
18: "Would Exceed Max Block Cost Limit", // Exceeded the maximum compute unit cost allowed for this slot
52+
19: "Unsupported Version", // Includes a transaction version that is not supported by this validator
53+
20: "Invalid Writable Account", // Includes an account marked as writable that is not in fact writable
54+
21: "Would Exceed Max Account Cost Limit", // Exceeded the maximum per-account compute unit cost allowed for this slot
55+
22: "Would Exceed Account Data Block Limit", // Retrieved accounts data size exceeds the limit imposed for this slot
56+
23: "Too Many Account Locks", // Locked too many accounts
57+
24: "Address Lookup Table Not Found", // Loads an address table account that doesn't exist
58+
25: "Invalid Address Lookup Table Owner", // Loads an address table account with an invalid owner
59+
26: "Invalid Address Lookup Table Data", // Loads an address table account with invalid data
60+
27: "Invalid Address Lookup Table Index", // Address table lookup uses an invalid index
61+
28: "Invalid Rent Paying Account", // Deprecated
62+
29: "Would Exceed Max Vote Cost Limit", // Exceeded the maximum vote compute unit cost allowed for this slot
63+
30: "Would Exceed Account Data Total Limit", // Deprecated
64+
31: "Duplicate Instruction", // Contains duplicate instructions
65+
32: "Insufficient Funds For Rent", // Deprecated
66+
33: "Max Loaded Accounts Data Size Exceeded", // Retrieved accounts data size exceeds the limit imposed for this transaction
67+
34: "Invalid Loaded Accounts Data Size Limit", // Requested an invalid data size (i.e. 0)
68+
35: "Resanitization Needed", // Sanitized transaction differed before/after feature activation. Needs to be resanitized
69+
36: "Program Execution Temporarily Restricted", // Execution of a program referenced by this transaciton is restricted
70+
37: "Unbalanced Transaction", // The total accounts balance before the transaction does not equal the total balance after
71+
38: "Program Cache Hit Max Limit", // The program cache allocated for transaction batch for this transaction hit its load limit
72+
39: "Commit Cancelled", // This transaction was part of a bundle that failed
73+
40: "Bundle Peer", // This transaction was part of a bundle that failed
74+
};

src/features/Navigation/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export default function Navigation() {
5151
return (
5252
<div
5353
style={{
54-
position: "relative",
5554
// resizes outlet content immediately
5655
width: isNarrow || isNavCollapsed ? "0" : `${width}px`,
5756
}}

src/features/Overview/SlotPerformance/TransactionBarsCard/BarsChart.tsx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@ import AutoSizer from "react-virtualized-auto-sizer";
99
import type { SlotTransactions } from "../../../../api/types";
1010
import { tooltipTxnIdxAtom, tooltipTxnStateAtom } from "./chartTooltipAtoms";
1111
import { timeScaleDragPlugin } from "./scaleDragPlugin";
12-
import { getChartData } from "./chartUtils";
12+
import { getChartData, getUplotId } from "./chartUtils";
1313
import { addPrevSeries, barCountAtom, chartFiltersAtom } from "./atoms";
1414
import { safeDivide } from "../../../../mathUtils";
1515
import { txnBarsTooltipPlugin } from "./txnBarsTooltipPlugin";
1616
import { wheelZoomPlugin } from "../../../../uplotReact/wheelZoomPlugin";
17-
import { txnBarsUplotIdPrefix } from "./consts";
1817
import { syncXScalePlugin } from "../../../../uplotReact/syncXScalePlugin";
1918
import { leftAxisSizeAtom, rightAxisSizeAtom } from "../ComputeUnitsCard/atoms";
2019
import { touchPlugin } from "../../../../uplotReact/touchPlugin";
@@ -23,10 +22,6 @@ import { chartAxisColor, chartGridStrokeColor } from "../../../../colors";
2322
/** Buffer of the canvas past the axes of the chart to prevent the first and last tick labels from being cut off */
2423
const xBuffer = 20;
2524

26-
function getUplotId(bankIdx: number) {
27-
return `${txnBarsUplotIdPrefix}${bankIdx}`;
28-
}
29-
3025
interface BarsChartProps {
3126
bankIdx: number;
3227
transactions: SlotTransactions;
@@ -81,8 +76,6 @@ export default function BarsChart({
8176
[bankIdx, maxTs, transactions],
8277
);
8378

84-
const chartId = getUplotId(bankIdx);
85-
8679
const options = useMemo<uPlot.Options | undefined>(() => {
8780
if (!chartData?.length) return;
8881

@@ -181,7 +174,7 @@ export default function BarsChart({
181174
return (
182175
<>
183176
<UplotReact
184-
id={chartId}
177+
id={getUplotId(bankIdx)}
185178
options={options}
186179
data={chartData}
187180
onCreate={handleCreate}

src/features/Overview/SlotPerformance/TransactionBarsCard/BarsChartContainer.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ import { getChartData } from "./chartUtils";
1313
import BarChartFloatingAction from "./BarChartFloatingAction";
1414
import CardHeader from "../../../../components/CardHeader";
1515
import { getMaxTsWithBuffer } from "../../../../transactionUtils";
16+
import {
17+
clusterIndicatorHeight,
18+
headerHeight,
19+
slotNavHeight,
20+
} from "../../../../consts";
21+
22+
const navigationTop = clusterIndicatorHeight + headerHeight;
23+
const stickyTop = navigationTop + slotNavHeight;
1624

1725
export default function BarsChartContainer() {
1826
const slot = useAtomValue(selectedSlotAtom);
@@ -53,8 +61,21 @@ export default function BarsChartContainer() {
5361
if (!query.response?.transactions) return null;
5462

5563
return (
56-
<Flex direction="column" key={slot}>
57-
<Flex gap="2" pb="2">
64+
<Flex direction="column" height="100%" key={slot}>
65+
<Flex
66+
id="transaction-bars-controls"
67+
gap="2"
68+
position="sticky"
69+
top={`${stickyTop}px`}
70+
style={{
71+
// Match card background
72+
background: "#141720",
73+
// To draw above txn bars and tooltip
74+
zIndex: 4,
75+
paddingBottom: "16px",
76+
marginBottom: "-8px",
77+
}}
78+
>
5879
<CardHeader text="Banks" />
5980
<ChartControls
6081
transactions={query.response.transactions}

0 commit comments

Comments
 (0)