Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 57 additions & 27 deletions benchmarks/gas-estimation.yml

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions benchmarks/perp-funding.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ subtitle: Funding cost in basis points to hold a long position for 24 hours at t
category: Trading
status: live
metric: Funding cost to hold a long 24h
unit: bps
unit: bp
higher_is_better: false

disclaimer: |
Expand Down Expand Up @@ -203,57 +203,57 @@ metric_panels:
label: Per-hour rate (ETH)
metric: perp_funding_rate_hourly_bps{asset="ETH"}
label_key: venue
unit: bps
unit: bp
description: "Live ETH funding normalized to a per hour basis, in bps. The snapshot behind the smoothed headline."
- id: btc_hold
label: BTC hold 24h
metric: perp_funding_hold_24h_bps{asset="BTC"}
label_key: venue
unit: bps
unit: bp
description: "Cost in bps of holding a BTC long for 24 hours at the current rate."
- id: sol_hold
label: SOL hold 24h
metric: perp_funding_hold_24h_bps{asset="SOL"}
label_key: venue
unit: bps
unit: bp
description: "Cost in bps of holding a SOL long for 24 hours at the current rate."
# Data-only panels (tab: false): they feed the ledger's 7d/30d
# timeframe toggle below.
- id: eth_hold_7d
label: ETH hold 7d avg
metric: avg_over_time(perp_funding_hold_24h_bps{asset="ETH"}[7d])
label_key: venue
unit: bps
unit: bp
tab: false
- id: eth_hold_30d
label: ETH hold 30d avg
metric: avg_over_time(perp_funding_hold_24h_bps{asset="ETH"}[30d])
label_key: venue
unit: bps
unit: bp
tab: false
- id: btc_hold_7d
label: BTC hold 7d avg
metric: avg_over_time(perp_funding_hold_24h_bps{asset="BTC"}[7d])
label_key: venue
unit: bps
unit: bp
tab: false
- id: btc_hold_30d
label: BTC hold 30d avg
metric: avg_over_time(perp_funding_hold_24h_bps{asset="BTC"}[30d])
label_key: venue
unit: bps
unit: bp
tab: false
- id: sol_hold_7d
label: SOL hold 7d avg
metric: avg_over_time(perp_funding_hold_24h_bps{asset="SOL"}[7d])
label_key: venue
unit: bps
unit: bp
tab: false
- id: sol_hold_30d
label: SOL hold 30d avg
metric: avg_over_time(perp_funding_hold_24h_bps{asset="SOL"}[30d])
label_key: venue
unit: bps
unit: bp
tab: false
- id: interval
label: Funding interval h
Expand Down
4 changes: 4 additions & 0 deletions src/components/time-series-chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,10 @@ function fmtTick(v: number, unit: string) {
if (abs >= 1e3) return `${(v / 1e3).toFixed(1)}K`;
return `${Math.round(v)}`;
}
if (unit === "bp") {
const abs = Math.abs(v);
return `${v.toFixed(abs < 10 ? 2 : abs < 100 ? 1 : 0)}bps`;
}
if (unit === "sec") {
if (v >= 86400) return `${(v / 86400).toFixed(1)}d`;
if (v >= 3600) return `${(v / 3600).toFixed(1)}h`;
Expand Down
14 changes: 13 additions & 1 deletion src/lib/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ export function fmtUnit(value: number, unit: string) {
// Legacy: bps stored. Convert to percent for display.
return formatPercent(value / 100);
}
if (unit === "bp") {
// Basis points displayed AS basis points (signed). Funding-style
// figures (fractions of a bp per day) become unreadable through the
// bps->percent conversion above: -0.74 bp rendered "-0.0074%".
const abs = Math.abs(value);
if (value === 0) return "0 bps";
if (abs < 0.005) return "~0 bps";
if (abs < 10) return `${value.toFixed(2)} bps`;
if (abs < 100) return `${value.toFixed(1)} bps`;
return `${value.toFixed(0)} bps`;
}
if (unit === "sec") {
// True seconds (unlike "s", whose input is ms by latency-bench
// convention). Used by gauges like hl_*_last_fill_age_seconds.
Expand Down Expand Up @@ -79,6 +90,7 @@ export function fmtUnit(value: number, unit: string) {
*/
export function unitSuffix(unit: string, value?: number): string {
if (unit === "pct" || unit === "bps") return " %";
if (unit === "bp") return " bps";
if (unit === "sec") {
if (value !== undefined && Number.isFinite(value)) {
if (value >= 172800) return " d";
Expand Down Expand Up @@ -106,7 +118,7 @@ export function unitSuffix(unit: string, value?: number): string {
export function fmtValue(value: number, unit: string): string {
// Keep K/M/B suffixes and $ prefix — they are part of the number, not a
// unit. Only strip trailing unit words that the caller renders separately.
return fmtUnit(value, unit).replace(/\s+(ms|s|min|h|d|slots?)$/, "").replace(/\s*%$/, "");
return fmtUnit(value, unit).replace(/\s+(ms|s|min|h|d|bps|slots?)$/, "").replace(/\s*%$/, "");
}

/** Compact short-form for large counts so the home table's narrow value
Expand Down
4 changes: 2 additions & 2 deletions src/lib/spec-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export const SpecSchema = z
/* Metric */
metric: z.string().min(1).max(100),
/** ms / s for latencies; pct for fees as percent of notional; bps for basis points; slots for Solana slot delta. */
unit: z.enum(["ms", "s", "sec", "pct", "bps", "count", "slots", "usd"]),
unit: z.enum(["ms", "s", "sec", "pct", "bps", "bp", "count", "slots", "usd"]),
/** True when bigger numbers are better (coverage, count). Default false:
* latency, fees, drift. every existing bench is "lower is better". */
higher_is_better: z.boolean().default(false),
Expand Down Expand Up @@ -369,7 +369,7 @@ export const SpecSchema = z
/** The PromQL label that holds each provider's slug. Defaults to
* "builder"; other benches may use "provider", "venue", etc. */
label_key: z.string().min(1).max(40).default("builder"),
unit: z.enum(["ms", "s", "sec", "pct", "bps", "count", "slots", "usd"]),
unit: z.enum(["ms", "s", "sec", "pct", "bps", "bp", "count", "slots", "usd"]),
higher_is_better: z.boolean().default(false),
/** When false the panel is data-only: it is loaded and can feed
* ledger_columns window variants, but renders no chart tab.
Expand Down
20 changes: 17 additions & 3 deletions src/lib/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ const loadBenchmarkUnfilteredCached = unstable_cache(
// v7: added ledgerColumns (per-bench ledger column relabeling).
// v8: outage panel unit s -> sec (true seconds); cached v7 objects keep
// the old unit and would render "0.0 s" via the ms-input formatter.
["bench-unfiltered-v8"],
// v9: perp-funding unit bps -> bp (true basis points display).
["bench-unfiltered-v9"],
{ revalidate: 60, tags: ["benchmarks"] },
);

Expand Down Expand Up @@ -172,7 +173,8 @@ const loadAllBenchmarksCached = unstable_cache(
// v8: bumped with bench-unfiltered-v6 (cellRanks) for the same reason.
// v9: bumped with bench-unfiltered-v7 (ledgerColumns).
// v10: bumped with bench-unfiltered-v8 (sec unit).
["all-benchmarks-v10"],
// v11: bumped with bench-unfiltered-v9 (bp unit).
["all-benchmarks-v11"],
{ revalidate: 60, tags: ["benchmarks"] },
);
export const loadAllBenchmarks = cache(loadAllBenchmarksCached);
Expand Down Expand Up @@ -217,7 +219,8 @@ const loadBenchmarkFiltered = unstable_cache(
},
// v4: bumped with bench-unfiltered-v7 (ledgerColumns).
// v5: bumped with bench-unfiltered-v8 (sec unit).
["bench-filters-v5"],
// v6: bumped with bench-unfiltered-v9 (bp unit).
["bench-filters-v6"],
{ revalidate: 60, tags: ["benchmarks"] }
);

Expand Down Expand Up @@ -658,6 +661,17 @@ function applyDimensionsToSpec(spec: Spec, labels: Record<string, string>): Spec
const inject = (q: string | undefined) => (q ? injectLabels(q, labels) : q);
return {
...spec,
// Panels declare a bare metric name (or metric{sel}); normalize to the
// braced form so dimension labels (chain=..., region=...) reach them
// like every provider query. Without this a panel on a chain-dimensioned
// bench silently mixes every chain's series.
metric_panels: spec.metric_panels?.map((panel) => ({
...panel,
metric: injectLabels(
panel.metric.includes("{") ? panel.metric : `${panel.metric}{}`,
labels,
),
})),
providers: spec.providers.map((p) => ({
...p,
queries: p.queries
Expand Down
1 change: 1 addition & 0 deletions src/lib/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const ALLOWED_BY_UNIT: Record<Benchmark["unit"], ViewType[]> = {
s: ["timeseries", "rankedBar", "distribution", "donut"],
sec: ["timeseries", "rankedBar", "distribution", "donut"],
bps: ["timeseries", "rankedBar", "distribution", "donut"],
bp: ["timeseries", "rankedBar", "distribution", "donut"],
pct: ["timeseries", "rankedBar", "distribution", "donut"],
count: ["countLeaderboard", "rankedBar", "donut", "distribution", "timeseries"],
// slots: integer-ish gauge values (Solana slot delta). Same view set as
Expand Down
6 changes: 3 additions & 3 deletions src/types/benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export type MetricPanel = {
label: string;
description?: string;
metric: string;
unit: "ms" | "s" | "sec" | "pct" | "bps" | "count" | "slots" | "usd";
unit: "ms" | "s" | "sec" | "pct" | "bps" | "bp" | "count" | "slots" | "usd";
higherIsBetter: boolean;
/** When false the panel is data-only (feeds ledger column window
* variants) and renders no chart tab. */
Expand Down Expand Up @@ -146,7 +146,7 @@ export type Benchmark = {
sampleSize: number;
abstract: string;
metric: string;
unit: "ms" | "s" | "sec" | "pct" | "bps" | "count" | "slots" | "usd";
unit: "ms" | "s" | "sec" | "pct" | "bps" | "bp" | "count" | "slots" | "usd";
higherIsBetter: boolean;
/** Optional drill-down dimensions exposed by the bench. When set, the
* bench page renders one tab selector per dimension and the queries get
Expand Down Expand Up @@ -217,7 +217,7 @@ export type LedgerColumn = {
panel?: string;
/** Display unit override; defaults to the panel's unit (panel columns)
* or the bench unit (slot columns). */
unit?: "ms" | "s" | "sec" | "pct" | "bps" | "count" | "slots" | "usd";
unit?: "ms" | "s" | "sec" | "pct" | "bps" | "bp" | "count" | "slots" | "usd";
/** Per-window value sources for the ledger's timeframe toggle: window
* key to metric_panels id. Columns without a mapping keep their 24h
* value when a longer window is selected. */
Expand Down
Loading