diff --git a/DOC/doc-BD.md b/DOC/doc-BD.md new file mode 100644 index 0000000..4bf9190 --- /dev/null +++ b/DOC/doc-BD.md @@ -0,0 +1,95 @@ +Документ: shine-server-bd — таблицы и структура +Таблицы (что хранят) + +solana_users — локальная таблица пользователей (логин + ключ устройства + опциональный solanaKey). + +active_sessions — активные сессии пользователей (секреты сессии, время, push-подписки, IP/клиент-инфо). + +users_params — сохранённые параметры пользователя (например, состояние просмотренности лент и прочие настройки), с подписью. + +ip_geo_cache — кэш геолокации по IP (чтобы не дергать внешние сервисы каждый раз). + +blockchain_state — агрегатное “текущее состояние” блокчейна по blockchainName (лимит, размер, последние хэши/номера). + +blocks — сохранённые блоки/сообщения блокчейна (байты блока + связи “кому/куда” для адресации). + +solana_users — пользователи и их ключи + +login TEXT — логин пользователя (PRIMARY KEY) +deviceKey TEXT — публичный ключ устройства (обязателен) +solanaKey TEXT — дополнительный ключ Solana (может быть NULL) + +active_sessions — активные сессии пользователя + +sessionId TEXT — идентификатор сессии (PRIMARY KEY) +login TEXT — логин владельца сессии (FK → solana_users.login) +sessionPwd TEXT — пароль/секрет сессии (используется сервером) +storagePwd TEXT — пароль/секрет для шифрования хранилища/данных +sessionCreatedAtMs INTEGER — время создания сессии (ms) +lastAuthirificatedAtMs INTEGER — время последней успешной аутентификации/refresh (ms) +pushEndpoint TEXT — endpoint для web-push (nullable) +pushP256dhKey TEXT — ключ p256dh для web-push (nullable) +pushAuthKey TEXT — auth key для web-push (nullable) +clientIp TEXT — IP клиента при auth/refresh (nullable) +clientInfoFromClient TEXT — строка client-info от клиента (nullable) +clientInfoFromRequest TEXT — строка client-info, собранная сервером (nullable) +userLanguage TEXT — предпочитаемый язык пользователя (nullable) + +users_params — параметры/состояния пользователя + +login TEXT — логин владельца параметра (FK → solana_users.login) +param TEXT — имя параметра (в паре с login образует UNIQUE) +bch_channel_id INTEGER — id канала/ленты/контекста блокчейна (по умолчанию 0) +value TEXT — значение параметра (nullable) +time_ms INTEGER — время обновления параметра (ms) +pubkey_num INTEGER — номер/индекс публичного ключа, которым подписано значение +signature TEXT — подпись значения параметра (строка) + +ip_geo_cache — кэш геоданных по IP + +ip TEXT — IP-адрес (PRIMARY KEY) +geo TEXT — строка гео-описания (“Country, City” и т.п.) (nullable) +updated_at_ms INTEGER — время последнего обновления (ms) + +blockchain_state — текущее состояние блокчейна по blockchainName + +blockchainName TEXT — имя/идентификатор блокчейна (PRIMARY KEY) +login TEXT — владелец блокчейна (FK → solana_users.login) +blockchainKey TEXT — публичный ключ блокчейна (используется для подписи блоков) +size_limit INTEGER — лимит размера блокчейн-файла (байты) +file_size_bytes INTEGER — текущий размер файла блокчейна (байты) +last_global_number INTEGER — номер последнего глобального блока (genesis обычно -1) +last_global_hash TEXT — хэш последнего глобального блока (пусто для “нулевого” состояния) +updated_at_ms INTEGER — время обновления состояния (ms) +line0_last_number INTEGER — последний номер в линии 0 +line0_last_hash TEXT — последний хэш в линии 0 +line1_last_number INTEGER — последний номер в линии 1 +line1_last_hash TEXT — последний хэш в линии 1 +line2_last_number INTEGER — последний номер в линии 2 +line2_last_hash TEXT — последний хэш в линии 2 +line3_last_number INTEGER — последний номер в линии 3 +line3_last_hash TEXT — последний хэш в линии 3 +line4_last_number INTEGER — последний номер в линии 4 +line4_last_hash TEXT — последний хэш в линии 4 +line5_last_number INTEGER — последний номер в линии 5 +line5_last_hash TEXT — последний хэш в линии 5 +line6_last_number INTEGER — последний номер в линии 6 +line6_last_hash TEXT — последний хэш в линии 6 +line7_last_number INTEGER — последний номер в линии 7 +line7_last_hash TEXT — последний хэш в линии 7 + +blocks — блоки/сообщения блокчейна (байтовое тело + адресация) + +login TEXT — владелец (FK → solana_users.login) +bchName TEXT — имя блокчейна (FK → blockchain_state.blockchainName) +blockGlobalNumber INTEGER — глобальный номер блока +blockGlobalPreHashe TEXT — предыдущий глобальный хэш (строка) +blockLineIndex INTEGER — индекс линии (0..7) +blockLineNumber INTEGER — номер блока внутри линии +blockLinePreHashe TEXT — предыдущий хэш внутри линии +msgType INTEGER — тип сообщения/записи (код) +blockByte BLOB — сырые байты блока (nullable) +to_login TEXT — адресат логин (nullable) +toBchName TEXT — адресат блокчейн (nullable) +toBlockGlobalNumber INTEGER — целевой глобальный номер (nullable) +toBlockHashe TEXT — целевой хэш (nullable) \ No newline at end of file diff --git a/DOC/doc_all_libs.md b/DOC/doc_all_libs.md new file mode 100644 index 0000000..3670426 --- /dev/null +++ b/DOC/doc_all_libs.md @@ -0,0 +1,23 @@ +Перечень библиотек и их краткое описание + +shine-server-log +Статический “сиренный” метод для максимально заметного критического лога администратору + +shine-server-config +Минимальный конфиг-лоадер, который один раз читает application.properties и даёт доступ к параметрам. +Внешние настройки (2): server.1port=7070, db.path=data/shine.sqlite. + +shine-server-geo +Утилиты, которые вытаскивают IP/язык/UA из Jetty WebSocket и (опционально) резолвят гео по IP с кэшем в БД. + +shine-server-crypto +Базовые крипто-утилиты для SHA-256 и Ed25519 (BouncyCastle) + проверка подписи/хэша для .bch сущностей и маленький self-test. + +shine-server-bd +Библиотека реалезующая всю работу с БД: + +shine-server-blockchain +Библиотека, которая задаёт единый бинарный формат блоков (RAW+signature+hash), парсит/валидирует “тело” блока по type/version, и проверяет целостность/подпись цепочки через SHA-256 + Ed25519 с привязкой к login и предыдущим хэшам. + +shine-server-protocol +Библиотека JSON-протокол поверх WebSocket для взаимодействия с клиентами. diff --git a/DOC/libs/shine-server-bd/DOC.md b/DOC/libs/shine-server-bd/DOC.md new file mode 100644 index 0000000..c95247f --- /dev/null +++ b/DOC/libs/shine-server-bd/DOC.md @@ -0,0 +1,17 @@ +shine-server-bd — это библиотека реалезующая всю работу с БД: + +хранит пользователей/сессии/параметры/кэш IP→гео и данные блокчейна (состояние + блоки), предоставляя единый SqliteDbController для соединений, набор DAO под каждую таблицу (Singleton, методы с Connection для транзакций и без Connection — сами открывают/закрывают), и простые entity-модели как контейнеры данных для маппинга ResultSet↔Java. + +Логика структуры классов (в двух словах): + +shine.db.SqliteDbController — один вход в БД: читает db.path, при отсутствии файла создаёт БД, выдаёт новые Connection и настраивает PRAGMA. +shine.db.DatabaseInitializer — разовая сборка схемы (таблицы + индексы). + + +shine.db.entities.* — POJO-модели строк таблиц (без логики, только поля/геттеры/сеттеры + иногда удобные методы вроде getDeviceKeyByte()). +shine.db.dao.* — DAO по таблицам: ActiveSessionsDAO, SolanaUsersDAO, UserParamsDAO, IpGeoCacheDAO, BlockchainStateDAO, BlocksDAO; плюс “сервисные” DAO: + +UserCreateDAO — атомарная регистрация пользователя в транзакции (BEGIN IMMEDIATE + rollback/commit). +// Временное решение позволяющее регистрировать новых пользователей +// атомарно и добавляет запись и в solana_users и в BlockchainState + diff --git a/DOC/libs/shine-server-blockchain/Doc.md b/DOC/libs/shine-server-blockchain/Doc.md new file mode 100644 index 0000000..151e05c --- /dev/null +++ b/DOC/libs/shine-server-blockchain/Doc.md @@ -0,0 +1,85 @@ +shine-server-blockchain — это библиотека, которая задаёт формат блока, правила парсинга/валидации тела, крипто-проверку (hash+Ed25519) и безопасную работу с файлами блокчейна (data/.bch через временный .tmp_bch). + +Как устроена структура и логика работы + +1) “Блок” как центральный объект (ядро) +BchBlockEntry — единая модель блока “как лежит на диске/в сети”: +читает/собирает байты в формате RAW + signature64 + hash32 +сразу парсит body через BodyRecordParser +сразу проверяет что lineIndex совпадает с тем, что ожидает конкретный тип body (expectedLineIndex()) +То есть: всё, что считается “блоком”, обязано быть самодостаточно валидным уже на этапе создания объекта. + +2) “Body” как плагины по типам (расширяемая часть) ! <-- Новые типы записей добавлть сюда ! +BodyRecord — интерфейс контракта для всех тел: +type/version — идентификаторы формата +expectedLineIndex() — жёсткое правило “в какой линии может жить” +check() — логическая валидация содержимого +toBytes() — сериализация обратно в бинарь + +BodyRecordParser — диспетчер: читает первые 4 байта (type+ver) и выбирает нужный класс: +HeaderBody (lineIndex=0) +TextBody (lineIndex=1) +ReactionBody (lineIndex=2) + +Добавление нового типа = добавить новый класс XxxBody + кейс в BodyRecordParser. + +3) Криптография как отдельный слой проверки +BchCryptoVerifier отвечает за “как получить хэш и как проверить подпись”: +строит preimage = "SHiNE" + login + prevGlobalHash32 + prevLineHash32 + rawBytes +считает sha256(preimage) и сравнивает с hash32 внутри блока +проверяет Ed25519 подпись над hash32 +Важно: BchBlockEntry не проверяет подпись — он проверяет структуру блока и правильность body/lineIndex, а криптопроверка вынесена отдельно. + +4) Утилиты вокруг имени и файлов + +BlockchainNameUtil — извлекает login из blockchainName (отрезает 3 символа суффикса). +FileStoreUtil — безопасное файловое хранилище: + + +5) Объяснение структуры работы + +Типичный сценарий: пришёл блок → проверить → принять +Шаг 0. Контекст (что у нас уже есть снаружи) + +Снаружи библиотеки (в сервере) у тебя уже известны: +userLogin — владелец блокчейна +publicKey32 — публичный ключ пользователя +prevGlobalHash32 — хэш предыдущего блока по глобальной цепи +prevLineHash32 — хэш предыдущего блока по текущей линии + +Библиотека не хранит это сама, она ожидает, что сервер это передаст. + +Шаг 1. Парсинг блока (структура + логика) +BchBlockEntry block = new BchBlockEntry(fullBytes); + + +Что происходит здесь автоматически: +проверяется длина блока +проверяется recordSize +парсится RAW-заголовок +парсится body через BodyRecordParser +проверяется, что lineIndex соответствует типу body +(HEADER → line 0, TEXT → line 1, REACTION → line 2 и т.д.) +❗ На этом шаге никакой криптографии ещё нет — только структура и логика формата. + +Если тут не упало исключение → блок структурно корректен. + +Шаг 2. Подготовка данных для криптопроверки (они получаются просто из частей байтов полного блокас подписью) +byte[] rawBytes = block.getRawBytes(); +byte[] signature64 = block.getSignature64(); +byte[] hash32FromTail = block.getHash32(); + +Важно: +rawBytes — это ровно те байты, которые участвовали в хэшировании +hash32FromTail — это то, что автор блока положил внутрь блока + +Шаг 3. Криптографическая проверка (ключевой вызов) +boolean ok = BchCryptoVerifier.verifyAll( +userLogin, +prevGlobalHash32, +prevLineHash32, +rawBytes, +signature64, +publicKey32, +hash32FromTail +); \ No newline at end of file diff --git a/DOC/libs/shine-server-blockchain/Общая структура блока.md b/DOC/libs/shine-server-blockchain/Общая структура блока.md new file mode 100644 index 0000000..51ae585 --- /dev/null +++ b/DOC/libs/shine-server-blockchain/Общая структура блока.md @@ -0,0 +1,48 @@ +Общая структура блока + +Блок — это бинарная запись фиксированного формата: + +[ RAW ][ signature64 ][ hash32 ] + +RAW — данные блока (участвуют в хэшировании и подписи) +signature64 — Ed25519-подпись над hash32 +hash32 — SHA-256 от preimage (привязан к цепочке и владельцу) + +RAW-часть (BigEndian) +recordSize int32 — размер RAW (без signature+hash) +recordNumber int32 — глобальный номер блока +timestamp int64 — unix time (seconds) +lineIndex int16 — индекс линии +lineNumber int32 — номер блока внутри линии +bodyBytes bytes — тело блока (type+version+payload) + +Общая структура блокчейна + +Блокчейн — это: +линейная цепочка блоков (по recordNumber) +внутри неё — параллельные логические линии (lineIndex) +каждая линия имеет собственную нумерацию (lineNumber) и prevLineHash +вся цепочка связана ещё и prevGlobalHash + +👉 Таким образом, каждый блок: +связан с предыдущим глобальным блоком +и с предыдущим блоком своей линии + +Это даёт: +строгий порядок всей истории +и независимую валидацию логических потоков + +Криптографический смысл блока + +Хэш блока считается от: +"SHiNE" + +login + +prevGlobalHash32 + +prevLineHash32 + +RAW + +Это означает: +блок жёстко привязан к владельцу (login) +блок невозможно перенести в другую цепочку +подмена предыдущего блока ломает всю цепь +Подпись Ed25519 делается над этим хэшем. \ No newline at end of file diff --git a/DOC/libs/shine-server-blockchain/Формат существующих Body.md b/DOC/libs/shine-server-blockchain/Формат существующих Body.md new file mode 100644 index 0000000..8b5a4ef --- /dev/null +++ b/DOC/libs/shine-server-blockchain/Формат существующих Body.md @@ -0,0 +1,36 @@ +Формат и смысл существующих Body + +1) HeaderBody (type=0, ver=1) + +Линия: lineIndex = 0 +Смысл: +Генезис-блок блокчейна, объявляет формат и владельца. + +Содержит: +сигнатуру формата "SHiNE" +login владельца блокчейна +👉 Всегда первый блок, всегда в линии 0. + +2) TextBody (type=1, ver=1) + +Линия: lineIndex = 1 +Смысл: +Основной контент — текстовые записи (посты, сообщения, дневник). + +Содержит: +UTF-8 текст произвольной длины +👉 Это “основная история” блокчейна пользователя. + +3) ReactionBody (type=2, ver=1) + +Линия: lineIndex = 2 +Смысл: +Связь с другим блокчейном или блоком (реакция, ответ, лайк, ссылка). + +Содержит: +код реакции +имя целевого блокчейна +globalNumber целевого блока +hash32 целевого блока +👉 Это механизм межблокчейн-связей без изменения чужих цепочек. + diff --git a/DOC/libs/shine-server-config/doc.md b/DOC/libs/shine-server-config/doc.md new file mode 100644 index 0000000..e2f4900 --- /dev/null +++ b/DOC/libs/shine-server-config/doc.md @@ -0,0 +1,7 @@ +shine-server-config + +Минимальная библиотека конфигурации, предоставляющая потокобезопасный singleton-доступ к параметрам из application.properties. + +Настройки: +server.port=7070 — порт запуска сервера +db.path=data/shine.sqlite — путь к SQLite базе данных \ No newline at end of file diff --git a/DOC/libs/shine-server-crypto/DOC.md b/DOC/libs/shine-server-crypto/DOC.md new file mode 100644 index 0000000..78a3ac5 --- /dev/null +++ b/DOC/libs/shine-server-crypto/DOC.md @@ -0,0 +1,8 @@ +shine-server-crypto + +О чём: базовые крипто-утилиты для SHA-256 и Ed25519 (BouncyCastle) + проверка подписи/хэша для .bch сущностей и маленький self-test. +Внешние методы, которые вызываются: +BchCryptoVerifier.verifyAll(), BchCryptoVerifier.buildPreimage(), Ed25519Util.generatePrivateKey(), Ed25519Util.generatePrivateKeyFromString(), Ed25519Util.derivePublicKey(), Ed25519Util.sign(), Ed25519Util.verify(), Ed25519Util.keyToBase64(), Ed25519Util.keyFromBase64(), +HashSHA256Util.sha256() + +HashSHA256Util.loginToLoginId(), HashSHA256Util.loginIdFromLogin(), \ No newline at end of file diff --git a/DOC/libs/shine-server-geo/DOC.md b/DOC/libs/shine-server-geo/DOC.md new file mode 100644 index 0000000..ad970f8 --- /dev/null +++ b/DOC/libs/shine-server-geo/DOC.md @@ -0,0 +1,19 @@ +shine-server-geo + +Назначение: утилиты для получения “кто подключился” (IP/UA/язык) и геолокации по IP (с опциональным кэшем в БД). + +Классы: + +ClientInfoService — собирает строку UA/ch-ua/platform/mobile/remoteIP, вытаскивает реальный IP (приоритет: X-Forwarded-For → X-Real-IP → remoteAddress), парсит первый Accept-Language. +GeoLookupService — геолокация по IP через внешний API (ip-api.com), умеет вариант без кэша и с кэшем в таблице ip_geo_cache через IpGeoCacheDAO (пишет даже unknown), плюс метод получения внешнего IP через api.ipify.org. +GeoLookupTestMain — консольный тест: берёт IP из аргумента или определяет внешний, вызывает геолокацию и печатает результат + время. + + +Внешние (публично используемые) методы: + +ClientInfoService.buildClientInfoString(Session) — формирует строку с User-Agent, client-hints и реальным IP клиента +ClientInfoService.extractClientIp(Session) — извлекает реальный IP (X-Forwarded-For / X-Real-IP / remoteAddress) +ClientInfoService.extractPreferredLanguageTag(Session) — возвращает основной язык клиента из Accept-Language +GeoLookupService.resolveCountryCityOrIp(String ip) — геолокация по IP без кэша (Country, City или unknown) +GeoLookupService.resolveCountryCityOrIpWithCache(String ip) — геолокация по IP с кэшированием в БД +GeoLookupService.fetchPublicIpOrDefault(String fallbackIp) — получение внешнего IP текущей машины \ No newline at end of file diff --git a/DOC/libs/shine-server-log/DOC.md b/DOC/libs/shine-server-log/DOC.md new file mode 100644 index 0000000..d9fcd77 --- /dev/null +++ b/DOC/libs/shine-server-log/DOC.md @@ -0,0 +1,10 @@ +shine-log (BlockchainAdminNotifier) + +Суть (1 предложение): единая точка для “красного” оповещения админа о критических проблемах консистентности, сейчас — через максимально заметный log.error, позже — через Telegram/email/webhook и т.п. + +Структура (очень кратко): + +BlockchainAdminNotifier (final utility) + +BlockchainAdminNotifier.critical(String message) +BlockchainAdminNotifier.critical(String message, Throwable t) \ No newline at end of file diff --git a/shine-server-blockchain/src/main/java/blockchain/README.md b/shine-server-blockchain/src/main/java/blockchain/README.md deleted file mode 100644 index 64725ca..0000000 --- a/shine-server-blockchain/src/main/java/blockchain/README.md +++ /dev/null @@ -1,205 +0,0 @@ -формат добавления блоков и из чего реально состоит блок, плюс как именно считаются хэши и подписи. - -1) Формат добавления блоков в файл .bch - -Файл — это просто конкатенация блоков один за другим, без разделителей: - -BLOCK_0 | BLOCK_1 | BLOCK_2 | ... - - -Чтобы читать файл, ты идёшь по нему последовательно: - -Читаешь первые 4 байта = recordSize - -Понимаешь, сколько всего байт занимает блок: - -fullBlockLen = recordSize + 64 + 32 - - -Считываешь оставшиеся байты блока и парсишь: - -RAW часть длиной recordSize - -затем signature64 - -затем hash32 - -Это удобно тем, что файл можно дописывать (APPEND) хоть по сети, хоть локально: блоки самодостаточные. - -2) Из чего состоит блок (формат блока) - 2.1. RAW (участвует в preimage и верификации; подпись/хэш к нему «пришиты») - -BigEndian, фиксированный заголовок + body: - -RAW: - -[4] recordSize (int) — размер RAW включая эти 4 байта, но без signature+hash - -[4] recordNumber (int) — глобальный номер блока (цепочка) - -[8] timestamp (long) — unix seconds - -[2] line (short) — линия (у вас пока по сути одна) - -[4] lineNumber (int) — номер в линии (у вас пока обычно равен global) - -[N] bodyBytes — тело, начинается с [2] type + [2] version, дальше payload - -RAW_HEADER_SIZE = 4 + 4 + 8 + 2 + 4 = 22 байта - -2.2. TAIL (не входит в recordSize) - -[64] signature64 — Ed25519 подпись - -[32] hash32 — SHA-256 хэш - -Итого полный блок: - -FULL = RAW(recordSize bytes) + signature64 + hash32 - -3) Формат body (тела блока) - -У тебя правило железное: каждый body начинается одинаково: - -[2] type - -[2] version - -дальше payload по типу/версии - -Парсер делает ключ: - -key = (type<<16) | version - -3.1 HeaderBody (type=0, ver=1) - -Полный bodyBytes: - -[2] type=0 - -[2] ver=1 - -[8] tag "SHiNE001" (ASCII) - -[1] loginLength (uint8) - -[N] login UTF-8 - -Это «генезис-смысл» для идентичности: в теле блока явно хранится логин. - -3.2 TextBody (type=1, ver=1) - -[2] type=1 - -[2] ver=1 - -[N] message UTF-8 - -4) Как считается хэш (hash32) - -Важно: hash32 в блоке — это не hash(rawBytes). - -Ты считаешь: - -4.1 Preimage -preimage = -"SHiNE" + -[1] loginLen + loginBytes(UTF-8) + -prevGlobalHash32 + -prevLineHash32 + -rawBytes - - -Где: - -"SHiNE" — доменная метка (защита от «подпиши этим же ключом что-то другое») - -loginLen + loginBytes — привязка блока к пользователю/цепочке - -prevGlobalHash32 — сцепление по глобальной цепи - -prevLineHash32 — сцепление по линии - -rawBytes — содержимое текущего блока без подписи/хэша - -4.2 Сам хэш -hash32 = SHA-256(preimage) - - -И именно этот hash32 должен лежать в конце блока. - -5) Как считается подпись (signature64) - -Подписывается не rawBytes, а hash32: - -signature64 = Ed25519.sign(hash32, privateKey) - - -Проверка: - -Пересобираем preimage - -Считаем hash32 = sha256(preimage) - -Сверяем hash32 с тем, что лежит в блоке - -Проверяем подпись: - -Ed25519.verify(hash32, signature64, publicKey32) - - -Это хорошая схема: подпись всегда фиксированного размера, а хэш — единая точка правды. - -6) Что является «цепочкой» и чем блоки сцеплены - -Сцепление идёт через prevGlobalHash32 и prevLineHash32, которые ты передаёшь в verifyAll(...). - -То есть логика добавления нового блока (в терминах данных) такая: - -берём последний блок - -достаём его hash32 - -это и будет prevGlobalHash32 для нового блока - -prevLineHash32 — по той линии, куда добавляем (у вас пока это то же самое, потому что одна линия/нет разветвления) - -У тебя даже отдельно отмечено: пока нет отдельных линий, lastLineHash == lastGlobalHash — значит сейчас обе цепочки фактически совпадают. - -7) Мини-схема “как добавить новый блок” (пошагово) - -Собрать BodyRecord → получить bodyBytes = body.toBytes() - -Собрать RAW: - -recordNumber = lastRecordNumber + 1 - -timestamp = nowSeconds - -line (скорее всего 0 или 1 — как вы договорились) - -lineNumber = lastLineNumber + 1 (сейчас равно global) - -recordSize = RAW_HEADER_SIZE + bodyBytes.length - -rawBytes = new BchBlockEntry(...).getRawBytes() (или собрать вручную) - -preimage = buildPreimage(login, prevGlobalHash32, prevLineHash32, rawBytes) - -hash32 = sha256(preimage) - -signature64 = Ed25519.sign(hash32, privateKey) - -Собрать финальный BchBlockEntry(..., signature64, hash32) - -Дописать toBytes() в файл .bch - -8) Важные нюансы (чтобы не словить «тихий баг») - -recordSize включает себя (первые 4 байта) — это ок, просто помнить. - -bodyLen = recordSize - RAW_HEADER_SIZE — значит RAW_HEADER_SIZE обязан быть всегда синхронен с реальным RAW. - -login в preimage ограничен 255 байт (у тебя [1] loginLen) — это правильно и предсказуемо. - -В HeaderBody tag фиксирован "SHiNE001" — фактически версия протокола body-header’а. \ No newline at end of file diff --git a/shine-server-blockchain/src/main/java/blockchain/body/HeaderBody.java b/shine-server-blockchain/src/main/java/blockchain/body/HeaderBody.java index 4c54084..2035e3e 100644 --- a/shine-server-blockchain/src/main/java/blockchain/body/HeaderBody.java +++ b/shine-server-blockchain/src/main/java/blockchain/body/HeaderBody.java @@ -11,7 +11,7 @@ import java.util.Objects; * Полный bodyBytes: * [2] type=0 * [2] version=1 - * [8] tag ASCII "SHiNE001" + * [8] tag ASCII "SHiNE" * [1] loginLength=N (uint8) * [N] login UTF-8 * @@ -23,9 +23,9 @@ public final class HeaderBody implements BodyRecord { public static final short TYPE = 0; public static final short VER = 1; - public static final String TAG = "SHiNE001"; + public static final String TAG = "SHiNE"; - public final String tag; // "SHiNE001" + public final String tag; // "SHiNE" public final String login; /** Десериализация из полного bodyBytes (включая type/version). */ @@ -42,7 +42,7 @@ public final class HeaderBody implements BodyRecord { if (bb.remaining() < 8 + 1) throw new IllegalArgumentException("Header payload too short"); - byte[] tagBytes = new byte[8]; + byte[] tagBytes = new byte[5]; bb.get(tagBytes); String t = new String(tagBytes, StandardCharsets.US_ASCII); if (!TAG.equals(t)) throw new IllegalArgumentException("Bad tag: " + t); diff --git a/shine-server-blockchain/src/main/java/utils/files/README.md b/shine-server-blockchain/src/main/java/utils/files/README.md deleted file mode 100644 index 7d5acf5..0000000 --- a/shine-server-blockchain/src/main/java/utils/files/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# utils.files - -Хранение блокчейнов в виде файлов в папке `data/`. - ---- - -## FileStoreUtil -Singleton для чтения и записи `.bch` файлов. - -- `newBlockchain(id, data)` — создать новый файл `data/.bch` -- `addDataToBlockchain(id, data)` — добавить байты в конец файла -- `readAllDataFromBlockchain(id)` — прочитать весь файл как массив байт - -Каждый файл содержит последовательность полных блоков `[RAW][signature64][hash32]...` - ---- - -## FileStoreUtilSelfTest -Тест: создаёт, дописывает и читает файл, чтобы проверить корректность. - ---- - -Пока используется как временное файловое хранилище. -В будущем всё это уйдёт в SQL. - - - diff --git a/shine-server-blockchain/src/main/java/utils/search/README.md b/shine-server-blockchain/src/main/java/utils/search/README.md deleted file mode 100644 index 00ef1a4..0000000 --- a/shine-server-blockchain/src/main/java/utils/search/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# utils.search - -Поиск пользователей по логину среди зарегистрированных блокчейнов. - ---- - -## UserSearchService -Singleton-сервис для поиска первых 5 логинов, содержащих подстроку (без учёта регистра). - -Основные методы: -- `searchFirst5(String query)` — вернуть список `Pair(id, login)` -- `packPair(Pair p)` — упаковать пару в бинарный ответ `[8]id + [1]len + [len]login` - -Используется сервером в операции `SEARCH_USERS (op=30)` для ответа клиенту. diff --git a/shine-server-crypto/concat_to_file.sh b/shine-server-crypto/concat_to_file.sh new file mode 100755 index 0000000..901712c --- /dev/null +++ b/shine-server-crypto/concat_to_file.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -euo pipefail + +OUTFILE="all_files.txt" + +# очищаем или создаём файл +: > "$OUTFILE" + +# собрать только *.java файлы и вывести их содержимое в файл +find . -type f -name "*.java" | sort | while read -r f; do + cat "$f" >> "$OUTFILE" + echo >> "$OUTFILE" # пустая строка-разделитель +done + +echo "Готово! Все .java файлы собраны в $OUTFILE" + diff --git a/shine-server-crypto/src/main/java/utils/crypto/HashSHA256Util.java b/shine-server-crypto/src/main/java/utils/crypto/HashSHA256Util.java index 75f4d4b..e19c63c 100644 --- a/shine-server-crypto/src/main/java/utils/crypto/HashSHA256Util.java +++ b/shine-server-crypto/src/main/java/utils/crypto/HashSHA256Util.java @@ -18,42 +18,6 @@ public final class HashSHA256Util { return out; } - /** Получить loginId из строки логина. - * Алгоритм: - * - login -> UTF-8 bytes - * - SHA-256 - * - берём последние 8 байт (справа) - * - интерпретируем как signed long (BigEndian) - */ - public static long loginToLoginId(String login) { - if (login == null || login.isBlank()) - throw new IllegalArgumentException("login is null or empty"); - - byte[] hash = sha256(login.getBytes(StandardCharsets.UTF_8)); - - // последние 8 байт SHA-256 - return ByteBuffer.wrap(hash, 24, 8) - .order(ByteOrder.BIG_ENDIAN) - .getLong(); - } - - /** - * loginId = last 8 bytes of sha256(login UTF-8), big-endian. - * (берём 8 байт справа и читаем как unsigned long в BE) - */ - public static long loginIdFromLogin(String login) { - if (login == null || login.isBlank()) - throw new IllegalArgumentException("login is blank"); - - byte[] h = sha256(login.getBytes(StandardCharsets.UTF_8)); - - long v = 0; - for (int i = 24; i < 32; i++) { - v = (v << 8) | (h[i] & 0xFFL); - } - return v; - } - /** Инкрементальный SHA-256 (если нужно будет кормить по кускам). */ public static final class Sha256 { private final SHA256Digest d = new SHA256Digest(); diff --git a/shine-server-db/src/main/java/shine/db/dao/SolanaBlockchainsDAO.java b/shine-server-db/src/main/java/shine/db/dao/SolanaBlockchainsDAO.java deleted file mode 100644 index 825fcc9..0000000 --- a/shine-server-db/src/main/java/shine/db/dao/SolanaBlockchainsDAO.java +++ /dev/null @@ -1,53 +0,0 @@ -package shine.db.dao; - -import shine.db.SqliteDbController; -import shine.db.entities.BlockchainStateEntry; - -import java.sql.*; - -/** - * SolanaBlockchainsDAO — таблица блокчейнов пользователя. - * - * Сейчас физически это blockchain_state, потому что: - * - у одного login может быть несколько blockchainName - * - у каждого blockchainName свой blockchainKey и size_limit - * - * Правило: - * - методы с Connection НЕ закрывают соединение - * - методы без Connection сами открывают и закрывают соединение - */ -public final class SolanaBlockchainsDAO { - - private static volatile SolanaBlockchainsDAO instance; - private final SqliteDbController db = SqliteDbController.getInstance(); - private final BlockchainStateDAO stateDao = BlockchainStateDAO.getInstance(); - - private SolanaBlockchainsDAO() {} - - public static SolanaBlockchainsDAO getInstance() { - if (instance == null) { - synchronized (SolanaBlockchainsDAO.class) { - if (instance == null) instance = new SolanaBlockchainsDAO(); - } - } - return instance; - } - - public BlockchainStateEntry getByBlockchainName(String blockchainName) throws SQLException { - return stateDao.getByBlockchainName(blockchainName); - } - - public BlockchainStateEntry getByBlockchainName(Connection c, String blockchainName) throws SQLException { - return stateDao.getByBlockchainName(c, blockchainName); - } - - /** Для HEADER: проверка, что blockchain_state существует и last_global_number=-1. */ - public BlockchainStateEntry requireExistingAtGenesis(Connection c, String blockchainName) throws SQLException { - return stateDao.requireExistingAtGenesis(c, blockchainName); - } - - /** Для добавления блока: атомарная проверка лимита + увеличение размера файла. */ - public boolean tryIncreaseFileSizeWithinLimit(Connection c, String blockchainName, long deltaBytes, long nowMs) throws SQLException { - return stateDao.tryIncreaseFileSizeWithinLimit(c, blockchainName, deltaBytes, nowMs); - } -} \ No newline at end of file diff --git a/shine-server-db/src/main/java/Описание таблиц в БД.md b/shine-server-db/src/main/java/Описание таблиц в БД.md deleted file mode 100644 index 4960b56..0000000 --- a/shine-server-db/src/main/java/Описание таблиц в БД.md +++ /dev/null @@ -1,44 +0,0 @@ -# Структура БД SHiNE (кратко) - -## Таблица `solana_users` -Локальная копия данных о пользователях из Solana. - -Поля: -- `login` (TEXT) — логин пользователя. -- `loginId` (INTEGER, PK) — ID пользователя, основной ключ. -- `bchId` (INTEGER) — ID блокчейна пользователя. -- `pubkey0` (TEXT) — первый публичный ключ. -- `pubkey1` (TEXT) — второй публичный ключ. -- `bchLimit` (INTEGER, NULL) — произвольный лимит для пользователя (опционально). - ---- - -## Таблица `active_sessions` -Активные сессии пользователей (WebSocket/WSS + Web Push). - -Поля: -- `sessionId` (INTEGER, PK) — ID сессии, генерируется приложением. -- `session_pwd` (TEXT) — секрет/пароль сессии. -- `loginId` (INTEGER, FK → solana_users.loginId) — владелец сессии. -- `time_ms` (INTEGER) — время создания/активности сессии (мс от эпохи). -- `pubkey_num` (INTEGER) — номер ключа пользователя, которым подписывались данные. -- `push_endpoint` (TEXT, NULL) — endpoint Web Push. -- `push_p256dh_key` (TEXT, NULL) — p256dh-ключ Web Push. -- `push_auth_key` (TEXT, NULL) — auth-ключ Web Push. - ---- - -## Таблица `users_params` -Сохранённые параметры и состояния пользователя (например, до какого сообщения прочитана лента). - -Поля: -- `loginId` (INTEGER, FK → solana_users.loginId) — пользователь. -- `param` (TEXT) — имя параметра (ключ). -- `bch_channel_id` (INTEGER, DEFAULT 0) — ID канала/ленты который просмотрен. -- `value` (TEXT, NULL) — значение параметра (строка). -- `time_ms` (INTEGER) — время последнего обновления (мс от эпохи). -- `pubkey_num` (INTEGER) — номер ключа, которым подписано значение. -- `signature` (TEXT, NULL) — подпись значения. - -Ограничения: -- `UNIQUE(loginId, param)` — у одного пользователя каждый `param` только один раз. diff --git a/shine-server-log/concat_to_file.sh b/shine-server-log/concat_to_file.sh new file mode 100755 index 0000000..901712c --- /dev/null +++ b/shine-server-log/concat_to_file.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -euo pipefail + +OUTFILE="all_files.txt" + +# очищаем или создаём файл +: > "$OUTFILE" + +# собрать только *.java файлы и вывести их содержимое в файл +find . -type f -name "*.java" | sort | while read -r f; do + cat "$f" >> "$OUTFILE" + echo >> "$OUTFILE" # пустая строка-разделитель +done + +echo "Готово! Все .java файлы собраны в $OUTFILE" + diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/JsonHandlerRegistry.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/JsonHandlerRegistry.java index 2c70728..fd540bd 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/JsonHandlerRegistry.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/JsonHandlerRegistry.java @@ -1,13 +1,12 @@ package server.logic.ws_protocol.JSON; import server.logic.ws_protocol.JSON.entyties.Net_Request; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_AuthChallenge_Request; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_CreateAuthSession_Request; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_RefreshSession_Request; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_CloseActiveSession_Request; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_ListSessions_Request; -import server.logic.ws_protocol.JSON.entyties.blockchain.Net_AddBlock_Request; -import server.logic.ws_protocol.JSON.entyties.tempToTest.Net_AddUser_Request; +import server.logic.ws_protocol.JSON.entyties.*; +import server.logic.ws_protocol.JSON.handlers.auth.entyties.*; +import server.logic.ws_protocol.JSON.handlers.blockchain.entyties.*; +import server.logic.ws_protocol.JSON.handlers.tempToTest.entyties.*; +import server.logic.ws_protocol.JSON.handlers.blockchain.entyties.Net_AddBlock_Request; +import server.logic.ws_protocol.JSON.handlers.tempToTest.entyties.Net_AddUser_Request; import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler; import server.logic.ws_protocol.JSON.handlers.auth.Net_AuthChallenge_Handler; import server.logic.ws_protocol.JSON.handlers.auth.Net_CreateAuthSession__Handler; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_AuthChallenge_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_AuthChallenge_Handler.java index 4c6077d..01b022b 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_AuthChallenge_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_AuthChallenge_Handler.java @@ -2,8 +2,7 @@ package server.logic.ws_protocol.JSON.handlers.auth; import server.logic.ws_protocol.JSON.ConnectionContext; import server.logic.ws_protocol.JSON.entyties.*; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_AuthChallenge_Request; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_AuthChallenge_Response; +import server.logic.ws_protocol.JSON.handlers.auth.entyties.*; import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler; import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory; import server.logic.ws_protocol.WireCodes; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CloseActiveSession_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CloseActiveSession_Handler.java index 442767b..1a2e95c 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CloseActiveSession_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CloseActiveSession_Handler.java @@ -4,8 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import server.logic.ws_protocol.JSON.ActiveConnectionsRegistry; import server.logic.ws_protocol.JSON.ConnectionContext; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_CloseActiveSession_Request; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_CloseActiveSession_Response; +import server.logic.ws_protocol.JSON.handlers.auth.entyties.*; import server.logic.ws_protocol.JSON.entyties.Net_Request; import server.logic.ws_protocol.JSON.entyties.Net_Response; import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java index 96435a1..ac53047 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java @@ -5,10 +5,9 @@ import org.slf4j.LoggerFactory; import org.eclipse.jetty.websocket.api.Session; import server.logic.ws_protocol.JSON.ActiveConnectionsRegistry; import server.logic.ws_protocol.JSON.ConnectionContext; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_CreateAuthSession_Response; +import server.logic.ws_protocol.JSON.handlers.auth.entyties.*; import server.logic.ws_protocol.JSON.entyties.Net_Request; import server.logic.ws_protocol.JSON.entyties.Net_Response; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_CreateAuthSession_Request; import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler; import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory; import server.logic.ws_protocol.WireCodes; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_ListSessions_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_ListSessions_Handler.java index 8291f92..8a4d759 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_ListSessions_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_ListSessions_Handler.java @@ -3,13 +3,12 @@ package server.logic.ws_protocol.JSON.handlers.auth; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import server.logic.ws_protocol.JSON.ConnectionContext; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_ListSessions_Request; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_ListSessions_Response; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_ListSessions_Response.SessionInfo; +import server.logic.ws_protocol.JSON.handlers.auth.entyties.*; import server.logic.ws_protocol.JSON.entyties.Net_Request; import server.logic.ws_protocol.JSON.entyties.Net_Response; import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler; import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory; +import server.logic.ws_protocol.JSON.handlers.auth.entyties.Net_ListSessions_Response.SessionInfo; import server.logic.ws_protocol.WireCodes; import shine.db.dao.ActiveSessionsDAO; import shine.db.entities.ActiveSessionEntry; @@ -144,7 +143,7 @@ public class Net_ListSessions_Handler implements JsonMessageHandler { // 4) Собираем DTO с геолокацией List resultList = new ArrayList<>(); for (ActiveSessionEntry s : sessions) { - SessionInfo info = new SessionInfo(); + SessionInfo info = new Net_ListSessions_Response.SessionInfo(); info.setSessionId(s.getSessionId()); info.setClientInfoFromClient(s.getClientInfoFromClient()); info.setClientInfoFromRequest(s.getClientInfoFromRequest()); diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_RefreshSession_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_RefreshSession_Handler.java index c5da508..9bfc70c 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_RefreshSession_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_RefreshSession_Handler.java @@ -4,8 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import server.logic.ws_protocol.JSON.ActiveConnectionsRegistry; import server.logic.ws_protocol.JSON.ConnectionContext; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_RefreshSession_Request; -import server.logic.ws_protocol.JSON.entyties.Auth.Net_RefreshSession_Response; +import server.logic.ws_protocol.JSON.handlers.auth.entyties.*; import server.logic.ws_protocol.JSON.entyties.Net_Request; import server.logic.ws_protocol.JSON.entyties.Net_Response; import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/AUTH_SESSION_NEW.md b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/AUTH_SESSION_NEW.md similarity index 100% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/AUTH_SESSION_NEW.md rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/AUTH_SESSION_NEW.md diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_AuthChallenge_Request.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_AuthChallenge_Request.java similarity index 94% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_AuthChallenge_Request.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_AuthChallenge_Request.java index 76845d2..af61de6 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_AuthChallenge_Request.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_AuthChallenge_Request.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.Auth; +package server.logic.ws_protocol.JSON.handlers.auth.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Request; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_AuthChallenge_Response.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_AuthChallenge_Response.java similarity index 94% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_AuthChallenge_Response.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_AuthChallenge_Response.java index 9e54746..a6edd1e 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_AuthChallenge_Response.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_AuthChallenge_Response.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.Auth; +package server.logic.ws_protocol.JSON.handlers.auth.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Response; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CloseActiveSession_Request.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CloseActiveSession_Request.java similarity index 97% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CloseActiveSession_Request.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CloseActiveSession_Request.java index b647083..a9b98ca 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CloseActiveSession_Request.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CloseActiveSession_Request.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.Auth; +package server.logic.ws_protocol.JSON.handlers.auth.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Request; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CloseActiveSession_Response.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CloseActiveSession_Response.java similarity index 90% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CloseActiveSession_Response.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CloseActiveSession_Response.java index 1b5792e..8be5c5c 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CloseActiveSession_Response.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CloseActiveSession_Response.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.Auth; +package server.logic.ws_protocol.JSON.handlers.auth.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Response; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CreateAuthSession_Request.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CreateAuthSession_Request.java similarity index 97% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CreateAuthSession_Request.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CreateAuthSession_Request.java index c3c6791..427f40b 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CreateAuthSession_Request.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CreateAuthSession_Request.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.Auth; +package server.logic.ws_protocol.JSON.handlers.auth.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Request; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CreateAuthSession_Response.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CreateAuthSession_Response.java similarity index 94% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CreateAuthSession_Response.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CreateAuthSession_Response.java index 51a8b66..80e1a06 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_CreateAuthSession_Response.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_CreateAuthSession_Response.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.Auth; +package server.logic.ws_protocol.JSON.handlers.auth.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Response; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_ListSessions_Request.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_ListSessions_Request.java similarity index 96% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_ListSessions_Request.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_ListSessions_Request.java index c080f8b..66598e1 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_ListSessions_Request.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_ListSessions_Request.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.Auth; +package server.logic.ws_protocol.JSON.handlers.auth.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Request; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_ListSessions_Response.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_ListSessions_Response.java similarity index 97% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_ListSessions_Response.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_ListSessions_Response.java index 3770b0b..414a817 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_ListSessions_Response.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_ListSessions_Response.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.Auth; +package server.logic.ws_protocol.JSON.handlers.auth.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Response; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_RefreshSession_Request.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_RefreshSession_Request.java similarity index 95% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_RefreshSession_Request.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_RefreshSession_Request.java index 543f871..70cddc6 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_RefreshSession_Request.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_RefreshSession_Request.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.Auth; +package server.logic.ws_protocol.JSON.handlers.auth.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Request; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_RefreshSession_Response.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_RefreshSession_Response.java similarity index 93% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_RefreshSession_Response.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_RefreshSession_Response.java index 1a535a1..f4a3fd5 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/Net_RefreshSession_Response.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/Net_RefreshSession_Response.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.Auth; +package server.logic.ws_protocol.JSON.handlers.auth.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Response; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/SESSION_REFRESH.md b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/SESSION_REFRESH.md similarity index 100% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/SESSION_REFRESH.md rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/SESSION_REFRESH.md diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/help.txt b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/help.txt similarity index 100% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/Auth/help.txt rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/entyties/help.txt diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java index 0561f2d..5e85888 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler.java @@ -7,8 +7,10 @@ import org.slf4j.LoggerFactory; import server.logic.ws_protocol.JSON.ConnectionContext; import server.logic.ws_protocol.JSON.entyties.Net_Request; import server.logic.ws_protocol.JSON.entyties.Net_Response; -import server.logic.ws_protocol.JSON.entyties.blockchain.Net_AddBlock_Request; -import server.logic.ws_protocol.JSON.entyties.blockchain.Net_AddBlock_Response; +import server.logic.ws_protocol.JSON.handlers.blockchain.Net_AddBlock_Handler_utils.BlockchainLocks; +import server.logic.ws_protocol.JSON.handlers.blockchain.Net_AddBlock_Handler_utils.BlockchainWriter; +import server.logic.ws_protocol.JSON.handlers.blockchain.entyties.Net_AddBlock_Request; +import server.logic.ws_protocol.JSON.handlers.blockchain.entyties.Net_AddBlock_Response; import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler; import server.logic.ws_protocol.WireCodes; import shine.db.dao.BlockchainStateDAO; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainLocks.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler_utils/BlockchainLocks.java similarity index 83% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainLocks.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler_utils/BlockchainLocks.java index 1b599e6..f429278 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainLocks.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler_utils/BlockchainLocks.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.handlers.blockchain; +package server.logic.ws_protocol.JSON.handlers.blockchain.Net_AddBlock_Handler_utils; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantLock; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainWriter.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler_utils/BlockchainWriter.java similarity index 99% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainWriter.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler_utils/BlockchainWriter.java index b701f8c..74110ec 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/BlockchainWriter.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/Net_AddBlock_Handler_utils/BlockchainWriter.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.handlers.blockchain; +package server.logic.ws_protocol.JSON.handlers.blockchain.Net_AddBlock_Handler_utils; import blockchain.BchBlockEntry; import blockchain.body.ReactionBody; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/blockchain/Net_AddBlock_Request.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/entyties/Net_AddBlock_Request.java similarity index 94% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/blockchain/Net_AddBlock_Request.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/entyties/Net_AddBlock_Request.java index dac0a81..a46299e 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/blockchain/Net_AddBlock_Request.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/entyties/Net_AddBlock_Request.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.blockchain; +package server.logic.ws_protocol.JSON.handlers.blockchain.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Request; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/blockchain/Net_AddBlock_Response.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/entyties/Net_AddBlock_Response.java similarity index 93% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/blockchain/Net_AddBlock_Response.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/entyties/Net_AddBlock_Response.java index 6fa0944..904dcc3 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/blockchain/Net_AddBlock_Response.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/blockchain/entyties/Net_AddBlock_Response.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.blockchain; +package server.logic.ws_protocol.JSON.handlers.blockchain.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Response; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/tempToTest/Net_AddUser_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/tempToTest/Net_AddUser_Handler.java index 8894b97..8b84da0 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/tempToTest/Net_AddUser_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/tempToTest/Net_AddUser_Handler.java @@ -5,8 +5,8 @@ import org.slf4j.LoggerFactory; import server.logic.ws_protocol.JSON.ConnectionContext; import server.logic.ws_protocol.JSON.entyties.Net_Request; import server.logic.ws_protocol.JSON.entyties.Net_Response; -import server.logic.ws_protocol.JSON.entyties.tempToTest.Net_AddUser_Request; -import server.logic.ws_protocol.JSON.entyties.tempToTest.Net_AddUser_Response; +import server.logic.ws_protocol.JSON.handlers.tempToTest.entyties.Net_AddUser_Request; +import server.logic.ws_protocol.JSON.handlers.tempToTest.entyties.Net_AddUser_Response; import server.logic.ws_protocol.JSON.handlers.JsonMessageHandler; import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory; import server.logic.ws_protocol.WireCodes; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/tempToTest/Net_AddUser_Request.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/tempToTest/entyties/Net_AddUser_Request.java similarity index 95% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/tempToTest/Net_AddUser_Request.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/tempToTest/entyties/Net_AddUser_Request.java index 8e0bd1e..f900f49 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/tempToTest/Net_AddUser_Request.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/tempToTest/entyties/Net_AddUser_Request.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.tempToTest; +package server.logic.ws_protocol.JSON.handlers.tempToTest.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Request; diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/tempToTest/Net_AddUser_Response.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/tempToTest/entyties/Net_AddUser_Response.java similarity index 88% rename from shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/tempToTest/Net_AddUser_Response.java rename to shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/tempToTest/entyties/Net_AddUser_Response.java index 8157511..e9452c0 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/entyties/tempToTest/Net_AddUser_Response.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/tempToTest/entyties/Net_AddUser_Response.java @@ -1,4 +1,4 @@ -package server.logic.ws_protocol.JSON.entyties.tempToTest; +package server.logic.ws_protocol.JSON.handlers.tempToTest.entyties; import server.logic.ws_protocol.JSON.entyties.Net_Response; diff --git a/src/main/docs/Формат блоков/Описанией записей/Начало блокчейна.md b/src/main/docs/Формат блоков/Описанией записей/Начало блокчейна.md index 88abf8f..a418a55 100644 --- a/src/main/docs/Формат блоков/Описанией записей/Начало блокчейна.md +++ b/src/main/docs/Формат блоков/Описанией записей/Начало блокчейна.md @@ -16,7 +16,7 @@ * * | Смещение | Размер | Поле | Формат | Описание | * |-----------|--------|--------------------|---------|-----------| -* | 0x00 | 8 | tag | ASCII | Статическая сигнатура "SHiNE001" | +* | 0x00 | 8 | tag | ASCII | Статическая сигнатура "SHiNE" | * * | 0x10 | 1 | userLoginLength=N | uint8 | Длина логина пользователя | * | 0x11 | N | userLogin | UTF-8 | Логин пользователя | @@ -34,7 +34,7 @@ * ---------------------------------------------------------------------------- * 💡 Пример структуры в байтах: * -* 0000: 53 48 69 4E 45 30 30 31 "SHiNE001" +* 0000: 53 48 69 4E 45 30 30 31 "SHiNE" * 0008: 00 00 00 00 01 23 45 67 blockchainId * 0010: 05 userLoginLength = 5 * 0011: 41 69 64 61 72 userLogin = "Aidar" diff --git a/src/main/java/server/logic/InboundMessageProcessor.java b/src/main/java/server/logic/InboundMessageProcessor.java index 4a2a267..9899932 100644 --- a/src/main/java/server/logic/InboundMessageProcessor.java +++ b/src/main/java/server/logic/InboundMessageProcessor.java @@ -18,7 +18,7 @@ public final class InboundMessageProcessor { private static final Logger log = LoggerFactory.getLogger(InboundMessageProcessor.class); private static final Map HANDLERS = Map.of( - WireCodes.Op.PING, new PingHandler() +// WireCodes.Op.PING, new PingHandler() // WireCodes.Op.ADD_BLOCK, new AddBlockHandler(), // WireCodes.Op.GET_BLOCKCHAIN,new GetBlockchainHandler() // WireCodes.Op.SEARCH_USERS, new SearchUsersHandler(), diff --git a/src/main/java/server/logic/ws_protocol/binary/handlers/AddBlockHandler.java b/src/main/java/server/logic/ws_protocol/binary/handlers/AddBlockHandler.java deleted file mode 100644 index 7988623..0000000 --- a/src/main/java/server/logic/ws_protocol/binary/handlers/AddBlockHandler.java +++ /dev/null @@ -1,250 +0,0 @@ -//package server.logic.ws_protocol.binary.handlers; -// -//import blockchain.BchBlockEntry; -//import blockchain.body.BodyRecord; -//import blockchain.BodyRecordParser; -//import blockchain.body.HeaderBody; -//import org.slf4j.Logger; -//import org.slf4j.LoggerFactory; -//import server.logic.ws_protocol.WireCodes; -//import utils.blockchain.BchInfoEntry; -//import utils.blockchain.BchInfoManager; -//import utils.crypto.BchCryptoVerifier; -//import utils.files.FileStoreUtil; -// -//import java.nio.ByteBuffer; -//import java.nio.ByteOrder; -//import java.util.Arrays; -// -///** -// * AddBlockHandler — обработчик команды "добавить блок" (ADD_BLOCK) -// * --------------------------------------------------------------- -// * Принимает бинарное сообщение от клиента и добавляет новый блок в цепочку. -// *. -// * Формат входного сообщения (msg): -// * [0..3] — 4 байта: код операции (WireCodes.ADD_BLOCK) -// * [4..11] — 8 байт: blockchainId (уникальный идентификатор цепочки) -// * [12..] — байты полного блока .bch: -// * ├── 4 байта recordSize = M + 18 -// * ├── 4 байта recordNumber -// * ├── 8 байт timestamp -// * ├── 2 байта recordType -// * ├── 2 байта recordVersion -// * ├── M байт body (содержимое блока) -// * ├── 64 байта signature (Ed25519) -// * └── 32 байта hash (SHA-256) -// *. -// * --------------------------------------------------------------- -// * Алгоритм работы: -// *. -// * 1️⃣ Распаковать BchBlockEntry из msg (т.е. выделить тело блока и подписи). -// * 2️⃣ Найти описание цепочки (BchInfoEntry) по blockchainId. -// *. -// * ─ Если описания нет (цепочка ещё не существует): -// * • принимаем только блок типа 0 (HeaderBody) и номера 0; -// * • парсим его, создаём новый BchInfoEntry на основе данных заголовка; -// * • проверяем подпись и хэш; -// * • проверяем корректность тела блока (check); -// * • сохраняем блок и создаём новый blockchain-файл; -// * • добавляем цепочку в менеджер BchInfoManager. -// * (💡 временное решение: создание цепочки допустимо только через HeaderBody) -// *. -// * ─ Если цепочка уже существует: -// * • проверяем, что номер блока равен (lastBlockNumber + 1); -// * • проверяем подпись и хэш; -// * • проверяем тело блока (check); -// * • добавляем блок в файл цепочки; -// * • обновляем состояние BchInfoEntry (номер, хэш, размер). -// *. -// * 3️⃣ Если все проверки пройдены — возвращаем статус OK. -// *. -// * Таким образом, единственное различие между первым блоком и последующими — -// * момент инициализации описания цепочки (BchInfoEntry). -// * Всё остальное (валидация, подпись, добавление, обновление) выполняется одинаково. -// */ -//public class AddBlockHandler implements MessageHandler { -// -// private static final Logger log = LoggerFactory.getLogger(AddBlockHandler.class); -// -// @Override -// public byte[] handle(byte[] msg) { -// try { -// // ===================================================================== -// // 1️⃣ Проверка минимальной длины пакета -// // ===================================================================== -// int minFull = BchBlockEntry.RAW_HEADER_SIZE + BchBlockEntry.SIGNATURE_LEN + BchBlockEntry.HASH_LEN; -// // (RAW_HEADER_SIZE = 18 байт, подпись = 64, хэш = 32) -// if (msg.length < 4 + 8 + minFull) -// return code(WireCodes.Status.BAD_REQUEST); -// -// // ===================================================================== -// // 2️⃣ Извлекаем blockchainId (8 байт начиная с позиции 4) -// // ===================================================================== -// long blockchainId = ByteBuffer.wrap(msg, 4, 8) -// .order(ByteOrder.BIG_ENDIAN) -// .getLong(); -// -// // Всё, что дальше, — это бинарное содержимое блока .bch -// int offset = 12; // первые 12 байт = код + blockchainId -// -// // ===================================================================== -// // 3️⃣ Парсим блок (RAW + подпись + хэш) -// // ===================================================================== -// byte[] fullBlock = Arrays.copyOfRange(msg, offset, msg.length); -// BchBlockEntry block = new BchBlockEntry(fullBlock); // сам распакует RAW-часть и подписи -// -// // ===================================================================== -// // 4️⃣ Получаем текущее описание цепочки (BchInfoEntry) -// // ===================================================================== -// BchInfoManager info = BchInfoManager.getInstance(); -// BchInfoEntry chain = info.getBchInfo(blockchainId); -// -// byte[] prevHash32; -// int expectedNum; -// String userLogin; -// byte[] publicKey32; -// -// // ===================================================================== -// // 🧩 СЦЕНАРИЙ 1: цепочка отсутствует — создаём новую -// // ===================================================================== -// if (chain == null) { -// // Допускаем только блок-заголовок (type=0, num=0) -// if (block.recordType != BchBlockEntry.TYPE_HEADER || block.recordNumber != 0) { -// log.warn("Попытка создать новую цепочку без корректного заголовка (type={}, num={})", -// block.recordType, block.recordNumber); -// return code(WireCodes.Status.BAD_REQUEST); -// } -// -// // Парсим тело блока → HeaderBody -// BodyRecord body = BodyRecordParser.parse(block.recordType, block.recordTypeVersion, block.body).check(); -// if (!(body instanceof HeaderBody)) -// return code(WireCodes.Status.BAD_REQUEST); -// -// HeaderBody hb = (HeaderBody) body; -// -// // Проверяем, что blockchainId совпадает -// if (hb.blockchainId != blockchainId) { -// log.warn("Несовпадение blockchainId в заголовке (ожидалось {}, получено {})", -// blockchainId, hb.blockchainId); -// return code(WireCodes.Status.BAD_REQUEST); -// } -// -// // Проверяем подпись и хэш первого блока (предыдущий хэш = 0) -// prevHash32 = new byte[32]; -// boolean verified = BchCryptoVerifier.verifyAll( -// hb.userLogin, -// blockchainId, -// prevHash32, -// block.rawBytes, -// block.getSignature64(), -// block.getHash32(), -// hb.publicKey32 -// ); -// if (!verified) { -// log.warn("❌ Подпись не прошла проверку при создании цепочки blockchainId={}", blockchainId); -// return code(WireCodes.Status.UNVERIFIED); -// } -// -// // ✅ Всё хорошо: создаём новую цепочку -// info.addBlockchain(blockchainId, hb.userLogin, hb.publicKey32, Integer.MAX_VALUE); -// info.updateBlockchainState(blockchainId, block.recordNumber, bytesToHex(block.getHash32()), fullBlock.length); -// -// FileStoreUtil.getInstance().addDataToBlockchain(blockchainId, fullBlock); -// -// log.info("✅ Создана новая цепочка blockchainId={}, user={}, blockNum={}", -// blockchainId, hb.userLogin, block.recordNumber); -// -// return code(WireCodes.Status.OK); -// } -// -// // ===================================================================== -// // 🧩 СЦЕНАРИЙ 2: цепочка существует — добавляем новый блок -// // ===================================================================== -// expectedNum = chain.lastBlockNumber + 1; -// -// // Проверка последовательности (и отправка lastBlockNumber) -// if (block.recordNumber < expectedNum) { -// log.info("🔁 Блок {} уже существует, последний = {}", block.recordNumber, chain.lastBlockNumber); -// ByteBuffer out = ByteBuffer.allocate(8).order(ByteOrder.BIG_ENDIAN); -// out.putInt(WireCodes.Status.BLOCK_ALREADY_EXISTS); -// out.putInt(chain.lastBlockNumber); -// return out.array(); -// } -// if (block.recordNumber > expectedNum) { -// log.warn("⚠️ Нарушена последовательность: получен {}, ожидался {}", block.recordNumber, expectedNum); -// ByteBuffer out = ByteBuffer.allocate(8).order(ByteOrder.BIG_ENDIAN); -// out.putInt(WireCodes.Status.OUT_OF_SEQUENCE); -// out.putInt(chain.lastBlockNumber); -// return out.array(); -// } -// -// userLogin = chain.userLogin; -// publicKey32 = chain.getPublicKey32(); -// -// // Хэш предыдущего блока (или 32 нуля, если это первый) -// prevHash32 = (chain.lastBlockHash == null || chain.lastBlockHash.isEmpty()) -// ? new byte[32] -// : hexToBytes(chain.lastBlockHash); -// -// // Проверяем подпись и хэш -// boolean verified = BchCryptoVerifier.verifyAll( -// userLogin, -// blockchainId, -// prevHash32, -// block.rawBytes, -// block.getSignature64(), -// block.getHash32(), -// publicKey32 -// ); -// if (!verified) { -// log.warn("❌ Подпись не прошла проверку: chainId={}, blockNum={}", blockchainId, block.recordNumber); -// return code(WireCodes.Status.UNVERIFIED); -// } -// -// // Проверяем тело блока (например, корректный UTF-8 или структура) -// BodyRecord body = BodyRecordParser.parse(block.recordType, block.recordTypeVersion, block.body).check(); -// -// // ✅ Добавляем блок в файл цепочки -// FileStoreUtil.getInstance().addDataToBlockchain(blockchainId, fullBlock); -// -// // Обновляем состояние цепочки (номер, хэш, размер) -// int newSize = chain.blockchainSize + fullBlock.length; -// info.updateBlockchainState(blockchainId, block.recordNumber, bytesToHex(block.getHash32()), newSize); -// -// log.info("✅ Блок добавлен: chain={}, num={}, type={}, bytes={}", -// blockchainId, block.recordNumber, block.recordType, fullBlock.length); -// -// return code(WireCodes.Status.OK); -// -// } catch (Exception e) { -// log.error("❌ ADD_BLOCK: внутренняя ошибка при обработке", e); -// return code(WireCodes.Status.INTERNAL_ERROR); -// } -// } -// -// // ===================================================================== -// // Утилиты -// // ===================================================================== -// -// /** Преобразовать статус (int) в 4 байта BigEndian. */ -// private static byte[] code(int status) { -// return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(status).array(); -// } -// -// /** Конвертация HEX → bytes (для хэшей). */ -// private static byte[] hexToBytes(String hex) { -// int len = hex.length(); -// byte[] out = new byte[len / 2]; -// for (int i = 0; i < len; i += 2) -// out[i / 2] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16); -// return out; -// } -// -// /** Конвертация bytes → HEX (для сохранения в BchInfo). */ -// private static String bytesToHex(byte[] b) { -// StringBuilder sb = new StringBuilder(b.length * 2); -// for (byte x : b) sb.append(String.format("%02x", x)); -// return sb.toString(); -// } -//} -// diff --git a/src/main/java/server/logic/ws_protocol/binary/handlers/GetBlockchainHandler.java b/src/main/java/server/logic/ws_protocol/binary/handlers/GetBlockchainHandler.java deleted file mode 100644 index 8495dde..0000000 --- a/src/main/java/server/logic/ws_protocol/binary/handlers/GetBlockchainHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -//package server.logic.ws_protocol.binary.handlers; -// -//import org.slf4j.Logger; -//import org.slf4j.LoggerFactory; -//import server.logic.ws_protocol.WireCodes; -//import utils.files.FileStoreUtil; -// -//import java.nio.ByteBuffer; -//import java.nio.ByteOrder; -// -///** -// * Возврат полного содержимого блокчейна (GET_BLOCKCHAIN). -// */ -//public class GetBlockchainHandler implements MessageHandler { -// private static final Logger log = LoggerFactory.getLogger(GetBlockchainHandler.class); -// -// @Override -// public byte[] handle(byte[] msg) { -// try { -// if (msg.length < 12) -// return intTo4Bytes(WireCodes.Status.BAD_REQUEST); -// -// long id = ByteBuffer.wrap(msg, 4, 8) -// .order(ByteOrder.BIG_ENDIAN) -// .getLong(); -// -// FileStoreUtil fs = FileStoreUtil.getInstance(); -// byte[] data = fs.readAllDataFromBlockchain(id); -// -// return packOk(data); -// -// } catch (IllegalStateException e) { -// log.warn("GET_BLOCKCHAIN: файл не найден ({})", e.getMessage()); -// return intTo4Bytes(WireCodes.Status.CHAIN_NOT_FOUND); -// } catch (Exception e) { -// log.error("GET_BLOCKCHAIN: ошибка", e); -// return intTo4Bytes(WireCodes.Status.INTERNAL_ERROR); -// } -// } -// -// private static byte[] packOk(byte[] data) { -// if (data == null) data = new byte[0]; -// ByteBuffer out = ByteBuffer.allocate(8 + data.length).order(ByteOrder.BIG_ENDIAN); -// out.putInt(WireCodes.Status.OK); -// out.putInt(data.length); -// out.put(data); -// return out.array(); -// } -// -// private static byte[] intTo4Bytes(int code) { -// return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(code).array(); -// } -//} diff --git a/src/main/java/server/logic/ws_protocol/binary/handlers/GetLastBlockInfoHandler.java b/src/main/java/server/logic/ws_protocol/binary/handlers/GetLastBlockInfoHandler.java deleted file mode 100644 index 7657aa5..0000000 --- a/src/main/java/server/logic/ws_protocol/binary/handlers/GetLastBlockInfoHandler.java +++ /dev/null @@ -1,66 +0,0 @@ -//package server.logic.ws_protocol.binary.handlers; -// -//import org.slf4j.Logger; -//import org.slf4j.LoggerFactory; -//import server.logic.ws_protocol.WireCodes; -//import utils.blockchain.BchInfoEntry; -//import utils.blockchain.BchInfoManager; -// -//import java.nio.ByteBuffer; -//import java.nio.ByteOrder; -//import java.util.Arrays; -// -///** -// * Возврат информации о последнем блоке цепочки (GET_LAST_BLOCK_INFO). -// */ -//public class GetLastBlockInfoHandler implements MessageHandler { -// private static final Logger log = LoggerFactory.getLogger(GetLastBlockInfoHandler.class); -// -// @Override -// public byte[] handle(byte[] msg) { -// try { -// if (msg.length < 12) -// return intTo4Bytes(WireCodes.Status.BAD_REQUEST); -// -// long blockchainId = ByteBuffer.wrap(msg, 4, 8) -// .order(ByteOrder.BIG_ENDIAN) -// .getLong(); -// -// BchInfoManager mgr = BchInfoManager.getInstance(); -// BchInfoEntry entry = mgr.getBchInfo(blockchainId); -// if (entry == null) -// return intTo4Bytes(WireCodes.Status.CHAIN_NOT_FOUND); -// -// int lastNum = entry.lastBlockNumber; -// byte[] hash = hexToBytes(entry.lastBlockHash); -// -// ByteBuffer out = ByteBuffer.allocate(4 + 4 + 32).order(ByteOrder.BIG_ENDIAN); -// out.putInt(WireCodes.Status.OK); -// out.putInt(lastNum); -// out.put(hash); -// return out.array(); -// -// } catch (Exception e) { -// log.error("GET_LAST_BLOCK_INFO: ошибка", e); -// return intTo4Bytes(WireCodes.Status.INTERNAL_ERROR); -// } -// } -// -// private static byte[] intTo4Bytes(int code) { -// return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(code).array(); -// } -// -// private static byte[] hexToBytes(String hex) { -// if (hex == null || hex.isEmpty()) return new byte[32]; -// int len = hex.length(); -// byte[] out = new byte[len / 2]; -// for (int i = 0; i < len; i += 2) -// out[i / 2] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16); -// if (out.length < 32) { // добиваем нулями -// byte[] full = new byte[32]; -// System.arraycopy(out, 0, full, 32 - out.length, out.length); -// return full; -// } -// return Arrays.copyOf(out, 32); -// } -//} diff --git a/src/main/java/server/logic/ws_protocol/binary/handlers/PingHandler.java b/src/main/java/server/logic/ws_protocol/binary/handlers/PingHandler.java deleted file mode 100644 index 7227ee2..0000000 --- a/src/main/java/server/logic/ws_protocol/binary/handlers/PingHandler.java +++ /dev/null @@ -1,16 +0,0 @@ -package server.logic.ws_protocol.binary.handlers; - -import server.logic.ws_protocol.WireCodes; - -/** - * Обработчик команды PING. - * Возвращает просто статус PONG. - */ -public class PingHandler implements MessageHandler { - @Override - public byte[] handle(byte[] msg) { - return new byte[]{ - 0, 0, 0, (byte) WireCodes.Status.PONG // проще и быстрее, можно и через ByteBuffer - }; - } -} diff --git a/src/main/java/server/logic/ws_protocol/binary/handlers/SearchUsersHandler.java b/src/main/java/server/logic/ws_protocol/binary/handlers/SearchUsersHandler.java deleted file mode 100644 index 514dcb0..0000000 --- a/src/main/java/server/logic/ws_protocol/binary/handlers/SearchUsersHandler.java +++ /dev/null @@ -1,59 +0,0 @@ -//package server.logic.ws_protocol.binary.handlers; -// -//import org.slf4j.Logger; -//import org.slf4j.LoggerFactory; -//import server.logic.ws_protocol.WireCodes; -//import utils.search.UserSearchService; -// -//import java.nio.ByteBuffer; -//import java.nio.ByteOrder; -//import java.nio.charset.StandardCharsets; -//import java.util.List; -// -///** -// * Поиск пользователей по логину (SEARCH_USERS). -// */ -//public class SearchUsersHandler implements MessageHandler { -// private static final Logger log = LoggerFactory.getLogger(SearchUsersHandler.class); -// -// @Override -// public byte[] handle(byte[] msg) { -// try { -// if (msg.length < 8) -// return intTo4Bytes(WireCodes.Status.BAD_REQUEST); -// -// int N = ByteBuffer.wrap(msg, 4, 4).order(ByteOrder.BIG_ENDIAN).getInt(); -// if (N < 0 || msg.length < 8 + N) -// return intTo4Bytes(WireCodes.Status.BAD_REQUEST); -// -// String query = new String(msg, 8, N, StandardCharsets.UTF_8); -// List found = UserSearchService.getInstance().searchFirst5(query); -// return pack(found); -// -// } catch (Exception e) { -// log.error("SEARCH_USERS: ошибка", e); -// return intTo4Bytes(WireCodes.Status.INTERNAL_ERROR); -// } -// } -// -// private static byte[] pack(List pairs) { -// if (pairs == null) pairs = List.of(); -// int total = 8; -// var chunks = new java.util.ArrayList(); -// for (var p : pairs) { -// byte[] packed = UserSearchService.packPair(p); -// chunks.add(packed); -// total += packed.length; -// } -// -// ByteBuffer out = ByteBuffer.allocate(total).order(ByteOrder.BIG_ENDIAN); -// out.putInt(WireCodes.Status.OK); -// out.putInt(pairs.size()); -// for (var c : chunks) out.put(c); -// return out.array(); -// } -// -// private static byte[] intTo4Bytes(int code) { -// return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(code).array(); -// } -//} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e969f67..d22a61d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,3 @@ server.1port=7070 - - db.path=data/shine.sqlite diff --git a/src/test/java/test/it/IT_03_AddBlock_NoAuth.java b/src/test/java/test/it/IT_03_AddBlock_NoAuth.java index 5c76376..991ea21 100644 --- a/src/test/java/test/it/IT_03_AddBlock_NoAuth.java +++ b/src/test/java/test/it/IT_03_AddBlock_NoAuth.java @@ -36,7 +36,7 @@ public class IT_03_AddBlock_NoAuth { public static void main(String[] args) { int failed = run(); - System.exit(failed); +// System.exit(failed); } /** Запуск одного теста (standalone). Возвращает 0 если ок, 1 если упал. */ diff --git a/src/test_ws.html b/src/test_ws.html index 80524b9..64361d3 100644 --- a/src/test_ws.html +++ b/src/test_ws.html @@ -66,7 +66,7 @@ // === Построение HEADER === function buildHeaderBody() { - const tag = textUtf8("SHiNE001"); + const tag = textUtf8("SHiNE"); const id = beLong(blockchainId); const login = textUtf8(userLogin); const loginLen = new Uint8Array([login.length]);