Skip to content

feat: rename lite/full to device and personhood names, with legacy gateway entrypoints - #321

Merged
re-gius merged 8 commits into
masterfrom
re-gius/device-personhood-naming
Sep 30, 2026
Merged

re-gius merged 8 commits into
masterfrom
re-gius/device-personhood-naming

Conversation

@re-gius

@re-gius re-gius commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Renames the Proof of Personhood surface from lite/full to the vocabulary v1.0.0 launches with: devicehood and personhood for what an account has proven or a label requires, device name (stem.NN) and personhood name for the names the gateway issues. v1.0.0 is the first mainnet launch, so this is the last moment the rename is cheap.

The gateway pallet runtime shipping with this release is frozen and keeps calling today's three controller functions and decoding today's errors. The controller therefore serves both: the new entrypoints, and a separate IDotnsPopControllerLegacy that keeps the old selectors. The next release (R2) will move the pallet to the new entrypoints and remove the legacy interface.

What changes

DotnsPopController / IDotnsPopController

Master This PR
reserveLiteName issueDeviceName
reserveBaseName issueDeviceNameWithReservation
reserveBaseNameOnly reservePersonhoodName
registerBaseName issuePersonhoodName
reservedBaseLabelOf reservedLabelOf
LiteRegistration, BaseReservation, BaseNameReservation, FullRegistration DeviceNameIssuance, DeviceNameIssuanceWithReservation, PersonhoodNameReservation, PersonhoodNameIssuance
LinkKind.LiteUsername LinkKind.DeviceName
LiteNameReserved DeviceNameIssued
StandaloneNameRegistered, BaseNameClaimed PersonhoodNameIssued on every issuance, plus ReservationClaimed on a claim
LiteToFullLinked DeviceNameLinked
InvalidLiteLabel, InvalidBaseLabel InvalidDeviceLabel, InvalidPersonhoodLabel
LiteNameAlreadyIssued DeviceNameAlreadyIssued
LiteLabelNotOwnedByUser DeviceNameNotOwned
BaseNameAlreadyRegistered PersonhoodNameUnavailable

"Issue" creates a gateway name; "reserve" is only the personhood-name queue. reserveLiteName issued a name, which is why it is renamed.

DotnsPopResolver: setLiteLink and LiteLinkUpdated become setDeviceLink and DeviceLinkUpdated. The getters are named by what they return, because the two directions take and return different identifiers: liteLink(personhoodNode) becomes deviceLabelhashOf(personhoodNode), returning a device-name labelhash, and fullClaim(deviceLabelhash) becomes personhoodNodeOf(deviceLabelhash), returning a personhood-name node.

