# 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 - **Система обновлений:** 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 ` | #### 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 с NaCl-envelopes | | `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`) — без. ### 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 --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 --cosigs pub:sig,pub:sig client admit-sign --key validator.json --target 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 слоя) |