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
5 changes: 5 additions & 0 deletions benchmarks/rpc-api-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ metric_panels:
metric: (avg by (provider) (avg_over_time(rpc_api_latency_milliseconds{api="eth_call_heavy"}[24h])) - avg by (provider) (avg_over_time(rpc_api_latency_milliseconds{api="eth_call_light"}[24h]))) > 0
unit: ms
higher_is_better: false
# Une valeur absente ici est une affirmation, pas une panne: la requete
# retire une difference non positive. Sans ce drapeau le worker la
# reporte, et le board a republie -1,84 ms pendant que la garde
# fonctionnait.
carry: false
description: "The compute term: the same eth_call through Multicall3, 50 state reads minus one, asked back to back on pooled connections. Each leg is primed first, so the handshake is paid outside the measurement and the difference is work. A value at or below zero is withheld."
- id: archive_read_ms
label: "Archive read"
Expand Down
1 change: 1 addition & 0 deletions src/lib/materialize/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1558,6 +1558,7 @@ async function tryLoadLive(
unit: panel.unit,
higherIsBetter: panel.higher_is_better,
tab: panel.tab,
carry: panel.carry,
values,
seriesByProvider,
seriesByProvider7d:
Expand Down
12 changes: 12 additions & 0 deletions src/lib/spec-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,18 @@ export const SpecSchema = z
* Listing a key here is a claim about the metric's label set, not
* a display preference: say what the harness actually emits. */
ignore_dimensions: z.array(z.string().min(1).max(40)).max(8).optional(),
/** False when a missing value is a STATEMENT rather than a gap, so
* the worker must not carry the previous one forward.
*
* The carry exists for a query that failed. A query that filters
* deliberately looks identical to it from the merge's side, and
* the result is a value the panel refused being republished for
* the length of the carry ceiling. Measured on bench 311: the
* eth_call work term drops a non-positive difference because the
* heavy leg cannot be the faster one, and the carry put minus
* 1.84 ms back on the board, where a lower-is-better view ranks
* it first. */
carry: z.boolean().optional(),
})
)
// Cap covers visible tabs plus data-only window panels (revenue,
Expand Down
14 changes: 11 additions & 3 deletions src/lib/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,13 @@ const loadBenchmarkUnfilteredCached = unstable_cache(
// v132: cost bench audit round (309, 310, 312): headline_slice, copy
// read from the curve, the bot FAQ. Moves with all-benchmarks-v125
// and bench-filters-v70.
["bench-unfiltered-v132", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
// v133: the eth_call work panel declares carry: false. Measured on the
// published blob: chainstack read minus 1.84 ms with staleSince in
// its valuesMeta, so the `> 0` guard was working and the panel carry
// was resurrecting the value it had refused, for the length of this
// bench's 24 h ceiling, first on a lower-is-better view. The cached
// entry holds panel values, so the old one stays without this.
["bench-unfiltered-v133", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
{ revalidate: 300, tags: ["benchmarks"] },
);

Expand Down Expand Up @@ -996,7 +1002,8 @@ const loadAllBenchmarksCached = unstable_cache(
// v123: lockstep with bench-unfiltered-v130 (per-chain leader).
// v124: lockstep with bench-unfiltered-v131 (ladder bound, primed legs).
// v125: lockstep with bench-unfiltered-v132 (cost bench audit round).
["all-benchmarks-v125", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
// v126: lockstep with bench-unfiltered-v133 (panel carry).
["all-benchmarks-v126", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
{ revalidate: 300, tags: ["benchmarks"] },
);
export const loadAllBenchmarks = cache(loadAllBenchmarksCached);
Expand Down Expand Up @@ -1191,7 +1198,8 @@ const loadBenchmarkFiltered = unstable_cache(
// v68: lockstep with bench-unfiltered-v130 (per-chain leader).
// v69: lockstep with bench-unfiltered-v131 (ladder bound).
// v70: lockstep with bench-unfiltered-v132 (cost bench audit round).
["bench-filters-v70", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
// v71: lockstep with bench-unfiltered-v133 (panel carry).
["bench-filters-v71", process.env.VERCEL_ENV === "production" ? "prod" : "all"],
{ revalidate: 300, tags: ["benchmarks"] }
);

Expand Down
3 changes: 3 additions & 0 deletions src/types/benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ export type MetricPanel = {
/** When false the panel is data-only (feeds ledger column window
* variants) and renders no chart tab. */
tab?: boolean;
/** When false a missing value is a statement rather than a gap, and the
* worker must not carry the previous one forward. See spec-schema. */
carry?: boolean;
/** Per-provider scalar values, keyed by provider slug. Providers with no
* live data for this metric are omitted; the renderer renders them as
* "no data" instead of zero. */
Expand Down
8 changes: 8 additions & 0 deletions worker/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ export function mergeWithPrevious(
(p: MetricPanel) => p.id === panel.id,
);
if (!prevPanel) continue;
// A panel can declare that a missing value is a STATEMENT, not a gap.
// The carry exists for a query that failed, and a query that filters
// deliberately is indistinguishable from one that failed when seen
// from here. Bench 311's eth_call work term drops a non-positive
// difference, because the heavy leg cannot be the faster one, and the
// carry put minus 1.84 ms back on the board for the length of the
// ceiling, where a lower-is-better view ranks it first.
if (panel.carry === false) continue;
panel.valuesMeta ??= {};
for (const slug of Object.keys(panel.values)) {
panel.valuesMeta[slug] = { observedAt: now };
Expand Down
91 changes: 91 additions & 0 deletions worker/stale-carry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,3 +436,94 @@ describe("carrying a per-cell stash through a failed matrix query", () => {
expect(dropped.cellRanks).toBeUndefined();
});
});

// Un panneau qui declare carry: false n'est pas reporte.
//
// Mesure sur le blob publie le 2026-10-30: la vue du terme de travail lisait
// chainstack a -1,84 ms avec `staleSince` dans son valuesMeta. La garde `> 0`
// du spec fonctionnait, chainstack sortait bien de la requete fraiche, et le
// carry de panneaux la ressuscitait. Sur une vue ou le plus bas gagne, cette
// valeur impossible se classait PREMIERE, et le plafond de carry de ce bench
// est son expected_freshness_seconds, soit vingt-quatre heures.
//
// Le carry existe pour une requete qui a echoue. Une requete qui filtre
// volontairement lui ressemble exactement, vue d'ici, donc c'est au spec de
// dire laquelle des deux il est.
describe("un panneau peut refuser d'etre reporte", () => {
const panel = (id: string, values: Record<string, number>, carry?: boolean) =>
({
id,
label: id,
metric: "x",
unit: "ms",
higherIsBetter: false,
values,
...(carry === undefined ? {} : { carry }),
}) as unknown as NonNullable<Benchmark["metricPanels"]>[number];

const withPanels = (
b: Benchmark,
panels: NonNullable<Benchmark["metricPanels"]>,
meta?: Record<string, { observedAt: number }>,
) =>
({
...b,
metricPanels: panels.map((p) => ({ ...p, valuesMeta: meta })),
}) as unknown as Benchmark;

test("carry: false laisse la valeur absente", () => {
const now = Date.now();
const prev = prevSnapshot([["chainstack", 1]], {}, now);
prev.bench = withPanels(
prev.bench,
[panel("work", { chainstack: -1.84 }, false)],
{ chainstack: { observedAt: now - 60_000 } },
);
const { bench: out } = mergeWithPrevious(
withPanels(bench([["chainstack", 1]]), [panel("work", {}, false)]),
prev,
now,
new Set(["chainstack"]),
86_400,
);
expect(out.metricPanels?.[0]?.values).toEqual({});
});

test("sans le drapeau, la valeur est reportee comme avant", () => {
// Le comportement par defaut ne change pas: le carry reste la protection
// contre une requete qui a echoue, qui est la raison de son existence.
const now = Date.now();
const prev = prevSnapshot([["chainstack", 1]], {}, now);
prev.bench = withPanels(
prev.bench,
[panel("other", { chainstack: 42 })],
{ chainstack: { observedAt: now - 60_000 } },
);
const { bench: out } = mergeWithPrevious(
withPanels(bench([["chainstack", 1]]), [panel("other", {})]),
prev,
now,
new Set(["chainstack"]),
86_400,
);
expect(out.metricPanels?.[0]?.values).toEqual({ chainstack: 42 });
});

test("carry: true se comporte comme l'absence du drapeau", () => {
const now = Date.now();
const prev = prevSnapshot([["chainstack", 1]], {}, now);
prev.bench = withPanels(
prev.bench,
[panel("other", { chainstack: 7 }, true)],
{ chainstack: { observedAt: now - 60_000 } },
);
const { bench: out } = mergeWithPrevious(
withPanels(bench([["chainstack", 1]]), [panel("other", {}, true)]),
prev,
now,
new Set(["chainstack"]),
86_400,
);
expect(out.metricPanels?.[0]?.values).toEqual({ chainstack: 7 });
});
});
Loading