DotnsPopLens: liteNamesOf + fullNamesOf and their two counts merge into namesOf(user, offset, limit) and nameCountOf(user): one listing of every gateway-issued name the user holds, with a single offset over store entries first and then pending claims. NameDetail.tier, liteLink, fullClaim become requiredTier, deviceLabelhash, personhoodNode. Name no longer carries a deadline, because pending claims never lapse (#324).

PopRules: PopStatus.PopLite / PopFull become Devicehood / Personhood (same uint8 values), and personhoodOf becomes popStatusOf, since it also returns devicehood. Revert messages follow the new vocabulary.

What keeps its name

  • Lite/Full where dotNS mirrors another team's code: the IPersonhood precompile interface. PopRules maps status 1 to Devicehood and 2 to Personhood in one place.
  • "PoP" in contract names, registry keys and isPopIssued.
  • The *BaseName* identifiers in PopRules, which the public controller and the SDK call. The prose now uses the same word: a label's base name is the label with any device suffix removed, and stem means only the letters of a device name.

Legacy entrypoints for the frozen pallet

IDotnsPopControllerLegacy keeps reserveLiteName, reserveBaseName and registerBaseName with their current selectors (0x220015c0, 0xd89f1bce, 0x7c4b376b), checked against the gateway pallet in individuality-community (v0.3.3 and main). Each forwards to its replacement's shared body. Called through them, label validation reverts with InvalidLiteLabel / InvalidBaseLabel (0x5c6c2eea, 0x39e67d31), the errors the pallet decodes; every other error is shared. supportsInterface reports both interfaces.

Behaviour changes

  • Every exit from a reservation queue now emits an event. ReservationClaimed and ReservationEvicted are new, and ReservationRelinquished is emitted wherever a user's entry is dropped (standalone issuance and re-reservation included), exactly once, and only when an entry existed.
  • DotnsPopLens.nameDetail(label) now returns the label and its required tier for a personhood name whose claim has not settled. It returned an empty label and NoStatus, because the registrar reads a tokenised name's label from the holder's LabelStore. nameDetailByNode still has no label for an unsettled name, which the node alone cannot recover.
  • DotnsPopLens.Name drops deadline. It reported mintedAt + reservationDuration, but pending claims never lapse and can be settled at any time, so the field had no meaning ([Feat]: Decide what the pending-claim deadline means #324). A claim's mintedAt is still available from IDotnsPopController.pendingClaims.

Upgrade shape

  • Code-only swaps of the DotnsPopController, DotnsPopResolver and PopRules proxies, plus a redeployed DotnsPopLens. No storage migration.
  • Storage layout is unchanged against master, apart from two annotated mapping renames in DotnsPopResolver; every __gap stays uint256[50].
  • DotnsPopController is 23,497 bytes, 1,079 under the limit.

Docs

  • README gains an Identifiers section defining label, labelhash, node and tokenId, including where a device name's labelhash and node diverge. It corrects the DotnsRegistrar description: a tokenId is uint256(node).
  • README, CONTRIBUTING, KNOWN_ISSUES and NatSpec follow the new vocabulary, and "dotNS" is spelled consistently across contracts, docs, scripts and workflows.
  • Stale statements fixed along the way:
    • baseLength was described as "digit-stripped", and classifyName as classifying "by the length it leaves"; every label is measured as written, less a device name's suffix.
    • Pending claims were described as expiring, or as settleable by third parties only after a window; settlement is permissionless at any time and always writes the label.
    • The commit-reveal controller was described as writing reservations; it only reads the slot, and clears a reclaimed name's stale slot.
    • The lens described ownership as read from the registrar; it reads the registry, which covers device-name subnames.
    • The escrow's zero-amount positions come from cross-paid registrations.

Consumers

Checked dotns-sdk, bulletin-deploy, getcash-community, host-rust-core, polkadot-ios-community, polkadot-android-community, polkadot-desktop-community, dotli-community, epoca, product-sdk: none calls a renamed selector, so nothing is affected in this release.

Type

  • Bug fix
  • Feature
  • Breaking change
  • Documentation
  • Chore
  • Refactor
  • Security

Scope

  • Registration
  • Resolver
  • Store
  • Proof of Personhood
  • Deployment scripts
  • Tests

Related Issues

#319
#324

Fixes

Closes #319
Closes #324

Checklist

Code

  • Follows project style
  • forge build passes
  • forge test passes
  • No new compiler warnings

Testing

  • New tests added for changed behavior
  • Fuzz tests added where applicable
  • Invariant tests verified

Security

  • No new selfdestruct or delegatecall
  • Access control reviewed
  • No storage layout conflicts (for upgradeable contracts)

Documentation

  • NatSpec updated on changed interfaces
  • README updated if needed

Breaking Changes

  • No breaking changes
  • Breaking changes documented below

Breaking changes:

  • ABI callers and indexers: renamed functions and errors get new selectors, and renamed events a new topic0 (see What changes). The three legacy entrypoints and InvalidLiteLabel / InvalidBaseLabel keep theirs.
  • Decoded struct fields: clients that decode structs by field name (viem, ethers) must read the new names: NameDetail.tier, liteLink, fullClaim become requiredTier, deviceLabelhash, personhoodNode, and the controller's request structs rename their fields too.
  • PopStatus: values stay uint8 0 to 3, so nothing on the wire changes. Member names are not part of the ABI, so the break is limited to Solidity code importing IPopRules and clients that hardcode the old labels (PopLite, PopFull); they need Devicehood, Personhood. The same applies to LinkKind.LiteUsername, now LinkKind.DeviceName.
  • PopRules revert strings: the PopError messages changed wording, so anything matching on the text breaks.
  • Lens listings: liteNamesOf / fullNamesOf and their counts are replaced by namesOf / nameCountOf, with a single offset, and Name drops deadline.

How to test

forge test

Notes

Once the dotNS gateway pallet will be updated to the new end points, we can stop supporting the legacy ones.

@re-gius
re-gius requested a review from a team as a code owner September 28, 2026 13:22
@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

CI Summary

Check Result
4naly3er Analysis Found 38 issues: 5 medium, 8 low, 13 gas, 12 informational - View Report
Slither Analysis Found 177 issues: 4 high, 40 medium, 74 low, 59 informational - View Report
Contract Tests (Unit + Fuzz) All tests passed (715 total) - View Report
Contract Tests (Invariant) Failed
Gas Report 9 contracts analyzed - View Report
Coverage Failed
Documentation Passed - 67 pages generated - View Docs
Format & Lint Passed - Code formatted correctly
File Validation Passed - All tracked files valid
Deploy Contracts Reproduces the expected address set; resume verified
PR Title PR Title Valid
Labels Unknown
Secret Scan Passed - No secrets detected

Per-section details omitted: combined body exceeded the 65000-char comment limit. Follow the View Report links above for each section's full output.

@GHkrishna

Copy link
Copy Markdown
Contributor

Overall looks good. Do we want to specify exact breaking like for eg.: enum PopStatus can be a breaking change?

Comment thread contracts/registrars/IDotnsPopLens.sol Outdated
@re-gius

re-gius commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator Author

Overall looks good. Do we want to specify exact breaking like for eg.: enum PopStatus can be a breaking change?

Yes, done. The Breaking changes section now lists the break per consumer. PopStatus keeps its uint8 values, so nothing changes on the wire; only Solidity code importing IPopRules and clients that hardcode PopLite / PopFull need updating. The same goes for LinkKind.LiteUsername.

@GHkrishna
GHkrishna self-requested a review September 29, 2026 15:08

@GHkrishna GHkrishna 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.

LGTM

re-gius pushed a commit that referenced this pull request Sep 30, 2026
…hanges first (#323)

## Description

This PR fixes two things in the release tooling
(`scripts/js/release-metadata.mjs`).

**1. `changedset` no longer flags StoreFactory after comment-only
edits**

StoreFactory deploys other contracts with `new`, so its bytecode carries
a copy of their creation code. Each copy ends with that contract's own
metadata hash, and that hash changes whenever a comment or NatSpec line
changes. `changedset` only stripped StoreFactory's own metadata at the
end of its bytecode, so a comment edit in LabelStore made StoreFactory
look changed and asked for an upgrade nobody needed.

Now the hash inside each embedded copy is set to zeros before hashing.
Real code changes still show up. `codehashes.json` gets a new
`hashScheme` field so that files hashed the old way and the new way are
never compared by mistake. `changedset` reads that field and hashes the
current build the same way the previous file was hashed.

**2. Release notes list breaking changes first**

The "ABI changes" section of the release body is now grouped by how much
each change matters:

1. Breaking changes: the ones declared in pull request descriptions,
then changed function signatures, removed functions, contracts that are
no longer published, and changed or removed events.
2. New contracts, new functions and new events.
3. Custom errors.

A new `pulls` command reads the pull requests merged since the previous
release. A pull request counts as breaking if any of these is true: its
"Breaking Changes" section has text, its title has a `!`, it has the
`breaking` label, or one of the breaking boxes is ticked. Its text is
copied into the notes. `abi-diff.json` gets a new `declaredBreaking`
list. Both publish workflows now need `pull-requests: read`.

## Type

- [x] Bug fix
- [x] Feature
- [ ] Breaking change
- [x] Documentation
- [ ] Chore
- [ ] Refactor
- [ ] Security

## Scope

- [ ] Registration
- [ ] Resolver
- [ ] Store
- [ ] Proof of Personhood
- [ ] Deployment scripts
- [ ] Tests

Release tooling only. No contract code changes.

## Related Issues

Found in #321, whose NatSpec-only edits to LabelStore put StoreFactory
in its changedset.

## Fixes

Fixes #322

## Checklist

### Code

- [x] Follows project style
- [x] `forge build` passes
- [ ] `forge test` passes
- [x] No new compiler warnings

### Testing

- [ ] New tests added for changed behavior
- [ ] Fuzz tests added where applicable
- [ ] Invariant tests verified

### Security

- [x] No new `selfdestruct` or `delegatecall`
- [ ] Access control reviewed
- [x] No storage layout conflicts (for upgradeable contracts)

### Documentation

- [ ] NatSpec updated on changed interfaces
- [x] README updated if needed

### Breaking Changes

- [x] No breaking changes
- [ ] Breaking changes documented below

**Breaking changes:**

## How to test

**changedset fix**

```bash
forge build
node scripts/js/release-metadata.mjs build --tag base --out /tmp/base --addresses false
# change only a comment in contracts/store/LabelStore.sol
forge build
node scripts/js/release-metadata.mjs changedset --previous /tmp/base/codehashes.json
# nothing is listed

# now make a real code change in LabelStore.sol
forge build
node scripts/js/release-metadata.mjs changedset --previous /tmp/base/codehashes.json
# LabelStore and StoreFactory are listed
```

**Release notes**

```bash
# needs gh logged in with read access to the repo
node scripts/js/release-metadata.mjs pulls --repo paritytech/dotns \
  --base <previous-tag> --head HEAD --out /tmp/pulls.json
node scripts/js/release-metadata.mjs abidiff --current <abis-dir> \
  --previous <previous-abis-dir> --previous-tag <previous-tag> --pulls /tmp/pulls.json
```

## Notes

- The next release still compares against the previous release's
`codehashes.json`, which was hashed the old way. So StoreFactory will
show up once more in that release's changedset if any contract it
deploys changed, even if only a comment changed. After that it is clean.
- If we want that next release to be clean too, we can regenerate the
previous release's metadata with this fix and compare against that
instead. Check out the previous release tag, apply this change, run
`forge build` and `release-metadata.mjs build`, then pass the new
`codehashes.json` to `changedset`. If StoreFactory is not listed, its
code did not change and it does not need an upgrade.
- `pulls` reads every merged pull request, not only the labelled ones,
because missing a breaking change is costly and a label is easy to
forget. It makes one API call per commit, which is fine for our release
size. If releases grow a lot, we can switch to a cheaper approach.
- If reading the pull requests fails, the release step fails. It is
better to re-run the step than to publish notes that miss a breaking
change.
- Any `@mention` in a pull request's breaking changes text will notify
that person when the release is published.

---------

Signed-off-by: GHkrishna <krishna@parity.io>
@github-actions github-actions Bot added the dependencies Pull requests that update a dependency file label Sep 30, 2026
@re-gius
re-gius requested a review from GHkrishna September 30, 2026 12:08
Comment thread contracts/registrars/IDotnsPopLens.sol Outdated

@GHkrishna GHkrishna 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.

LGTM

@re-gius
re-gius merged commit 9a84fa7 into master Sep 30, 2026
25 of 27 checks passed
@re-gius
re-gius deleted the re-gius/device-personhood-naming branch September 30, 2026 13:40
github-actions Bot added a commit that referenced this pull request Sep 30, 2026
github-actions Bot added a commit that referenced this pull request Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

2 participants