Skip to content

fix(ensapi): correct ensv2 fallback behavior#2290

Merged
shrugs merged 2 commits into
mainfrom
fix/walk-namegraph
Jun 12, 2026
Merged

fix(ensapi): correct ensv2 fallback behavior#2290
shrugs merged 2 commits into
mainfrom
fix/walk-namegraph

Conversation

@shrugs

@shrugs shrugs commented Jun 12, 2026

Copy link
Copy Markdown
Member

What

The namegraph walk (domain(by: name) and related Name→Domain lookups) fell back to the ENSv1 disjoint namegraph whenever the ENSv2 Root walk didn't exact-match (added in #2286). UniversalResolverV2 has no registry-level ENSv1 fallback. Its only ENSv1 fallback is the ENSV1Resolver (a mirror Resolver) set within the ENSv2 namegraph on reserved entries — which the walk already follows via its existing ENSv1Resolver hop. I confirmed this against contracts-v2 (LibRegistry.findResolver walks only the ENSv2 registry tree; the overview docs describe the ENSV1Resolver reserved-entry mechanism).

So a name present only in ENSv1 and not reserved in ENSv2 is simply not resolvable under UR2 — the fallback fabricated resolution the protocol doesn't have.

Changes

  • Revert the fallback in get-domain-by-interpreted-name.ts (file is byte-identical to its pre-feat(ensapi): improve seedDevnet - add names with contenthash #2286 state) so the walk faithfully models UR2.
  • Faithful devnet seed: reserve the ENSv1 fixtures in the ENSv2 ETHRegistry (resolver = ENSV1Resolver), mirroring migration. domain(by: name) now returns the preferred ENSv2 Domain.
  • Tests: the domain(by: name) ENSv1 blocks (which only passed via the fallback) now assert the reserved ENSv2 Domain id + literal canonical name. The domains(where: name eq) direct-lookup and ENSv1 virtual-registry tests are untouched.

Notes

  • The devnet reservation goes through the normal ETHRegistrar commit-reveal (owner = seed account) rather than a migration-controller owner=0 reserved registration. Indistinguishable to the walk/indexer (what matters is the ENSv2 entry with resolver = ENSV1Resolver), but a simplification of the true reserved-entry shape.
  • The changed integration tests run only against a live devnet (test:integration:ci) — not exercised locally.

Verify

pnpm -F ensapi typecheck ✓ · pnpm -F @ensnode/integration-test-env typecheck ✓ · pnpm lint ✓ · pnpm test --project ensapi → 293 passed

The namegraph walk (domain(by: name)) fell back to the ENSv1 disjoint
namegraph whenever the ENSv2 Root walk didn't exact-match. UniversalResolverV2
has no such registry-level fallback: its only ENSv1 fallback is the
ENSV1Resolver mirror Resolver set within the ENSv2 namegraph on reserved
entries, which the walk already follows. Revert the fallback so the walk
faithfully models UR2.

Faithfully reserve the ENSv1 devnet fixtures in the ENSv2 ETHRegistry
(resolver = ENSV1Resolver), mirroring migration, so domain(by: name) returns
the preferred ENSv2 Domain. Update the integration tests accordingly.
@shrugs shrugs requested a review from a team as a code owner June 12, 2026 15:18
Copilot AI review requested due to automatic review settings June 12, 2026 15:18
@changeset-bot

changeset-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b13e84e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
admin.ensnode.io Ready Ready Preview, Comment Jun 12, 2026 3:23pm
enskit-react-example.ensnode.io Ready Ready Preview, Comment Jun 12, 2026 3:23pm
ensnode.io Ready Ready Preview, Comment Jun 12, 2026 3:23pm
ensrainbow.io Ready Ready Preview, Comment Jun 12, 2026 3:23pm

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR removes the ENSv2→ENSv1 fallback behavior from namegraph resolution and replaces it with ENSv2 reserved-entry mirroring: ENSv1 names are seeded into the ENSv2 ETHRegistry via ENSV1Resolver, the resolution logic no longer attempts a secondary ENSv1-root walk, and tests verify that ENSv1-only names now resolve through their ENSv2 reserved entries.

Changes

ENSv1 Fallback Removal and ENSv2 Reserved-Entry Migration

Layer / File(s) Summary
Remove ENSv1 fallback from core resolution logic
apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts
Delete the conditional ENSv1-root walk that previously executed when ENSv2-root exact-match failed, remove the unused maybeGetENSv2RootRegistryId import, and update the internal documentation to reflect the simplified namegraph-walking flow through Bridged Resolvers without ENSv1 fallback.
Seed ENSv1 names as ENSv2 reserved entries
packages/integration-test-env/src/seed/registered-names.ts, apps/ensapi/src/test/integration/devnet-names.ts
Extend seedEnsV1Name to additionally register each ENSv1 label in the ENSv2 ETHRegistry pointing to ENSV1Resolver, mirroring the migration reserved-entry state. Update related documentation to clarify this ENSv2/ENSv1 mirroring behavior for legacy controller registration and targeted walk tests.
Update test assertions for reserved-entry resolution
apps/ensapi/src/omnigraph-api/schema/query.integration.test.ts
Adjust imports to use labelhashInterpretedLabel and related types, add V2_ETH_REGISTRY datasource constant, and replace prior ENSv1 "healed/unhealed" assertions with new expectations that ENSv1-only reserved names resolve via their computed ENSv2 Domain ID in the ETHRegistry.
Release notes for ENSv1 fallback removal
.changeset/walk-namegraph-no-ensv1-fallback.md
Changeset documents that the Omnigraph namegraph walk no longer falls back to the ENSv1 root when ENSv2-root exact-match fails, clarifying that UR2 has no registry-level ENSv1 fallback.

Possibly related PRs

  • namehash/ensnode#1983: Directly overlaps with refactoring of namegraph/domain resolution logic in get-domain-by-interpreted-name.ts and related Query/domain test updates.
  • namehash/ensnode#2265: Both PRs modify Omnigraph namegraph-walking in get-domain-by-interpreted-name.ts; this PR removes the ENSv2→ENSv1 root fallback while the retrieved PR refactors the shared forward-walk implementation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A fallback no more, we've cleared the way,
ENSv2's reserved entries now hold sway,
Legacy names find their home within,
No dance to v1—just clean, simple resolve to win! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description provides a comprehensive summary with clear sections for What, Changes, Notes, and Verify, addressing the template's key requirements of describing what changed, why, and testing status.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The PR title states 'correct ensv2 fallback behavior' but the actual change removes a fabricated ENSv1 fallback from the namegraph walk, which is more specific than what the title conveys.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/walk-namegraph

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 and usage tips.

@shrugs shrugs changed the title fix(ensapi): remove fabricated ENSv1 fallback from namegraph walk fix(ensapi): correct ensv2 fallback behavior Jun 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Aligns ENSApi’s namegraph walk (domain(by: name) and related lookups) with UniversalResolverV2 semantics by removing an artificial ENSv1 registry-level fallback when the ENSv2 root walk doesn’t exact-match, and updates the devnet seed + integration assertions to reflect the reserved-entry mechanism (ENSv2 entry pointing at ENSV1Resolver).

Changes:

  • Removed the ENSv1 disjoint-namegraph fallback from forwardWalkNamegraph’s internal walk logic, preserving only resolver-mediated hops (e.g. ENSv1Resolver, ENSv2Resolver, bridged resolvers).
  • Updated devnet seeding so ENSv1 fixtures are also registered in the ENSv2 ETHRegistry with resolver = ENSV1Resolver, mirroring the migration “reserved entry” shape used for UR2 resolution.
  • Updated integration tests to assert ENSv1 fixture lookups resolve to the reserved ENSv2 Domain IDs (and literal canonical names), matching the new walk behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/integration-test-env/src/seed/registered-names.ts Reserves ENSv1 fixture names in ENSv2 ETHRegistry via ENSV1Resolver to mirror migration behavior under UR2.
apps/ensapi/src/test/integration/devnet-names.ts Clarifies that ENSv1 fixtures are reserved in ENSv2; keeps a dedicated list for ENSv1-targeted assertions.
apps/ensapi/src/omnigraph-api/schema/query.integration.test.ts Updates domain(by: name) integration assertions so ENSv1 fixture names resolve to the reserved ENSv2 Domains/IDs.
apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts Removes the fabricated ENSv1 fallback when ENSv2 doesn’t exact-match, keeping only resolver-driven hops.
.changeset/walk-namegraph-no-ensv1-fallback.md Adds a changeset documenting the behavior change as a patch for ensapi.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@greptile-apps

greptile-apps Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reverts a fabricated ENSv1 fallback in the namegraph walk (get-domain-by-interpreted-name.ts) that was mistakenly added in #2286. UniversalResolverV2 has no registry-level ENSv1 fallback; ENSv1 names are only reachable via the ENSV1Resolver reserved-entry hop that the walk already follows.

  • Core revert: removes the maybeGetENSv2RootRegistryId import and the 17-line conditional that recursively re-walked the ENSv1 disjoint namegraph when the ENSv2 walk didn't exact-match.
  • Devnet seed update: seedEnsV1Name now additionally calls registerEthName to create an ENSv2 ETHRegistry reservation (resolver = ENSV1Resolver, subregistry = zero), mirroring the real migration's reserved-entry pattern so the preferred ENSv2 domain is returned by the walk.
  • Test alignment: the two ENSv1 integration test cases (healed/unhealed) are merged into one that asserts the ENSv2 Domain ID and literal canonical name for all ENSv1 fixtures, including the previously unhealed entry whose ENSv1 canonical was an encoded label hash.

Confidence Score: 5/5

Safe to merge — the fallback removal is a targeted, well-reasoned revert, and the devnet seed + tests are updated to stay consistent with the new protocol-accurate behavior.

All four changed files move in lockstep: the walk is corrected, the devnet seed mirrors it, and the tests are updated to assert the now-preferred ENSv2 domain. The removed code path had no legitimate protocol backing per UR2, so its absence does not regress real behaviour.

No files require special attention. The seed change adds one sequential registerEthName call per ENSv1 fixture and the test merges two cases into one — both are low-risk mechanical changes.

Important Files Changed

Filename Overview
apps/ensapi/src/omnigraph-api/lib/get-domain-by-interpreted-name.ts Reverts the ENSv1 disjoint-namegraph fallback added in #2286; the walk now faithfully models UR2.
packages/integration-test-env/src/seed/registered-names.ts seedEnsV1Name now also calls registerEthName to create an ENSv2 ETHRegistry reservation mirroring migration reserved-entry pattern.
apps/ensapi/src/test/integration/devnet-names.ts canonical field simplified to entry.name for all ENSv1 entries; comment updated to reflect ENSv2 reservation.
apps/ensapi/src/omnigraph-api/schema/query.integration.test.ts Merged the two ENSv1 test cases into one asserting ENSv2 Domain ID and literal canonical name; V2_ETH_REGISTRY added.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["forwardWalkNamegraph(name)"] --> B["walkNamegraphFromRegistry(ENSv2 Root)"]
    B --> C{Exact match in ENSv2?}
    C -- "Yes + has resolver" --> D["Return ENSv2 Domain"]
    C -- "No match" --> E["Find deepest resolver"]
    E --> F{Resolver type?}
    F -- "Bridged Resolver" --> G["Recurse to target registry"]
    F -- "ENSv1Resolver" --> H["Recurse to ENSv1 Root"]
    F -- "ENSv2Resolver" --> I["Recurse to ENSv2 Root"]
    F -- "None / other" --> J["Not resolvable"]
    H --> K["Return ENSv1 Domain"]
Loading

Reviews (1): Last reviewed commit: "chore: remove changeset" | Re-trigger Greptile

@shrugs shrugs merged commit 4ecd8d9 into main Jun 12, 2026
21 checks passed
@shrugs shrugs deleted the fix/walk-namegraph branch June 12, 2026 15:26
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