Files
SHiNE-server/docs/Blockchain/sync-between-servers.md
T

3.2 KiB

Синхронизация blockchain между SHiNE-серверами

Локальная модель хранения

PostgreSQL является единственным локальным хранилищем пользовательских блоков. Файлы <blockchain>.bch, .tmp_bch, .write_pending, .write_check, .resync_pending не используются.

blocks.block_bytes хранит полный подписанный ANS-104 DataItem. blockchain_state хранит текущую вершину цепочки.

Обычный AddBlock

Все проверки и запись выполняются под lock конкретной chain. После проверки Frame v1, подписи и prevHash одна SQL-транзакция записывает block + derived state + новую вершину.

Локально созданный пользовательский блок получает arweave_publish_pending=true.

Периодический peer-to-peer sync

Старый межсерверный P2P sync может получать GetBlockchainBlock и применять полученный полный DataItem через AddBlock. При divergence full-resync:

  1. берёт lock chain;
  2. очищает derived rows/blocks/state через BlockchainResyncCleanupDAO;
  3. пересоздаёт state из актуального пользовательского реестра;
  4. последовательно проигрывает удалённую цепочку с блока 0;
  5. никаких файловых swap/recovery операций нет.

Этот прямой sync включается параметром:

blockchain.sync.enabled=true

Для проверки режима без прямых server-to-server связей его можно выключить в override-конфиге сервера:

blockchain.sync.enabled=false

При выключенном прямом sync сервер по-прежнему может синхронизировать пользователей из Solana и импортировать пользовательские блоки через Arweave, если включён arweave.blocks.sync.enabled.

Arweave sync

Дополнительно каждый сервер может независимо включить ArweaveBlockSyncScheduler.

Он ищет child DataItems по тестовому тегу App=test5590, проверяет их и импортирует через ту же бизнес-проверку AddBlock. Импортированные блоки не публикуются повторно.

Если блоки обнаружены не по порядку, persistent queue оставляет более поздние блоки pending до появления предыдущих.

Источник истины для цепочки

Arweave не участвует в вычислении SHiNE chain hash:

block_hash = SHA256(FrameV1Bytes)
next.prevHash32 = block_hash

Поэтому цепочка остаётся проверяемой и переносимой независимо от конкретного storage backend.