Files
SHiNE-server/docs/Blockchain/TODO_BACK32_HASH.md
T

7.7 KiB

TODO — резервные ссылки back32Hash для SHiNE blockchain

Статус: TODO / не реализовано.

Цель этой идеи — повысить устойчивость проверки SHiNE blockchain и отдельных логических линий к ситуации, когда один или несколько DataItem временно или постоянно недоступны у конкретного Arweave gateway, CDN, сервера или другого источника.

Это не замена обычным ссылкам на предыдущий блок. Основная цепочка по-прежнему строится через prevHash32 / prevLineHash32. back32... — только дополнительная резервная ссылка назад.


1. Глобальная цепочка пользователя

В общий Frame в будущем добавить одно поле:

[32] back32Hash32

Смысл:

back32Hash32 = HASH(global block N - 32)

То есть блок N дополнительно содержит hash глобального блока N-32.

Пример:

block #100
  prevHash32   -> HASH(#99)
  back32Hash32 -> HASH(#68)

Для первых блоков

Если блока N-32 ещё не существует, поле содержит 32 нулевых байта:

#0 ... #31 -> back32Hash32 = ZERO_HASH_32
#32         -> HASH(#0)
#33         -> HASH(#1)
...

Номер блока отдельно НЕ хранить

Поле вида back32BlockNumber не нужно.

Номер однозначно вычисляется:

back32BlockNumber = blockNumber - 32

Поэтому хранить ещё 4 байта номера в каждом блоке бессмысленно.

Дополнительный размер глобального блока: ровно +32 байта.


2. Логические линии

Для line-based блоков в будущем добавить ещё одно поле:

[32] back32LineHash32

Оно относится не к глобальной последовательности блоков, а к конкретной логической линии.

Используется для:

  • TEXT — линия конкретного канала;
  • TECH — техническая линия пользователя;
  • CONNECTION — линия изменений связей;
  • USER_PROFILE — линия изменений профиля.

Смысл:

back32LineHash32 = HASH(line item with sequence = currentSequence - 32)

Пример для канала:

channel sequence 100
  prevLineHash32       -> HASH(channel sequence 99)
  back32LineHash32     -> HASH(channel sequence 68)

Пример для профиля:

profileSequence = 50
  prevProfileBlockHash32 -> HASH(profile sequence 49)
  back32LineHash32       -> HASH(profile sequence 18)

Если элемента линии с sequence - 32 ещё нет, используется:

ZERO_HASH_32

Номер элемента -32 отдельно НЕ хранить

Он вычисляется из текущего sequence:

back32LineSequence = currentSequence - 32

А глобальный номер нужного старого блока при необходимости определяется по уже загруженной/проиндексированной линии.

Дополнительный размер line-based блока:

+32 байта global back32Hash32
+32 байта back32LineHash32
= +64 байта

3. Зачем это нужно

Обычная цепочка имеет только соседнюю связь:

N -> N-1

Если блок N-1 недоступен, проверить обычную связь следующего блока назад уже невозможно, хотя остальные данные могут быть доступны.

С дополнительной ссылкой получается:

N -> N-1
N -> N-32

Поэтому даже если часть соседних блоков недоступна, можно получить дополнительную криптографическую связь с более ранней частью истории.

То же самое для отдельной линии:

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.