Person's usernames: read from Asset Hub dotNS instead of the People Chain (rebase of #349) - #426
Merged
Conversation
…eo-assethub address The documented 0x1c858C… value predates the Paseo Asset Hub Next V2 reset; the live DotnsPopController is 0xCC9323… (paritytech/dotns DEPLOYMENTS.md, same drift as paritytech/dotns#221). Discovery is on-chain, so this only touches the env-override docs.
…inst the live gateway Review findings on #349 after the rebase, verified against the live paseo-next-v2 and previewnet Asset Hubs (spec 2000036, identical) and the dotNS contracts on master. In-core identity lookup - Open the identity follow withRuntime=true. chainHead_v1_call is refused on a follow opened without runtime, so every ReviveApi_call view failed and no in-core session ever resolved a username; only the CLI's plain-RPC path worked. Adds a scripted chainHead test that fails on the old value. - LabelStore labels carry the network TLD (DotnsPopController._writeRecord appends protocolRegistry.tld(); ".paseo" on paseo-next-v2), and the classifier only stripped ".dot", so a settled "alice01.paseo" became the full username "alice01.paseo". resolve_labels now reads tld(), strips it, and drops subnames; classify_labels takes bare labels. - Always merge pendingClaims with the store: a public registration or an incoming transfer deploys the store while gateway names stay pending, so the store alone hid them. Page the store (append-only ledger shared with public names) instead of reading only the first 16 labels. - Probe TARGET() and pendingClaims first; target()/pendingClaim are the legacy fallbacks (the deployed dispatcher and controller only have the former). checked_add on chain-supplied ABI lengths. - Lite stems follow StringUtils.isSingleDotLiteLabel (DNS label + two digits), not alphabetic-only. register-name - AsDotnsGatewayInfo::RegisterFullName is {proof, ring_index, revision, signature} on the live runtime (individuality#1013); the shape assertion and the extra encoding lacked revision, so the command failed at the metadata check. Read the People-collection root revision at the pinned block, wait for Asset Hub's members-subscriber to import it, and encode it. Ring/root/roots helpers take the collection identifier; the LitePeople wrappers keep their behaviour. - Refresh the Asset Hub metadata fixture to the live V16 (spec 2000036). - Fail early when the member key is onboarded but not yet built into a root (the sliced members read cannot prove it), and validate the label and --link-lite shape before signing.
…sets - Previewnet has a live Bulletin chain (wss://previewnet.substrate.dev/bulletin, genesis 0x2778b1c9…, "Bulletin Local"), which dotli and dotns-sdk already use; the preset borrowed paseo's, so the host advertised and routed a Bulletin genesis that disagreed with the app's config. - The live drift test accepts "Individuality" for the People role (previewnet's People chain calls itself "Individuality Local"); it now passes for all six roles. - SPEC.md: previewnet endpoint table (pinned by the genesis-table test for every preset), register-name section, env/override wording; README: register-name, previewnet, HOST_CLI_* env vars. - Doc comments still describing usernames as People-chain Resources.Consumers reads now name the dotNS contracts on Asset Hub (regenerated Swift bindings and codegen golden follow).
…warm-path reads Ignored network tests against paseo-next-v2 Asset Hub: the live AsDotnsGatewayInfo::RegisterFullName shape (4 fields) the host asserts before signing, and the full dotNS resolution chain (pallet storage → dispatcher TARGET() → controller → registry → store factory → LabelStore) for an account with a settled store, proving the TLD is stripped and paging covers the store. Same rationale as the PGAS live tests: a fixture is a snapshot.
is_person_label in paritytech/individuality (support/src/labels.rs) accepts lowercase ASCII letters only, no digits or hyphens; the register-name pre-check now enforces the same instead of a looser DNS-label rule.
The paseo-next-v2 identity backend answers POST /usernames with "dotNS gateway is not enabled in this environment" (verified live), and since usernames are now read only from dotNS on Asset Hub, accounts registered through such a backend can never resolve one. Say so, and point at the previewnet preset / HOST_CLI_IDENTITY_BACKEND_BASE.
This was referenced Aug 17, 2026
…already minted Review on #349 (re-gius) and paritytech/dotns#235: the gateway enqueues a reservation for a reserved_base_label without asking the registrar, so a reservation over a registered name can never be claimed and holds the whole stem's reservation queue for the reservation window. The contract-side guard lands in dotns; the client asks first so an attestation cannot fail as a whole (and lose the lite name) once that guard exists. label_available reads DotnsRegistrar.available(uint256(node)) for the label's node under the network tldNode(), through the same transport as the username reads. attest() checks the reserved base name (shape per the pallet's is_valid_person, then availability); register-name checks its label. Live test on paseo: a minted name reports unavailable, an unminted one available.
…tNS registries
Previewnet's DotnsProtocolRegistry predates the configurable TLD (dotns
b4096968) and has no tld()/tldNode(); its TLD is ".dot". Username reads
of a settled LabelStore and the registrar availability check therefore
reverted there. network_tld() reads tld() and falls back to ".dot" when the
view reverts; the TLD node is derived locally (namehash) instead of read.
Live: settled-store labels and available() resolve on both paseo-next-v2
(".paseo") and previewnet (".dot"). The live tests take LIVE_ASSET_HUB_WS,
LIVE_MINTED_LABEL and LIVE_TLD to point at another network.
filip-parity
requested review from
GHkrishna,
Zebedeusz,
re-gius and
sphamjoli
August 17, 2026 11:08
main's #431 introduced PersonhoodCollection and made the ring, root and subscriber-root helpers take it; the branch's identifier-based generalisation of the same helpers folds into that API. read_member_ring_index and read_subscriber_ring_exponent take a PersonhoodCollection; register-name uses PersonhoodCollection::People. ChainState literals carry restrict_origins.
Contributor
Author
|
Testing — done against the live identity backend and live chains (previewnet and paseo-next-v2), not local nodes.
CI ( |
… the reserved name reachable Repo-conventions review of #426. - discover_pop_controller reads DotnsGateway.DispatcherAddress and the dispatcher's TARGET(); pending claims come from pendingClaims(address). The target(), pendingClaim(address) and PopControllerAddress fallbacks, and the singular pending-claim decoder, are gone: no deployed network answers them (live-probed on paseo-next-v2 and previewnet). The ".dot" fallback stays: previewnet's registry has no tld() view. - is_full_person_label now matches the pallet's is_person_label ([a-z]+, at most 32 bytes); the earlier commit changed only the messages. - signing-host takes --reserved-username for a newly created auto account (same conflict rules as --lite-username-prefix), so the reserved-name pre-flight added for re-gius' review is reachable; live: a minted name and a malformed label are refused before the backend is called. - Comments describe current behaviour only; availability responses are the flat map both identity backends serve; backend token env/mint share one cell; MemberRingPosition projects only the fields it reads (covered by the projection test); read_member_ring_index_at names the pinned read; the scripted identity test asserts the H160 argument.
…at the gateway rejects Findings of the second five-agent verification pass on #426. - DotnsTransport::view returns DotnsViewError: a contract revert is an answer, a transport or decode failure is not. network_tld() falls back to ".dot" only on a revert (a registry without tld(), as on previewnet); any other failure is an error, since guessing the TLD would drop every label carrying the real one and let label_available approve minted names. - label_available asks DotnsRegistrar.ownerOf: a minted name is taken whoever holds it, the escrow included, because the gateway only mints fresh ids. classify_labels skips non-ASCII store labels instead of panicking. A malformed DispatcherAddress is an error, not "not deployed". - register-name refuses up front what the gateway extension rejects: an account that already holds a DotnsGateway.AccountAlias, and a lite link the account does not own per DotnsGateway.LiteLabelOwner. Labels follow the PopRules tiers as well as the pallet rule: registrable full names are six to thirty-two lowercase letters, reservable base names six to eight; --reserved-username is validated before startup. - The Asset Hub metadata fixture is main's paseo-next-asset-hub-metadata.scale (byte-identical). The settled-store live test proves paging. The scripted in-core test asserts the exact view sequence, origin and H160 argument. - Docs: previewnet is the only preset whose identity backend onboards new auto accounts today; register-name output lines; HOST_CLI_SIGNER_MNEMONIC scope; availability response shape; SigningHostConfig's Asset Hub genesis is a parity field.
sphamjoli
reviewed
Aug 18, 2026
SessionUiInfo/SessionInfo carry the identity material from #403 next to the dotNS username fields; the codegen golden and Swift bindings are regenerated.
… harden the CLI reads Review of #426 by sphamjoli. - The in-core dotNS lookup has a 45 s budget for the whole walk (best block, discovery, contract views, label pages) and 10 s per step, instead of 10 s for everything. - resolve_labels warns when the last label page read was still full, so a name past the paged range shows in the logs rather than as "no username". - Backend access tokens are cached per backend base, so two backends in one process never share a token. - AssetHubReader errors on AccountAlias / LiteLabelOwner values of the wrong length instead of treating them as absent, and resolves the controller once per reader.
sphamjoli
approved these changes
Aug 18, 2026
re-gius
reviewed
Aug 18, 2026
TarikGul
reviewed
Aug 19, 2026
TarikGul
reviewed
Aug 19, 2026
TarikGul
reviewed
Aug 19, 2026
TarikGul
reviewed
Aug 19, 2026
TarikGul
reviewed
Aug 19, 2026
TarikGul
reviewed
Aug 19, 2026
TarikGul
reviewed
Aug 19, 2026
TarikGul
requested changes
Aug 19, 2026
TarikGul
left a comment
Member
There was a problem hiding this comment.
4 blockers, and a few nits, overall looks great
main's #440/#455 brought their own previewnet preset with the post-wipe genesis hashes; the branch keeps its per-chain endpoint constants and backend override, updated to those values. The SPEC/README previewnet sections merge main's wording with the dotNS onboarding note; the 401 caveat does not apply here, since the CLI mints the backend token itself.
- hosts/dotli passes runtimeConfig.assetHub (dotli-community#180); the
submodule points at that commit, so make dev and make e2e-dotli keep
working with the required field.
- The auto-linked lite username passes the same `name.NN` shape check as an
explicit --link-lite before it enters the signed ring-VRF message.
- The 45 s lookup budget bounds the whole username resolution of a session
(identity account, root fallback, every retry); each step keeps its 10 s
operation timeout, and running out of budget installs the session without
a username instead of blocking activation.
- The ".dot" TLD fallback is verified instead of guessed: on a tld() revert
the registry must hold the record for namehash("dot")
(DotnsRegistry.recordExists), or resolution errors.
- Every dotNS view names its call in errors; a pendingClaims revert is the
controller's answer (warn, read the store) rather than the end of the
whole resolution.
- SigningHostConfig carries no Asset Hub genesis: nothing reads it there,
the pairing config is where it drives the dotNS lookup. The field is gone
from the native records, the wasm signing-host config, and the Swift and
Kotlin wrappers, so native hosts do not carry a dead required field.
- VIEW_CALL_ORIGIN maps to a non-zero eth-derived address, since Solidity
guards commonly reject address(0) and a revert is read as an answer.
- TODO(#334) on the second Members.Members reader.
Carries the runtime-config contract test for assetHub and the deepmerge-ts audit pin alongside the assetHub field itself.
Member
|
Feel free to ping me when you need a re-review |
Contributor
Author
Ping, Github's re-request review is not working as usualy FYI I also raised paritytech/dotli-community#180 |
Contributor
Author
|
@Zebedeusz since you contributed with the first commit can you also review this E2E please? |
TarikGul
reviewed
Aug 21, 2026
TarikGul
reviewed
Aug 21, 2026
TarikGul
reviewed
Aug 21, 2026
TarikGul
reviewed
Aug 21, 2026
TarikGul
left a comment
Member
There was a problem hiding this comment.
Just 3 comments, once they are addressed we should be good to go :) Thanks
Review of #426 by TarikGul. - classify_labels accepts only canonical DNS labels (lowercase letters, digits, hyphens, at most 63 octets), so no unscreened contract string — oversized, control characters, markup, ANSI — reaches SessionUiInfo or any later caller; the bound lives in one place instead of per call site. - label_available reads DotnsRegistrar.exists(uint256), a total view: minted and unminted are both answers, and a revert is a broken deployment and an error, never "available". Covered offline for all four outcomes.
Contributor
Author
TarikGul
approved these changes
Aug 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
Rebase of #349 ("Person's usernames - read from AH dotNS instead of PC", by @Zebedeusz — kept as the first commit) onto
main, with the review fixes on top. Tracks #397; the client half of paritytech/individuality#755 and paritytech/dotns#230.What the host does after this PR
Usernames come from the dotNS contracts on Asset Hub.
host_logic::dotns_gatewayholds the resolution steps once, over a two-method transport (storage,view=ReviveApi_calldry-run from the always-mappedVIEW_CALL_ORIGIN); the CLI drives it over plain RPC (dotns_read.rs) and the in-core runtime over onechainHead_v1follow opened with runtime (runtime/identity.rs). Every session-identity site (pairing_host.rs,sso_pairing.rs) resolves against the Asset Hub genesis.Resolution:
DotnsGateway.DispatcherAddress→RootGatewayDispatcher.TARGET()→DotnsPopController→pendingClaims(user)(gateway-minted names not yet settled byclaimLabelStore) merged with the user'sLabelStorelabels viaprotocolRegistry()→get(storeFactory)→getLabelStore(user)→ pagedgetLabels. Store labels carry the network TLD (protocolRegistry.tld(),.paseoon paseo-next-v2;.dotwhere the registry has notld()view, as on previewnet); it is stripped and subnames are dropped.label_availableasksDotnsRegistrar.availablefor a label's node under that TLD.classify_labelsre-dots flat lite labels (alice01→alice.01, perStringUtils.isSingleDotLiteLabel) and treats the rest as full names.HOST_CLI_DOTNS_POP_CONTROLLERoverrides discovery when needed.register-name(CLI) registers a full-person username throughDotnsGateway.register_name: reads the People-collection ring index, members and root revision at one pinned People block, waits for Asset Hub'smembers-subscriberto hold that revision, then submits a General (v5) extrinsic authorized byAsDotnsGateway=RegisterFullName { proof, ring_index, revision, signature }(shape asserted from metadata before signing) withRestrictOrigins(true);Link::LiteUsername(default: the account's own lite name from dotNS) orLink::None(chat_key). Labels are validated with the pallet's rules ([a-z]+, ≤32 bytes; litestem.NN) and checked against the registrar up front.signing-host --reserved-username <label>reserves a full-person name for a newly created auto account, after the same label and registrar checks.Configuration: every host config carries the Asset Hub genesis —
PairingHostConfig/SigningHostConfig,NativeRuntimeConfig/NativeHostRuntimeConfig(uniffi, Swift/Kotlin wrappers), wasmruntimeConfig.assetHub.genesisHash(required), JS types. Presets:paseo-next-v2andpreviewnet(own People/Bulletin/Asset Hub and identity backend), documented in SPEC §14.1 and pinned by the genesis-table test;HOST_CLI_IDENTITY_BACKEND_BASE/_TOKENoverride the backend.statement_allowancering/root helpers take a collection identifier (LitePeople wrappers unchanged; PGAS and allowance paths untouched).Verified
cargo build/test --workspace --all-features(812 tests), wasm32 check,fmt,clippy -D warnings, iOS bindings--check, codegen no drift.202→ name visible through dotNS/Asset Hub → ring onboarding → paired);identity-checkresolves it; pairing-host ⇄ signing-host SSO withgetUserIdresolved in-core from Asset Hub.identity-checkcold path; ignored live tests for theRegisterFullNameshape and for a settled store (TLD stripped, ~90 labels paged); the ignored preset-genesis test passes for all six roles.Link, proof message,DOTNS_GATEWAY_CONTEXT,RegisterFullNameand the label rules matchpallets/dotns-gatewayon paritytech/individualitymain; contract selectors and ABI shapes match paritytech/dotnsmaster.Review pointers
Each commit message carries the rationale for its change; the first commit is #349 as authored.
Known, outside this PR
POST /usernameswith "dotNS gateway is not enabled in this environment", so accounts registered through it cannot get a dotNS-readable username; the CLI says so and points at previewnet.hosts/dotlimust sendruntimeConfig.assetHub.genesisHash(required by the wasm host config) — companion change in dotli-community.claimLabelStoreis user-signed from the user's own funded H160 and stays outside the host; pending claims expire after 7 days (dotns side).