Repository navigation
envio subgraph diff: parity report against a graph-node endpoint - #1731
moose-code wants to merge 9 commits into
Conversation
Run inside a subgraph project, it compares the indexer's own Postgres (the
same ENVIO_PG_* settings, read in one REPEATABLE READ snapshot) with the
subgraph's old graph-node endpoint, pinned with `block: {number: N}` to the
block the indexer has processed. `--ours <graph-endpoint>` compares a Graph
endpoint of ours (envio-serve) instead.
Per entity type from the subgraph schema it pages every reference id by
cursor, diffs the id sets, and compares a deterministic sample (sha256 of
the id) field by field after normalizing both sides to graph-node's
encodings: BigInt/Int8/Timestamp as integers, BigDecimal normalized to 34
significant digits, Bytes lowercase hex, relations by id, stored entity
lists as sorted id sets; derived fields are skipped. A field graph-node
can't resolve is dropped and reported instead of failing the type.
Prints a table or, with --json, a stable schemaVersion 1 report. Exit 0 on a
match within --tolerance (0.1% per type) and --max-field-mismatches (0),
1 on a mismatch, 2 when it couldn't compare. The new `exit` runtime command
carries that code through the Node host.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Public endpoints behind a shared key (ENS's community key) answer 429 for longer than five retries cover; eight with the 30s backoff cap ride out about a minute and a half. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A type whose reference listing stopped at --max-entities with nothing differing so far wasn't compared fully, but nothing failed either; agents reading the JSON need to tell the two apart. Both still exit 2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dropping a field the reference can't resolve keeps a defect in the old host's data from hiding the rest of the type. A field ours fails on is different: every frontend query that selects it breaks, so the type is a mismatch and the field is listed as unservable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
|
@DZakh: two PRs into your #1626 branch from the subgraph-hosting hackathon, for review when you have time. No merge needed during the hack.
🤖 Generated with Claude Code |
…es it graph-node resolves a relation by joining the target's table, so a nullable relation whose entity doesn't exist comes back null, and a list of ids leaves such ids out (relational_queries.rs, child types D and C). The Postgres side compared the stored id instead, which was the only cause of the Aave v3 (User.eModeCategoryId → EModeCategory "0") and Klima (Activity.user, 275k rows) mismatches. It now joins the same way and counts what it nulled or dropped per field as a note (`danglingRelations`), not a mismatch. Non-null relations keep failing graph-node's query, which the first batch already handles; interface targets have no table and are compared as stored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rence Through a gateway, the id_gt-paged listing can come back short: two listings of the same Request Network Payment set lost 24 and 81 ids that id_in finds, so ours' rows were reported as "only ours". Indexers behind one gateway can also answer the same pinned query differently (Nouns Proposal 708: 142/13, then 147/14 at the same block). Every id on one side only (up to 1000 per type and side) is now asked for by id_in at the same block on the side missing it, and every sampled entity that differs or wasn't returned is fetched again, under its own alias so a caching proxy doesn't replay the first answer. Only what the second answer still shows is reported; what it settled is counted under `recheck` in the JSON and "Notes" in the table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…introspect envio-serve answers no introspection, so the diff guessed ours' collection names with a hand-rolled plural and missed Aave v3's ATokenBalanceHistoryItem (atokenBalanceHistoryItems), EModeCategory (emodeCategories) and Nouns' DynamicQuorumParams (dynamicQuorumParams_collection): those types were never reached. A side without introspection now uses the other side's names, and when neither has them, graph-node's own rule: camel_cased_names (graph/src/data/graphql/ext.rs) on Inflector =0.11.4, the version graph-node pins, with `_collection` when the plural is the singular. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
3 diff-tool fixes (head
This removes the false positives seen on Aave v3 and Klima. 🤖 Generated with Claude Code |
envio subgraph diff beside sg-codegen's subgraph-codegen: module list, compat docs §6b/§6c, CLI help and snapshot regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merged |
Adds
envio subgraph diff <endpoint>: a parity report between a local subgraph-mode indexer and the graph-node endpoint a team is migrating from, at one pinned block. Targets #1626's branch.What it does
envio_chains.progress_block, read in one read-only snapshot. The reference is queried withblock: {number: N}and checked with_meta. It refuses (exit 2) a reference that hasn't reached N or reports indexing errors.subgraph.yaml's schema, it compares the full id sets (paged with anid_gtcursor), then field-by-field on a deterministic sample (sha256 of the id), normalised to graph-node's encodings.--ours <graph endpoint>compares two Graph endpoints instead of Postgres, for example envio-serve'ssubgraph_api.--json(stableschemaVersion: 1). Exit codes: 0 match, 1 mismatch, 2 couldn't compare.Tried on real data
nouns-mainnetdeploymentapi.thegraph.com/.../ensdomains/ensResolverdata source never runs, and labels are unhealed (ENSRainbow is gone)Notes
packages/cli, because the schema translation and.envloading are already there. Addstokio-postgres, plus anExit{code}command inBin.resso Node can exit 2.--max-entitiescaps big types and marks themincomplete.ENVIO_DIFF_TEST_PG).cargo fmtandclippy --all-targetspass. Help docs, snapshot anddocs/subgraph-compat.md§6c are updated.🤖 Generated with Claude Code