SHA256
17 12 25
Ещё промежуточный комит верии - не работает :) 2
This commit is contained in:
+1
-159
@@ -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 (для поиска), если он будет нужен.
|
||||
зделать что бы конекшины к БД закрывались или как что :)
|
||||
Reference in New Issue
Block a user