update docs

This commit is contained in:
root 2025-10-22 12:47:38 +00:00
parent 2916e49973
commit c6c6276fe6
2 changed files with 176 additions and 120 deletions

View File

@ -1,27 +1,28 @@
# System Architecture Overview # Обзор архитектуры системы
This document is the single source of truth for the platforms architecture, protocols, data flows, and operational details. It supersedes previous scattered docs. Этот документ — единый и актуальный источник информации по платформе: архитектура, протоколы, данные, конфигурация, сценарии, эксплуатация. Заменяет собой разрозненные и устаревшие документы.
## Contents ## Содержание
- Components & Topology - Компоненты и топология
- Decentralized Layer (Membership, Replication, Metrics) - Децентрализованный слой (членство, оценка размера сети, репликации, метрики)
- Upload/Conversion Pipeline - Загрузка и конвертация контента
- Content View & Purchase Flow - Просмотр и покупка контента (UI/UX требования)
- API Surface (selected endpoints) - API (ключевые эндпойнты и полезная нагрузка)
- Data Keys & Schemas - Ключи и схемы данных (DHT)
- Configuration & Defaults - Конфигурация и значения по умолчанию
- Observability & Metrics - Наблюдаемость и метрики
- Sequence Diagrams (Mermaid) - Диаграммы последовательностей (Mermaid)
- Сборка и тестирование
--- ---
## Components & Topology ## Компоненты и топология
- Backend API: Sanic-based service (Telegram bots embedded) with PostgreSQL (SQLAlchemy + Alembic). - Backend API: сервис на Sanic (Python) с бота́ми Telegram; база данных PostgreSQL (SQLAlchemy + Alembic).
- Storage: Local FS for uploaded/derived data; IPFS used for discovery/pinning; tusd for resumable uploads. - Хранилище: локальная ФС (uploads/derivatives); IPFS (kubo) для ретривания/пининга; tusd (resumable upload).
- Converter workers: Dockerized ffmpeg pipeline (convert_v3, convert_process) driven by background tasks. - Конвертеры: воркеры (ffmpeg) в контейнерах — `convert_v3`, `convert_process`.
- Frontend: Vite + TypeScript client served via nginx container. - Frontend: SPA (Vite + TypeScript), отдается nginx-контейнером.
- Decentralized overlay (in-process DHT): Membership, replication lease management, windowed content metrics. - Децентрализованный слой: встроенный DHT (в процессе) — членство, лизы реплик, метрики контента.
```mermaid ```mermaid
flowchart LR flowchart LR
@ -29,7 +30,7 @@ flowchart LR
Frontend -- REST --> API[Backend API] Frontend -- REST --> API[Backend API]
API -- tus hooks --> tusd API -- tus hooks --> tusd
API -- SQL --> Postgres API -- SQL --> Postgres
API -- IPC --> Workers[Converter Workers] API -- IPC --> Workers[Converters]
API -- IPFS --> IPFS API -- IPFS --> IPFS
API -- DHT --> DHT[(In-Process DHT)] API -- DHT --> DHT[(In-Process DHT)]
DHT -- CRDT Merge --> DHT DHT -- CRDT Merge --> DHT
@ -37,183 +38,238 @@ flowchart LR
--- ---
## Decentralized Layer ## Децентрализованный слой
### Identity & Versions ### Идентификаторы и версии
- NodeID = blake3(Ed25519 public key), ContentID = blake3(encrypted_blob) - NodeID = blake3(Ed25519 публичного ключа) — шестнадцатеричная строка (256 бит).
- schema_version = v1 embedded into DHT keys/records. - ContentID = blake3(зашифрованного блоба) — неизменяемый идентификатор контента.
- schema_version = v1 — фиксируется во всех DHT-ключах/записях.
### Membership ### Членство (membership)
- Signed `/api/v1/network.handshake` with Ed25519; includes: - Рукопожатие `/api/v1/network.handshake` — запрос подписан Ed25519; верифицируется на стороне получателя. Без корректной подписи — 400 BAD_SIGNATURE.
- Node info, capabilities, metrics, IPFS metadata. - Полезная нагрузка включает: сведения о ноде (версия, возможности, IPFS), метрики, массив известных публичных нод, квитанции достижимости (reachability_receipts: issuer, target, ASN, timestamp, signature).
- reachability_receipts: (issuer, target, ASN, timestamp, signature). - Состояние членства — CRDT LWW-Set (добавления/удаления) с TTL (`DHT_MEMBERSHIP_TTL=600` сек), плюс HyperLogLog для оценки мощности (N_local).
- State: LWW-Set for members + receipts, HyperLogLog for population estimate. - Фильтрация «островов»: ноды с `reachability_ratio < q` (по умолчанию `q=0.6`) исключаются при вычислении N_estimate и выборе реплик.
- Island filtering: nodes with `reachability_ratio < q` are excluded (`k=5`, `q=0.6`, TTL=600s). - Итоговая оценка `N_estimate = max(валидных N_local от пиров)`.
- N_estimate: `max(valid N_local reports)` across sufficiently reachable peers.
### Replication & Leases ```mermaid
- Compute prefix `p = max(0, round(log2(N_estimate / R_target)))` with `R_target ≥ 3`. sequenceDiagram
- Responsible nodes: first `p` bits of NodeID equal first `p` bits of ContentID. participant A as Узел A
- Leader = min NodeID among responsible. participant B as Узел B
- Leader maintains `replica_leases` with TTL=600s and diversity: ≥3 IP first octets and ≥3 ASN if available. A->>B: POST /network.handshake {nonce, ts, node, receipts, signature}
- Rendezvous ranking: blake3(ContentID || NodeID) for candidate selection. B->>B: верификация ts/nonce, подписи
- Heartbeat interval 60s, miss threshold 3 → failover within ≤180s. B->>B: upsert member; merge(receipts)
B-->>A: {node, known_public_nodes, n_estimate, server_signature}
A->>A: merge; N_estimate = max(N_local, полученные)
```
### Metrics (Windowed CRDT) ### Репликации и лизы
- On view: PN-Counter for views; HyperLogLog for uniques (ViewID = blake3(ContentID || device_salt)); G-Counter for watch_time, bytes_out, completions. - Выбор префикса: `p = max(0, round(log2(N_estimate / R_target)))`, где `R_target ≥ 3` (по умолчанию 3).
- Keys are windowed by hour; commutative merges ensure deterministic convergence. - Ответственные ноды: чьи первые `p` бит NodeID совпадают с первыми `p` бит ContentID.
- Лидер — минимальный NodeID среди ответственных.
- Лидер выдаёт `replica_leases` (TTL=600 сек), соблюдая разнообразие: не менее 3 разных первых октетов IP и, если доступно, 3 разных ASN.
- Ранжирование кандидатов — rendezvous score `blake3(ContentID || NodeID)`.
- Сердцебиение (heartbeat) держателей — каждые 60 сек; 3 пропуска → признать down и переназначить ≤180 сек.
- Недобор/перебор фиксируются в `conflict_log` и прометеус‑метриках.
```mermaid ```mermaid
stateDiagram-v2 stateDiagram-v2
[*] --> Discover [*] --> Discover
Discover: Handshake + receipts Discover: Рукопожатия + квитанции
Discover --> Active: k ASN receipts & TTL ok Discover --> Active: TTL & кворм ASN
Active --> Leader: Content prefix p elects min NodeID Active --> Leader: Выбор лидера префикса p
Leader --> Leased: Assign replica_leases (diversity) Leader --> Leased: Выдача лизов (diversity)
Leased --> Monitoring: Heartbeats every 60s Leased --> Monitoring: Heartbeat 60s
Monitoring --> Reassign: Missed 3 intervals Monitoring --> Reassign: 3 пропуска
Reassign --> Leased Reassign --> Leased
``` ```
### Метрики (окна)
- На событии просмотра формируются дельты CRDT:
- PNCounter — количество просмотров;
- HyperLogLog — уникальные ViewID (ViewID = blake3(ContentID || соль_устройства));
- GCounter — watch_time, bytes_out, количество завершений.
- Окно по часу (`DHT_METRIC_WINDOW_SEC`), ключ `MetricKey = blake3(ContentID || WindowID)`.
- Мерджи коммутативные, детерминированные.
--- ---
## Upload & Conversion Pipeline ## Загрузка и конвертация контента
1) Client uploads via `tusd` (resumable). Backend receives hooks (`/api/v1/upload.tus-hook`). 1) Клиент грузит в `tusd` (resumable). Бэкенд получает HTTPhooks `/api/v1/upload.tus-hook`.
2) Encrypted content is registered; converter workers derive preview/low/high (for media) or original (for binaries). 2) Создается запись в БД для зашифрованного контента, воркеры размещают производные:
3) Derivative metadata stored in DB and surfaced via `/api/v1/content.view`. - для медиа — preview/low/high;
- для бинарей — оригинал (доступен только при наличии лицензии).
3) `/api/v1/content.view` возвращает `display_options` и агрегированное состояние конвертации/загрузки.
```mermaid ```mermaid
sequenceDiagram sequenceDiagram
participant C as Client participant C as Клиент
participant T as tusd participant T as tusd
participant B as Backend participant B as Бэкенд
participant W as Workers participant W as Воркеры
participant DB as PostgreSQL participant DB as PostgreSQL
C->>T: upload chunks C->>T: upload
T->>B: hooks (pre/post-finish) T->>B: hooks (pre/post-finish)
B->>DB: create content record B->>DB: create content
B->>W: enqueue conversion B->>W: очередь конвертации
W->>DB: store derivatives W->>DB: derive/previews
C->>B: GET /content.view C->>B: GET /content.view
B->>DB: resolve latest derivatives B->>DB: resolve derivatives
B-->>C: display_options + status B-->>C: display_options + status
``` ```
--- ---
## Content View & Purchase Flow ## Просмотр и покупка (UI/UX)
- `/api/v1/content.view/<content_address>` resolves content and derivatives: - `/api/v1/content.view/<content_address>` определяет доступные отображения:
- For binary content without previews: present original only when licensed. - бинарный контент без превью — оригинал только при наличии лицензии;
- For audio/video: use preview/low for unauth; decrypted_low/high for licensed users. - аудио/видео — для неавторизованных preview/low, для имеющих доступ — decrypted_low/high.
- Frontend shows processing state when derivatives are pending. - В процессе конвертации фронтенд показывает статус «processing», без фальшивых ссылок.
- Purchase options (TON/Stars) remain in a single row (UI constraint). - Обложка (cover):
- Cover art layout: fixed square slot; image fits without stretching; background follows page color, not black. - фиксированный квадратный слот; изображение «вписывается» без растягивания/искажения;
- пустые области не заполняются чёрным — фон совпадает с фоном страницы.
- Кнопки «Купить за TON/Stars»: всегда в одной строке (без горизонтального/вертикального скролла контента на малых экранах).
```mermaid ```mermaid
flowchart LR flowchart LR
View[content.view] --> Resolve[Resolve encrypted/decrypted rows] View[content.view] --> Resolve[Определение деривативов]
Resolve --> Derivations{Derivatives ready?} Resolve --> Ready{Готово?}
Derivations -- No --> Status[processing/pending] Ready -- Нет --> Info[Статус: processing/pending]
Derivations -- Yes --> Options Ready -- Да --> Options
Options -- Binary + No License --> Original hidden Options -- Бинарь + нет лицензии --> HideOriginal[Скрыть оригинал]
Options -- Media + No License --> Preview/Low Options -- Медиа + нет лицензии --> PreviewLow[preview/low]
Options -- Licensed --> Decrypted Low/High or Original Options -- Есть лицензия --> Decrypted[decrypted low/high|original]
``` ```
--- ---
## Selected APIs ## API (ключевые)
- `GET /api/system.version` liveness/protocol version. - `GET /api/system.version` — актуальность сервиса.
- `POST /api/v1/network.handshake` signed membership exchange. - `POST /api/v1/network.handshake` — обмен членством (обязательная Ed25519подпись запроса). Пример запроса:
- `GET /api/v1/content.view/<content_address>` resolves display options, status, and downloadability.
- `GET /api/v1.5/storage/<file_hash>` static file access. ```json
- `POST /api/v1/storage` legacy upload endpoint. {
"version": "3.0.0",
"schema_version": "v1",
"public_key": "<base58 ed25519 pubkey>",
"node_id": "<blake3(pubkey)>",
"public_host": "https://node.example",
"node_type": "public|private",
"metrics": {"uptime_sec": 123, "content_count": 42},
"capabilities": {"accepts_inbound": true, "is_bootstrap": false},
"ipfs": {"multiaddrs": ["/ip4/.../tcp/4001"], "peer_id": "..."},
"known_public_nodes": [],
"reachability_receipts": [],
"timestamp": 1710000000,
"nonce": "<hex>",
"signature": "<base58 ed25519 signature>"
}
```
- `GET /api/v1/content.view/<content_address>``display_options`, `status`, `conversion`.
- `GET /api/v1.5/storage/<file_hash>` — отдача файла.
- `GET /metrics` — экспозиция метрик Prometheus (либо fallbackдамп счётчиков).
--- ---
## Data Keys & Schemas ## Ключи и схемы DHT
- MetaKey(content_id): tracks `replica_leases`, `leader`, `conflict_log`, `revision`. - `MetaKey(content_id)` — метаданные репликаций:
- MembershipKey(node_id): LWW-Set of members & receipts, HyperLogLog population, N_reports. - `replica_leases`: карта `{lease_id -> {node_id, issued_at, expires_at, asn, ip_first_octet, heartbeat_at, score}}`;
- MetricKey(content_id, window_id): PN-/G-/HLL serialized state. - `leader`: NodeID лидера; `revision`: номер ревизии;
- `conflict_log`: массив событий `UNDER/OVER/LEASE_EXPIRED` и т.п.
All DHT records are signed and merged via deterministic CRDT strategies + LWW dominance (logical_counter, timestamp, node_id). - `MembershipKey(node_id)` — членство:
- `members`: LWWSet; `receipts`: LWWSet;
- `hll`: HyperLogLog; `reports`: карты локальных оценок N;
- `logical_counter`: логический счётчик для LWWдоминации.
- `MetricKey(content_id, window_id)` — метрики окна:
- `views`: PNCounter; `unique`: HLL; `watch_time`, `bytes_out`, `completions`: GCounters.
Все записи подписываются и сливаются детерминированно: CRDTлогика + LWWдоминация (`logical_counter`, `timestamp`, `node_id`).
--- ---
## Configuration & Defaults ## Конфигурация и значения по умолчанию
- Network: `NODE_PRIVACY`, `PUBLIC_HOST`, `HANDSHAKE_INTERVAL_SEC`, TLS verify, IPFS peering. - Сеть/рукопожатия: `NODE_PRIVACY`, `PUBLIC_HOST`, `HANDSHAKE_INTERVAL_SEC`, `NETWORK_TLS_VERIFY`, IPFSпиры/бустрапы.
- DHT: `DHT_MIN_RECEIPTS=5`, `DHT_MIN_REACHABILITY=0.6`, `DHT_MEMBERSHIP_TTL=600`, `DHT_REPLICATION_TARGET=3`, `DHT_LEASE_TTL=600`, `DHT_HEARTBEAT_INTERVAL=60`, `DHT_HEARTBEAT_MISS_THRESHOLD=3`, `DHT_MIN_ASN=3`, `DHT_MIN_IP_OCTETS=3`, `DHT_METRIC_WINDOW_SEC=3600`. - DHT:
- Conversion resources: `CONVERT_*` limits (CPU/mem), `MAX_CONTENT_SIZE_MB`. - `DHT_MIN_RECEIPTS=5`, `DHT_MIN_REACHABILITY=0.6`, `DHT_MEMBERSHIP_TTL=600`;
- `DHT_REPLICATION_TARGET=3`, `DHT_LEASE_TTL=600`,
- `DHT_HEARTBEAT_INTERVAL=60`, `DHT_HEARTBEAT_MISS_THRESHOLD=3`;
- `DHT_MIN_ASN=3`, `DHT_MIN_IP_OCTETS=3`,
- `DHT_METRIC_WINDOW_SEC=3600`.
- Конвертация: квоты `CONVERT_*`, `MAX_CONTENT_SIZE_MB`.
Примечание: PoWдопуски и Kademlia kbuckets на текущем этапе не активированы в коде — заложены в дизайн и могут быть реализованы отдельно.
--- ---
## Observability & Metrics ## Наблюдаемость и метрики
Prometheus (exported in-process): Prometheus:
- dht_replication_under / dht_replication_over / dht_leader_changes_total - `dht_replication_under_total`, `dht_replication_over_total`, `dht_leader_changes_total`;
- dht_merge_conflicts_total - `dht_merge_conflicts_total`;
- dht_view_count_total / dht_unique_view_estimate / dht_watch_time_seconds - `dht_view_count_total`, `dht_unique_view_estimate`, `dht_watch_time_seconds`.
Logs track replication conflict_log entries and HTTP structured errors (with session_id/error_id). Логи: структурированные ошибки HTTP (с id), `conflict_log` по репликациям, события регистрации нод.
--- ---
## Sequence Diagrams (Consolidated) ## Диаграммы последовательностей (сводные)
### Membership & N_estimate ### Обновление N_estimate
```mermaid ```mermaid
sequenceDiagram sequenceDiagram
participant A as Node A participant Peer
participant B as Node B participant Membership
A->>B: POST /network.handshake {nonce, ts, signature} participant DHT
B->>B: verify ts, nonce, signature Peer->>Membership: handshake(payload, receipts)
B->>B: upsert member; store receipts Membership->>Membership: merge LWW/receipts
B-->>A: {node, known_public_nodes, n_estimate, signature} Membership->>Membership: update HLL и N_local
A->>A: merge; recompute N_estimate = max(N_local, peers) Membership->>DHT: persist MembershipKey
Membership->>Membership: N_estimate = max(valid reports)
``` ```
### Replication Leader Election ### Выбор лидера и выдача лизов
```mermaid ```mermaid
sequenceDiagram sequenceDiagram
participant L as Leader participant L as Leader
participant Peers as Responsible Nodes participant R as Responsible
L->>L: compute p from N_estimate L->>L: p = round(log2(N_est/R))
L->>Peers: rendezvous scores for ContentID L->>R: rank by rendezvous(ContentID, NodeID)
L->>L: assign leases (diversity) L->>L: assign leases (diversity)
Peers-->>L: heartbeat every 60s R-->>L: heartbeat/60s
L->>L: reassign on 3 misses (≤180s) L->>L: reassign on 3 misses
``` ```
### Metrics Publication ### Публикация метрик окна
```mermaid ```mermaid
sequenceDiagram sequenceDiagram
participant C as Client participant C as Client
participant API as Backend participant API as Backend
participant M as MetricsAggregator participant M as Metrics
participant D as DHT participant D as DHT
C->>API: GET content.view?watch_time,bytes_out
C->>API: GET content.view?watch_time&bytes_out
API->>M: record_view(delta) API->>M: record_view(delta)
M->>D: merge MetricKey(ContentID, Window) M->>D: merge MetricKey(ContentID, window)
M->>API: update gauges API-->>Prom: /metrics
``` ```
--- ---
## Run & Test ## Сборка и тестирование
```bash ```bash
# Spin services # Старт окружения (пример для /home/configs)
docker compose -f /home/configs/docker-compose.yml --env-file /home/configs/.env up -d --build docker compose -f /home/configs/docker-compose.yml --env-file /home/configs/.env up -d --build
# Backend unit tests (DHT integration) # Тесты слоя DHT
cd uploader-bot cd uploader-bot
python3 -m unittest discover -s tests/dht python3 -m unittest discover -s tests/dht
``` ```

View File

@ -1,8 +1,8 @@
# Sanic Telegram Bot [template] # Sanic Telegram Bot [template]
See the consolidated system design with protocol, flows, configuration, and diagrams in `ARCHITECTURE.md`. Полная документация по системе (архитектура, протоколы, конфигурация, диаграммы) — см. `ARCHITECTURE.md`.
### Running DHT integration tests ### Запуск тестов интеграции DHT
```shell ```shell
cd uploader-bot cd uploader-bot