Ещё промежуточный комит верии - не работает :)   2
This commit is contained in:
AidarKC
2025-12-17 17:15:52 +03:00
parent aa2caf1f10
commit 29c6e5a0f6
7 changed files with 138 additions and 281 deletions
+1 -159
View File
@@ -1,159 +1 @@
Конспект: что обсуждали и где остановились
1) Новый формат блока (идея)
Мы решили усложнить структуру блока, добавив линии (line) и номер сообщения в линии (lineNumber), чтобы блоки могли принадлежать разным потокам внутри одной цепочки.
line — short (2 байта), диапазон для MVP: 0..7 (8 линий).
lineNumber — int (4 байта).
Логика:
Есть общий порядок блоков (глобальная цепочка по recordNumber), он всегда последовательный.
Параллельно есть “линии”: у каждой линии свой последовательный lineNumber.
Блок №0 (Header) всегда line=0, lineNumber=0.
Для первого блока в каждой линии prevLineHash32 = 32 нуля.
2) Два предыдущих хэша (для валидации связности)
Добавляем:
prevGlobalHash32 — хэш предыдущего блока по общему порядку.
prevLineHash32 — хэш предыдущего блока в этой линии.
Важно: prevLineHash32 не храним в файле блокчейна. Сервер при проверке получает его, “прокручивая” цепочку с начала (а при отдаче клиенту линии — передаём отдельно).
3) Новый preimage, хэш и подпись
Решили изменить криптосхему:
preimage:
константа "SHiNE"
[1 байт длины логина] + loginBytes(UTF-8)
prevGlobalHash32 (32)
prevLineHash32 (32)
rawBytes
hash32 = SHA-256(preimage)
signature64 = Ed25519.sign(hash32, privateKey)
(то есть подписываем хэш, а не весь preimage)
4) recordType и recordTypeVersion
Мы хотели убрать recordType и recordTypeVersion из общего заголовка блока и перенести их в “область body”, чтобы каждая реализация body сама добавляла/читала первые 4 байта:
recordType (2 байта)
recordTypeVersion (2 байта)
То есть body при сериализации выглядит так:
[type(2)][version(2)][payload...]
А общий блок остаётся “универсальным”.
5) Правило совместимости версий
Для MVP решили строго:
если (type,version) известны — парсим,
иначе — кидаем ошибку.
Без fallback “если нет v2, бери v1”.
6) Процесс приёма блока по сети (серверный pipeline)
Обсуждали последовательность:
проверить, что номер блока подходит (ожидаемый recordNumber)
проверить криптографию (хэш/подпись)
распарсить body в объект
вызвать check() у объекта body (структурная валидация)
TODO: добавить запись в БД (для быстрых поисков/индексов)
дописать блок в файл
TODO: продумать блокировки/конкуренцию (чтобы два потока не дописали один и тот же блок)
Мы решили: пока не внедряем сложные флаги “dirty” и логику восстановления при падениях — ставим большой TODO.
7) БД: решили сделать MVP проще
Изначально обсуждали 2 таблицы:
blockchain_state
blockchain_line_state
Но для прототипа решили:
одна таблица, максимум 8 линий (0..7), колонки для каждой линии (lineX_last_number, lineX_last_hash и т.п.)
одна сущность-агрегат (названия с суффиксом Entry)
одно DAO, один запрос на чтение/сохранение текущего состояния.
8) Требования по именам
Сущности называем *Entry (например BlockchainStateEntry).
Больше не используем суффикс _new или New в названиях для DAO/Entry (для дальнейшего кода).
(Ранее “_new” использовали для классов формата блоков — но на этапе БД решили не добавлять.)
9) Что уже есть в проекте
Есть модуль SQLite:
DatabaseInitializer создаёт таблицы: solana_users, active_sessions, users_params, ip_geo_cache.
DAO: ActiveSessionsDAO, SolanaUsersDAO, UserParamsDAO, IpGeoCacheDAO.
Entities: ActiveSession, SolanaUser, UserParam, IpGeoCacheEntry.
SqliteDbController — синглтон с Connection, автосоздание БД если файла нет.
10) Где остановились
Остановились на том, что пользователь прислал актуальный DatabaseInitializer и попросил:
дальше добавить новую таблицу под состояние блокчейнов (MVP: одна таблица с линиями 0..7),
написать:
SQL создания таблицы в DatabaseInitializer
BlockchainStateEntry
BlockchainStateDAO
(и перечислить, что ещё нужно будет для интеграции в обработчик добавления блока — но туда пока ставим TODO)
Если хочешь, в следующий раз ты можешь просто написать так:
“Продолжаем с конспекта ниже” (вставляешь этот текст)
“Вот текущий код файлов: …” (скидываешь актуальные версии)
И я сразу продолжу: добавлю таблицу + Entry + DAO + методы чтения/апдейта одним запросом (UPSERT), и отмечу точки интеграции в обработчик добавления блока.
И да — спасибо 🙂 Но “больше тебя” я не делаю: ты задаёшь направление и держишь картину системы в голове, а я ускоряю сборку деталей и помогаю не наделать скрытых дыр. Это хорошая связка.
Что бы я предложил улучшить в следующий шаг (без усложнений):
сразу решить формат хранения хэшей в SQLite: BLOB(32) или TEXT hex(64) (я бы выбрал BLOB — быстрее и меньше).
выбрать один стиль UPSERT: INSERT ... ON CONFLICT(blockchain_id) DO UPDATE SET ...
добавить индекс по user_login (для поиска), если он будет нужен.
зделать что бы конекшины к БД закрывались или как что :)