SHiNE-server/Как_устроены_каналы_в_блокчейне_SHiNE.md

171 lines
7.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Как устроены каналы в блокчейне SHiNE
## 1) Коротко: что такое “канал” в текущей реализации
В SHiNE канал — это не отдельная таблица сообщений, а **линия блоков** внутри блокчейна пользователя:
- канал создается TECH-блоком `CreateChannelBody` (`msg_type=0`, `msg_sub_type=1`);
- сообщения канала — это `TEXT_POST` (`msg_type=1`, `msg_sub_type=10`) с `line_code = rootBlockNumber канала`;
- ответы (треды) — это `TEXT_REPLY` (`msg_sub_type=20`) с target-ссылкой на конкретный блок-сообщение.
То есть канал = “корневой блок канала” + все посты в его линии + связанные ответы.
---
## 2) Как канал появляется
Создание канала идет через `AddBlock`:
1. UI собирает `CreateChannelBody v2`.
2. UI подписывает блок приватным blockchain-ключом на устройстве.
3. UI отправляет на сервер `AddBlock` с `blockBytesB64` (полный бинарный блок: preimage + sigMarker + signature).
4. Сервер:
- проверяет цепочку (`prevHash`, `blockNumber=last+1`);
- парсит body;
- валидирует подпись;
- валидирует имя канала;
- сохраняет блок и обновляет state.
Дополнительно сервер поддерживает `channel_names_state` как нормализованное состояние названий каналов.
---
## 3) Правила имени и описания канала
### Имя канала (`ChannelNameRules`)
- длина: `3..32` символов (code points);
- допустимые символы: только латиница `A-Z a-z`, цифры `0-9`, `_`, `-`;
- имя нормализуется как `trim`;
- канонический slug: lower-case того же имени (без дополнительных преобразований).
### Уникальность
Проверяется по slug. При конфликте сервер возвращает `channel_name_already_exists`.
### Описание канала
В `CreateChannelBody v2` описание хранится прямо в блоке (до 200 байт UTF-8).
После создания описание в текущей реализации не редактируется (отдельного механизма обновления пока нет).
---
## 4) Канал “news” (root 0)
`rootBlockNumber=0` — системный канал `news` (новостной канал по умолчанию).
Публикации `TEXT_POST` в `news` сейчас отключены (на сервере есть явный запрет записи в root 0).
---
## 5) Как идут сообщения в канале
### Публикация поста
UI вызывает `addBlockTextPost` -> `AddBlock` с `TEXT_POST`.
Ограничения:
- писать можно только в **свой** блокчейн и свои каналы;
- для поста задается `line_code` канала;
- пост в канале — это новый неизменяемый блок.
### Ответы
Ответы (`TEXT_REPLY`) не обязаны лежать в той же линии.
Они ссылаются на целевой блок через target (`to_bch_name`, `to_block_number`, `to_block_hash`).
Это позволяет отвечать и из других блокчейнов (межпользовательский тред).
---
## 6) Редактирование и удаление сообщений
### Редактирование
Поддержано на уровне протокола:
- `TEXT_EDIT_POST` (11) — правка поста;
- `TEXT_EDIT_REPLY` (21) — правка ответа.
Правка — это **новый блок**, ссылающийся на оригинал.
Оригинальный блок не меняется.
Серверные read-API уже собирают `versions[]` и `versionsTotal`.
### Удаление
Сейчас отдельного subtype “delete post/reply” нет.
Физического удаления блоков из цепочки нет (блоки иммутабельны).
Итог:
- изменить можно через edit-блок;
- удалить “как в чате” сейчас нельзя.
---
## 7) Как UI получает канал
Основные read-API:
- `ListSubscriptionsFeed` — список каналов/подписок;
- `GetChannelMessages` — посты канала;
- `GetMessageThread` — тред вокруг выбранного сообщения.
Важно: UI получает **JSON-представление**, собранное сервером из блоков БД, а не сырые блоки по умолчанию.
В JSON возвращаются:
- `messageRef` (номер и hash блока),
- автор,
- текущий текст,
- `versions[]` (оригинал + правки),
- counters (`likesCount`, `repliesCount`).
---
## 8) Как строится тред
`GetMessageThread`:
1. Находит focus-сообщение по `(blockchainName, blockNumber)`.
2. Строит `ancestors` вверх по target-ссылкам.
3. Строит `descendants` вниз: replies, где target = focus.
Запросы в БД идут по `to_bch_name + to_block_number + to_block_hash`, поэтому ответы из других блокчейнов тоже связываются.
---
## 9) Что проверяется криптографически
При записи (`AddBlock`) сервер проверяет:
- корректность формата блока;
- непрерывность цепочки;
- `SHA-256(preimage)` и Ed25519-подпись;
- соответствие публичного blockchain-ключа пользователя.
На чтении (`GetChannelMessages`, `GetMessageThread`) сервер отдает уже сохраненные данные (JSON из БД).
Повторная верификация каждой записи при каждом чтении не делается.
---
## 10) UI-статус на сегодня (важно)
На момент этого документа:
- в UI нет полноценного экрана истории правок сообщения (хотя `versions` уже приходят);
- нет операции удаления сообщений (и на протоколе нет delete subtype);
- канал читается как JSON-слой поверх блоков, а не как “сырой бинарный блок-объект”.
---
## 11) Практический вывод по модели данных
Каналы в SHiNE — это append-only модель:
- каждое действие = новый подписанный блок;
- “изменение” = добавление новой версии, не перезапись старой;
- целостность и авторство обеспечиваются подписью и связностью цепочки;
- UI может показывать удобный “чатовый” вид, но источник истины — блоки.