canonical.gno
1.79 Kb · 46 lines
1package namereg
2
3import (
4 susers "gno.land/r/sys/users"
5)
6
7// reservedSet is the runtime O(1) lookup for the role-name blacklist.
8// Built in init() from reservedNames in blacklist.gno: each source
9// entry contributes BOTH `Canonicalize(n)` and `Canonicalize(n+"s")`
10// as keys, implementing the "implicit `s` suffix" rule documented on
11// reservedNames.
12//
13// Why canonicalize the blacklist itself: validation canonicalizes the
14// candidate stem before checking, so the comparison set must also be
15// in canonical form. Otherwise a candidate like "vital1k" would
16// canonicalize to "vitaiik" but the blacklist would contain only
17// "vitalik" — the comparison would miss the match. Keeping both sides
18// in canonical form makes the lookup exact.
19//
20// The blacklist remains namereg/v1-local because it is policy specific
21// to the Open Nym Tier. Other controllers may have entirely different
22// reserved-name policies, or none at all.
23var reservedSet map[string]struct{}
24
25func init() {
26 reservedSet = make(map[string]struct{}, len(reservedNames)*2)
27 for _, n := range reservedNames {
28 reservedSet[Canonicalize(n)] = struct{}{}
29 reservedSet[Canonicalize(n+"s")] = struct{}{}
30 }
31}
32
33// Canonicalize is a delegating shim to r/sys/users.Canonicalize.
34//
35// HISTORY: namereg/v1 used to host its own per-stem canonical store and
36// its own Canonicalize (l→i only). Option B unified the canonical lookup
37// into r/sys/users keyed by full canonical name with broader
38// substitutions ({l,i,1}→i, {0,o}→o, {-,.,_} stripped). This shim
39// preserves the call-site name for local consumers (blacklist init,
40// IsReserved) and any external consumer that imported the function
41// from namereg/v1 before Option B.
42//
43// New code should call susers.Canonicalize directly.
44func Canonicalize(s string) string {
45 return susers.Canonicalize(s)
46}