Добавить resync блокчейна при рассинхроне

This commit is contained in:
AidarKC
2026-06-26 15:25:11 +04:00
parent 23edad416c
commit be4f76834a
11 changed files with 783 additions and 17 deletions
@@ -86,6 +86,7 @@
- `bad_signature`, `signature_verify_failed`
- `prev_line_block_not_found`, `bad_prev_line_hash`
- `limit_exceeded`
- `chain_resync_in_progress` — цепочка временно заблокирована полным resync
- `repost_disabled` — репосты временно отключены до будущей реализации
- `internal_error`
+13 -2
View File
@@ -74,6 +74,13 @@
3. если локальная цепочка слабее, сервер по одному блоку вызывает `GetBlockchainBlock`;
4. каждый скачанный блок локально применяется через существующий `AddBlock`;
5. если у сервера ещё нет локальной записи пользователя/цепочки, перед этим подготавливается локальный `solana_users + blockchain_state`.
6. если во время replay обнаруживается рассинхрон или на одинаковой высоте удалённая цепочка сильнее, запускается полный resync:
- цепочка помечается in-memory как `resync in progress`;
- создаётся marker-file в `data/`;
- в одной SQL-транзакции очищаются локальные данные цепочки и корректируются чужие счётчики;
- удаляются `.bch` и `.tmp_bch`;
- цепочка подтягивается заново с `0` через `GetBlockchainBlock`.
- обычный `AddBlock` на эту цепочку в этот момент возвращает `chain_resync_in_progress`.
### 4.4 Зачем понадобился `GetSyncUserProfile`
@@ -161,8 +168,12 @@
| Push новых DM партнёрам | Нужна реализация |
| Push блоков блокчейна партнёрам | ✅ Реализована базовая one-shot версия |
| Periodic backfill отсутствующего хвоста | ✅ Реализовано |
| Разрешение рассинхрона / divergence | Нужна реализация |
| Разрешение рассинхрона / divergence | ✅ Реализована базовая full-resync схема во время periodic sync |
| Маршрутизация DM через access_servers | Нужна реализация (заглушка) |
Текущая версия сервера уже умеет базовую синхронизацию блокчейнов между партнёрами.
Не реализованы ещё DM-sync, постоянные server-to-server соединения и автоматическое исправление рассинхрона цепочек.
Не реализованы ещё DM-sync, постоянные server-to-server соединения и recovery при старте по marker-file для resync.
Следующие отдельные шаги после текущего этапа:
- добавить startup recovery по marker-file для resync-цепочек;
- вернуть обычному `AddBlock` настоящую `tmp_bch`-схему записи и recovery при резком рестарте.
+1
View File
@@ -30,6 +30,7 @@
- `near/2026-05-25_1106_telegram_agent_players.md` - разрешённые пользователи Telegram для агента, отдельные папки игроков, персональные истории и публикация краткого вопроса/ответа в общий канал.
- `near/2026-05-25_1106_wallet_topup_solana_arweave.md` - пополнение Solana и Arweave через внешний сервис покупки с подсказкой и копированием адреса.
- `near/2026-06-26_1215_tmp_bch_для_обычного_addblock.md` - вернуть обычному `AddBlock` настоящую crash-safe схему через `.tmp_bch` и привести writer к модели startup-recovery.
### Среднесрочные
@@ -0,0 +1,45 @@
# Вернуть настоящую tmp_bch-схему для обычного AddBlock
## Зачем нужна эта доработка
Сейчас обычный `AddBlock` пишет данные так:
1. в SQL-транзакции добавляет блок в БД и обновляет `blockchain_state`;
2. делает `commit`;
3. только после этого дописывает основной файл `<blockchainName>.bch`.
Это рабочая схема, но она не идеально crash-safe. Если сервер резко упадёт между `commit` БД и записью файла, можно получить состояние:
- в БД новый блок уже есть;
- в `.bch` файла этого блока ещё нет.
При этом в проекте уже есть логика startup-recovery через `*.tmp_bch`, но текущий `BlockchainWriter` её полноценно не использует. Из-за этого writer и recovery сейчас живут в разных моделях.
## Что планируем сделать
Нужно вернуть единую и понятную схему:
1. обычный `AddBlock` работает через временный файл `<blockchainName>.tmp_bch`;
2. после успешной подготовки нового содержимого выполняется атомарная подмена `tmp -> main`;
3. `BlockchainTmpRecoveryOnStartup` и `BlockchainWriter` используют одну и ту же модель;
4. при резкой перезагрузке сервер на старте может корректно добрать или откатить незавершённый файловый шаг.
## Что уже есть в коде
- recovery-класс: `SHiNE-server/src/main/java/server/ws/BlockchainTmpRecoveryOnStartup.java`
- файловые helper-методы под `tmp_bch`: `SHiNE-server/shine-server-blockchain/src/main/java/utils/files/FileStoreUtil.java`
- текущий writer: `SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler_utils/BlockchainWriter.java`
## Что надо будет изменить
1. Переписать `BlockchainWriter`, чтобы он больше не писал сразу в основной `.bch`.
2. Привести порядок записи и замены файла в соответствие с `BlockchainTmpRecoveryOnStartup`.
3. Проверить сценарии:
- обычный `AddBlock`;
- резкий restart до commit БД;
- резкий restart после commit БД, но до замены файла;
- recovery на старте при наличии `*.tmp_bch`.
## Почему это отложено отдельно
Это отдельная задача от server-to-server resync. Для divergence-resync сейчас важнее сначала закончить безопасный SQL cleanup одной цепочки, а усиление crash-safety обычного `AddBlock` делать следующим самостоятельным шагом.
@@ -0,0 +1,19 @@
# DAO очистки одной blockchain-цепочки перед полным resync
- Краткое описание:
- Добавлен отдельный DAO-метод, который в одной SQL-транзакции очищает одну blockchain-цепочку перед её полной повторной загрузкой.
- Внутри транзакции сначала уменьшаются чужие `likes_count` и `replies_count`, которые были увеличены блоками удаляемой цепочки.
- Затем удаляются локальные записи цепочки и её derived-state.
- Файлы `.bch` / `.tmp_bch` этот DAO не удаляет: файловый шаг будет отдельной следующей задачей.
- DAO уже используется в periodic full-resync flow, но это ещё не было вручную проверено на прод-цикле.
- Что именно проверять:
- Метод корректно компилируется и не ломает сборку.
- Метод подключён в рабочий periodic full-resync path, но manual e2e verification ещё нужна.
- Комментарии в коде понятны и соответствуют реальному порядку SQL-шагов.
- Ожидаемый результат:
- Появилась изолированная транзакционная точка очистки одной цепочки, на которую можно безопасно опереться при следующем шаге реализации divergence-resync.
- Статус:
- `pending`