Skip to content

Commit 048da03

Browse files
refactor(frontend): update block time tracker components for improved execution time visualization
1 parent 2282403 commit 048da03

File tree

6 files changed

+186
-150
lines changed

6 files changed

+186
-150
lines changed

frontend/components/block-time-tracker/block-time-legend.tsx

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,24 @@ export const BlockTimeLegend = () => {
44
return (
55
<div className="flex flex-col justify-between gap-6 text-xs sm:gap-4 sm:flex-row sm:text-sm text-zinc-400">
66
<div className="flex flex-row gap-2 sm:max-w-1/3 text-zinc-500">
7-
<Info className="w-4 h-lh" />
7+
<Info className="w-4 h-4 shrink-0 mt-0.5" />
88
<div className="flex flex-col gap-1">
9-
<span className="text-sm">Height = execution time</span>
9+
<span className="text-sm">Bar height reflects execution time.</span>
1010
<span className="text-sm">
11-
Purple glow = concurrent transactions observed
11+
Factor = total tx exec time / block exec time.
1212
</span>
1313
</div>
1414
</div>
1515
<div className="flex flex-wrap gap-2 xs:gap-6">
1616
<div className="flex items-center gap-2">
17-
<div className="w-4 h-10 bg-zinc-600 rounded-t-sm" />
18-
<p className="hidden xs:block">Block Execution Time</p>
19-
<p className="block xs:hidden">Block Exec. Time</p>
17+
<div className="w-4 h-10 bg-tracker-active/25 rounded-t-sm ring-1 ring-tracker-active/25" />
18+
<p className="hidden xs:block">Block execution time</p>
19+
<p className="block xs:hidden">Block</p>
2020
</div>
2121
<div className="flex items-center gap-2">
22-
<div className="w-4 h-10 bg-zinc-600 rounded-t-sm relative">
23-
<div className="absolute bottom-0 left-0 w-full h-1/2 bg-bg-card-darker rounded-t-sm" />
24-
</div>
25-
<p className="hidden xs:block">Transaction Execution Time</p>
26-
<p className="block xs:hidden">Tx Exec. Time</p>
27-
</div>
28-
<div className="flex items-center gap-2">
29-
<div
30-
className="w-4 h-10 bg-[#7B66A2] rounded-t-sm"
31-
style={{
32-
boxShadow:
33-
'0 0 0.3125rem var(--color-purple-glow), 0 0 0.625rem var(--color-purple-glow)',
34-
}}
35-
/>
36-
<p className="hidden xs:block">Parallel Execution</p>
37-
<p className="block xs:hidden">Parallel Exec.</p>
22+
<div className="w-4 h-10 bg-tracker-active rounded-t-sm" />
23+
<p className="hidden xs:block">Total tx execution time</p>
24+
<p className="block xs:hidden">Tx exec</p>
3825
</div>
3926
</div>
4027
</div>

frontend/components/block-time-tracker/block-time-timeline.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import type { Block } from '@/types/block'
88
import { BlockTime } from './block-time'
99

1010
const BLOCK_DIMENSIONS = {
11-
small: { itemWidth: 120, gridHeight: 280 },
12-
large: { itemWidth: 140, gridHeight: 280 },
11+
small: { itemWidth: 150, gridHeight: 280 },
12+
large: { itemWidth: 180, gridHeight: 280 },
1313
}
1414

1515
const getResponsiveDimensions = () => {
@@ -27,27 +27,27 @@ const getResponsiveDimensions = () => {
2727
interface BlockTimeTimelineProps {
2828
blocks: Block[]
2929
isFollowingChain: boolean
30-
normalizedBlockExecutionTime: number
30+
normalizedTimeScaleMs: number
3131
}
3232

3333
interface BlockCellData {
3434
blocks: Block[]
35-
normalizedBlockExecutionTime: number
35+
normalizedTimeScaleMs: number
3636
}
3737

3838
function BlockCell({
3939
columnIndex,
4040
style,
4141
blocks,
42-
normalizedBlockExecutionTime,
42+
normalizedTimeScaleMs,
4343
}: CellComponentProps<BlockCellData>) {
4444
const block = blocks[columnIndex]
4545

4646
return (
4747
<div style={style} className="flex items-center justify-center relative">
4848
<BlockTime
4949
block={block}
50-
normalizedBlockExecutionTime={normalizedBlockExecutionTime}
50+
normalizedTimeScaleMs={normalizedTimeScaleMs}
5151
/>
5252
</div>
5353
)
@@ -61,7 +61,7 @@ function BlockCell({
6161
export function BlockTimeTimeline({
6262
blocks,
6363
isFollowingChain,
64-
normalizedBlockExecutionTime,
64+
normalizedTimeScaleMs,
6565
}: BlockTimeTimelineProps) {
6666
const containerRef = useRef<HTMLDivElement>(null)
6767
const [containerWidth, setContainerWidth] = useState(0)
@@ -117,7 +117,7 @@ export function BlockTimeTimeline({
117117
defaultWidth={containerWidth}
118118
overscanCount={3}
119119
cellComponent={BlockCell}
120-
cellProps={{ blocks: sortedBlocks, normalizedBlockExecutionTime }}
120+
cellProps={{ blocks: sortedBlocks, normalizedTimeScaleMs }}
121121
className="scrollbar-none"
122122
style={{
123123
overflowX: isFollowingChain ? 'hidden' : 'auto',

frontend/components/block-time-tracker/block-time.tsx

Lines changed: 98 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -6,80 +6,77 @@ import {
66
TooltipTrigger,
77
} from '@/components/ui/tooltip'
88
import { EXPLORER_URL } from '@/constants/common'
9-
import { calculateBarMetrics, fromNsToMsPrecise } from '@/lib/block-metrics'
9+
import { PARALLEL_EXECUTION_RATIO_THRESHOLD } from '@/hooks/use-block-tracker'
10+
import { calculateBarMetrics } from '@/lib/block-metrics'
1011
import { formatBlockNumber } from '@/lib/ui'
1112
import { cn } from '@/lib/utils'
1213
import type { Block } from '@/types/block'
1314
import { ExternalLink } from '../ui/external-link'
1415

1516
interface BlockTimeProps {
1617
block: Block
17-
normalizedBlockExecutionTime: number
18+
normalizedTimeScaleMs: number
1819
}
1920

20-
export const BlockTime = ({
21-
block,
22-
normalizedBlockExecutionTime,
23-
}: BlockTimeProps) => {
21+
export const BlockTime = ({ block, normalizedTimeScaleMs }: BlockTimeProps) => {
2422
const {
25-
barHeightPercentage,
26-
fillPercentage,
23+
blockHeightPct,
24+
txHeightPct,
25+
blockMs,
2726
totalTransactionTime,
28-
isHighlyParallel,
27+
isParallelExecution,
28+
parallelizationRatio,
29+
timeSavedMs,
2930
} = useMemo(
30-
() => calculateBarMetrics(block, normalizedBlockExecutionTime),
31-
[block, normalizedBlockExecutionTime],
31+
() =>
32+
calculateBarMetrics(
33+
block,
34+
normalizedTimeScaleMs,
35+
PARALLEL_EXECUTION_RATIO_THRESHOLD,
36+
),
37+
[block, normalizedTimeScaleMs],
3238
)
3339

34-
const formattedBlockExecutionTime = fromNsToMsPrecise(
35-
block.executionTime ?? BigInt(0),
36-
).toFixed(3)
40+
const formattedBlockExecutionTime = blockMs.toFixed(3)
3741
const formattedTotalTransactionTime = totalTransactionTime.toFixed(3)
3842
const numberOfTransactions = (block.transactions ?? []).length
39-
const parallelPercentage = isHighlyParallel
40-
? (Number(formattedTotalTransactionTime) * 100) /
41-
Number(formattedBlockExecutionTime) -
42-
100
43-
: 0 // Compute actual percentage of difference tx time and execution between block
44-
const timeSaved =
45-
Number(formattedTotalTransactionTime) - Number(formattedBlockExecutionTime)
43+
const parallelRatioLabel = `${parallelizationRatio.toFixed(2)}×`
44+
const timeSaved = timeSavedMs
4645

4746
return (
48-
<div className="flex flex-col items-center gap-4 min-w-20">
47+
<div className="flex flex-col items-center gap-4 min-w-20 w-full">
4948
{/* Block Bar Container */}
50-
<div className="relative w-full h-32 flex flex-col justify-end p-1.5">
51-
{/* Block Time Container (represents total block execution time) */}
49+
<div className="relative w-full h-32 flex flex-col justify-end">
50+
{/* Dual bar comparison (Block exec time vs total tx exec time) */}
5251
<Tooltip>
5352
<TooltipTrigger asChild>
54-
<motion.div
55-
initial={{ height: 0 }}
56-
animate={{ height: `${barHeightPercentage}%` }}
57-
transition={{ duration: 0.2 }}
53+
<div
5854
className={cn(
59-
'w-full rounded-t-md relative bg-zinc-600',
60-
'hover:shadow-lg transition-all duration-200 cursor-pointer',
55+
'w-full h-full flex items-end gap-2 px-3.5 py-1.5 rounded-lg',
56+
'hover:bg-white/5 transition-all duration-200 cursor-pointer',
6157
)}
62-
title={`Block ${block.number}: ${formattedBlockExecutionTime}ms execution time, ${formattedTotalTransactionTime}ms total tx time, ${numberOfTransactions} transactions`}
58+
title={`Block ${block.number}: ${formattedBlockExecutionTime}ms block execution time, ${formattedTotalTransactionTime}ms total tx execution time`}
6359
>
64-
{/* Transaction Time Fill */}
6560
<motion.div
6661
initial={{ height: 0 }}
67-
animate={{ height: `${fillPercentage}%` }}
68-
transition={{
69-
duration: 0.4,
70-
}}
62+
animate={{ height: `${blockHeightPct}%` }}
63+
transition={{ duration: 0.2 }}
7164
className={cn(
72-
'absolute bottom-0 left-0 w-full rounded-t-md bg-bg-card-darker',
73-
isHighlyParallel && 'bg-[#7B66A2]',
65+
'flex-1 rounded-t-md bg-tracker-active/25 ring-1 ring-tracker-active/25',
7466
)}
75-
style={{
76-
boxShadow: isHighlyParallel
77-
? '0 0 0.625rem var(--color-purple-glow), 0 0 1.25rem var(--color-purple-glow)'
78-
: undefined,
79-
}}
80-
title={`${formattedTotalTransactionTime}ms total transaction execution time`}
67+
title={`${formattedBlockExecutionTime}ms block execution time`}
8168
/>
82-
</motion.div>
69+
<motion.div
70+
initial={{ height: 0 }}
71+
animate={{ height: `${txHeightPct}%` }}
72+
transition={{ duration: 0.2 }}
73+
className={cn(
74+
'flex-1 rounded-t-md bg-tracker-active ring-1 ring-tracker-active/25',
75+
isParallelExecution && 'ring-1 ring-tracker-active/60',
76+
)}
77+
title={`${formattedTotalTransactionTime}ms total tx execution time`}
78+
/>
79+
</div>
8380
</TooltipTrigger>
8481
<TooltipContent
8582
sideOffset={5}
@@ -96,15 +93,15 @@ export const BlockTime = ({
9693
<div className="flex flex-col gap-1">
9794
<div className="flex flex-row items-center justify-between">
9895
<p className="text-xs font-mono text-tooltip-text-secondary break-all">
99-
Block Execution Time
96+
Block execution time
10097
</p>
10198
<p className="text-tooltip-text text-sm font-medium">
10299
{formattedBlockExecutionTime}ms
103100
</p>
104101
</div>
105102
<div className="flex flex-row items-center justify-between">
106103
<p className="text-xs font-mono text-tooltip-text-secondary break-all">
107-
Transaction Execution Time
104+
Total tx execution time
108105
</p>
109106
<p className="text-tooltip-text text-sm font-medium">
110107
{formattedTotalTransactionTime}ms
@@ -120,30 +117,37 @@ export const BlockTime = ({
120117
</div>
121118
<div className="flex flex-row items-center justify-between">
122119
<p className="text-xs font-mono text-tooltip-text-secondary break-all">
123-
Time Saved
120+
Time saved
124121
</p>
125122
<p className="text-tooltip-text text-sm font-medium">
126-
{timeSaved < 0 ? 0 : timeSaved.toFixed(3)}
127-
ms
123+
{timeSaved.toFixed(3)}ms
128124
</p>
129125
</div>
130126
<div className="flex flex-row items-center justify-between">
131127
<p className="text-xs font-mono text-tooltip-text-secondary break-all">
132-
Parallel Efficiency
128+
Parallel factor
133129
</p>
134-
<p className="text-tooltip-text-accent text-sm font-medium">
135-
{parallelPercentage.toFixed(3)}%
130+
<p
131+
className={cn(
132+
'text-sm font-medium',
133+
isParallelExecution
134+
? 'text-tooltip-text-accent'
135+
: 'text-tooltip-text',
136+
)}
137+
>
138+
{parallelRatioLabel}
136139
</p>
137140
</div>
138141
</div>
139142
</div>
140-
{isHighlyParallel && (
143+
{isParallelExecution && (
141144
<div className="flex flex-col gap-0">
142145
<div className="border-t border-tooltip-separator my-2" />
143146
<div className="flex flex-row items-center gap-2">
144147
<div className="bg-tooltip-text-accent w-2 h-2 rounded-full" />
145148
<p className="text-tooltip-text-accent font-medium">
146-
High parallel execution detected
149+
Parallel execution: total tx execution time &gt; block
150+
execution time
147151
</p>
148152
</div>
149153
</div>
@@ -154,19 +158,51 @@ export const BlockTime = ({
154158
</div>
155159

156160
{/* Block Stats */}
157-
<div className="text-center space-y-1">
158-
<p className="text-zinc-600 font-medium text-base">
159-
{formattedBlockExecutionTime}ms
160-
</p>
161-
<p className="text-zinc-500 text-sm">{numberOfTransactions} tx</p>
161+
<div className="w-full px-3.5 flex flex-col gap-2 tabular-nums">
162+
<div className="w-full grid grid-cols-2 gap-2">
163+
<div className="flex flex-col items-center leading-tight text-center">
164+
<span className="text-[10px] text-zinc-400 uppercase tracking-wide">
165+
Block
166+
</span>
167+
<span className="text-base font-semibold text-zinc-100">
168+
{blockMs.toFixed(2)}ms
169+
</span>
170+
</div>
171+
<div className="flex flex-col items-center leading-tight text-center">
172+
<span className="text-[10px] text-zinc-400 uppercase tracking-wide">
173+
Tx exec
174+
</span>
175+
<span className="text-base font-semibold text-tracker-active">
176+
{totalTransactionTime.toFixed(2)}ms
177+
</span>
178+
</div>
179+
</div>
180+
181+
<div className="w-full h-7 mt-1 flex items-center justify-center">
182+
<span
183+
className={cn(
184+
'inline-flex max-w-full items-center rounded-md border px-2 py-0.5 text-[12px] font-medium whitespace-nowrap truncate',
185+
isParallelExecution
186+
? 'border-tracker-active/60 bg-tracker-active/20 text-white shadow-[0_0_0_0.5px_rgba(131,110,249,0.35)]'
187+
: 'border-zinc-700 bg-zinc-800/40 text-zinc-300',
188+
)}
189+
title="Parallel factor (Tx exec / Block exec)"
190+
>
191+
{isParallelExecution
192+
? `Parallel ${parallelRatioLabel}`
193+
: `Factor ${parallelRatioLabel}`}
194+
</span>
195+
</div>
162196
</div>
163197

164198
{/* Separator */}
165199
<div className="w-full h-px bg-zinc-700" />
166200

167201
{/* Block number Label */}
168-
<div className="text-sm font-medium text-zinc-600">
169-
{formatBlockNumber(block.number)}
202+
<div className="w-full px-3.5 flex items-center justify-center">
203+
<div className="text-sm font-medium text-zinc-400">
204+
{formatBlockNumber(block.number)}
205+
</div>
170206
</div>
171207
</div>
172208
)

frontend/components/block-time-tracker/index.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ import { BlockTimeTimeline } from './block-time-timeline'
2222
* and calculates execution timing metrics for visualization.
2323
*/
2424
export function BlockTimeExecutionTracker() {
25-
const {
26-
finalizedBlocks,
27-
maxBlockExecutionTime,
28-
normalizedBlockExecutionTime,
29-
} = useBlockTracker()
25+
const { finalizedBlocks, maxBlockExecutionTime, normalizedTimeScaleMs } =
26+
useBlockTracker()
3027
const [isFollowingChain, setIsFollowingChain] = useState(true)
3128
const { isHovering, hoverProps } = useMouseHover()
3229
const isPaused = !isFollowingChain || isHovering
@@ -80,7 +77,7 @@ export function BlockTimeExecutionTracker() {
8077
<div className="w-full flex flex-col gap-4 sm:gap-6">
8178
<SectionHeader
8279
title="Block Execution Timeline"
83-
description="Each bar represents a block. Height shows execution time."
80+
description="Two bars per block: block execution time (gray) and total tx execution time (purple). Purple bar taller than gray bar indicates parallel execution in the block."
8481
>
8582
<button
8683
type="button"
@@ -106,13 +103,13 @@ export function BlockTimeExecutionTracker() {
106103
<span>Tap Pause to freeze and scroll through blocks</span>
107104
</div>
108105

109-
<div className="w-full flex flex-col gap-5 dark-component-colors rounded-xl border p-4 sm:p-6 lg:p-8">
106+
<div className="w-full flex flex-col gap-5 dark-component-colors rounded-xl border p-4 sm:p-5">
110107
{/* Scrollable Blocks Container */}
111108
<button type="button" className="flex-1" {...hoverProps}>
112109
<BlockTimeTimeline
113110
blocks={finalizedBlocks}
114111
isFollowingChain={!isPaused}
115-
normalizedBlockExecutionTime={normalizedBlockExecutionTime}
112+
normalizedTimeScaleMs={normalizedTimeScaleMs}
116113
/>
117114
</button>
118115

0 commit comments

Comments
 (0)