# Синхронизация блоков и DM между серверами SHiNE Документ описывает архитектуру и протокол синхронизации данных между партнёрскими серверами SHiNE. ## 1. Зачем нужна синхронизация Пользователи SHiNE могут быть «приписаны» к разным серверам. Когда пользователь A (на сервере X) пишет пользователю B (на сервере Y): 1. Сервер X принимает сообщение; 2. Сервер X должен переслать DM-блок серверу Y; 3. Сервер Y сохраняет блок и доставляет в активные сессии пользователя B. Аналогично, блоки пользовательского блокчейна (записи `AddBlock`) должны синхронизироваться, чтобы любой партнёрский сервер мог отдать полную историю пользователя. ## 2. Список серверов синхронизации (`sync_servers`) Каждый сервер регистрирует в своей Solana PDA список `sync_servers` — логины SHiNE-аккаунтов партнёрских серверов, с которыми он синхронизируется. - Список хранится в блоке `ServerProfileBlock` внутри `user_pda` сервера. - Адрес каждого партнёрского сервера читается из его PDA на Solana. - Синхронизация двусторонняя: оба сервера должны иметь друг друга в `sync_servers`. ## 3. Что синхронизируется ### 3.1 Личные сообщения (DM) - Все DM-блоки форматов типов `1/2` (текст) и `3/4` (read-receipt). - Сервер-отправитель: при получении пары блоков от клиента перенаправляет их серверу получателя. - Сервер-получатель: сохраняет блоки в `signed_messages_v2`, доставляет в активные сессии. - Дедупликация по уникальному `message_key = from|to|timeMs|nonce|type`. ### 3.2 Блоки пользовательского блокчейна - Все блоки `AddBlock` пользователей, зарегистрированных на сервере или синхронизирующихся через него. - Синхронизируются в обе стороны между всеми партнёрами из `sync_servers`. - Порядок блоков сохраняется (по глобальному номеру блока и хэшу). - Дедупликация по глобальному номеру блока и хэшу. ## 4. Протокол синхронизации (целевой, не реализован) ### 4.1 Межсерверное соединение - Серверы устанавливают постоянное WebSocket-соединение друг с другом. - Адрес партнёра определяется по `server_address` из его Solana PDA. - Аутентификация: подпись Ed25519 корневым ключом сервера (`root_key` из PDA). - При разрыве — переподключение с экспоненциальным backoff. ### 4.2 Доставка новых данных (push) - При получении нового блока или DM сервер немедленно пушит его всем подключённым партнёрам. - Партнёр подтверждает приём (ACK). Без ACK — повтор с backoff. ### 4.3 Начальная синхронизация (backfill) - При первом подключении к партнёру серверы обмениваются «курсорами» состояния: последний глобальный номер блока, последний известный DM-ключ. - Сервер с более полной историей досылает недостающее партнёру. ### 4.4 Разрешение конфликтов - Блоки пользовательского блокчейна: порядок определяется глобальным номером блока. Конфликтующие ветки (fork) разрешаются по правилам `AddBlock` (см. `Dev_Docs/Blockchain/README.md`). - DM: конфликтов нет, `message_key` уникален. ## 5. Маршрутизация DM между серверами При отправке DM от пользователя A к пользователю B: 1. Клиент A отправляет пару блоков на свой сервер X. 2. Сервер X определяет, на каком сервере зарегистрирован пользователь B. - Сначала проверяет локально (если B зарегистрирован на X). - Иначе читает PDA пользователя B из Solana и смотрит `access_servers`. - Выбирает первый доступный сервер из `access_servers` и перенаправляет туда DM. 3. Сервер Y (из `access_servers` B) сохраняет и доставляет блоки. Кэш адресов серверов: обновляется раз в сессию (при ошибке соединения). ## 6. Безопасность - Все блоки подписаны ключами пользователя на клиенте — сервер не может подделать содержимое. - Серверы не расшифровывают DM-контент (шифрование — задача следующего этапа). - При синхронизации каждый блок проходит валидацию подписи на принимающем сервере. ## 7. Статус реализации | Компонент | Статус | |-----------|--------| | Регистрация серверной PDA в Solana | ✅ Реализовано | | Чтение `sync_servers` из PDA | Нужна реализация | | Межсерверный WebSocket-канал | Нужна реализация | | Push новых DM партнёрам | Нужна реализация | | Push блоков блокчейна партнёрам | Нужна реализация | | Backfill при первом подключении | Нужна реализация | | Маршрутизация DM через access_servers | Нужна реализация (заглушка) | Текущая версия сервера работает без межсерверной синхронизации. Синхронизация — задача следующего этапа разработки.