Files
dchain/README.md
vsecoder 1a8731f479 docs: update README + api docs + architecture for v2.0.0 feed
README
  - Mention social feed in the one-line description and feature bullets
  - Add relay + feed endpoint tables to the API overview (was
    previously empty on messaging)
  - List media/ package in the repo structure

docs/api/
  - New docs/api/feed.md: full reference for /feed/publish, fetch,
    stats, view, author, timeline, trending, foryou, hashtag; all
    on-chain CREATE_POST / DELETE_POST / FOLLOW / LIKE payloads;
    fee economics; server-side scrubbing contract.
  - docs/api/relay.md rewritten: /relay/broadcast is now the primary
    E2E path with a complete envelope schema; /relay/send kept but
    flagged ⚠ NOT E2E; DELETE /relay/inbox/{id} documented with the
    new Ed25519 signed-auth body.
  - docs/api/README.md index: added feed.md row.

docs/architecture.md
  - L2 Transport layer description updated to include the feed
    mailbox alongside the 1:1 relay mailbox.
  - New "Социальная лента (v2.0.0)" section right after the 1:1
    message flow: ASCII diagram of publish + on-chain commit +
    timeline fetch, economic summary, metadata-scrub summary.

docs/node/README.md
  - Removed stale chan:/chan-member: keys from the BadgerDB schema
    reference; replaced with the v2.0.0 feed keys (post:,
    postbyauthor:, follow:, followin:, like:, likecount:).

docs/update-system.md
  - Example features[] array updated to match the actual node output
    (channels_v1 removed, feed_v2 / media_scrub / relay_broadcast added).

Node feature flags
  - api_well_known_version.go: dropped channels_v1 tag (the
    /api/channels/:id endpoint was removed in the feed refactor);
    added feed_v2, media_scrub, relay_broadcast so clients can
    feature-detect the v2.0.0 surface.
  - Comment example updated channels_v2/v1 → feed_v3/v2.

Client
  - CLIENT_REQUIRED_FEATURES expanded to include the v2.0.0 feature
    flags the client now depends on (feed_v2, media_scrub,
    relay_broadcast); checkNodeVersion() will flag older nodes as
    unsupported and surface an upgrade prompt.

All 7 Go test packages green; tsc --noEmit clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 22:06:06 +03:00

