Переписать shine_users и shine_login_guard на чистый Rust

This commit is contained in:
AidarKC
2026-06-04 23:05:45 +04:00
parent 60049442f1
commit 832eea5889
17 changed files with 1355 additions and 1621 deletions
+82 -21
View File
@@ -52,26 +52,26 @@
Пользовательская запись строится так:
- seed prefix: `login=`
- seed prefix: `user_login=`
- второй seed: логин в нижнем регистре
- program id: `shine_users`
Формула:
```text
user_pda = PDA(["login=", lower(login)], shine_users_program_id)
user_pda = PDA(["user_login=", lower(login)], shine_users_program_id)
```
### 3.2. Economy config PDA
PDA экономических настроек:
- seed: `shine_users_economy_config`
- seed: `shine_users_economy_config_v2`
Формула:
```text
users_economy_config_pda = PDA(["shine_users_economy_config"], shine_users_program_id)
users_economy_config_pda = PDA(["shine_users_economy_config_v2"], shine_users_program_id)
```
## 4. Состояния программы
@@ -105,8 +105,8 @@ users_economy_config_pda = PDA(["shine_users_economy_config"], shine_users_progr
Базовые значения из текущей логики:
- seed `user_pda`: `login=`
- seed economy config: `shine_users_economy_config`
- seed `user_pda`: `user_login=`
- seed economy config: `shine_users_economy_config_v2`
- стартовый размер `user_pda`: `768` байт
- `LIMIT_STEP = 10_000`
- `START_REGISTRATION_FEE_LAMPORTS = 10_000_000`
@@ -199,9 +199,15 @@ On-chain инвариант только один:
### Правила
- PDA должна ещё не существовать;
- адрес PDA обязан совпадать с seed `shine_users_economy_config`;
- адрес PDA обязан совпадать с seed `shine_users_economy_config_v2`;
- в PDA записывается стартовый `UsersEconomyConfigState`.
### Бинарный ABI
```text
- tag: u8 = 1
```
## 9. Инструкция `update_users_economy_config`
### Назначение
@@ -223,6 +229,15 @@ On-chain инвариант только один:
- PDA должна существовать и принадлежать программе;
- `lamports_per_limit_step > 0`.
### Бинарный ABI
```text
- tag: u8 = 2
- registration_fee_lamports: u64 LE
- lamports_per_limit_step: u64 LE
- start_bonus_limit: u64 LE
```
## 10. Инструкция `create_user_pda`
### Назначение
@@ -259,6 +274,18 @@ On-chain инвариант только один:
- mutable fields записи
- `root` signature по unsigned части
### Бинарный ABI
```text
- tag: u8 = 3
- login: string_u8
- root_key: [u8; 32]
- created_at_ms: u64 LE
- additional_limit: u64 LE
- fields: UserMutableFieldsV1
- root_signature: [u8; 64]
```
### Обязательные проверки
1. Логин валиден по синтаксису.
@@ -352,16 +379,20 @@ topup_fee = limit_fee(additional_limit)
Если `additional_limit = 0`, доплата не требуется.
### Важная пометка о текущем состоянии
### Бинарный ABI
Логика `update_user_pda` в текущей Anchor-версии описана именно так и должна работать именно так.
Но фактическая текущая Anchor-реализация на момент подготовки этого документа имеет runtime-проблемы в Solana BPF:
- create-сценарий работает корректно;
- update-сценарий логически реализован, но требует исправления багов реализации.
При переписи на чистый Rust нужно сохранять именно правила этого документа, а не привязываться к деталям текущей Anchor-реализации.
```text
- tag: u8 = 4
- login: string_u8
- root_key: [u8; 32]
- created_at_ms: u64 LE
- updated_at_ms: u64 LE
- version: u32 LE
- prev_hash: [u8; 32]
- additional_limit: u64 LE
- fields: UserMutableFieldsV1
- root_signature: [u8; 64]
```
## 12. Ed25519-проверки и порядок инструкций
@@ -426,6 +457,36 @@ signature = Ed25519(blockchain_private_key, message_hash)
## 15. Правила серверных и сессионных полей
### UserMutableFieldsV1
```text
- device_key: [u8; 32]
- blockchain_public_key: [u8; 32]
- blockchain_name: string_u8
- used_bytes: u64 LE
- last_block_number: u32 LE
- last_block_hash: [u8; 32]
- last_block_signature: [u8; 64]
- arweave_tx_id: string_u8
- is_server: u8
- if is_server = 1:
- address_format_type: u8
- address_format_version: u8
- server_address: string_u8
- sync_servers_count: u8
- sync_servers[sync_servers_count]: string_u8[]
- access_servers_count: u8
- access_servers[access_servers_count]: string_u8[]
- sessions_mode: u8
- sessions_count: u8
- sessions[sessions_count]:
- session_type: u8
- session_version: u8
- session_name: string_u8
- session_pub_key: [u8; 32]
- trusted_count: u8
```
### Server profile
Если `is_server = false`:
@@ -483,7 +544,7 @@ signature = Ed25519(blockchain_private_key, message_hash)
## 18. Что должно сохраниться при переписи без Anchor
При переписи на чистый Rust нужно сохранить без изменений:
В текущей чисто-rust реализации уже сохранены:
- те же PDA seed-правила;
- тот же формат `user_pda`;
@@ -493,9 +554,9 @@ signature = Ed25519(blockchain_private_key, message_hash)
- ту же валидацию логина и CPI в `shine_login_guard`;
- ту же зависимость от inflow vault программы `shine_payments`.
Что не обязано сохраниться:
Сознательно не сохранялись:
- структура Anchor `Context`;
- Anchor discriminator'ы;
- внутренние helper-функции текущей реализации;
- текущие runtime-баги update-path.
- Anchor discriminator'ы и Anchor-ABI инструкций;
- старые seed'ы, которые конфликтовали с уже существующим Anchor-состоянием в devnet;
- внутренние helper-функции старой реализации.