SHA256
143 lines
5.0 KiB
Markdown
143 lines
5.0 KiB
Markdown
# Программа `shine_users`
|
||
|
||
Актуальный пользовательский формат — `user_pda 1.2`.
|
||
Полный бинарный формат: `doc/formats/shine-user-pda-format-v.1.2.md`.
|
||
Legacy 1.0 считается тестовым и не мигрируется.
|
||
|
||
## Что хранит программа
|
||
|
||
- `root_key` — cold recovery authority;
|
||
- `client_key`;
|
||
- append-only список blockchain fork keys с временем создания и оплаченной квотой;
|
||
- один optional server address;
|
||
- ноль или один access server;
|
||
- `record_number`, `prev_record_hash` и переносимую Ed25519-подпись состояния.
|
||
|
||
Пользовательские SHiNE-блоки/Arweave этим патчем не меняются.
|
||
|
||
## Инструкции
|
||
|
||
### `1 init_users_economy_config`
|
||
Без изменений.
|
||
|
||
### `2 update_users_economy_config`
|
||
Без изменений.
|
||
|
||
### `3 create_user_pda`
|
||
|
||
```text
|
||
tag:u8 = 3
|
||
login:string_u8
|
||
root_key:[32]
|
||
created_at_ms:u64
|
||
additional_limit:u64
|
||
client_key:[32]
|
||
blockchain_key:[32]
|
||
address_count:u8 // 0 или 1
|
||
[address]
|
||
access_server_count:u8 // 0 или 1
|
||
[access_server]
|
||
record_signature:[64]
|
||
[promo_seller_login:string_u8]
|
||
```
|
||
|
||
Server address:
|
||
|
||
```text
|
||
address_format_type:u8
|
||
address_format_version:u8
|
||
address:string_u8
|
||
```
|
||
|
||
Fee payer — любой переданный signer; он не обязан совпадать с client key.
|
||
`created_at_ms` должен быть в пределах ±5 минут от Solana Clock.
|
||
Root даёт proof-of-possession, а initial blockchain key подписывает саму новую PDA.
|
||
|
||
### `4 update_user_pda`
|
||
|
||
Работает только с PDA 1.2.
|
||
|
||
```text
|
||
tag:u8 = 4
|
||
login:string_u8
|
||
new_root_key:[32]
|
||
updated_at_ms:u64
|
||
additional_limit:u64
|
||
new_client_key:[32]
|
||
auth_mode:u8 // 0 blockchain, 1 root
|
||
new_blockchain_present:u8
|
||
[new_blockchain_key:[32]]
|
||
address_count:u8 // 0 или 1
|
||
[address]
|
||
access_server_count:u8 // 0 или 1
|
||
[access_server]
|
||
record_signature:[64]
|
||
```
|
||
|
||
Программа сама вычисляет `record_number=old+1` и `prev_record_hash`.
|
||
`updated_at_ms` должен быть в пределах ±5 минут от Solana Clock.
|
||
|
||
Перед update идут две Ed25519 instructions по hash нового unsigned state:
|
||
|
||
1. старый authority разрешает переход;
|
||
2. authority нового состояния подписывает запись; эта подпись сохраняется в PDA.
|
||
|
||
Blockchain-mode:
|
||
|
||
- используется для всех обычных update;
|
||
- старый authority = последний blockchain key;
|
||
- `signature[64]` нового состояния = активный blockchain key либо новый blockchain key, если добавляется fork;
|
||
- root/client менять нельзя;
|
||
- новый fork — только после 72 часов от времени активного fork.
|
||
|
||
Root-mode:
|
||
|
||
- допустим только для recovery/полной ротации ключей;
|
||
- старый authority = текущий root;
|
||
- полная ротация одной транзакцией меняет `root_key`, `client_key` и добавляет новый blockchain fork;
|
||
- transition-подпись делает старый root, а `signature[64]` нового состояния делает новый blockchain key;
|
||
- recovery fork может обходить 72-часовой cooldown;
|
||
- смена root без одновременной смены client key и добавления нового blockchain fork отклоняется.
|
||
|
||
Обе Ed25519-подписи проверяются по одному и тому же hash нового unsigned PDA state, поэтому новые root/client/blockchain public keys входят в подписываемое состояние.
|
||
|
||
### `5 upsert_promo_seller`
|
||
Без изменений.
|
||
|
||
### `6 close_legacy_pda`
|
||
|
||
Временная cleanup-инструкция для тестовых PDA 1.0.
|
||
|
||
```text
|
||
tag:u8 = 6
|
||
login:string_u8
|
||
```
|
||
|
||
Accounts:
|
||
|
||
1. caller signer + writable;
|
||
2. legacy user PDA writable.
|
||
|
||
Программа проверяет PDA seed/owner и `format=1.0`, переводит все lamports PDA вызывающему и обнуляет account data. PDA 1.2 этой инструкцией закрыть нельзя.
|
||
|
||
## BlockchainRegistry 1.2
|
||
|
||
```text
|
||
fork_count:u16
|
||
forks[]:
|
||
blockchain_key:[32]
|
||
created_at_ms:u64
|
||
paid_limit_bytes:u32
|
||
```
|
||
|
||
Последний fork активный. Старые записи неизменяемы.
|
||
|
||
## Server/access limits в 1.2
|
||
|
||
Бинарный формат использует count/arrays для forward compatibility, но текущая программа намеренно ограничивает:
|
||
|
||
- `ServerProfileBlock`: один адрес;
|
||
- `AccessServersBlock`: 0 или 1 сервер доступа.
|
||
|
||
Позже лимиты можно увеличить без изменения структуры блоков.
|