291 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DChain
Блокчейн-стек для децентрализованного мессенджера + социальной ленты:
- **PBFT** консенсус с multi-sig validator governance и equivocation slashing
- **Native Go контракты** рядом с WASM (wazero) — нулевая задержка для
системных сервисов типа `username_registry`
- **WebSocket push API** — клиент не опрашивает, все события прилетают
на соединение
- **E2E-шифрованный relay mailbox** на libp2p gossipsub с TTL live-detection
(1:1 чаты через NaCl box; посты в ленте — plaintext-публичные)
- **Социальная лента v2.0.0** (заменила каналы): публичные посты
с оплатой за размер (автор платит, хостящая релей-нода получает);
on-chain граф подписок + лайки; off-chain просмотры + хэштеги;
мандаторный server-side scrubber метаданных (EXIF/GPS-стрип + FFmpeg
sidecar для видео); share-to-chat c embedded post-карточкой
- **Система обновлений:** build-time версия → `/api/well-known-version`,
peer-version gossip, `/api/update-check` против Gitea releases,
`update.sh` с semver guard
- **Prometheus `/metrics`**, Caddy auto-HTTPS, observer mode, load-test
## Содержание
- [Быстрый старт](#быстрый-старт)
- [Продакшен деплой](#продакшен-деплой)
- [Архитектура](#архитектура)
- [REST / WebSocket API](#rest--websocket-api)
- [CLI](#cli)
- [Мониторинг](#мониторинг)
- [Тесты](#тесты)
- [Документация](#документация)
---
## Быстрый старт
Одна нода в Docker, HTTP API на `localhost:8080`, Explorer UI и Swagger
открыты:
```bash
# 1. Собираем prod-образ
docker build -t dchain-node-slim -f deploy/prod/Dockerfile.slim .
# 2. Ключ ноды (один раз)
mkdir -p keys
docker run --rm --entrypoint /usr/local/bin/client \
-v "$PWD/keys:/out" dchain-node-slim \
keygen --out /out/node.json
# 3. Запуск (genesis-валидатор)
docker run -d --name dchain --restart unless-stopped \
-p 4001:4001 -p 8080:8080 \
-v dchain_data:/data \
-v "$PWD/keys:/keys:ro" \
-e DCHAIN_GENESIS=true \
-e DCHAIN_ANNOUNCE=/ip4/127.0.0.1/tcp/4001 \
dchain-node-slim \
--db=/data/chain --mailbox-db=/data/mailbox --key=/keys/node.json \
--relay-key=/data/relay.json --listen=/ip4/0.0.0.0/tcp/4001 --stats-addr=:8080
# 4. Проверка
open http://localhost:8080/ # Explorer
open http://localhost:8080/swagger # Swagger UI
curl -s http://localhost:8080/api/well-known-version | jq .
```
3-node dev-кластер (для тестов PBFT кворума, slashing, federation): `docker compose up --build -d` — см. [`docs/quickstart.md`](docs/quickstart.md).
## Продакшен деплой
Два варианта, по масштабу.
### 🔸 Single-node (`deploy/single/`)
**Рекомендуется для личного/первого узла.** Один узел + Caddy TLS +
опциональный Prometheus. Полный runbook с 6 сценариями (публичная с UI,
headless, полностью приватная, genesis, joiner, auto-update) — в
[`deploy/single/README.md`](deploy/single/README.md).
#### Модели доступа
| Режим | `DCHAIN_API_TOKEN` | `DCHAIN_API_PRIVATE` | Поведение |
|-------|:------------------:|:--------------------:|-----------|
| Public (default) | не задан | — | Все могут читать и писать |
| Token writes | задан | `false` | Читать — любой; submit tx — только с токеном |
| Fully private | задан | `true` | Всё требует `Authorization: Bearer <token>` |
#### UI / Swagger — включать или нет?
| Нужно | `DCHAIN_DISABLE_UI` | `DCHAIN_DISABLE_SWAGGER` | Открыто |
|-------|:-------------------:|:------------------------:|---------|
| Публичная с эксплорером + docs | не задано | не задано | `/` Explorer, `/swagger`, `/api/*`, `/metrics` |
| Headless API-нода с OpenAPI | `true` | не задано | `/swagger`, `/api/*`, `/metrics` |
| Личная hardened | `true` | `true` | `/api/*` + `/metrics` |
Флаги читаются и из CLI (`--disable-ui`, `--disable-swagger`), и из env.
`/api/*` JSON-поверхность регистрируется всегда — отключить её можно
только на уровне Caddy / firewall.
#### Auto-update
```ini
# node.env — когда проект в Gitea
DCHAIN_UPDATE_SOURCE_URL=https://gitea.example.com/api/v1/repos/OWNER/REPO/releases/latest
UPDATE_ALLOW_MAJOR=false
```
```bash
# Hourly systemd timer с 15-мин jitter
sudo cp deploy/single/systemd/dchain-update.{service,timer} /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now dchain-update.timer
```
Подробно: [`docs/update-system.md`](docs/update-system.md) + [`deploy/UPDATE_STRATEGY.md`](deploy/UPDATE_STRATEGY.md).
### 🔹 Multi-validator (`deploy/prod/`)
3 validator'а в PBFT-кворуме, Caddy с `ip_hash` для WS-стикинесса и
`least-conn` для REST. Для федераций / консорциумов — см.
[`deploy/prod/README.md`](deploy/prod/README.md) и
[`docs/node/multi-server.md`](docs/node/multi-server.md).
## Архитектура
```
┌────────────┐ libp2p ┌────────────┐ libp2p ┌────────────┐
│ node-A │◄─────pubsub──►│ node-B │◄─────pubsub──►│ node-C │
│ validator │ │ validator │ │ validator │
│ + relay │ │ + relay │ │ + relay │
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘
│ │ │
│ HTTPS / wss (via Caddy) │ │
▼ ▼ ▼
mobile / web / CLI clients (ip_hash для WS, least-conn для REST)
```
Четыре слоя: network → chain → transport → app. Детали — в
[`docs/architecture.md`](docs/architecture.md).
Основные пакеты:
| Путь | Роль |
|------|------|
| `blockchain/` | Блочная машина, applyTx, native-контракты, schema-migrations |
| `consensus/` | PBFT (Pre-prepare → Prepare → Commit), мемпул, equivocation |
| `p2p/` | libp2p host, gossipsub, sync протокол, peer-version gossip |
| `node/` | HTTP + WS API, SSE, metrics, access control |
| `node/version/` | Build-time version metadata (ldflags-инжектимый) |
| `vm/` | wazero runtime для WASM-контрактов + gas model |
| `relay/` | E2E mailbox (1:1 envelopes) + public feed-mailbox (post bodies, view counter, hashtag index) |
| `media/` | Server-side metadata scrubber (EXIF strip + FFmpeg sidecar client) |
| `identity/` | Ed25519 + X25519 keypair, tx signing |
| `economy/` | Fee model, rewards |
| `wallet/` | Optional payout wallet (отдельный ключ) |
## REST / WebSocket API
Обзор (полный reference — [`docs/api/README.md`](docs/api/README.md)):
### Chain + stats
| Endpoint | Описание |
|----------|----------|
| `GET /api/netstats` | height, total_txs, supply, validator_count |
| `GET /api/network-info` | chain_id, genesis, peers, validators, contracts |
| `GET /api/blocks?limit=N` / `/api/block/{index}` | Блоки |
| `GET /api/tx/{id}` / `/api/txs/recent?limit=N` | Транзакции |
| `GET /api/address/{pub_or_addr}` | Баланс + история |
| `GET /api/validators` | Validator set |
| `GET /api/peers` | Connected peers + их версии |
| `POST /api/tx` | Submit signed tx (rate-limited, size-capped) |
### Discovery + update
| Endpoint | Описание |
|----------|----------|
| `GET /api/well-known-version` | `{node_version, build{}, protocol_version, features[], chain_id}` |
| `GET /api/well-known-contracts` | `{name → contract_id}` map |
| `GET /api/update-check` | Diff с Gitea release (см. [`docs/update-system.md`](docs/update-system.md)) |
### Real-time
- `GET /api/ws`**WebSocket** (recommended). Ops: `auth`, `subscribe`,
`unsubscribe`, `submit_tx`, `typing`, `ping`. Push: `block`, `tx`,
`inbox`, `typing`, `submit_ack`.
- `GET /api/events` — SSE legacy one-way.
Scoped WS-топики (`addr:`, `inbox:`, `typing:`) требуют auth через
Ed25519-nonce; публичные (`blocks`, `tx`, `contract_log`) — без.
### Relay (E2E messaging)
| Endpoint | Описание |
|----------|----------|
| `POST /relay/broadcast` | Опубликовать pre-sealed envelope (E2E-путь, рекомендован) |
| `GET /relay/inbox?pub=<x25519>` | Прочитать входящие конверты |
| `DELETE /relay/inbox/{id}` | Удалить envelope (требует Ed25519-подписи владельца) |
Детали — [`docs/api/relay.md`](docs/api/relay.md). `/relay/send` оставлен
для backward-compat, но ломает E2E (nod-релей запечатывает своим ключом)
и помечен как non-recommended.
### Social feed (v2.0.0)
| Endpoint | Описание |
|----------|----------|
| `POST /feed/publish` | Загрузить тело поста + EXIF-скраб + вернуть fee |
| `GET /feed/post/{id}` | Тело поста |
| `GET /feed/post/{id}/attachment` | Сырые байты картинки/видео (cache'able) |
| `GET /feed/post/{id}/stats?me=<pub>` | `{views, likes, liked_by_me?}` |
| `POST /feed/post/{id}/view` | Бамп off-chain счётчика просмотров |
| `GET /feed/author/{pub}?before=<ts>&limit=N` | Посты автора (пагинация `before`) |
| `GET /feed/timeline?follower=<pub>&before=<ts>&limit=N` | Merged лента подписок |
| `GET /feed/trending?window=24&limit=N` | Топ по `likes × 3 + views` за окно |
| `GET /feed/foryou?pub=<pub>&limit=N` | Рекомендации (неподписанные авторы) |
| `GET /feed/hashtag/{tag}?limit=N` | Посты по хэштегу |
Детали + спецификация — [`docs/api/feed.md`](docs/api/feed.md).
### Docs / UI
- `GET /swagger`**Swagger UI** (рендерится через swagger-ui-dist).
- `GET /swagger/openapi.json` — сырая OpenAPI 3.0 спека.
- `GET /` — block-explorer HTML (выключается `DCHAIN_DISABLE_UI=true`).
## CLI
```bash
client keygen --out key.json
client --version # → dchain-client vX.Y.Z (commit=... date=...)
client balance --key key.json --node URL
client transfer --key key.json --to <pub> --amount <µT> --node URL
client call-contract --key key.json --contract native:username_registry \
--method register --arg alice --amount 10000 \
--node URL
client add-validator --key key.json --target <pub> --cosigs pub:sig,pub:sig
client admit-sign --key validator.json --target <candidate-pub>
client deploy-contract --key key.json --wasm ./my.wasm --abi ./my_abi.json --node URL
# полный список — `client` без аргументов, или в docs/cli/README.md
```
Все флаги `node` — в [`docs/node/README.md`](docs/node/README.md), либо
`node --help`.
## Мониторинг
Prometheus endpoint `/metrics` на каждой ноде. Ключевые метрики:
```
dchain_blocks_total # committed blocks count
dchain_txs_total # tx count
dchain_tx_submit_accepted_total
dchain_tx_submit_rejected_total
dchain_ws_connections # current WS sockets
dchain_peer_count_live # live libp2p peer count
dchain_max_missed_blocks # worst validator liveness gap
dchain_block_commit_seconds # histogram of AddBlock time
```
Grafana + Prometheus поднимаются вместе с нодой через
`docker compose --profile monitor up -d` (см. `deploy/single/docker-compose.yml`).
## Тесты
```bash
# Unit + integration
go test ./... # blockchain + consensus + identity + relay + vm
go vet ./... # static checks
# End-to-end load (3-node dev cluster должен быть поднят):
docker compose up --build -d
go run ./cmd/loadtest \
--node http://localhost:8081 \
--funder testdata/node1.json \
--clients 50 --duration 60s
```
## Документация
Полный справочник в `docs/` — см. [`docs/README.md`](docs/README.md) как
оглавление. Ключевые документы:
| Документ | О чём |
|----------|-------|
| [`docs/quickstart.md`](docs/quickstart.md) | Три пути: локально, single-node prod, федерация |
| [`docs/architecture.md`](docs/architecture.md) | 4 слоя, consensus, storage, gas model |
| [`docs/update-system.md`](docs/update-system.md) | Versioning + update-check + semver guard |
| [`docs/api/README.md`](docs/api/README.md) | REST + WebSocket reference |
| [`docs/cli/README.md`](docs/cli/README.md) | CLI команды и флаги |
| [`docs/node/README.md`](docs/node/README.md) | Запуск ноды (native + Docker) |
| [`docs/contracts/README.md`](docs/contracts/README.md) | Системные + WASM контракты |
| [`docs/development/README.md`](docs/development/README.md) | SDK для своих контрактов |
| [`deploy/single/README.md`](deploy/single/README.md) | Single-node operator runbook |
| [`deploy/prod/README.md`](deploy/prod/README.md) | Multi-validator federation |
| [`deploy/UPDATE_STRATEGY.md`](deploy/UPDATE_STRATEGY.md) | Forward-compat design (4 слоя) |