# Синхронизация блоков и 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 | Нужна реализация (заглушка) |

Текущая версия сервера работает без межсерверной синхронизации.
Синхронизация — задача следующего этапа разработки.
