Skip to content

Conversation

@tk-o
Copy link
Contributor

@tk-o tk-o commented Jan 14, 2026

Substantial PR


Reviewer Focus (Read This First)

What reviewers should focus on

Where should reviewers spend most of their time?

Call out:

  • The risky or non-obvious parts
  • Areas where you're least confident
  • The kind of feedback you actually want

If your answer is "everything," explain why targeted review isn't possible.

Limit this to 1-3 areas.

  • Registrars Schema
  • Creating a logical key for all events within a "logical registrar action".
  • Writing metadata about the current "logical registrar action" into ENSDb.

Problem & Motivation

Why this exists

Explain:

  • What problem this PR is solving
  • What's broken, fragile, or getting worse without it
  • Why this change is happening now
  • Links to issues, incidents, or prior discussion

Keep this tight. Bullets are fine.

This PR solves two issues:

  • Indexing logic bug that was introduced in v1.4.0 that caused the logical key value to be differ when handling events from different contracts within the same “logical registrar action”.

    • Details described in a Slack post here.
    • This issue is a blocker for ENSIndexer Alpha and ENSIndexer Alpha Sepolia. Both ENSIndexer instances crashed in the Green env (running ENSNode v1.4.0). Screenshot 2026-01-14 at 13 52 57
  • ENSDb storage requirements. Multiple temporary records were stored (one for each indexed "logical registrar action") in ENSDb.


What Changed (Concrete)

What actually changed

List the concrete behavioral or structural changes in this PR.

This should be a factual inventory, not a narrative.
Prefer numbered bullets.

If this list starts getting long, that's a signal the PR may need splitting.

  1. Database schema for registrars plugin was updated to only allow storing up to one record for the current "logical registrar action" metadata.
  2. Indexing logic was updated to stop inserting a new metadata record for each indexed "logical registrar action". Instead, the indexing logic will upsert the metadata record for the current "logical registrar action" being indexed. This guarantees at most one metadata record will be stored at a time in ENSDb.
  3. A method for making a logical key for the given event indexed within a "local registrar action" was updated to produce the key based only on the node (domain ID) and transactionHash.

Design & Planning

How this approach was chosen
  • Link any design docs or notes that existed before or during implementation
  • If this didn't warrant upfront design, say why
  • Mention the most realistic alternatives you considered and why you didn't take them
  • If planning was lightweight, be explicit about that
  • Planning artifacts:
    • There was a long discussion on Slack that led to the final design: image
    • We considered multiple options for how to build the logical key, and how to manage the metadata records in ENSDb.
    • We figured that all the logical key needs is the domain ID of the registration associated with the "logical registrar action", and the transaction hash. EVM event processing semantics guarantees all events from a single "logical registrar action" are processed before any event from another "logical registrar actions".
    • We decided to store a metadata record in ENSDb to hold the current "logical registrar action" details for all events that still need to be processed within the same "logical registrar action". This approach also solves Constrain _ensindexer_registrar_action_metadata to at most 1 row #1287.
  • Reviewed / approved by: @shrugs, @lightwalker-eth

Self-Review

What you caught yourself

Describe what changed after you reviewed your own diff end-to-end.

This is not optional.

  • Bugs caught:
    • A call to handleUniversalRegistrarRenewalEvent function didn't have its params updated. I then removed the subregistryId and it fixed the issue.
  • Logic simplified:
  • Naming / terminology improved:
    • I renamed insertRegistrarAction to upsertRegistrarAction, but then, during self-review, I noticed the logic is still about just the insert when it comes to registrar action records. The implementation detail of insertRegistrarAction changed from insert to upsert the metadata record. After that, I renamed upsertRegistrarAction back to insertRegistrarAction
  • Dead or unnecessary code removed (or why none was):

Cross-Codebase Alignment

Related code you checked

Show that you looked beyond just the files in this PR.

  • Terms you searched for to find related code or docs
  • Files or packages you reviewed but intentionally didn't change
  • Areas you left alone on purpose (and why)

