5.9 KiB
Программа shine_login_guard
Документ описывает целевое поведение программы классификации логинов SHiNE.
Задача программы:
- по логину определить класс регистрации;
- вернуть результат в
return_data; - не хранить PDA и не вести собственное состояние.
1. Назначение
shine_login_guard — маленькая служебная программа, которую вызывает shine_users через CPI до регистрации пользователя.
Она отвечает только на вопрос:
- можно ли зарегистрировать логин автоматически;
- является ли логин premium;
- является ли логин trademark/company.
2. Program ID
Текущий program id:
3xkopA7cXagxzMFrKdv3NCBfV6BKiRJCk69kr27M2sRo
3. Состояние
У программы нет PDA-состояний и persistent storage.
Она опирается на статически сгенерированные словари, встроенные в бинарник на этапе сборки.
4. Внешние артефакты
Словари хранятся в:
src/dictionaries/premium/**/*.txtsrc/dictionaries/trademarks/**/*.txt
На этапе build:
- все
.txtфайлы рекурсивно собираются; - слова нормализуются;
- дубль-слова детектятся и логируются как warning;
- итоговые массивы слов вшиваются в generated Rust file.
5. Нормализация словаря
Слово словаря считается валидным, если:
- не пустое;
- длина не больше
20; - содержит только ASCII-буквы и цифры;
- после
trim()иlowercase()остаётся валидным.
Символ _ в словарных словах не допускается.
6. Единственная инструкция
Инструкция:
classify_login(login: String)
Бинарный ABI инструкции:
- tag: u8 = 1
- login_len: u32 LE
- login_bytes[login_len]: UTF-8
Аккаунты:
- аккаунты не требуются
Подпись транзакции для самой классификации не имеет бизнес-смысла. Если вызов идёт через CPI из shine_users, программа shine_login_guard не требует signer-аккаунтов вообще.
7. Выходные классы
Программа возвращает u32 через set_return_data:
0—CLASS_FREE1—CLASS_PREMIUM2—CLASS_TRADEMARK
8. Правила нормализации логина
Перед классификацией логин нормализуется:
- пустой логин запрещён;
- длина исходного логина не больше
20; - символ
_удаляется; - остальные символы обязаны быть ASCII alnum;
- буквы приводятся к нижнему регистру.
Если нормализация не удалась:
- логин считается
CLASS_PREMIUM.
Это намеренно жёсткое поведение: сомнительный логин не должен автоматически попадать в free-класс.
9. Правила классификации
Алгоритм:
- Нормализовать логин.
- Попробовать разрезать его на
1..3слов из словарей. - Если среди найденных частей есть trademark-слово, вернуть
CLASS_TRADEMARK. - Если есть только premium-слова, вернуть
CLASS_PREMIUM. - Если словарное совпадение не найдено и длина нормализованного логина
<= 7, вернутьCLASS_PREMIUM. - Иначе вернуть
CLASS_FREE.
10. Разбиение на слова
Максимум слов в логине:
3
Алгоритм разбиения:
- DFS/backtracking по префиксам строки;
- на каждом шаге берётся префикс длиной
1..20; - если префикс найден в premium или trademark словаре, поиск продолжается на остатке строки;
- если найден хотя бы один путь с trademark-словом, итог =
CLASS_TRADEMARK; - если найден путь только с premium-словами, итог =
CLASS_PREMIUM.
11. Инварианты
Должно быть сохранено при переписи:
- тот же способ нормализации логина;
- та же семантика классов
0/1/2; - тот же лимит
MAX_WORDS_PER_LOGIN = 3; - тот же fallback
len <= 7 => premium, если словарь ничего не нашёл; - тот же порядок приоритета
TRADEMARK > PREMIUM > FREE.
12. Что не обязано сохраниться при переписи
Можно менять без изменения бизнес-логики:
- build pipeline словарей;
- структуру хранения слов внутри бинарника;
- способ поиска слов, если сохраняется тот же результат;
- техническую форму возврата, если внешний контракт для
shine_usersостанется совместимым.
Но если меняется именно интерфейс return_data или классы, это уже требует обновления shine_users и документации.