# topo_node_sqlite — SQLite-персистентность топологии ## 1. Назначение Обеспечивает сохранение и восстановление топологии P2P-сети (ноды, адреса, каналы, участники каналов) в SQLite-базе. База используется как основной источник данных для chatgui и восстановления состояния между запусками utun. В отличие от LMDB-слоя (`topo_node_lmdb`), который хранит данные в бинарном формате BGP-сообщений, SQLite-слой работает с нормализованными таблицами и используется для клиентских целей — чтение данных chatgui, получение списка участников канала, проверка online-статуса. ## 2. Как пользоваться 1. Получить готовый `sqlite3* db` (открывается извне, обычно в `chat_sync.c`) 2. Вызвать `topo_node_sqlite_init(db)` для создания таблиц 3. Сохранять/обновлять ноды через `topo_node_sqlite_node_put()` 4. Сохранять каналы через `topo_node_sqlite_channel_put()` (автоматически создаёт таблицу `peers_`) 5. Добавлять участников в канал через `topo_node_sqlite_member_put()` 6. Читать участников канала через `topo_node_sqlite_channel_peers_all()` — возвращает бинарный буфер со всеми участниками (node_id, ключи, подписи, адреса) **Нюансы:** - Имена таблиц `peers_` санитизируются: все символы кроме `[a-zA-Z0-9_]` заменяются на `_` - `topo_node_sqlite_channel_peers_all()` формирует компактный бинарный буфер с числом записей в начале (uint16_t) - Ключи в BLOB-полях всегда 32 байта (x25519/ed25519), подписи — 64 байта - Функции `online` и `get_ed25519_pubkey` — простые SELECT-запросы без JOIN ## 3. API | Функция | Описание | |---------|----------| | `topo_node_sqlite_init(db)` | Создаёт таблицы `nodes`, `node_addresses`, `channels` (если не существуют) | | `topo_node_sqlite_node_put(db, nq)` | Сохраняет ноду и её адреса (IPv4/IPv6) в транзакции; старые адреса удаляются | | `topo_node_sqlite_channel_put(...)` | Сохраняет канал в `channels` + создаёт таблицу `peers_` | | `topo_node_sqlite_member_put(...)` | Добавляет/обновляет участника в `peers_` (INSERT OR REPLACE) | | `topo_node_sqlite_member_get_join(db, ch_id, node_id, ...)` | Читает join_sig и join_ts участника канала | | `topo_node_sqlite_member_del(db, ch_id, node_id)` | Удаляет участника из `peers_` | | `topo_node_sqlite_node_update_verified(...)` | Обновляет ключи и имя ноды по условию `update_ts < новое_значение` (защита от stale-данных) | | `topo_node_sqlite_channel_get(...)` | Читает метаданные канала (имя, владелец, ключи, подпись) | | `topo_node_sqlite_channel_peers_all(...)` | Сериализует всех участников канала в бинарный буфер (count + [node_id\|x25519\|ed25519\|flags\|sigs\|name\|addrs]) | | `topo_node_sqlite_node_set_online(db, id, online)` | Устанавливает флаг `online` для ноды | | `topo_node_sqlite_node_get_online(db, id)` | Возвращает 1 если нода online | | `topo_node_sqlite_get_ed25519_pubkey(db, id, out)` | Извлекает ed25519-публичный ключ ноды (32 байта) | **Структуры:** внешние — `sqlite3*`, `struct TOPO_NODEQ`, `struct TOPO_NODE`; собственных структур нет.