Skip to content

Commit 7a7e1b8

Browse files
authored
perf: add gas limit bands and RLPx cap (#868)
1 parent 875921d commit 7a7e1b8

1 file changed

Lines changed: 184 additions & 72 deletions

File tree

apps/perf/src/routes/benchmark.$id.tsx

Lines changed: 184 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,12 @@ function RunDetailPage(): React.JSX.Element {
259259
const residentSeries = findSeries(m, 'reth_jemalloc_resident')
260260
const allocatedSeries = findSeries(m, 'reth_jemalloc_allocated')
261261

262+
// Gas limit breakdown (derived from block gas limit)
263+
const refGasLimit = blocks?.[0]?.gasLimit ?? 0
264+
const sharedGasLimit = Math.floor(refGasLimit / 10)
265+
const generalGasLimit = 30_000_000
266+
const paymentGasLimit = refGasLimit - sharedGasLimit - generalGasLimit
267+
262268
return (
263269
<div>
264270
<div className="mb-4">
@@ -380,6 +386,99 @@ function RunDetailPage(): React.JSX.Element {
380386
]}
381387
formatValue={(v) => formatGas(v, false)}
382388
xFormat="block"
389+
referenceBands={
390+
refGasLimit > 0
391+
? [
392+
{
393+
label: `General (${formatGas(generalGasLimit, false)})`,
394+
from: 0,
395+
to: generalGasLimit,
396+
color: COLORS.blue,
397+
},
398+
{
399+
label: `Payment (${formatGas(paymentGasLimit, false)})`,
400+
from: generalGasLimit,
401+
to: generalGasLimit + paymentGasLimit,
402+
color: COLORS.orange,
403+
},
404+
{
405+
label: `Shared (${formatGas(sharedGasLimit, false)})`,
406+
from: generalGasLimit + paymentGasLimit,
407+
to: refGasLimit,
408+
color: COLORS.purple,
409+
},
410+
]
411+
: undefined
412+
}
413+
/>
414+
<TimeSeriesChart
415+
title="Gas Fill %"
416+
tooltip="Percentage of the block gas limit that was used."
417+
showMean
418+
series={[
419+
{
420+
label: 'Fill %',
421+
color: COLORS.blue,
422+
data: blocks
423+
.filter((b) => b.gasLimit > 0)
424+
.map((b) => ({
425+
x: b.index,
426+
y: (b.gasUsed / b.gasLimit) * 100,
427+
})),
428+
},
429+
]}
430+
formatValue={(v) => `${v.toFixed(1)}%`}
431+
yMax={100}
432+
xFormat="block"
433+
referenceBands={
434+
refGasLimit > 0
435+
? [
436+
{
437+
label: `General (${((generalGasLimit / refGasLimit) * 100).toFixed(0)}%)`,
438+
from: 0,
439+
to: (generalGasLimit / refGasLimit) * 100,
440+
color: COLORS.blue,
441+
},
442+
{
443+
label: `Payment (${((paymentGasLimit / refGasLimit) * 100).toFixed(0)}%)`,
444+
from: (generalGasLimit / refGasLimit) * 100,
445+
to:
446+
((generalGasLimit + paymentGasLimit) / refGasLimit) *
447+
100,
448+
color: COLORS.orange,
449+
},
450+
{
451+
label: `Shared (${((sharedGasLimit / refGasLimit) * 100).toFixed(0)}%)`,
452+
from:
453+
((generalGasLimit + paymentGasLimit) / refGasLimit) *
454+
100,
455+
to: 100,
456+
color: COLORS.purple,
457+
},
458+
]
459+
: undefined
460+
}
461+
/>
462+
<TimeSeriesChart
463+
title="RLP Block Size"
464+
tooltip="RLP-encoded size of each block in kilobytes."
465+
showMean
466+
series={[
467+
{
468+
label: 'Size',
469+
color: COLORS.green,
470+
data: transformSamples(rlpSizeSeries, (v) => v / 1024),
471+
},
472+
]}
473+
formatValue={(v) => `${v.toFixed(0)} KB`}
474+
referenceBands={[
475+
{
476+
label: 'RLPx hard cap (16 MiB)',
477+
from: 16 * 1024,
478+
to: 16 * 1024 * 1.05,
479+
color: COLORS.red,
480+
},
481+
]}
383482
/>
384483
</div>
385484
</section>
@@ -521,48 +620,6 @@ function RunDetailPage(): React.JSX.Element {
521620
</div>
522621
</section>
523622

524-
<section className="mb-10">
525-
<SectionHeader
526-
title="Block Headroom"
527-
tooltip="How close blocks are to their gas limit and size constraints."
528-
/>
529-
<div className="grid grid-cols-1 gap-3 md:grid-cols-2">
530-
<TimeSeriesChart
531-
title="Gas Fill %"
532-
tooltip="Percentage of the block gas limit that was used."
533-
showMean
534-
series={[
535-
{
536-
label: 'Fill %',
537-
color: COLORS.blue,
538-
data: (blocks ?? [])
539-
.filter((b) => b.gasLimit > 0)
540-
.map((b) => ({
541-
x: b.index,
542-
y: (b.gasUsed / b.gasLimit) * 100,
543-
})),
544-
},
545-
]}
546-
formatValue={(v) => `${v.toFixed(1)}%`}
547-
yMax={100}
548-
xFormat="block"
549-
/>
550-
<TimeSeriesChart
551-
title="RLP Block Size"
552-
tooltip="RLP-encoded size of each block in kilobytes."
553-
showMean
554-
series={[
555-
{
556-
label: 'Size',
557-
color: COLORS.green,
558-
data: transformSamples(rlpSizeSeries, (v) => v / 1024),
559-
},
560-
]}
561-
formatValue={(v) => `${v.toFixed(0)} KB`}
562-
/>
563-
</div>
564-
</section>
565-
566623
<section className="mb-10">
567624
<SectionHeader
568625
title="Txgen"
@@ -860,6 +917,13 @@ function seriesMean(data: Array<ChartPoint>): number {
860917
return data.reduce((sum, p) => sum + p.y, 0) / data.length
861918
}
862919

920+
type ReferenceBand = {
921+
label: string
922+
from: number
923+
to: number
924+
color: string
925+
}
926+
863927
function TimeSeriesChart(props: {
864928
series: Array<ChartSeries>
865929
title?: string | undefined
@@ -869,6 +933,7 @@ function TimeSeriesChart(props: {
869933
formatValue?: ((v: number) => string) | undefined
870934
xFormat?: 'time' | 'block' | undefined
871935
yMax?: number | undefined
936+
referenceBands?: Array<ReferenceBand> | undefined
872937
}): React.JSX.Element {
873938
const plotRef = React.useRef<HTMLDivElement>(null)
874939
const [hoverX, setHoverX] = React.useState<number | null>(null)
@@ -897,6 +962,10 @@ function TimeSeriesChart(props: {
897962
const xMax = refSeries.data.at(-1)?.x ?? 1
898963
const xRange = xMax - xMin || 1
899964

965+
const refBandMax = props.referenceBands?.length
966+
? Math.max(...props.referenceBands.map((rb) => rb.to))
967+
: 0
968+
900969
let yMax: number
901970
if (props.yMax != null) {
902971
yMax = props.yMax
@@ -907,9 +976,12 @@ function TimeSeriesChart(props: {
907976
for (const s of props.series) sum += s.data[i]?.y ?? 0
908977
sums.push(sum)
909978
}
910-
yMax = (Math.max(...sums) || 1) * 1.1
979+
yMax = Math.max((Math.max(...sums) || 1) * 1.1, refBandMax * 1.05)
911980
} else {
912-
yMax = (Math.max(...allPoints.map((p) => p.y)) || 1) * 1.1
981+
yMax = Math.max(
982+
(Math.max(...allPoints.map((p) => p.y)) || 1) * 1.1,
983+
refBandMax * 1.05,
984+
)
913985
}
914986
const yMin = 0
915987
const yRange = yMax - yMin || 1
@@ -1082,6 +1154,46 @@ function TimeSeriesChart(props: {
10821154
))
10831155
))}
10841156

1157+
{/* Reference bands */}
1158+
{props.referenceBands?.map((rb) => {
1159+
const y1 = sy(rb.to)
1160+
const y2 = sy(rb.from)
1161+
const h = y2 - y1
1162+
const midY = y1 + h / 2
1163+
return (
1164+
<React.Fragment key={rb.label}>
1165+
<rect
1166+
x={0}
1167+
y={y1}
1168+
width={SVG_W}
1169+
height={h}
1170+
fill={rb.color}
1171+
opacity={0.1}
1172+
/>
1173+
<line
1174+
x1={0}
1175+
y1={y1}
1176+
x2={SVG_W}
1177+
y2={y1}
1178+
stroke={rb.color}
1179+
vectorEffect="non-scaling-stroke"
1180+
strokeWidth={0.5}
1181+
opacity={0.3}
1182+
/>
1183+
<text
1184+
x={SVG_W - 4}
1185+
y={h > 12 ? midY + 3 : y1 + 11}
1186+
textAnchor="end"
1187+
fill={rb.color}
1188+
fontSize={8}
1189+
opacity={0.8}
1190+
>
1191+
{rb.label}
1192+
</text>
1193+
</React.Fragment>
1194+
)
1195+
})}
1196+
10851197
{/* Stacked area fills */}
10861198
{props.stacked &&
10871199
stackedAreas.map((a) => (
@@ -1141,36 +1253,36 @@ function TimeSeriesChart(props: {
11411253
strokeDasharray="3 3"
11421254
/>
11431255
)}
1256+
</svg>
11441257

1145-
{/* Hover dots */}
1146-
{hoverX !== null &&
1147-
props.series.map((s) => {
1148-
const pt = closestPoint(s.data, hoverX)
1149-
if (!pt) return null
1150-
let y = pt.y
1151-
if (props.stacked) {
1152-
const si = props.series.indexOf(s)
1153-
y = 0
1154-
for (let j = 0; j <= si; j++) {
1155-
const cp = closestPoint(props.series[j].data, hoverX)
1156-
y += cp?.y ?? 0
1157-
}
1258+
{/* Hover dots (HTML to avoid SVG stretch distortion) */}
1259+
{hoverX !== null &&
1260+
props.series.map((s) => {
1261+
const pt = closestPoint(s.data, hoverX)
1262+
if (!pt) return null
1263+
let y = pt.y
1264+
if (props.stacked) {
1265+
const si = props.series.indexOf(s)
1266+
y = 0
1267+
for (let j = 0; j <= si; j++) {
1268+
const cp = closestPoint(props.series[j].data, hoverX)
1269+
y += cp?.y ?? 0
11581270
}
1159-
return (
1160-
<circle
1161-
key={s.label}
1162-
cx={sx(pt.x)}
1163-
cy={sy(y)}
1164-
r={3}
1165-
fill={s.color}
1166-
stroke="currentColor"
1167-
className="text-surface"
1168-
vectorEffect="non-scaling-stroke"
1169-
strokeWidth={1.5}
1170-
/>
1171-
)
1172-
})}
1173-
</svg>
1271+
}
1272+
const xPct = ((pt.x - xMin) / xRange) * 100
1273+
const yPct = (1 - (y - yMin) / yRange) * 100
1274+
return (
1275+
<div
1276+
key={s.label}
1277+
className="pointer-events-none absolute h-2 w-2 -translate-x-1/2 -translate-y-1/2 rounded-full border-[1.5px] border-surface"
1278+
style={{
1279+
left: `${xPct}%`,
1280+
top: `${yPct}%`,
1281+
backgroundColor: s.color,
1282+
}}
1283+
/>
1284+
)
1285+
})}
11741286

11751287
{/* Hover tooltip */}
11761288
{hoverX !== null && (

0 commit comments

Comments
 (0)