# TODO — резервные ссылки `back32Hash` для SHiNE blockchain Статус: **TODO / не реализовано**. Цель этой идеи — повысить устойчивость проверки SHiNE blockchain и отдельных логических линий к ситуации, когда один или несколько DataItem временно или постоянно недоступны у конкретного Arweave gateway, CDN, сервера или другого источника. Это **не замена** обычным ссылкам на предыдущий блок. Основная цепочка по-прежнему строится через `prevHash32` / `prevLineHash32`. `back32...` — только дополнительная резервная ссылка назад. --- ## 1. Глобальная цепочка пользователя В общий Frame в будущем добавить одно поле: ```text [32] back32Hash32 ``` Смысл: ```text back32Hash32 = HASH(global block N - 32) ``` То есть блок `N` дополнительно содержит hash глобального блока `N-32`. Пример: ```text block #100 prevHash32 -> HASH(#99) back32Hash32 -> HASH(#68) ``` ### Для первых блоков Если блока `N-32` ещё не существует, поле содержит 32 нулевых байта: ```text #0 ... #31 -> back32Hash32 = ZERO_HASH_32 #32 -> HASH(#0) #33 -> HASH(#1) ... ``` ### Номер блока отдельно НЕ хранить Поле вида `back32BlockNumber` не нужно. Номер однозначно вычисляется: ```text back32BlockNumber = blockNumber - 32 ``` Поэтому хранить ещё 4 байта номера в каждом блоке бессмысленно. Дополнительный размер глобального блока: **ровно +32 байта**. --- ## 2. Логические линии Для line-based блоков в будущем добавить ещё одно поле: ```text [32] back32LineHash32 ``` Оно относится не к глобальной последовательности блоков, а к конкретной логической линии. Используется для: - `TEXT` — линия конкретного канала; - `TECH` — техническая линия пользователя; - `CONNECTION` — линия изменений связей; - `USER_PROFILE` — линия изменений профиля. Смысл: ```text back32LineHash32 = HASH(line item with sequence = currentSequence - 32) ``` Пример для канала: ```text channel sequence 100 prevLineHash32 -> HASH(channel sequence 99) back32LineHash32 -> HASH(channel sequence 68) ``` Пример для профиля: ```text profileSequence = 50 prevProfileBlockHash32 -> HASH(profile sequence 49) back32LineHash32 -> HASH(profile sequence 18) ``` Если элемента линии с `sequence - 32` ещё нет, используется: ```text ZERO_HASH_32 ``` ### Номер элемента `-32` отдельно НЕ хранить Он вычисляется из текущего sequence: ```text back32LineSequence = currentSequence - 32 ``` А глобальный номер нужного старого блока при необходимости определяется по уже загруженной/проиндексированной линии. Дополнительный размер line-based блока: ```text +32 байта global back32Hash32 +32 байта back32LineHash32 = +64 байта ``` --- ## 3. Зачем это нужно Обычная цепочка имеет только соседнюю связь: ```text N -> N-1 ``` Если блок `N-1` недоступен, проверить обычную связь следующего блока назад уже невозможно, хотя остальные данные могут быть доступны. С дополнительной ссылкой получается: ```text N -> N-1 N -> N-32 ``` Поэтому даже если часть соседних блоков недоступна, можно получить дополнительную криптографическую связь с более ранней частью истории. То же самое для отдельной линии: ```text line N -> line N-1 line N -> line N-32 ``` Это особенно полезно для каналов: если конкретный пост оказался недоступен или заблокирован одним источником, отсутствие этого DataItem не должно автоматически делать всю последующую историю канала полностью непроверяемой. --- ## 4. Что этот механизм НЕ решает `back32Hash` не означает, что отсутствующий блок восстановлен или проверен. Если блока нет, его содержимое остаётся неизвестным. Механизм даёт только дополнительный проверяемый мост между доступными частями истории. Он также не заменяет: - `prevHash32`; - `prevLineHash32`; - sequence логической линии; - подпись ANS-104 DataItem; - проверку текущего хвоста линии; - отдельный механизм доказательства того, что скачан самый последний существующий блок/элемент линии. --- ## 5. Почему шаг именно 32 Шаг `32` выбран как простой компромисс: - всего 32 дополнительных байта на глобальную цепочку; - ещё 32 байта только для line-based блоков; - позволяет делать длинный резервный переход без сложной структуры skip-list; - номер ссылки не надо хранить — он вычисляется арифметически; - реализация и проверка остаются очень простыми. В будущем шаг можно пересмотреть только через новую версию Frame/body, если появится убедительная причина. --- ## 6. План реализации в будущем Когда будет принято решение реализовать TODO: 1. добавить `back32Hash32` в новую версию общего Frame; 2. при создании блока вычислять hash глобального блока `N-32`; 3. добавить `back32LineHash32` в новые версии всех line-based body; 4. вычислять его по элементу той же линии с sequence `currentSequence-32`; 5. серверу проверять эти hashes при `AddBlock`; 6. импортерам/Arweave sync/viewer использовать резервные ссылки при проверке частично доступной истории; 7. обновить тесты бинарного формата и документацию; 8. не добавлять отдельные поля номера для ссылок `-32`. До выполнения этих пунктов текущий канонический формат SHiNE остаётся без `back32Hash32` и `back32LineHash32`.