paritytech / paritytech/dotns

[Feat]: A re-registered or transferred name keeps serving the previous owner's records

Open
#220 5 comments 0 reactions 1 assignee View on GitHub

@GHkrishna is already working on this.

Since Aug 17, 2026.

P1 scope: resolver type: feature
Dominant language
Solidity
Stars
4
Forks
2
Avg merge
1d 18h
Merged PRs (30d)
24

Description

Component

Resolver

Priority

P1

Summary

Resolver records are keyed by node, so they outlive every ownership change. DotnsResolver.addressOf, DotnsContentResolver.contenthash and DotnsContentResolver.text all return whatever the previous owner wrote, with no check that the current owner wrote it, so immediately after a sale or a re-registration the name still resolves to the previous owner's address. A payment sent to that name reaches the wrong person, which closed #100 described as an identity hijacking vector. Nothing clears the records. Delegations do reset by themselves, because the content resolver's operator map is keyed by the current owner, which makes the inconsistency sharper: permissions follow ownership and data does not. DotnsReverseResolver.nameOf already validates current ownership before returning and fails closed, so the three resolvers disagree with each other on the same question.

This was a deliberate trade rather than an oversight. PR #124 recorded it as a known limitation, on the basis that clients should invalidate on the NameReclaimed event and that cleanup of critical records is governance's responsibility. Two things have changed since. That acceptance was made when only funded NoStatus names could be released, and the rule restricting release to funded positions has since been removed, so every name is now recyclable. And the exposure is currently masked by #219, because the escrow deadlock blocks reclaim in practice, so it becomes live as soon as that lands.

The UI makes this worse today. TransferDomainModal.vue:116-120 warns about losing ownership but never mentions records, so the buyer inherits and re-publishes the seller's. And it tells sellers it cleared records when it did not: store/useResolverStore.ts:74 filters out empty values so no setText is issued, while views/WhoProfileView.vue:769-791 blanks the field locally and reports success (components/EditRecordsModal.vue:259-261 does the same for "Remove"). A seller cleaning up before a sale is told it worked.

Proposal
  • Decide the rule: either records are invalidated when ownership changes, or consumers are required to validate ownership themselves. Right now it is neither, and the interfaces say nothing either way.
  • Preferred mechanism: namespace record storage by a per-node epoch bumped on every ownership change, so a new holder starts clean and stale data becomes unreachable without needing deletion. Deletion is not viable for text records, which cannot be enumerated. That constraint binds the UI too: views/WhoProfileView.vue:688-698 reads four hardcoded keys, so a new owner cannot see or clear inherited custom records. An epoch makes stale records unreachable without enumerating them, which decides it from the client side.
  • Apply whatever is chosen consistently across all three resolvers.
  • If we accept the current behaviour instead, state it in the interface docs and make sure enough is emitted on an ownership change for a consumer to invalidate reliably, including on a plain transfer.
  • Independent of the decision: the UI reporting a successful clear for a write it never issued (store/useResolverStore.ts:74) is a bug either way and should not wait on this.
Acceptance criteria
  • A record written by a previous owner is not returned after ownership changes, or the interfaces state explicitly that callers must validate ownership themselves.
  • The rule is the same across all three resolvers.
  • Text records are covered, not only the address and content hash.
  • Tests cover both paths that change ownership: a plain transfer, and a release followed by reclaim to a different account.
  • A test reads every record type after the ownership change and asserts the chosen behaviour.
  • The transfer confirmation states that records follow the name.
  • Emptying a record field either issues the write or reports failure, never success.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.