SHA256
Документировать API и сервис агента-кодера
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
краткая «памятка себе» по базовым классам и как они связаны.
|
||||
|
||||
server.logic.InboundMessageProcessor (устаревший путь)
|
||||
|
||||
Роль: маршрутизатор бинарного протокола: берёт входящие байты, читает первые 4 байта как op, находит MessageHandler и отдаёт ему сообщение.
|
||||
Что возвращает: байтовый ответ хэндлера; при ошибках — 4 байта со статусом (BAD_REQUEST/INTERNAL_ERROR).
|
||||
Важно: сейчас фактически не используется (карта HANDLERS пустая/закомментирована) — это «след» старого бинарного протокола, который вы заменили на JSON-WS.
|
||||
|
||||
server.ws.BlockchainTmpRecoveryOnStartup
|
||||
|
||||
Роль: «автослесарь» при старте: чинит последствия падения во время записи блокчейн-файла.
|
||||
Логика: ищет *.tmp_bch в data/, сравнивает размеры tmp, main .bch и state.fileSizeBytes из БД.
|
||||
Решения:
|
||||
если stateSize == mainSize → tmp мусор, удаляем;
|
||||
если stateSize == tmpSize → tmp актуален, атомарно заменяем main;
|
||||
если не сходится / подозрительно (нет state, но есть main+tmp и т.п.) → CRITICAL + стоп сервера.
|
||||
Итог: гарантирует, что на запуске не будет «тихо битого» блокчейна.
|
||||
|
||||
server.ws.BlockchainWsEndpoint
|
||||
|
||||
Роль: WS-эндпоинт Jetty, который принимает и бинарные, и текстовые сообщения.
|
||||
Connect: сохраняет Session, кладёт её в ConnectionContext.
|
||||
Binary: асинхронно вызывает InboundMessageProcessor.process(msg) и отправляет байтовый ответ. (Это тот самый устаревший путь.)
|
||||
Text (JSON): асинхронно вызывает JsonInboundProcessor.processJson(message, connectionContext) и отправляет строку JSON.
|
||||
Close: удаляет соединение из ActiveConnectionsRegistry, чистит ConnectionContext.
|
||||
Смысл: один входной узел WS, где JSON — основной протокол, binary — “наследие”.
|
||||
|
||||
server.ws.WsServer
|
||||
|
||||
Роль: точка входа сервера.
|
||||
|
||||
Порядок запуска:
|
||||
BlockchainTmpRecoveryOnStartup.runRecoveryOrThrow() — если не смог починить/сопоставить → сервер не стартует;
|
||||
читает порт из AppConfig (server.port), иначе 7070;
|
||||
поднимает Jetty, конфигурирует WS-контейнер, маппит /ws → BlockchainWsEndpoint, ставит idleTimeout.
|
||||
Итог: «бутстрап»: сначала безопасность файлов, потом сеть.
|
||||
@@ -1,286 +0,0 @@
|
||||
JSON WebSocket протокол сервера: список существующих запросов (op)
|
||||
|
||||
Общий формат любого запроса (client → server):
|
||||
op - имя операции (строка)
|
||||
requestId - идентификатор запроса для связывания с ответом (строка)
|
||||
payload - объект с параметрами конкретной операции (object)
|
||||
|
||||
Общий формат любого ответа (server → client):
|
||||
op - имя операции (строка, совпадает с запросом)
|
||||
requestId - идентификатор запроса (строка, совпадает с запросом)
|
||||
status - статус результата (200 = успех, другое = ошибка)
|
||||
payload - объект с полями ответа (object; при ошибке содержит code/message)
|
||||
|
||||
Группа: Авторизация и сессии
|
||||
|
||||
Эта группа управляет входом пользователя, созданием/обновлением сессий и безопасным завершением активных подключений.
|
||||
|
||||
----- AuthChallenge
|
||||
Одноразовый шаг 1: по логину выдаёт nonce (authNonce), который затем подписывается на шаге 2.
|
||||
|
||||
Запрос:
|
||||
op - "AuthChallenge"
|
||||
requestId - id запроса
|
||||
login - логин пользователя, для которого начинается авторизация
|
||||
|
||||
Ответ (успех):
|
||||
op - "AuthChallenge"
|
||||
requestId - id запроса
|
||||
status - 200 если успех
|
||||
authNonce - одноразовый nonce, Base64Url(32 bytes) без padding
|
||||
|
||||
Ответ (ошибка):
|
||||
op - "AuthChallenge"
|
||||
requestId - id запроса
|
||||
status - код ошибки
|
||||
code - строковый код ошибки
|
||||
message - человекочитаемое описание ошибки
|
||||
|
||||
----- CreateAuthSession
|
||||
Шаг 2: проверяет подпись владения ключом, создаёт новую active_session и возвращает sessionId/sessionPwd.
|
||||
|
||||
Запрос:
|
||||
op - "CreateAuthSession"
|
||||
requestId - id запроса
|
||||
storagePwd - ключ/пароль хранилища клиента, base64(32 bytes)
|
||||
timeMs - время на клиенте в мс (для защиты от повторов и проверки рассинхрона)
|
||||
signatureB64 - подпись Ed25519 над строкой "AUTHORIFICATED:" + timeMs + authNonce (base64)
|
||||
clientInfo - короткая строка о клиенте/устройстве (до 50 символов), опционально
|
||||
|
||||
Ответ (успех):
|
||||
op - "CreateAuthSession"
|
||||
requestId - id запроса
|
||||
status - 200 если успех
|
||||
sessionId - идентификатор сессии, Base64Url(32 bytes)
|
||||
sessionPwd - секрет сессии, Base64Url(32 bytes)
|
||||
|
||||
Ответ (ошибка):
|
||||
op - "CreateAuthSession"
|
||||
requestId - id запроса
|
||||
status - код ошибки
|
||||
code - строковый код ошибки
|
||||
message - человекочитаемое описание ошибки
|
||||
|
||||
----- RefreshSession
|
||||
Повторный вход без подписи: проверяет sessionId+sessionPwd, обновляет метаданные сессии и возвращает storagePwd.
|
||||
|
||||
Запрос:
|
||||
op - "RefreshSession"
|
||||
requestId - id запроса
|
||||
sessionId - идентификатор ранее выданной сессии (base64/url-safe строка)
|
||||
sessionPwd - секрет ранее выданной сессии (base64/url-safe строка)
|
||||
clientInfo - короткая строка о клиенте/устройстве (до 50 символов), опционально
|
||||
|
||||
Ответ (успех):
|
||||
op - "RefreshSession"
|
||||
requestId - id запроса
|
||||
status - 200 если успех
|
||||
storagePwd - пароль хранилища, сохранённый в сессии (base64(32 bytes))
|
||||
|
||||
Ответ (ошибка):
|
||||
op - "RefreshSession"
|
||||
requestId - id запроса
|
||||
status - код ошибки
|
||||
code - строковый код ошибки
|
||||
message - человекочитаемое описание ошибки
|
||||
|
||||
----- ListSessions
|
||||
Возвращает список всех активных сессий текущего пользователя (для управления устройствами/входами).
|
||||
|
||||
Запрос:
|
||||
op - "ListSessions"
|
||||
requestId - id запроса
|
||||
timeMs - время на клиенте в мс (нужно только если статус AUTH_IN_PROGRESS)
|
||||
signatureB64 - подпись Ed25519 над строкой "AUTHORIFICATED:" + timeMs + authNonce (нужно только если статус AUTH_IN_PROGRESS)
|
||||
|
||||
Ответ (успех):
|
||||
op - "ListSessions"
|
||||
requestId - id запроса
|
||||
status - 200 если успех
|
||||
sessions - массив активных сессий пользователя
|
||||
|
||||
Поля элемента sessions[i]:
|
||||
sessionId - идентификатор сессии, Base64Url(32 bytes)
|
||||
clientInfoFromClient - что прислал клиент в clientInfo
|
||||
clientInfoFromRequest - что собрал сервер из окружения (UA/платформа и т.п.)
|
||||
geo - строка "Country, City" или "unknown"
|
||||
lastAuthirificatedAtMs - время последней успешной авторизации/refresh (мс)
|
||||
|
||||
Ответ (ошибка):
|
||||
op - "ListSessions"
|
||||
requestId - id запроса
|
||||
status - код ошибки
|
||||
code - строковый код ошибки
|
||||
message - человекочитаемое описание ошибки
|
||||
|
||||
----- CloseActiveSession
|
||||
Закрывает одну активную сессию пользователя (указанную или текущую), при необходимости подтверждая владение ключом подписью.
|
||||
|
||||
Запрос:
|
||||
op - "CloseActiveSession"
|
||||
requestId - id запроса
|
||||
sessionId - идентификатор сессии для закрытия (если пусто, закрывается текущая)
|
||||
timeMs - время на клиенте в мс (нужно только если статус AUTH_IN_PROGRESS)
|
||||
signatureB64 - подпись Ed25519 над строкой "AUTHORIFICATED:" + timeMs + authNonce (нужно только если статус AUTH_IN_PROGRESS)
|
||||
|
||||
Ответ (успех):
|
||||
op - "CloseActiveSession"
|
||||
requestId - id запроса
|
||||
status - 200 если успех
|
||||
|
||||
Ответ (ошибка):
|
||||
op - "CloseActiveSession"
|
||||
requestId - id запроса
|
||||
status - код ошибки
|
||||
code - строковый код ошибки
|
||||
message - человекочитаемое описание ошибки
|
||||
|
||||
Группа: Блокчейн (загрузка блоков)
|
||||
|
||||
Эта группа отвечает за приём и валидацию блоков (цепочка, линии, подпись/хэш) и атомарную запись в БД+файл.
|
||||
|
||||
----- AddBlock
|
||||
Добавляет следующий блок в конкретный blockchainName, строго проверяя номера, prev-хэши, линии, подпись и лимит размера.
|
||||
|
||||
Запрос:
|
||||
op - "AddBlock"
|
||||
requestId - id запроса
|
||||
blockchainName - имя цепочки (по нему вычисляется login)
|
||||
globalNumber - глобальный номер добавляемого блока (должен быть serverLastGlobalNumber+1)
|
||||
prevGlobalHash - HEX(64) предыдущего глобального хэша (или "" только там, где это допускается правилами)
|
||||
blockBytesB64 - полный блок (raw+signature+hash) в Base64
|
||||
|
||||
Ответ (успех):
|
||||
op - "AddBlock"
|
||||
requestId - id запроса
|
||||
status - 200 если успех
|
||||
reasonCode - null при успехе
|
||||
serverLastGlobalNumber - последний глобальный номер, который сервер считает актуальным после обработки
|
||||
serverLastGlobalHash - последний глобальный хэш (HEX(64)) после обработки
|
||||
|
||||
Ответ (ошибка):
|
||||
op - "AddBlock"
|
||||
requestId - id запроса
|
||||
status - код ошибки (например 400/404/413/500)
|
||||
reasonCode - строка причины (например bad_block_base64, bad_global_number, limit_exceeded и т.п.)
|
||||
serverLastGlobalNumber - текущий серверный lastGlobalNumber
|
||||
serverLastGlobalHash - текущий серверный lastGlobalHash (HEX(64), если известен)
|
||||
|
||||
Группа: Параметры пользователя (UserParams)
|
||||
|
||||
Эта группа хранит и отдаёт подписанные клиентом параметры (ключ-значение) для синхронизации и состояния.
|
||||
|
||||
----- UpsertUserParam
|
||||
Добавляет или обновляет параметр пользователя, проверяя подпись Ed25519 и применяя запись только если time_ms новее.
|
||||
|
||||
Запрос:
|
||||
op - "UpsertUserParam"
|
||||
requestId - id запроса
|
||||
login - логин пользователя
|
||||
param - имя параметра
|
||||
time_ms - метка времени значения в мс
|
||||
value - значение параметра
|
||||
device_key - публичный ключ устройства, base64(32 bytes)
|
||||
signature - подпись Ed25519 от строки USER_PARAMETER_PREFIX + login + param + time_ms + value
|
||||
|
||||
Ответ (успех):
|
||||
op - "UpsertUserParam"
|
||||
requestId - id запроса
|
||||
status - 200 если успех
|
||||
|
||||
Ответ (ошибка):
|
||||
op - "UpsertUserParam"
|
||||
requestId - id запроса
|
||||
status - код ошибки
|
||||
code - строковый код ошибки
|
||||
message - человекочитаемое описание ошибки
|
||||
|
||||
----- GetUserParam
|
||||
Возвращает один сохранённый параметр пользователя.
|
||||
|
||||
Запрос:
|
||||
op - "GetUserParam"
|
||||
requestId - id запроса
|
||||
login - логин пользователя
|
||||
param - имя параметра
|
||||
|
||||
Ответ (успех):
|
||||
op - "GetUserParam"
|
||||
requestId - id запроса
|
||||
status - 200
|
||||
login
|
||||
param
|
||||
time_ms
|
||||
value
|
||||
device_key
|
||||
signature
|
||||
|
||||
Ответ (не найдено):
|
||||
op - "GetUserParam"
|
||||
requestId
|
||||
status - 404
|
||||
|
||||
Ответ (ошибка):
|
||||
op
|
||||
requestId
|
||||
status
|
||||
code
|
||||
message
|
||||
|
||||
----- ListUserParams
|
||||
Возвращает все сохранённые параметры пользователя.
|
||||
|
||||
Запрос:
|
||||
op - "ListUserParams"
|
||||
requestId
|
||||
login
|
||||
|
||||
Ответ (успех):
|
||||
op
|
||||
requestId
|
||||
status - 200
|
||||
login
|
||||
params - массив параметров
|
||||
|
||||
Поля params[i]:
|
||||
login
|
||||
param
|
||||
time_ms
|
||||
value
|
||||
device_key
|
||||
signature
|
||||
|
||||
Ответ (ошибка):
|
||||
op
|
||||
requestId
|
||||
status
|
||||
code
|
||||
message
|
||||
|
||||
Группа: Тестовые/временные операции
|
||||
|
||||
Эта группа предназначена для отладки и первичного наполнения БД.
|
||||
|
||||
----- AddUser
|
||||
Тестовая регистрация локального пользователя.
|
||||
|
||||
Запрос:
|
||||
op - "AddUser"
|
||||
requestId
|
||||
login
|
||||
blockchainName
|
||||
solanaKey
|
||||
deviceKey
|
||||
bchLimit
|
||||
|
||||
Ответ (успех):
|
||||
op
|
||||
requestId
|
||||
status - 200
|
||||
|
||||
Ответ (ошибка):
|
||||
op
|
||||
requestId
|
||||
status
|
||||
code
|
||||
message
|
||||
@@ -1,165 +0,0 @@
|
||||
нет это неправильно откатись к1) Общий формат записи блока (BchBlockEntry)
|
||||
|
||||
Блок хранится как FULL = RAW + TAIL, где RAW участвует в хэшировании/подписи, а TAIL хранит подпись и итоговый хэш.
|
||||
|
||||
RAW (BigEndian)
|
||||
|
||||
recordSize [4] int32 — размер RAW в байтах (включая поля RAW-заголовка и bodyBytes), без signature64 и hash32.
|
||||
|
||||
recordNumber [4] int32 — глобальный порядковый номер блока (сквозной по всему блокчейну).
|
||||
|
||||
timestamp [8] int64 — Unix seconds (время создания блока).
|
||||
|
||||
lineIndex [2] int16 — номер линии (канонические линии см. LineIndex).
|
||||
|
||||
lineNumber [4] int32 — порядковый номер внутри выбранной линии.
|
||||
|
||||
bodyBytes [N] bytes — тело блока, начинается с [type][version] (и дальше подформат конкретного body).
|
||||
|
||||
TAIL (не входит в recordSize)
|
||||
|
||||
signature64 [64] bytes — подпись Ed25519 над hash32.
|
||||
|
||||
hash32 [32] bytes — SHA-256 от preimage (см. ниже).
|
||||
|
||||
2) Как считается хэш и что подписываем (BchCryptoVerifier)
|
||||
|
||||
preimage =
|
||||
|
||||
"SHiNE" (ASCII)
|
||||
|
||||
loginLen[1] + loginBytes[loginLen] (UTF-8, 1..255)
|
||||
|
||||
prevGlobalHash32[32]
|
||||
|
||||
prevLineHash32[32]
|
||||
|
||||
rawBytes[recordSize]
|
||||
|
||||
hash32 = SHA-256(preimage)
|
||||
Далее верификация:
|
||||
|
||||
hash32 должен совпасть с hash32, записанным в блоке.
|
||||
|
||||
signature64 проверяется как Ed25519 подпись над hash32 публичным ключом пользователя.
|
||||
|
||||
3) Типы body и разновидности (по 1 предложению на тип)
|
||||
|
||||
HeaderBody (type=0) — генезис/идентификация блокчейна: фиксирует владельца (login) и тег формата.
|
||||
|
||||
TextBody (type=1) — текстовое сообщение: либо новое, либо ответ (reply), либо репост (repost) со ссылкой на целевой блок.
|
||||
|
||||
ReactionBody (type=2) — реакция на конкретный блок (в MVP — лайк) по ссылке на блок.
|
||||
|
||||
ConnectionBody (type=3) — событие связи с другим пользователем (friend/contact/follow) или отмена этой связи.
|
||||
|
||||
UserParamBody (type=4) — изменение/заявление одного параметра профиля в формате key/value.
|
||||
|
||||
4) Общий формат bodyBytes (для всех body)
|
||||
|
||||
type [2] int16 — код типа тела (0..4).
|
||||
|
||||
version [2] int16 — версия формата конкретного типа (сейчас везде 1).
|
||||
|
||||
subType [2] uint16 — подтип внутри типа (для Header всегда 0; для Text — NEW/REPLY/REPOST; для Reaction — LIKE; для Connection — set/unset + вид; для UserParam — TEXT_TEXT).
|
||||
|
||||
payload [N] bytes — поля конкретного body (строго по формату; “мусор” в конце запрещён).
|
||||
|
||||
5) Формат каждого типа body (по 1 строке на поле)
|
||||
5.1 HeaderBody (type=0, ver=1, lineIndex=0)
|
||||
|
||||
type [2] — 0.
|
||||
|
||||
version [2] — 1.
|
||||
|
||||
subType [2] — 0 (compat).
|
||||
|
||||
tag [5] — ASCII "SHiNE".
|
||||
|
||||
loginLen [1] — длина login в UTF-8 (1..255).
|
||||
|
||||
login [N] — login UTF-8 (^[A-Za-z0-9_]+$).
|
||||
|
||||
5.2 TextBody (type=1, ver=1, lineIndex=1)
|
||||
|
||||
type [2] — 1.
|
||||
|
||||
version [2] — 1.
|
||||
|
||||
subType [2] — 1=NEW, 2=REPLY, 3=REPOST.
|
||||
|
||||
textLenBytes [2] — длина текста в байтах UTF-8 (1..65535).
|
||||
|
||||
text [N] — текст UTF-8 (валидный, не blank).
|
||||
|
||||
toBlockchainNameLen [1] — (только для REPLY/REPOST) длина имени блокчейна цели (1..255).
|
||||
|
||||
toBlockchainName [N] — (только для REPLY/REPOST) UTF-8 имя блокчейна цели.
|
||||
|
||||
toBlockGlobalNumber [4] — (только для REPLY/REPOST) globalNumber целевого блока.
|
||||
|
||||
toBlockHash32 [32] — (только для REPLY/REPOST) raw-хэш целевого блока.
|
||||
|
||||
5.3 ReactionBody (type=2, ver=1, lineIndex=2)
|
||||
|
||||
type [2] — 2.
|
||||
|
||||
version [2] — 1.
|
||||
|
||||
subType [2] — 1=LIKE (зарезервировано под будущие реакции).
|
||||
|
||||
toBlockchainNameLen [1] — длина имени блокчейна цели (1..255).
|
||||
|
||||
toBlockchainName [N] — UTF-8 имя блокчейна цели.
|
||||
|
||||
toBlockGlobalNumber [4] — globalNumber целевого блока.
|
||||
|
||||
toBlockHash32 [32] — raw-хэш целевого блока.
|
||||
|
||||
5.4 ConnectionBody (type=3, ver=1, lineIndex=3)
|
||||
|
||||
type [2] — 3.
|
||||
|
||||
version [2] — 1.
|
||||
|
||||
subType [2] — 10/20/30 (FRIEND/CONTACT/FOLLOW) или 11/21/31 (UNFRIEND/UNCONTACT/UNFOLLOW).
|
||||
|
||||
toLoginLen [1] — длина login цели (1..255).
|
||||
|
||||
toLogin [N] — UTF-8 login цели (^[A-Za-z0-9_]+$).
|
||||
|
||||
toBlockchainNameLen [1] — длина имени блокчейна цели (1..255).
|
||||
|
||||
toBlockchainName [N] — UTF-8 имя блокчейна цели (снимок/якорь).
|
||||
|
||||
toBlockGlobalNumber [4] — lastKnown globalNumber у цели (снимок/якорь).
|
||||
|
||||
toBlockHash32 [32] — lastKnown hash у цели (снимок/якорь).
|
||||
|
||||
5.5 UserParamBody (type=4, ver=1, lineIndex=4)
|
||||
|
||||
type [2] — 4.
|
||||
|
||||
version [2] — 1.
|
||||
|
||||
subType [2] — 1=TEXT_TEXT.
|
||||
|
||||
keyLenBytes [2] — длина ключа в байтах UTF-8 (1..65535).
|
||||
|
||||
keyUtf8 [N] — ключ параметра UTF-8 (валидный, не blank).
|
||||
|
||||
valueLenBytes [2] — длина значения в байтах UTF-8 (1..65535).
|
||||
|
||||
valueUtf8 [M] — значение UTF-8 (валидное, не blank).
|
||||
|
||||
6) Канонические линии (LineIndex)
|
||||
|
||||
0 HEADER — генезис/идентификация.
|
||||
|
||||
1 TEXT — сообщения.
|
||||
|
||||
2 REACTION — реакции.
|
||||
|
||||
3 CONNECTION — связи.
|
||||
|
||||
4 USER_PARAM — параметры профиля.
|
||||
Reference in New Issue
Block a user