SHiNE-server/src/TODO.txt
AidarKC ab44cc5282 16 12 25
Промежуточная версия и ТУДУ на чём остановился
2025-12-16 17:56:36 +03:00

159 lines
7.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Конспект: что обсуждали и где остановились
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 (для поиска), если он будет нужен.