Focus on directly related domains. Don't boil the ocean.

  • Search terms used:
    • insertRegistrarAction
    • handleRegistrarControllerEvent
    • internal_registrarActionMetadata
    • DomainId`
    • logicalEventId
    • makeLogicalEventKey
    • getThisAccountId
  • Reviewed but unchanged:
    • Replacing node: Node with domainId: DomainId. The DomainId type is a branded type extending the Node type, but update is not straight-forward. Is there a method we should apply to create DomainId value from Node value?
  • Deferred alignment (with rationale):

Downstream & Consumer Impact

Who this affects and how

Explain how this change impacts:

  • Callers
  • Readers
  • Operators
  • Future maintainers

Call out:

  • Terminology or concepts that might confuse someone new
  • What you changed to reduce that confusion

Point to actual diffs where possible.

  • Public APIs affected
    • None
    • Changes affect only the internal APIs (internal ENSDb table, internal ENSIndexer logic)
  • Docs updated:
    • Only comment blocks in the code
  • Naming decisions worth calling out:
    • None

Testing Evidence

How this was validated

Explain:

  • How this was tested locally and/or in CI
  • What important behavior is not covered by tests
  • If this is wrong, what breaks first
  • Testing performed:
    • I ran ENSIndexer locally and let it reach the "following" omnichain indexing status
      • Command I used: PLUGINS=subgraph NAMESPACE=sepolia pnpm -F ensindexer dev
      • Checked ENSDb multiple times, and there was always only just one record in _ensindexer_registrar_action_metadata table at any given moment.
  • Known gaps:
    • None
  • What reviewers have to reason about manually (and why):

Scope Reductions

What you intentionally didn't do

List follow-ups you identified but explicitly deferred to keep this PR reviewable.

Link issues where applicable and explain the tradeoffs.


Risk Analysis

How this could go wrong

Call out:

  • Assumptions this PR relies on
  • Likely failure modes
  • Blast radius if it breaks
  • Risk areas:
    • Aggregated registrar actions differ from the ones in v1.3.1
  • Mitigations or rollback options:
    • There's a need to compare records stored registrar_actions table in ENSDb so we can make sure no regressions were introduced to the last working codebase (v1.3.1).
  • Named owner if this causes problems:

Pre-Review Checklist (Blocking)

  • I reviewed every line of this diff and understand it end-to-end
  • I'm prepared to defend this PR line-by-line in review
  • I'm comfortable being the on-call owner for this change
  • Relevant changesets are included (or explicitly not required)

Resolves #1287

tk-o added 5 commits January 14, 2026 13:25
Add `UniversalRegistrarRenewalWithReferrer` config
Constrain `_ensindexer_registrar_action_metadata` to at most 1 row.

Related to #1287
Use upsert instead of insert when initializing temp record for storing metadata about the current "logical registrar action". This guarantees at most 1 record being stored in ENSDb at any given time.
Use a constant metadata type value for fetching metadata for the current "logical registarar action" from ENSDb. Also, add new invaraint to enforce that only events related to the current "logical registrar action" can be indexed.
@vercel
Copy link

vercel bot commented Jan 14, 2026

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

Project Deployment Review Updated (UTC)
admin.ensnode.io Ready Ready Preview, Comment Jan 14, 2026 6:50pm
ensnode.io Ready Ready Preview, Comment Jan 14, 2026 6:50pm
ensrainbow.io Ready Ready Preview, Comment Jan 14, 2026 6:50pm

@changeset-bot
Copy link

changeset-bot bot commented Jan 14, 2026

🦋 Changeset detected

Latest commit: 41d8bad

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 17 packages
Name Type
@ensnode/ensnode-schema Major
ensindexer Major
ensadmin Major
ensapi Major
ensrainbow Major
fallback-ensapi Major
@ensnode/datasources Major
@ensnode/ensrainbow-sdk Major
@ensnode/ponder-metadata Major
@ensnode/ensnode-react Major
@ensnode/ponder-subgraph Major
@ensnode/ensnode-sdk Major
@ensnode/shared-configs Major
@docs/ensnode Major
@docs/ensrainbow Major
@namehash/ens-referrals Major
@namehash/namehash-ui Major

Not sure what this means? Click here to learn what changesets are.

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

@tk-o tk-o marked this pull request as ready for review January 14, 2026 15:05
@tk-o tk-o requested a review from a team as a code owner January 14, 2026 15:05
@github-actions

This comment was marked as resolved.

tk-o added 2 commits January 14, 2026 16:23
…t most one metadata record in ENSDb for current "logical registrar action".
Copy link
Member

@lightwalker-eth lightwalker-eth left a comment

Choose a reason for hiding this comment

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

@tk-o Looks great 😄 Thank you! 🚀

@tk-o
Copy link
Contributor Author

tk-o commented Jan 14, 2026

Confirming that the counts of indexed "logical registrar actions" for ENSNode v1.3.0 and ENSNode v1.5.0 are matching.

ENSNode v1.3.0 ENSNode `v1.5.0
image image

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.

Constrain _ensindexer_registrar_action_metadata to at most 1 row

3 participants