Skip to content

Registrar Actions: Inconsistent Order#1742

Open
Goader wants to merge 6 commits intomainfrom
fix/registrar-actions-inconsistent-order
Open

Registrar Actions: Inconsistent Order#1742
Goader wants to merge 6 commits intomainfrom
fix/registrar-actions-inconsistent-order

Conversation

@Goader
Copy link
Contributor

@Goader Goader commented Mar 9, 2026

Inconsistent Order of Registrar Actions

closes: #1704

Summary

  • Changed the SQL query to order by Registrar Actions ID, not timestamp

Why

  • Registrar Actions order returned from ENSApi is inconsistent, causing undeterministic behavior on the frontend
  • Sorting by id just like we did with rev-share-limit leaderboard building (not that eventType is not processed contrary to leaderboard building)
  • See: Inconsistent order of Registrar Actions #1704

Testing

  • Automatic, CI testing
  • Manual validation (using older version of ENSIndexer and ENSRainbow, but as far as I understand this shouldn't affect the outcome)

Notes for Reviewer (Optional)

  • Whether id is sufficient for the deterministic ordering

Pre-Review Checklist (Blocking)

  • This PR does not introduce significant changes and is low-risk to review quickly.
  • Relevant changesets are included (or are not required)

@Goader Goader self-assigned this Mar 9, 2026
Copilot AI review requested due to automatic review settings March 9, 2026 15:09
@vercel
Copy link
Contributor

vercel bot commented Mar 9, 2026

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

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped Mar 13, 2026 3:00pm
ensnode.io Skipped Skipped Mar 13, 2026 3:00pm
ensrainbow.io Skipped Skipped Mar 13, 2026 3:00pm

@changeset-bot
Copy link

changeset-bot bot commented Mar 9, 2026

🦋 Changeset detected

Latest commit: 5228c69

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

This PR includes changesets to release 19 packages
Name Type
@ensnode/ensnode-sdk Major
@namehash/ens-referrals Major
ensapi Major
ensadmin Major
ensindexer Major
ensrainbow Major
fallback-ensapi Major
@ensnode/ensnode-react Major
@ensnode/ensrainbow-sdk Major
@ensnode/integration-test-env Patch
@namehash/namehash-ui Major
@ensnode/datasources Major
@ensnode/ensnode-schema Major
@ensnode/ponder-sdk Major
@ensnode/ponder-subgraph Major
@ensnode/shared-configs Major
@docs/ensnode Major
@docs/ensrainbow Major
@docs/mintlify 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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 9, 2026

Warning

Rate limit exceeded

@Goader has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 28 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c6702773-fbc5-4f81-9f46-e684f95f9fab

📥 Commits

Reviewing files that changed from the base of the PR and between 05e4548 and 8cb3820.

📒 Files selected for processing (3)
  • .changeset/brave-cups-wave.md
  • .changeset/mighty-dogs-cheer.md
  • .changeset/tall-icons-return.md
📝 Walkthrough

Walkthrough

Orders deterministic sorting: registrar actions now sort by id (Ponder checkpoint) instead of timestamp; rev-share-limit leaderboard now uses lexicographic sorting on event id; two checkpoint helper functions were removed and tests updated for the new ID format.

Changes

Cohort / File(s) Summary
Changelog
.changeset/tall-icons-return.md
Adds a patch changeset documenting ordering fixes for ensapi and @namehash/ens-referrals.
Registrar Actions Query
apps/ensapi/src/lib/registrar-actions/find-registrar-actions.ts
Changed buildOrderByClause for LatestRegistrarActions to sort by registrarActions.id (Ponder checkpoint) instead of registrarActions.timestamp.
Rev-share-limit core
packages/ens-referrals/src/v1/award-models/rev-share-limit/checkpoint.ts, packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts
Removed helpers resetEncodedEventType and compareEventIds; replaced bigint-based checkpoint comparison with direct lexicographic comparison on event.id.
Rev-share-limit tests & docs
packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.test.ts, packages/ens-referrals/src/v1/award-models/rev-share-limit/referral-event.ts
Updated test ID construction and expectations to match new checkpoint ID format and lexicographic ordering; adjusted JSDoc describing ReferralEvent.id.
SDK request constant
packages/ensnode-sdk/src/ensapi/api/registrar-actions/request.ts
Updated RegistrarActionsOrders.LatestRegistrarActions from orderBy[timestamp]=desc to orderBy[id]=desc and added docblock explaining lexicographic/chronological semantics.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

ensnode-internal

Poem

🐇 I hopped through checkpoints, tidy and spry,

Swapped timestamps for ids that line up just right,
Trimmed old helpers, gave tests a new tune,
Now rows stand in order beneath the moon. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% 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
Title check ✅ Passed The title 'Registrar Actions: Inconsistent Order' is partially related to the changeset; it highlights the issue being fixed but lacks specificity about the solution (sorting by id instead of timestamp).
Description check ✅ Passed The PR description follows the template with all required sections completed: Summary, Why, Testing, Notes for Reviewer, and Pre-Review Checklist all provided.
Linked Issues check ✅ Passed The PR directly addresses issue #1704 by changing the sorting mechanism from timestamp to id field, ensuring deterministic ordering of registrar actions as required.
Out of Scope Changes check ✅ Passed All changes are tightly scoped to fixing the inconsistent ordering: sorting changes in registrar actions and mirror changes in rev-share-limit leaderboard; helpers removed as they became unused.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/registrar-actions-inconsistent-order
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to make the ENSApi “registrar actions” list ordering deterministic when multiple actions share the same block timestamp, improving pagination stability and repeatability of results.

Changes:

  • Update “latest registrar actions” ordering to sort by registrar_actions.id (Ponder checkpoint) instead of timestamp.
  • Add a Changesets entry to release the fix as an ensapi patch.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
apps/ensapi/src/lib/registrar-actions/find-registrar-actions.ts Changes the ORDER BY used for “latest” registrar actions to use id for deterministic ordering.
.changeset/tall-icons-return.md Declares a patch release for ensapi describing the ordering fix.

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

Copilot AI review requested due to automatic review settings March 13, 2026 14:25
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 13, 2026 14:26 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 13, 2026 14:26 Inactive
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.


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

You can also share your feedback on Copilot code review. Take the survey.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 13, 2026

Greptile Summary

This PR fixes non-deterministic ordering of Registrar Actions by switching the SQL ORDER BY clause from the non-unique timestamp column to the globally unique Ponder checkpoint id field, and simplifies the referral leaderboard race sort to use direct lexicographic string comparison instead of bigint arithmetic with a zeroed eventType digit.

Key changes:

  • find-registrar-actions.ts: desc(registrarActions.timestamp)desc(registrarActions.id). Because id is the text primary key and a constant-length (75-char) zero-padded decimal string, lexicographic descending order equals chronological descending order — resolving the inconsistent ordering seen on the frontend when multiple actions share the same block timestamp.
  • leaderboard.ts: Replaces compareEventIds (which converted strings to BigInt after zeroing the eventType digit) with a plain JS string comparison (a.id < b.id ? -1 : a.id > b.id ? 1 : 0). This is semantically equivalent for log events (which all share the same eventType digit), and is simpler and faster.
  • checkpoint.ts: Deleted — compareEventIds and resetEncodedEventType are no longer used anywhere.
  • leaderboard.test.ts: CHECKPOINT_PREFIX is corrected to include the eventType digit ("0"), and the default makeEvent ID no longer manually inserts that digit, keeping every generated ID at the correct 75-character length.
  • request.ts (SDK): LatestRegistrarActions constant value updated from "orderBy[timestamp]=desc" to "orderBy[id]=desc" — a minor breaking change correctly versioned in the changeset.
  • referral-event.ts: Documentation clarified to note the id field is fixed-length, reinforcing why lexicographic comparison works.

Confidence Score: 4/5

  • Safe to merge — the fix is well-reasoned and supported by updated tests; one implicit invariant in the leaderboard sort is worth documenting but does not affect correctness today.
  • The core ordering change is correct: registrarActions.id is the text primary key, a constant-length all-decimal Ponder checkpoint string, so lexicographic DESC order equals chronological DESC order and is fully deterministic. The leaderboard simplification is equivalent under the invariant that all referral events are Ponder log events sharing the same eventType digit — which holds today but is undocumented. Tests are correctly updated to match the new 75-character ID format. One point is withheld because the eventType assumption in leaderboard.ts is implicit and could silently break ordering if Ponder ever emits mixed-type events for referrals.
  • packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts — the implicit assumption that all ReferralEvent ids share the same eventType digit should be documented.

Important Files Changed

Filename Overview
apps/ensapi/src/lib/registrar-actions/find-registrar-actions.ts Core fix: ORDER BY clause changed from timestamp to id for deterministic pagination; safe since id is the text primary key and all-decimal constant-length strings compare lexicographically in the same order as chronologically.
packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts Simplified sort from bigint comparison (with eventType zeroed) to direct lexicographic string comparison; correct under the assumption that all referral events share the same eventType digit, which holds for log events.
packages/ens-referrals/src/v1/award-models/rev-share-limit/checkpoint.ts File deleted — compareEventIds and resetEncodedEventType helpers removed as they are no longer needed after switching to direct lexicographic comparison.
packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.test.ts Tests correctly updated: CHECKPOINT_PREFIX now includes the eventType digit ("0"), and makeEvent no longer manually inserts the digit, keeping total ID length at 75 characters.
packages/ensnode-sdk/src/ensapi/api/registrar-actions/request.ts SDK constant LatestRegistrarActions renamed from "orderBy[timestamp]=desc" to "orderBy[id]=desc" — a minor breaking change correctly marked as such in the changeset.
packages/ens-referrals/src/v1/award-models/rev-share-limit/referral-event.ts Doc-only addition of "fixed-length" to the id field description to reinforce the lexicographic-equals-chronological property.

Sequence Diagram

sequenceDiagram
    participant Client as SDK Client
    participant ENSApi as ENSApi Server
    participant DB as Database (registrarActions)
    participant Leaderboard as Leaderboard Builder

    note over Client,DB: Registrar Actions API – deterministic ordering fix

    Client->>ENSApi: GET /api/registrar-actions?orderBy=orderBy[id]=desc
    ENSApi->>ENSApi: buildOrderByClause(LatestRegistrarActions)<br/>→ desc(registrarActions.id)  [was: desc(timestamp)]
    ENSApi->>DB: SELECT … ORDER BY id DESC LIMIT n OFFSET m
    note over DB: id is TEXT primary key (Ponder checkpoint)<br/>Lexicographic DESC = Chronological DESC<br/>because id is constant-length (75-char) decimal string
    DB-->>ENSApi: Rows ordered newest-first, fully deterministic
    ENSApi-->>Client: RegistrarActionsResponse

    note over Leaderboard,DB: Referral Leaderboard – sort simplification

    Leaderboard->>DB: SELECT id, referrer, … ORDER BY id ASC
    DB-->>Leaderboard: ReferralEvent[] (pre-sorted by id)
    Leaderboard->>Leaderboard: events.sort((a,b) => a.id < b.id ? -1 : …)<br/>[was: compareEventIds with BigInt + zeroed eventType]
    note over Leaderboard: Lexicographic string sort ≡ numeric sort<br/>for constant-length decimal strings
    Leaderboard->>Leaderboard: Run sequential race algorithm
    Leaderboard-->>Client: ReferrerLeaderboardRevShareLimit
Loading

Last reviewed commit: 8cb3820

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.test.ts:79

  • In these tests, makeEvent() accepts a timestamp but the generated checkpoint id does not incorporate it (the prefix hard-codes blockTimestamp to all zeros). Since production ordering relies on id encoding the block timestamp, consider either encoding the timestamp into the checkpoint prefix for realism or clarifying/removing the separate timestamp param to avoid misleading “chronological order” assumptions in test cases.
function makeEvent(
  referrer: `0x${string}`,
  timestamp: number,
  incrementalDuration: number,
  opts: Partial<Pick<ReferralEvent, "id">> = {},
): ReferralEvent {
  const counter = ++eventIdCounter;
  return {
    id: opts.id ?? `${CHECKPOINT_PREFIX}${String(counter).padStart(16, "0")}`,
    referrer,
    timestamp,
    incrementalDuration,
    incrementalRevenueContribution: ZERO_ETH,
  };

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

You can also share your feedback on Copilot code review. Take the survey.

@vercel vercel bot temporarily deployed to Preview – ensnode.io March 13, 2026 15:00 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 13, 2026 15:00 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io March 13, 2026 15:00 Inactive
@Goader Goader requested a review from lightwalker-eth March 13, 2026 15:00
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 13, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":403,"request":{"method":"PATCH","url":"https://api.github.com/repos/namehash/ensnode/issues/comments/4024456987","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- This is an auto-generated comment: failure by coderabbit.ai -->\n\n> [!CAUTION]\n> ## Review failed\n> \n> An error occurred during the review process. Please try again later.\n\n<!-- end of auto-generated comment: failure by coderabbit.ai -->\n\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nOrders deterministic sorting: registrar actions now sort by `id` (Ponder checkpoint) instead of `timestamp`; rev-share-limit leaderboard now uses lexicographic sorting on event `id`; two checkpoint helper functions were removed and tests updated for the new ID format.\n\n## Changes\n\n|Cohort / File(s)|Summary|\n|---|---|\n|**Changelog** <br> ` .changeset/tall-icons-return.md`|Adds a patch changeset documenting ordering fixes for `ensapi` and `@namehash/ens-referrals`.|\n|**Registrar Actions Query** <br> `apps/ensapi/src/lib/registrar-actions/find-registrar-actions.ts`|Changed `buildOrderByClause` for LatestRegistrarActions to sort by `registrarActions.id` (Ponder checkpoint) instead of `registrarActions.timestamp`.|\n|**Rev-share-limit core** <br> `packages/ens-referrals/src/v1/award-models/rev-share-limit/checkpoint.ts`, `packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.ts`|Removed helpers `resetEncodedEventType` and `compareEventIds`; replaced bigint-based checkpoint comparison with direct lexicographic comparison on `event.id`.|\n|**Rev-share-limit tests & docs** <br> `packages/ens-referrals/src/v1/award-models/rev-share-limit/leaderboard.test.ts`, `packages/ens-referrals/src/v1/award-models/rev-share-limit/referral-event.ts`|Updated test ID construction and expectations to match new checkpoint ID format and lexicographic ordering; adjusted JSDoc describing `ReferralEvent.id`.|\n|**SDK request constant** <br> `packages/ensnode-sdk/src/ensapi/api/registrar-actions/request.ts`|Updated `RegistrarActionsOrders.LatestRegistrarActions` from `orderBy[timestamp]=desc` to `orderBy[id]=desc` and added docblock explaining lexicographic/chronological semantics.|\n\n## Estimated code review effort\n\n🎯 3 (Moderate) | ⏱️ ~20 minutes\n\n## Suggested labels\n\n`ensnode-internal`\n\n## Poem\n\n> 🐇 I hopped through checkpoints, tidy and spry,  \n> > Swapped timestamps for ids that line up just right,  \n> > Trimmed old helpers, gave tests a new tune,  \n> > Now rows stand in order beneath the moon. ✨\n\n</details>\n\n<!-- walkthrough_end -->\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 4 | ❌ 1</summary>\n\n### ❌ Failed checks (1 warning)\n\n|     Check name     | Status     | Explanation                                                                           | Resolution                                                                         |\n| :----------------: | :--------- | :------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n<details>\n<summary>✅ Passed checks (4 passed)</summary>\n\n|         Check name         | Status   | Explanation                                                                                                                                                                                                 |\n| :------------------------: | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n|         Title check        | ✅ Passed | The title 'Registrar Actions: Inconsistent Order' is partially related to the changeset; it highlights the issue being fixed but lacks specificity about the solution (sorting by id instead of timestamp). |\n|      Description check     | ✅ Passed | The PR description follows the template with all required sections completed: Summary, Why, Testing, Notes for Reviewer, and Pre-Review Checklist all provided.                                             |\n|     Linked Issues check    | ✅ Passed | The PR directly addresses issue `#1704` by changing the sorting mechanism from timestamp to id field, ensuring deterministic ordering of registrar actions as required.                                       |\n| Out of Scope Changes check | ✅ Passed | All changes are tightly scoped to fixing the inconsistent ordering: sorting changes in registrar actions and mirror changes in rev-share-limit leaderboard; helpers removed as they became unused.          |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `fix/registrar-actions-inconsistent-order`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- pr_review_plan_action_start -->\n\n<details>\n<summary>📝 Coding Plan</summary>\n\n- [ ] <!-- {\"checkboxId\": \"6ad8a4e1-0b3a-4ea2-9b5b-d82c1f47d1f2\"} --> Generate coding plan for human review comments\n\n</details>\n\n<!-- pr_review_plan_action_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=namehash/ensnode&utm_content=1742)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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= -->\n\n<!-- internal state end -->"},"request":{"retryCount":1}},"response":{"url":"https://api.github.com/repos/namehash/ensnode/issues/comments/4024456987","status":403,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","content-encoding":"gzip","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Fri, 13 Mar 2026 15:00:24 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","transfer-encoding":"chunked","vary":"Accept-Encoding, Accept, X-Requested-With","x-accepted-github-permissions":"issues=write; pull_requests=write","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-api-version-selected":"2022-11-28","x-github-media-type":"github.v3; format=json","x-github-request-id":"3C43:20164A:3B0FEF7:F87DB9B:69B42686","x-ratelimit-limit":"5000","x-ratelimit-remaining":"4947","x-ratelimit-reset":"1773417428","x-ratelimit-resource":"core","x-ratelimit-used":"53","x-xss-protection":"0"},"data":{"message":"Resource not accessible by integration","documentation_url":"https://docs.github.com/rest/issues/comments#update-an-issue-comment","status":"403"}}}

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.

@Goader Hey looks good. Thanks. Shared a few suggestions. Please feel welcome to merge when ready 👍

* A deterministic and globally unique fixed-length identifier for the "logical registrar action"
* associated with the ReferralEvent.
*
* A Ponder-encoded checkpoint string that uniquely and deterministically identifies
Copy link
Member

Choose a reason for hiding this comment

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

Suggest we not document the implementation details of this id string value at this layer of responsibility.

Suggested action items:

  1. We should move all the strong documentation about the implementation details of this id field into the ensnode-schema package. Specifically here: https://github.com/namehash/ensnode/blob/main/packages/ensnode-schema/src/schemas/registrars.schema.ts#L170
  2. ... therefore, we can expose the implementation details of this id field to those building directly on ENSDb.
  3. The documentation about this id field within the ens-referrals package should treat the id field as an opaque identifier without any mention of its implementation details. Within the ens-referrals package we should just identify the following invariants about this id field:
    1. It is deterministic and globally unique.
    2. Sorting by this value achieves a chronological ordering of each registrar action by the order they were executed onchain.
  4. ... all the other implementation details, including any reference to Ponder or details of the "sub-fields" encoded within this string, etc.. should move into ensnode-schema.

* Records Orders
*/
export const RegistrarActionsOrders = {
LatestRegistrarActions: "orderBy[timestamp]=desc",
Copy link
Member

Choose a reason for hiding this comment

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

Suggest we revert the change here and keep the sort at an API layer as sorting by timestamp, not by id.

Yes, it's true that we would actually implement timestamp sorting by sorting by id, but that seems like an internal implementation detail of the API.

At the level of an external API consumer, if I say I want to sort by timestamp then I interpret that as wanting to sort in chronological order. The implementation of the API then translates that intention into a sort by id.

For background: Each block has a single timestamp and contain contain hundreds / thousands of events. Each of those events therefore share the same timestamp, but each event was executed in a specific order within the block.

Sorting by id is the same as sorting by timestamp with the added benefit that it correctly sorts events that share the same timestamp into the correct chronological order of when each event was executed within the same block.

/**
* Returns registrar actions newest-first.
*
* Sorts by the `id` field descending. Each `id` is a Ponder checkpoint string
Copy link
Member

Choose a reason for hiding this comment

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

This is a great comment, but suggest a few action items:

  1. Transfer all the nice ideas in this comment into a new "sort events" utility function in the ens-referrals package.
  2. Please see the feedback above suggesting to revert the removal of "orderBy[timestamp]=desc". Suggest to add a comment there about how sorting by timestamp not only sorts by timestamp, but further sorts by the chronological execution order of each registrar action.

// Ponder log (smart-contract event) handlers and therefore share the same
// eventType digit. If mixed event types are ever introduced, ordering by id
// directly would need revisiting.
const sortedEvents = [...events].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for this 👍 Suggest moving this logic and it's associated comments into a dedicated utility function.

"ensapi": patch
---

Fix inconsistent ordering of registrar actions by sorting on the constant-length Ponder checkpoint `id` field (lexicographic = chronological order) instead of timestamp alone.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Fix inconsistent ordering of registrar actions by sorting on the constant-length Ponder checkpoint `id` field (lexicographic = chronological order) instead of timestamp alone.
Provide deterministic sorting of registrar actions by their execution order.

Goal: Avoid reference to Ponder implementation details in our release notes unless there's a special reason to mention them.

"@namehash/ens-referrals": patch
---

Simplify rev-share-limit leaderboard race sort to use direct lexicographic comparison of the constant-length Ponder checkpoint `id`, removing the now-unnecessary `compareEventIds` and `resetEncodedEventType` helpers.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Simplify rev-share-limit leaderboard race sort to use direct lexicographic comparison of the constant-length Ponder checkpoint `id`, removing the now-unnecessary `compareEventIds` and `resetEncodedEventType` helpers.
Simplify how rev-share-limit leaderboard race sorting achieves deterministic sorting by execution order.

Goal: Avoid reference to Ponder implementation details in our release notes unless there's a special reason to mention them.

"@ensnode/ensnode-sdk": minor
---

Rename `RegistrarActionsOrders.LatestRegistrarActions` query parameter value from `orderBy[timestamp]=desc` to `orderBy[id]=desc` to accurately reflect the sort column.
Copy link
Member

Choose a reason for hiding this comment

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

Please see related comment where I suggested to revert this change.

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.

Inconsistent order of Registrar Actions

3 participants