Skip to content

multi network ENS resolver - #836

Merged
barnabasbusa merged 9 commits into
masterfrom
pk910/ens-multi-network
Aug 17, 2026
Merged

multi network ENS resolver#836
barnabasbusa merged 9 commits into
masterfrom
pk910/ens-multi-network

Conversation

@pk910

@pk910 pk910 commented Aug 17, 2026

Copy link
Copy Markdown
Member

No description provided.

barnabasbusa and others added 4 commits August 14, 2026 10:35
Adds forward ENS resolution (name -> address) on top of the existing
reverse-resolution subsystem, wired into the header search:

- typing a complete ENS name (e.g. vitalik.eth) shows an "ENS Names"
  typeahead section with the resolved address; selecting it (or
  submitting the search) redirects to the /address page
- new "ens" search-ahead type; the global 0x-strip is skipped for it
  since ENS labels may legitimately contain "0x"
- forward results are cached in a dedicated LRU (honoring the existing
  refreshPositive/refreshNegative intervals) plus the page cache
- gated on both ensResolver.enabled and executionIndexer.enabled
  (resolved names redirect to /address, which needs the indexer)

ENS lookups now always run against Ethereum mainnet: the configured
ensResolver.endpoints, defaulting to a public mainnet RPC
(ethereum-rpc.publicnode.com) when unset. The local execution pool is
no longer used as fallback - on devnets/testnets it serves a chain
without an ENS deployment.
- resolve ENS names on the local network (via the main execution pool) and on
  configured remote networks (ensResolver.remoteNetworks, each with own RPC
  endpoints + registries); drops the single-network ensResolver.endpoints config
- persist results per (address, network) in ens_names (PK address+network) and
  show all resolved names in the UI: clickable ENS icon (tag=local, globe=remote)
  in front of swapped names opens a callout with the raw address and every
  name+network, all copyable
- forward resolution + typeahead ENS search across all networks, including
  prefix suggestions from already-resolved names
- fix probe-once bug: registry/multicall bytecode probing is retried every 5min
  while incomplete, so contracts deployed after startup are picked up
- append ?v=<git build version> (startup time for dev builds) to all /js, /css
  and /ui-package/react-ui.js includes via new assetVersion template func,
  replacing the buildTime param that only covered explorer.js/layout.css
- add a timestamp param to the index page's /index/data ajax refresh so
  cloudflare doesn't serve stale refresh data
@barnabasbusa barnabasbusa added the build-docker-image Automatically build docker image for PR branch label Aug 17, 2026
barnabasbusa and others added 3 commits August 17, 2026 14:21
remote networks without registryAddresses/multicallAddress now fall back to the
top-level ensResolver values instead of the built-in canonical addresses (the
top-level values themselves still default to those, so behavior is unchanged
when nothing is configured)

@redpandabot redpandabot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Summary

Multi-network ENS resolver rework: names are now resolved on the local chain plus optional remote networks (persisted per (address,network)), a new ENS forward-search path, a schema migration, and CDN cache-busting for static assets. The design is solid and I found no blockers, but there are two operational concerns: a perpetual re-enqueue loop when a remote network endpoint stays down, and a silent removal of the old top-level ensResolver.endpoints config key.

Issues

  • 🟡 services/ensresolver.go:724permanently-failing network keeps every viewed address in an endless re-resolve loop — see the thread on that line
  • 🟡 types/config.go:221top-level ensResolver.endpoints silently removed — existing configs lose their ENS target — The old EnsResolver.Endpoints field (used to point the resolver at a dedicated mainnet RPC, the only way to show mainnet ENS from a non-mainnet explorer) is deleted with no migration or warning; yaml.Unmarshal silently ignores the stale key. After upgrade such deployments resolve against the indexed chain's own execution pool and ENS stops resolving until they migrate to remoteNetworks. Worth a release note / deprecation shim (e.g. map old endpoints into a synthetic remote network).

Reviewed @ d5e933fd
"Documentation is a love letter you write to your future self." — Damian Conway

Comment thread services/ensresolver.go
processBatch persisted rows only for succeeded networks, so a failing network's
missing or outdated row kept the whole cache entry stale forever: every page
view of an already-resolved address re-enqueued it and re-ran a full resolve
batch against the healthy networks until the broken endpoint recovered.

Cache entries now track resolve state per network, and staleness skips networks
in error backoff, so addresses settle on the networks that do answer. The
backoff escalates 30s..15m per consecutive failure and resets on success, and
the forward (search) path honors it too instead of blocking each query on the
unreachable endpoint for the full 10s timeout. Network availability is shown
on the ens debug tab.
@redpandabot

redpandabot Bot commented Aug 17, 2026

Copy link
Copy Markdown

Summary

This PR reworks the ENS resolver into a multi-network service: per-(address,network) persistence with a composite PK migration, probe-based registry discovery with backoff, per-network staleness so addresses settle while an endpoint is down, forward resolution for search, a client-side callout, and a cache-busting assetVersion helper. The core resolve/persist/refresh logic is coherent and well-tested; I found one mismatch between the documented failure handling and what the code actually persists, plus a small search-regex gap.

Issues

  • 🟡 services/ensresolver.go:834transient ENS call errors are persisted as negative results instead of triggering backoff — resolveWithRegistry/resolveForward swallow callBatch errors (ensresolver_ens.go:161/197/226/254 and :92/105) and return an empty map, so resolveBatchOnNetwork returns nil error and processBatch marks the network available (ensresolver.go:772) and inserts Name:'' rows for the whole batch. A short RPC hiccup or the global 60s batch deadline therefore stores false negatives that are not retried until RefreshNegative (6h), contradicting the processBatch comment that networks failing with a client error get no persisted result; the individual-call path (ensresolver_ens.go:286) also swallows per-call errors as "no name".
  • 🟢 handlers/search.go:33ENS search regex excludes 2-char TLDs such as cb.id — ensNameRE requires the final label to be >=3 chars, so complete names like username.cb.id (Coinbase's ENS TLD) never match and are never forward-resolved/redirected by the search; they can still surface via prefix suggestions only if already reverse-resolved.

Reviewed @ c7d32a6e
"Documentation is a love letter you write to your future self." — Damian Conway

@barnabasbusa
barnabasbusa enabled auto-merge August 17, 2026 19:45
@barnabasbusa
barnabasbusa merged commit dd0234a into master Aug 17, 2026
11 of 13 checks passed
@barnabasbusa
barnabasbusa deleted the pk910/ens-multi-network branch August 17, 2026 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build-docker-image Automatically build docker image for PR branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants