Skip to content

Enforce Goldsky subgraph version cap (max 2) + 24h alert - #360

Draft
Siddharth2207 wants to merge 1 commit into
mainfrom
feature/rai-1962-goldsky-subgraph-version-cap
Draft

Enforce Goldsky subgraph version cap (max 2) + 24h alert#360
Siddharth2207 wants to merge 1 commit into
mainfrom
feature/rai-1962-goldsky-subgraph-version-cap

Conversation

@Siddharth2207

@Siddharth2207 Siddharth2207 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Implements RAI-1962 in rainix so raindex (and other subgraph-deploy consumers) get version-budget enforcement without per-repo scripts.
  • After each network deploy in subgraph-deploy, call subgraph_goldsky_enforce_version_cap for ${GOLDSKY_SUBGRAPH_NAME}-$network: delete older versions down to a hard cap of 2, fail if more remain, and fail when a 2-version migration has been live for >24h.
  • Adds subgraph-goldsky-version-cap check-only task for cron/manual audits across networks.json.
  • Unit-tests pure helpers via bats (parse_versions, versions_to_delete, migration overlap).

What the cap means

The limit is 2 always-on Goldsky versions per network subgraph name (e.g. raindex-base, raindex-ethereum) — not 2 per orderbook.

Multiple orderbooks on one chain (e.g. two production orderbooks on Base) are indexed by the same network subgraph and do not each get a separate version budget. The cap only limits side-by-side deployments like:

  • raindex-base/<addr>-<commit1>
  • raindex-base/<addr>-<commit2> ← allowed during migration
  • raindex-base/<addr>-<commit3> ← excess; deleted / fails the check

Exactly 2 versions is allowed briefly for migration; staying at 2 for >24h fails so forgotten old versions don't keep double-billing.

Consumer impact (raindex)

raindex deploy-subgraph already runs subgraph-deploy. After bumping rainix, deploys automatically enforce the cap. Optional follow-up: add a scheduled workflow calling subgraph-goldsky-version-cap.

Test plan

  • nix develop -c bats test/bats/task/subgraph-goldsky-version-cap.test.bats test/bats/task/subgraph-deploy-version.test.bats
  • Bump rainix in raindex and dry-run / deploy to confirm post-deploy cleanup
  • Confirm Telegram CI reporter still surfaces deploy failures on raindex

After each network deploy, keep at most two always-on versions and fail
when a two-version migration exceeds 24h. Also add a check-only task for
scheduled audits (RAI-1962).

Co-authored-by: Cursor <cursoragent@cursor.com>
@linear

linear Bot commented Aug 24, 2026

Copy link
Copy Markdown

RAI-1962

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kaisbaccour

Copy link
Copy Markdown

Reviewed this purely on the cost question: does it stop us paying for versions we do not need? Goldsky bills per running version at roughly $34/month each, so that is the only axis I looked at. Agreed the rainix level is the right home for it, and agreed that two versions with a 24h migration window is the right policy.

Everything below was checked against goldsky CLI 13.9.0 against the live Rain Open Source project, not read off the diff.

1. The 24h window never closes, so the second version lives forever

Two separate breakages, and they compound.

The per-version detail call the code uses to read a creation date does not exist:

$ goldsky subgraph list "raindex-base/0xb05D...-105c526" --filter deployments
Subgraph listing failed: Route GET:/api/admin/subgraph/v1/subgraphs/raindex-base/deployments/0xb05D...-105c526 not found

That error is swallowed by || true, so epoch stays 0. And even with output in hand, the date regex wants ISO YYYY-MM-DD while the CLI prints US locale: Created: 7/16/2026, 9:51:30 PM. Scraping the real listing returns an empty string.

So every version's age reads as 0, and subgraph_goldsky_migration_overlap_fail goes both ways at once:

  • deploy path (has_keep=1): passes silently, always. A forgotten second version never warns.
  • audit path (has_keep=0): fails, always, for any chain with two versions. A permanently red job is one everybody learns to ignore.

Good news is the fix is free. The name-only listing already carries Created: for every version, so the second call can be dropped entirely and the date parsed from output we already have. That also saves N extra API calls per network.

2. Every version is counted twice, and the first real run deletes a live one

subgraph_goldsky_parse_versions matches name/... twice per version: once on the * raindex-base/<version> line, and again inside the GraphQL URL on the line below, where the trailing /gn survives as <version>gn after the punctuation strip. Against the live raindex-base listing, two real versions parse as four:

0xb05D73E6...-105c526
0xb05D73E6...-105c526gn      <- phantom
0xe522cB4a...-8e9477b
0xe522cB4a...-8e9477bgn      <- phantom

Replaying the deploy path against real-shaped output with three versions present:

Live versions (6):            <- there are 3
Deleting raindex-base/0xe522cB4a...-8e9477b
Subgraph deleted
Deleting raindex-base/0xb05D73E6...-105c526gn
[job exits 1]

It deletes a real serving version, then dies on a phantom name. Under set -euo pipefail that abort also ends the loop over networks, so every chain after the failing one is skipped and keeps its extras.

The check-only path reports the same inflated number: raindex-base has 4 live versions; max allowed is 2 when there are 2.

Related: with every epoch at 0, subgraph_goldsky_versions_to_delete falls through to a reverse string sort on the version name. On raindex-base that keeps 0xe522... and deletes 0xb05D... purely because "e" sorts above "b". Age and traffic do not come into it.

3. Any CLI failure silently switches the guard off

raw="$(_subgraph_goldsky_cmd subgraph list "$subgraph_name" --filter deployments 2>&1 || true)"

A bad token, a rate limit or an API blip produces zero parsed versions, prints No deployments found, and returns 0. The deploy goes green and the extras keep billing. For a cost guard that is worse than having none, because we stop looking. It should fail loudly when the listing does not parse.

4. The audit only sees names it can derive from the current networks.json

That is exactly where the money went last time. Of the 18 versions deleted on 2026-08-22, most were chains that had already left the config, and the survivors include legacy names (ob4-base, metadata-base) that this will never look at.

goldsky subgraph list --summary with no name argument returns the whole account. An audit built on that, diffed against an allowlist, catches orphans. An audit built on networks.json structurally cannot.

5. Nothing ever reclaims the second version

The 24h rule does not delete, it only turns a job red, and the scheduled workflow is listed as an optional follow-up. So today the only thing that enforces anything is a manual deploy dispatch. If nobody deploys, nothing is ever reclaimed and we keep paying.

Worth making the scheduled job enforce rather than report: same function, drop --check-only, so an expired migration window actually frees the money instead of just going red.

Not this PR, noted for completeness

raindex/subgraph/networks.json still lists arbitrum-one, matic and flare. subgraph-deploy deploys one always-on version per entry, so the next dispatch stands up subgraphs on three chains we currently have none on, about $102/month. No version cap can prevent that, since two per chain is permitted. I am raising that separately on raindex.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants