Сохранить текущий снимок DM-синхронизации

This commit is contained in:
AidarKC
2026-08-24 17:50:36 +04:00
parent 015fade4c0
commit d8e0c77951
48 changed files with 2498 additions and 383 deletions
+27 -17
View File
@@ -32,9 +32,11 @@
### 3.1 Личные сообщения (DM)
- Все DM-блоки форматов типов `1/2` (текст) и `3/4` (read-receipt).
- Сервер-отправитель: при получении пары блоков от клиента перенаправляет их серверу получателя.
- Сервер-получатель: сохраняет блоки в `signed_messages_v2`, доставляет в активные сессии.
- Сервер-отправитель: сохраняет пару и ставит асинхронную delivery-задачу.
- Сервер-получатель: сохраняет входящий блок в `signed_messages`, затем доставляет его активным сессиям.
- Дедупликация по уникальному `message_key = from|to|timeMs|nonce|type`.
- Репликация между двумя access-серверами пользователя работает через `dm_sync_outbox.synced`, без постоянного time-cursor.
- Полная актуальная схема: `docs/Personal_Messages/Доставка_и_синхронизация_DM.md`.
### 3.2 Блоки пользовательского блокчейна
@@ -181,7 +183,9 @@ Full resync запускается только тогда, когда:
Настройка влияет именно на этап подготовки отсутствующей локальной цепочки во время periodic sync.
## 5. Целевой протокол следующего этапа
## 5. Возможное развитие server-to-server транспорта
Этот раздел не описывает текущую DM-доставку. DM уже использует короткие one-shot WebSocket-вызовы, indexed outbox и ACK. Ниже остаётся возможное развитие постоянного транспорта и server-auth.
### 5.1 Межсерверное соединение
@@ -192,14 +196,15 @@ Full resync запускается только тогда, когда:
### 5.2 Доставка новых данных (push)
- При получении нового блока или DM сервер немедленно пушит его всем подключённым партнёрам.
- При получении нового блока сервер может немедленно пушить его всем подключённым партнёрам.
- Партнёр подтверждает приём (ACK). Без ACK — повтор с backoff.
- DM использует отдельное расписание, описанное в `docs/Personal_Messages/Доставка_и_синхронизация_DM.md`.
### 5.3 Начальная синхронизация (backfill)
- При первом подключении к партнёру серверы обмениваются «курсорами» состояния:
последний глобальный номер блока, последний известный DM-ключ.
- При первом подключении к партнёру серверы могут обмениваться курсорами состояния блокчейнов.
- Сервер с более полной историей досылает недостающее партнёру.
- DM time-cursor удалён: новый peer получает историю после сброса `dm_sync_outbox.synced=false`.
### 5.4 Разрешение конфликтов
@@ -212,19 +217,21 @@ Full resync запускается только тогда, когда:
При отправке DM от пользователя A к пользователю B:
1. Клиент A отправляет пару блоков на свой сервер X.
2. Сервер X определяет, на каком сервере зарегистрирован пользователь B.
- Сначала проверяет локально (если B зарегистрирован на X).
- Иначе читает PDA пользователя B из Solana и смотрит `access_servers`.
- Выбирает первый доступный сервер из `access_servers` и перенаправляет туда DM.
3. Сервер Y (из `access_servers` B) сохраняет и доставляет блоки.
2. Сервер X валидирует и локально сохраняет пару.
3. До ответа клиенту X параллельно отправляет входящую копию максимум двум актуальным `access_servers` B.
4. ACK хотя бы одного маршрута B означает терминальный `delivered`; второй сервер B догоняется собственной DM-синхронизацией.
5. После первой попытки X передаёт полную пару второму access-серверу A старым `ReceiveOutcomingMessage`, без delivery-state.
6. При нулевой доставке выполняются повторы через 30 секунд, 5 минут, 25 минут и 1 час. Перед тремя последними X спрашивает peer A через `GetDmDeliveryStatus(messageKey)`.
7. После неудачной попытки через час ставится терминальный `failed`.
Кэш адресов серверов: обновляется раз в сессию (при ошибке соединения).
Изменения routing B учитываются до терминального состояния, потому что список маршрутов перечитывается на каждой попытке.
## 7. Безопасность
- Все блоки подписаны ключами пользователя на клиенте — сервер не может подделать содержимое.
- Серверы не расшифровывают DM-контент (шифрование — задача следующего этапа).
- Серверы не расшифровывают DM-контент; E2EE уже выполняется клиентами.
- При синхронизации каждый блок проходит валидацию подписи на принимающем сервере.
- Межсерверная авторизация DM-операций пока отложена; `sourceServerLogin` временно считается доверенным.
## 8. Статус реализации
@@ -240,15 +247,18 @@ Full resync запускается только тогда, когда:
| Обход Solana RPC через `sync.importUserProfileFromPartner.enabled` | ✅ Реализовано |
| Обычный `AddBlock` через `tmp_bch`/`write_check`/`write_pending` | ✅ Реализовано |
| Межсерверный постоянный WebSocket-канал | Нужна реализация |
| Push новых DM партнёрам | Нужна реализация |
| Асинхронная доставка DM на access-серверы получателя | ✅ Реализовано |
| Retry DM до 1 часа + UI-state | ✅ Реализовано |
| Репликация DM на второй access-сервер по `synced` | ✅ Реализовано |
| Read-only `GetDmDeliveryStatus` | ✅ Реализовано |
| Push блоков блокчейна партнёрам | ✅ Реализована базовая one-shot версия |
| Periodic backfill отсутствующего хвоста | ✅ Реализовано |
| Разрешение рассинхрона / divergence | ✅ Реализована базовая full-resync схема во время periodic sync |
| Startup recovery по `*.resync_pending` marker-file | ✅ Реализовано |
| Маршрутизация DM через access_servers | Нужна реализация (заглушка) |
| Маршрутизация DM через один/два `access_servers` | ✅ Реализовано |
| Криптографическая server-to-server авторизация DM | Нужна реализация |
Текущая версия сервера уже умеет базовую синхронизацию блокчейнов между партнёрами.
Не реализованы ещё DM-sync и постоянные server-to-server соединения.
Текущая версия сервера умеет синхронизацию блокчейнов и DM. Постоянные server-to-server соединения не требуются для текущей one-shot WS-реализации; отдельной будущей задачей остаётся криптографическая авторизация DM-вызовов.
Следующие отдельные шаги после текущего этапа:
- отдельно проверить full-resync и startup-recovery на реальном тестовом прогоне после ручного удаления БД/файлов.