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
21 changes: 21 additions & 0 deletions harnesses/axelar-gmp-latency/cmd/script/chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,27 @@ import "strings"
// - Cosmos chains (osmosis, injective, sei, celestia, kava) are
// Axelar-exclusive coverage vs Wormhole/LayerZero/CCIP/Hyperlane
//
// axelarTrackedChains is the set of OCB canonical slugs we record metrics for.
// Only messages where BOTH source AND destination are in this set are
// observed, capping cardinality at len²×buckets.
// Derived from the bench YAML provider slugs.
var axelarTrackedChains = map[string]bool{
"ethereum": true,
"polygon": true,
"base": true,
"moonbeam": true,
"osmosis": true,
"arbitrum": true,
"avalanche": true,
"bnb": true,
"celo": true,
"injective": true,
"linea": true,
"mantle": true,
"optimism": true,
"scroll": true,
}

// Unknown names fall through to `chain-<lowered>` so we never drop data.
var axelarChainSlug = map[string]string{
// EVM L1s
Expand Down
6 changes: 4 additions & 2 deletions harnesses/axelar-gmp-latency/cmd/script/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,10 @@ func poll(ctx context.Context, client *http.Client, seen *lruSet) error {
totalMs := float64(m.TimeSpent.Total) * 1000
if totalMs > 0 && totalMs <= maxLatencyMs {
dst := canonicalizeAxelarChain(m.Call.ReturnValues.DestinationChain)
axelarE2ELatencyMs.WithLabelValues(src, dst).Observe(totalMs)
axelarSeenTotal.WithLabelValues(src, dst).Inc()
if axelarTrackedChains[src] && axelarTrackedChains[dst] {
axelarE2ELatencyMs.WithLabelValues(src, dst).Observe(totalMs)
axelarSeenTotal.WithLabelValues(src, dst).Inc()
}
}

seen.add(m.ID)
Expand Down
26 changes: 26 additions & 0 deletions harnesses/chainlink-ccip-latency/cmd/script/chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,32 @@ package main
// makes the mapping legible and the audit trail obvious when CCIP
// adds a new chain we didn't anticipate.
//
// ccipTrackedChains is the set of OCB canonical slugs we record metrics for.
// Only messages where BOTH source AND destination are in this set are
// observed, capping cardinality at len²×buckets.
// Derived from the bench YAML provider slugs.
var ccipTrackedChains = map[string]bool{
"ethereum": true,
"bnb": true,
"polygon": true,
"avalanche": true,
"arbitrum": true,
"base": true,
"robinhood": true,
"berachain": true,
"celo": true,
"ink": true,
"linea": true,
"mantle": true,
"monad": true,
"moonbeam": true,
"optimism": true,
"scroll": true,
"solana": true,
"unichain": true,
"world-chain": true,
}

// Only mainnet entries are mapped; testnet rows are dropped in main.go
// via the `environment != "mainnet"` guard so we never emit test-chain
// latency.
Expand Down
4 changes: 4 additions & 0 deletions harnesses/chainlink-ccip-latency/cmd/script/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ func poll(ctx context.Context, client *http.Client, seen *lruSet) error {
seen.add(m.MessageID)
continue
}
if !ccipTrackedChains[srcSlug] || !ccipTrackedChains[dstSlug] {
seen.add(m.MessageID)
continue
}
ccipLatencyMs.WithLabelValues(srcSlug, dstSlug).Observe(deltaMs)
ccipSeenTotal.WithLabelValues(srcSlug, dstSlug).Inc()
seen.add(m.MessageID)
Expand Down
29 changes: 29 additions & 0 deletions harnesses/layerzero-message-latency/cmd/script/chains.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,35 @@ package main
// - LayerZero exposes a bunch of exotic chains (orderly, flare, ape,
// robinhood, hyperliquid) that map to our slugs where they exist.
//
// lzTrackedChains is the set of OCB canonical slugs we record metrics for.
// Only messages where BOTH source AND destination are in this set are
// observed. This caps cardinality at len²×buckets instead of the full
// N×N cross-product of all chains LayerZero supports.
// Derived from the bench YAML provider slugs — add here when adding a
// new chain to the bench.
var lzTrackedChains = map[string]bool{
"ethereum": true,
"solana": true,
"bnb": true,
"arbitrum": true,
"base": true,
"optimism": true,
"polygon": true,
"avalanche": true,
"robinhood": true,
"monad": true,
"berachain": true,
"celo": true,
"injective": true,
"ink": true,
"linea": true,
"mantle": true,
"moonbeam": true,
"scroll": true,
"sui": true,
"unichain": true,
}

// Unknown names fall through to a synthetic `chain-<lowered>` slug in
// main.go so we never drop data silently.
var lzChainSlug = map[string]string{
Expand Down
4 changes: 4 additions & 0 deletions harnesses/layerzero-message-latency/cmd/script/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ func poll(ctx context.Context, client *http.Client, seen *lruSet) error {
continue
}
dstSlug := chainSlug(m.Pathway.Receiver.Chain)
if !lzTrackedChains[srcSlug] || !lzTrackedChains[dstSlug] {
seen.add(m.GUID)
continue
}
lzLatencyMs.WithLabelValues(srcSlug, dstSlug).Observe(deltaMs)
lzSeenTotal.WithLabelValues(srcSlug, dstSlug).Inc()
seen.add(m.GUID)
Expand Down
15 changes: 12 additions & 3 deletions src/app/api/fee-compare/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1110,27 +1110,36 @@
}

function reconstructGainsPositions(trades: GainsApiTrade[], cutoffMs: number): PositionSlice[] {
const OPEN_ACTIONS = new Set(["MarketOpened", "LimitOrderExecuted"]);
// v5 names: MarketOpened, LimitOrderExecuted — v6 names: TradeOpenedMarket, TradeOpenedLimit
const OPEN_ACTIONS = new Set(["MarketOpened", "LimitOrderExecuted", "TradeOpenedMarket", "TradeOpenedLimit"]);
// TradePosSizeIncrease updates the position size; use latest size as notional
const INCREASE_ACTIONS = new Set(["TradePosSizeIncrease"]);
const CLOSE_ACTIONS = new Set(["TradeClosedMarket", "TradeClosedTP", "TradeClosedSL", "TradeClosedLIQ"]);

const byId = new Map<number, { open?: GainsApiTrade; close?: GainsApiTrade }>();
for (const t of trades) {
if (!byId.has(t.id)) byId.set(t.id, {});
const e = byId.get(t.id)!;
if (OPEN_ACTIONS.has(t.action)) e.open = t;
else if (INCREASE_ACTIONS.has(t.action) && e.open) {
e.open = { ...e.open, size: t.size, leverage: t.leverage };
}
else if (CLOSE_ACTIONS.has(t.action)) e.close = t;
}

const now = Date.now();
const slices: PositionSlice[] = [];
for (const { open, close } of byId.values()) {
if (!open || !close) continue;
if (!open) continue;
const openMs = new Date(open.date).getTime();
if (openMs < cutoffMs) continue;
// Still-open positions use now as close time (same as reconstructHlPositions)
const closeMs = close ? new Date(close.date).getTime() : now;
slices.push({
coin: open.pair.split("/")[0],
notionalUsd: open.size * open.leverage,
openMs,
closeMs: new Date(close.date).getTime(),
closeMs,
isLong: open.buy !== false,
});
}
Expand Down Expand Up @@ -1204,7 +1213,7 @@
}

// Estimate GMX borrow fees for a set of position slices.
function estimateGmxBorrowFees(

Check warning on line 1216 in src/app/api/fee-compare/route.ts

View workflow job for this annotation

GitHub Actions / check

'estimateGmxBorrowFees' is defined but never used
positions: PositionSlice[],
borrowPerSecPerCoin: Record<string, number>
): number {
Expand Down
35 changes: 33 additions & 2 deletions src/lib/aggregate-blob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,37 @@ import type { Benchmark } from "@/types/benchmark";
import { loadSpecsUncached } from "@/lib/materialize/load";
import { overlayEditorial, slimBenchmarkForCache } from "@/lib/spec";

// Aggressive slim for the aggregate blob. Hub pages (homepage, categories,
// chains, products) only need card data — they never render editorial text
// or metric panels. Stripping these fields drops the serialized aggregate
// from ~4.3 MB to well under the 2 MB unstable_cache ceiling.
//
// Fields stripped beyond slimBenchmarkForCache (which already removes
// 7d/30d series):
// - extras.seriesByRegion24h (only used on bench detail pages)
// - metricPanels (only used on bench detail pages)
// - seoIntro, faq, disclaimer (editorial, bench detail only)
// - perChainExplainer (bench detail + worker's sitemap.json handles sitemap)
// - findings, methodology (bench detail only; required fields → [])
// - abstract (bench detail only; required field → "")
function slimForBlobAggregate(b: Benchmark): Benchmark {
const base = slimBenchmarkForCache(b);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { seriesByRegion24h: _sbr, ...slimExtras } = base.extras;
return {
...base,
extras: slimExtras,
metricPanels: undefined,
seoIntro: undefined,
faq: undefined,
perChainExplainer: undefined,
disclaimer: undefined,
findings: [],
methodology: [],
abstract: "",
};
}

// On any Vercel deployment (production or preview), use the self-hosted
// CDN proxy (/api/aggregate on openchainbench.com) so Vercel functions
// pay ~1 ms (edge cache hit) instead of ~12 s fetching the 7.5 MB blob
Expand Down Expand Up @@ -113,7 +144,7 @@ async function fetchAndProject(): Promise<Benchmark[] | null> {
for (const bench of raw.benches) {
const spec = specBySlug.get(bench.slug);
if (!spec) continue; // Bench in blob no longer has a spec — skip.
projected.push(slimBenchmarkForCache(overlayEditorial(bench, spec)));
projected.push(slimForBlobAggregate(overlayEditorial(bench, spec)));
}
return projected.sort((a, b) =>
(a.number ?? "").localeCompare(b.number ?? ""),
Expand All @@ -130,6 +161,6 @@ async function fetchAndProject(): Promise<Benchmark[] | null> {
*/
export const loadAggregateFromBlob = unstable_cache(
fetchAndProject,
["aggregate-blob-v2"],
["aggregate-blob-v3"],
{ revalidate: 60, tags: ["bench-aggregate", "benchmarks"] },
);
Loading