SHA256
back32hash 5591: готово к тестам
Вроде как всё готово к тестам.
This commit is contained in:
@@ -27,6 +27,7 @@ ANS-104 DataItem
|
||||
|---|---:|---|
|
||||
| `frameCode` | 2 | `0x0001` |
|
||||
| `prevHash32` | 32 | SHA-256 полного Frame v1 предыдущего SHiNE-блока; для блока 0 — нули |
|
||||
| `back32Hash32` | 32 | SHA-256 Frame блока `N-32`; для `N<32` — 32 нулевых байта |
|
||||
| `blockSize` | 4 | точный размер Frame v1, включая header и body |
|
||||
| `blockNumber` | 4 | номер блока, начиная с 0 |
|
||||
| `timestamp` | 8 | Unix time seconds |
|
||||
@@ -35,11 +36,12 @@ ANS-104 DataItem
|
||||
| `version` | 2 | версия body |
|
||||
| `body` | N | данные конкретного типа |
|
||||
|
||||
`FRAME_HEADER_SIZE = 56` bytes.
|
||||
`FRAME_HEADER_SIZE = 88` bytes.
|
||||
|
||||
```text
|
||||
blockHash32 = SHA256(FrameV1Bytes)
|
||||
next.prevHash32 = blockHash32
|
||||
blockN.back32Hash32 = (N < 32 ? ZERO_HASH_32 : HASH(block N-32))
|
||||
```
|
||||
|
||||
Подписи внутри Frame v1 нет. Единственная подпись пользователя — подпись окружающего ANS-104 DataItem.
|
||||
@@ -72,7 +74,7 @@ next.prevHash32 = blockHash32
|
||||
Каждый блок:
|
||||
|
||||
```text
|
||||
App = test5590
|
||||
App = test5591
|
||||
```
|
||||
|
||||
Это временное namespace-значение для разработки. Перед реальным запуском оно будет заменено отдельным изменением протокола/кода.
|
||||
@@ -94,7 +96,7 @@ t=prof # USER_PROFILE
|
||||
Если блок относится к конкретному каналу, он дополнительно содержит:
|
||||
|
||||
```text
|
||||
c_test5590 = <canonical_channel_slug>
|
||||
c = <canonical_channel_slug>
|
||||
```
|
||||
|
||||
Slug входит в подпись DataItem и не может быть изменён сервером после подписи.
|
||||
@@ -118,16 +120,17 @@ Slug входит в подпись DataItem и не может быть изм
|
||||
Сервер обязан:
|
||||
|
||||
1. распарсить полный ANS-104 DataItem;
|
||||
2. проверить `App=test5590`;
|
||||
2. проверить `App=test5591`;
|
||||
3. проверить `t`, если тип блока требует фиксированный индексный поток;
|
||||
4. проверить `c_test5590`, если тип блока требует канал;
|
||||
4. проверить `c`, если тип блока требует канал;
|
||||
5. проверить ANS-104 Ed25519 подпись;
|
||||
6. проверить, что `owner` равен текущему blockchain public key пользователя;
|
||||
7. распарсить Frame v1 и body;
|
||||
8. проверить `blockNumber == last + 1`;
|
||||
9. проверить `prevHash32 == lastBlockHash`;
|
||||
10. проверить строгую непрерывность логической линии, если body line-based;
|
||||
11. записать DataItem и новое состояние атомарно в PostgreSQL.
|
||||
10. проверить `back32Hash32`: нули для `N<32`, иначе hash блока `N-32`;
|
||||
11. проверить строгую непрерывность логической линии, если body line-based;
|
||||
12. записать DataItem и новое состояние атомарно в PostgreSQL.
|
||||
|
||||
|
||||
## Нормативное правило версий body
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
## 2. Логические линии внутри пользовательской цепочки
|
||||
|
||||
Глобально все блоки пользователя идут одной последовательностью `blockNumber` и `prevHash32`. Дополнительно некоторые типы образуют собственные проверяемые линии.
|
||||
Глобально все блоки пользователя идут одной последовательностью `blockNumber` и `prevHash32`; каждый Frame также содержит резервный `back32Hash32` на блок `N-32` (нули для `N<32`). Дополнительно некоторые типы образуют собственные проверяемые линии. Отдельного back32 внутри линий нет.
|
||||
|
||||
Актуальные линии:
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ HEADER сам не хранит line-prefix, но является root TECH-л
|
||||
- является очередным шагом TECH-линии;
|
||||
- является root нового канала;
|
||||
- имеет `t=tech`;
|
||||
- имеет `c_test5590=<canonical_channel_slug>`.
|
||||
- имеет `c=<canonical_channel_slug>`.
|
||||
|
||||
Начало body:
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# ANS-104 / Arweave transport для пользовательских блоков SHiNE
|
||||
|
||||
> **Текущий transport namespace:** `test5591`. Он намеренно хранится отдельно в трёх рабочих местах: сервер (`ShineProtocolTags.java`), UI (`js/services/protocol-tags.js`) и актуальный Viewer (`static-sites/arweave-viewer/index.html`). При смене тестовой эпохи эти три значения меняются синхронно. Имя канального индексного тега постоянно и не зависит от namespace: `c`.
|
||||
|
||||
## Цель
|
||||
|
||||
Каждый пользовательский блок SHiNE уже на клиенте является самостоятельным подписанным ANS-104 DataItem. Сервер проверяет и хранит **точно эти signed bytes** и может публиковать их одним из двух транспортов: через Turbo по одному DataItem либо через прямую Arweave L1-транзакцию в составе стандартного большого ANS-104 bundle.
|
||||
@@ -11,7 +13,7 @@
|
||||
Для тестового контура обязательно:
|
||||
|
||||
```text
|
||||
App=test5590
|
||||
App=test5591
|
||||
```
|
||||
|
||||
Для фиксированных потоков:
|
||||
@@ -25,10 +27,10 @@ t=prof # USER_PROFILE
|
||||
Для блоков конкретного канала дополнительно:
|
||||
|
||||
```text
|
||||
c_test5590=<canonical_channel_slug>
|
||||
c=<canonical_channel_slug>
|
||||
```
|
||||
|
||||
`TECH_CREATE_CHANNEL` несёт оба индекса: `t=tech` и `c_test5590=<slug>`. `STATUS_ACTION` не получает `t`-тег.
|
||||
`TECH_CREATE_CHANNEL` несёт оба индекса: `t=tech` и `c=<slug>`. `STATUS_ACTION` не получает `t`-тег.
|
||||
|
||||
Теги входят в ANS-104 подпись пользователя. Сервер проверяет соответствие `t` фактическому `msg_type` и отклоняет лишний/неверный `t`. Старый тестовый тег `c` новым кодом не создаётся и не принимается как channel tag.
|
||||
|
||||
@@ -92,7 +94,7 @@ Bundle-Version=2.0.0
|
||||
Content-Type=application/octet-stream
|
||||
```
|
||||
|
||||
Специальный `App=test5590-batch` больше не используется. Важны вложенные user DataItems, у которых уже есть `App=test5590`.
|
||||
Специальный `App=test5591-batch` больше не используется. Важны вложенные user DataItems, у которых уже есть `App=test5591`.
|
||||
|
||||
### `none`
|
||||
|
||||
@@ -112,7 +114,7 @@ Content-Type=application/octet-stream
|
||||
Importer всегда выполняет один discovery-запрос:
|
||||
|
||||
```text
|
||||
App=test5590
|
||||
App=test5591
|
||||
```
|
||||
|
||||
Он **не ищет root bundles** и не зависит от `publish.mode`.
|
||||
@@ -130,7 +132,7 @@ App=test5590
|
||||
|
||||
Поэтому importer:
|
||||
|
||||
1. получает `data_item_id` через GraphQL `App=test5590`;
|
||||
1. получает `data_item_id` через GraphQL `App=test5591`;
|
||||
2. запрашивает `GET /ar-io/offsets/{data_item_id}`;
|
||||
3. получает `rootTxId`, `rootOffset`, `size`;
|
||||
4. делает range-read `GET /raw/{rootTxId}` ровно по этому диапазону;
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 2026-10-02 — Transport namespace `test5591`
|
||||
|
||||
- Текущий ANS-104 namespace переключён с `test5590` на `test5591`: `App=test5591`; channel index теперь постоянный и не зависит от namespace: `c=<slug>`.
|
||||
- Namespace хранится отдельно в трёх рабочих местах: сервер, UI и актуальный `shine-UI/static-sites/arweave-viewer`; это намеренная простая конфигурация без cross-module runtime-зависимости.
|
||||
- Сервер, UI и актуальный Viewer используют свои локальные константы namespace; общего cross-module `protocol-config` нет.
|
||||
- Серверные AddBlock/key-rotation/archive-sync проверки больше не содержат захардкоженного `test5591`.
|
||||
- Исторические упоминания `test5590` в старых changelog/legacy patch-документах оставлены как история предыдущего тестового namespace.
|
||||
- Изменение рассчитано на новую чистую тестовую БД/цепочки; старые `App=test5590` DataItem новым namespace автоматически не подхватываются.
|
||||
- Frame header увеличен с 56 до 88 bytes из-за `back32Hash32`; сервер проверяет N-32, Viewer показывает и проверяет резервную ссылку.
|
||||
|
||||
## 2026-10-01 — Проверяемые USER_PROFILE / CONNECTION / TECH линии и signed `t` index
|
||||
|
||||
- Тип `4` в документации называется `USER_PROFILE`; внутренние исторические имена классов могут сохраняться. USER_PROFILE предназначен только для данных профиля.
|
||||
@@ -5,8 +15,8 @@
|
||||
- `TECH_FORK` включён в общую TECH-линию вместе с `TECH_CREATE_CHANNEL`; оба используют `lineCode=0`, предыдущий TECH block/hash и `techSequence`.
|
||||
- Серверная line-валидация стала строгой: новый блок обязан продолжать фактический текущий хвост той же линии и иметь sequence `+1`; произвольная ссылка на существующий блок больше не принимается. Это также устраняет боковую ветку канала после `EDIT_POST`.
|
||||
- Добавлены подписанные ANS-104 индексы: `t=prof`, `t=conn`, `t=tech`. `STATUS_ACTION` не изменён.
|
||||
- В отдельном `shine-solana-arweave-viewer-v3` исправлен legacy-фильтр канала `c` → канонический `c_test5590`.
|
||||
- `back32Hash` и дополнительные skip-ссылки не добавлялись.
|
||||
- Единственным актуальным Viewer считается `shine-UI/static-sites/arweave-viewer`; старые корневые Viewer перенесены в его `history/legacy-root-viewers/`.
|
||||
- В общий Frame добавлен глобальный `back32Hash32`: для блоков `#0..#31` нули, начиная с `#32` — SHA-256 Frame блока `N-32`. Отдельный back32 для line-body не добавляется.
|
||||
- Формат USER_PROFILE/CONNECTION/TECH_FORK несовместим с предыдущей тестовой схемой; проект находится до production и миграция старых блоков не предусмотрена.
|
||||
|
||||
## 2026-09-27 — TECH_FORK v1
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
> **LEGACY / historical patch note.** Current protocol uses `App=test5591` and the permanent channel tag `c=<slug>`. Do not apply the `c_test5590` instructions below to current code.
|
||||
|
||||
# Применение patch: Turbo + direct Arweave для `App=test5590`
|
||||
|
||||
## Что меняется
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
```text
|
||||
User
|
||||
-> создаёт Frame v1
|
||||
-> tags: App=test5590; t=tech/conn/prof для фиксированных потоков; при канале c_test5590=<slug>
|
||||
-> tags: App=test5591; t=tech/conn/prof для фиксированных потоков; при канале c=<slug>
|
||||
-> Ed25519 подписывает ANS-104 deep-hash
|
||||
-> готовый DataItem
|
||||
-> AddBlock
|
||||
@@ -27,7 +27,7 @@ Server
|
||||
ИЛИ publish.mode=none: наружу не публиковать
|
||||
|
||||
Other servers
|
||||
-> GraphQL App=test5590
|
||||
-> GraphQL App=test5591
|
||||
-> скачивают/извлекают DataItem
|
||||
-> verify
|
||||
-> PostgreSQL без повторной публикации
|
||||
@@ -38,4 +38,4 @@ Other servers
|
||||
- SHiNE `prevHash` остаётся SHA-256 предыдущего Frame v1 и не зависит от Arweave.
|
||||
- `data_item_id` нужен для Arweave, поиска и дедупликации.
|
||||
- PostgreSQL — единственное локальное хранилище пользовательских блоков.
|
||||
- Тестовый namespace `App=test5590` специально отделён от будущего production namespace.
|
||||
- Тестовый namespace `App=test5591` специально отделён от будущего production namespace.
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
# TODO — резервные ссылки `back32Hash` для SHiNE blockchain
|
||||
# `back32Hash32` — глобальная резервная ссылка SHiNE
|
||||
|
||||
Статус: **TODO / не реализовано**.
|
||||
Статус: **реализовано для общей пользовательской цепочки**. Отдельный `back32` для логических линий намеренно не добавляется.
|
||||
|
||||
Цель этой идеи — повысить устойчивость проверки SHiNE blockchain и отдельных логических линий к ситуации, когда один или несколько DataItem временно или постоянно недоступны у конкретного Arweave gateway, CDN, сервера или другого источника.
|
||||
## Правило
|
||||
|
||||
Это **не замена** обычным ссылкам на предыдущий блок. Основная цепочка по-прежнему строится через `prevHash32` / `prevLineHash32`. `back32...` — только дополнительная резервная ссылка назад.
|
||||
|
||||
---
|
||||
|
||||
## 1. Глобальная цепочка пользователя
|
||||
|
||||
В общий Frame в будущем добавить одно поле:
|
||||
Каждый SHiNE Frame содержит:
|
||||
|
||||
```text
|
||||
[32] prevHash32
|
||||
[32] back32Hash32
|
||||
```
|
||||
|
||||
Смысл:
|
||||
`prevHash32` остаётся основной соседней связью `N -> N-1`.
|
||||
|
||||
`back32Hash32` — дополнительная резервная связь:
|
||||
|
||||
```text
|
||||
back32Hash32 = HASH(global block N - 32)
|
||||
N < 32 -> ZERO_HASH_32
|
||||
N >= 32 -> SHA256(Frame блока N-32)
|
||||
```
|
||||
|
||||
То есть блок `N` дополнительно содержит hash глобального блока `N-32`.
|
||||
Номер блока для этой ссылки отдельно не хранится: он всегда равен `blockNumber - 32`. Поэтому дополнительных 4 байта номера нет. Стоимость механизма — **ровно +32 байта на каждый глобальный блок**.
|
||||
|
||||
## Зачем
|
||||
|
||||
Если соседний DataItem недоступен у конкретного gateway/CDN/сервера, обычная проверка через `prevHash32` прерывается. `back32Hash32` даёт второй криптографический мост к более ранней части истории. Это не восстанавливает отсутствующий блок и не доказывает его содержимое, но позволяет связать доступный последующий участок с историей на 32 блока раньше.
|
||||
|
||||
Пример:
|
||||
|
||||
@@ -32,172 +34,18 @@ block #100
|
||||
back32Hash32 -> HASH(#68)
|
||||
```
|
||||
|
||||
### Для первых блоков
|
||||
|
||||
Если блока `N-32` ещё не существует, поле содержит 32 нулевых байта:
|
||||
Для первых 32 блоков:
|
||||
|
||||
```text
|
||||
#0 ... #31 -> back32Hash32 = ZERO_HASH_32
|
||||
#32 -> HASH(#0)
|
||||
#33 -> HASH(#1)
|
||||
...
|
||||
```
|
||||
|
||||
### Номер блока отдельно НЕ хранить
|
||||
Сервер при `AddBlock` обязан сам проверить это поле по сохранённому блоку `N-32`; клиентское значение не принимается на доверии.
|
||||
|
||||
Поле вида `back32BlockNumber` не нужно.
|
||||
## Почему без `back32` внутри линий
|
||||
|
||||
Номер однозначно вычисляется:
|
||||
CHANNEL / TECH / CONNECTION / USER_PROFILE уже имеют собственные `prev...BlockNumber`, `prev...Hash32` и sequence. Эти линии — дополнительный способ выборочной загрузки и проверки поверх основной пользовательской цепочки. Если в выборочно скачанной линии обнаружена дырка, блоки всё равно можно криптографически проверить через глобальную цепочку, где уже есть `prevHash32 + back32Hash32`.
|
||||
|
||||
```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`.
|
||||
Поэтому добавлять ещё +32 байта в каждый line-based body сейчас нецелесообразно. Если когда-нибудь появится требование полностью проверять отдельный канал/профиль без доступа к глобальной цепочке даже через недоступный line-блок, line-back32 можно рассмотреть отдельной новой версией body.
|
||||
|
||||
@@ -40,7 +40,7 @@ blockchain.sync.enabled=false
|
||||
|
||||
Дополнительно каждый сервер может независимо включить `ArweaveBlockSyncScheduler`.
|
||||
|
||||
Он ищет child DataItems по тестовому тегу `App=test5590`, проверяет их и импортирует через ту же бизнес-проверку AddBlock. Импортированные блоки не публикуются повторно.
|
||||
Он ищет child DataItems по тестовому тегу `App=test5591`, проверяет их и импортирует через ту же бизнес-проверку AddBlock. Импортированные блоки не публикуются повторно.
|
||||
|
||||
Если блоки обнаружены не по порядку, persistent queue оставляет более поздние блоки pending до появления предыдущих.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user