Files
dchain/docs/architecture.md
vsecoder 7e7393e4f8 chore: initial commit for v0.0.1
DChain single-node blockchain + React Native messenger client.

Core:
- PBFT consensus with multi-sig validator admission + equivocation slashing
- BadgerDB + schema migration scaffold (CurrentSchemaVersion=0)
- libp2p gossipsub (tx/v1, blocks/v1, relay/v1, version/v1)
- Native Go contracts (username_registry) alongside WASM (wazero)
- WebSocket gateway with topic-based fanout + Ed25519-nonce auth
- Relay mailbox with NaCl envelope encryption (X25519 + Ed25519)
- Prometheus /metrics, per-IP rate limit, body-size cap

Deployment:
- Single-node compose (deploy/single/) with Caddy TLS + optional Prometheus
- 3-node dev compose (docker-compose.yml) with mocked internet topology
- 3-validator prod compose (deploy/prod/) for federation
- Auto-update from Gitea via /api/update-check + systemd timer
- Build-time version injection (ldflags → node --version)
- UI / Swagger toggle flags (DCHAIN_DISABLE_UI, DCHAIN_DISABLE_SWAGGER)

Client (client-app/):
- Expo / React Native / NativeWind
- E2E NaCl encryption, typing indicator, contact requests
- Auto-discovery of canonical contracts, chain_id aware, WS reconnect on node switch

Documentation:
- README.md, CHANGELOG.md, CONTEXT.md
- deploy/single/README.md with 6 operator scenarios
- deploy/UPDATE_STRATEGY.md with 4-layer forward-compat design
- docs/contracts/*.md per contract
2026-04-17 14:16:44 +03:00

208 lines
10 KiB
Markdown
Raw 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
## Обзор
DChain — это L1-блокчейн для децентрализованного мессенджера. Архитектура разделена на четыре слоя:
```
┌─────────────────────────────────────────────────────────────┐
│ L3 Application — messaging, usernames, auctions, escrow │
│ (Smart contracts: username_registry, governance, auction, │
│ escrow; deployed on-chain via DEPLOY_CONTRACT) │
├─────────────────────────────────────────────────────────────┤
│ L2 Transport — relay mailbox, E2E NaCl encryption │
│ (relay/, mailbox, GossipSub envelopes, RELAY_PROOF tx) │
├─────────────────────────────────────────────────────────────┤
│ L1 Chain — PBFT consensus, WASM VM, BadgerDB │
│ (blockchain/, consensus/, vm/, identity/) │
├─────────────────────────────────────────────────────────────┤
│ L0 Network — libp2p, GossipSub, DHT, mDNS │
│ (p2p/) │
└─────────────────────────────────────────────────────────────┘
```
---
## Консенсус (PBFT)
**Алгоритм:** Practical Byzantine Fault Tolerance, кворум 2/3.
**Фазы:**
```
Leader Validator-2 Validator-3
│── PRE-PREPARE ──▶│ │
│── PRE-PREPARE ────────────────────────▶ │
│◀─ PREPARE ───────│ │
│◀─ PREPARE ────────────────────────────── │
│── COMMIT ────────▶│ │
│── COMMIT ──────────────────────────────▶ │
│◀─ COMMIT ────────│ │
│◀─ COMMIT ────────────────────────────── │
AddBlock()
```
**Свойства:**
- Safety при ≤ f Byzantine нодах где N ≥ 3f+1
- Текущий testnet: N=2 валидатора, f=0 (узел node3 — relay-only observer)
- View-change при недоступном лидере: таймаут 10 секунд
**Блок-производство:**
- Fast ticker (500 ms) — при наличии транзакций в mempool
- Idle ticker (5 s) — пустые блоки для heartbeat и синхронизации
**Ключевые файлы:**
```
consensus/engine.go — PBFT engine
consensus/msg.go — ConsensusMsg типы (PRE-PREPARE, PREPARE, COMMIT, VIEW-CHANGE)
```
---
## Хранилище (BadgerDB)
Весь state хранится в BadgerDB (LSM-дерево, pure Go).
**Пространства ключей:**
| Префикс | Тип | Описание |
|---------|-----|---------|
| `block:<index_20d>` | JSON | Блоки по индексу |
| `height` | uint64 JSON | Текущая высота |
| `balance:<pubkey>` | uint64 JSON | Балансы токенов |
| `id:<pubkey>` | JSON | Identity (RegisterKey payload) |
| `validator:<pubkey>` | presence | Активный сет валидаторов |
| `relay:<pubkey>` | JSON | Зарегистрированные relay-ноды |
| `contract:<id>` | JSON | ContractRecord (метаданные + WASM) |
| `cstate:<id>:<key>` | raw bytes | Состояние контракта |
| `clog:<id>:<height_20d>:<seq_05d>` | JSON | Логи контракта |
| `rep:<pubkey>` | JSON | Репутация (blocks, relays, slashes) |
| `contact_in:<to>:<from>` | JSON | Входящие contact requests |
| `mail:<x25519>:<ts>:<id>` | JSON | Relay mailbox (TTL 7 дней) |
**Две отдельные БД:**
- `--db ./chaindata` — chain state (consensus state machine)
- `--mailbox-db ./mailboxdata` — relay mailbox (отдельная изоляция)
---
## P2P сеть (libp2p)
**Компоненты:**
- **Transport:** TCP `/ip4/0.0.0.0/tcp/4001`
- **Identity:** Ed25519 peer key (вывод из node identity)
- **Discovery:** mDNS (локалка) + Kademlia DHT (WAN)
- **Pub/Sub:** GossipSub с тремя топиками:
| Топик | Содержимое |
|-------|-----------|
| `dchain/tx/v1` | Транзакции (gossip) |
| `dchain/blocks/v1` | Готовые блоки (gossip от лидера) |
| `dchain/relay/v1` | Relay envelopes (зашифрованные сообщения) |
- **Direct streams:** PBFT consensus messages (pre-prepare/prepare/commit/view-change) идут напрямую между валидаторами через `/dchain/consensus/1.0.0` протокол
- **Sync:** block range sync по `/dchain/sync/1.0.0` при подключении нового пира
---
## WASM Virtual Machine
**Runtime:** wazero v1.7.3, interpreter mode (детерминированный на всех платформах).
**Жизненный цикл контракта:**
```
DEPLOY_CONTRACT tx
├── validate: wazero.CompileModule() — если ошибка, tx отклоняется
├── contractID = hex(sha256(deployerPubKey || wasmBytes))[:16]
├── BadgerDB: contract:<id> → ContractRecord{WASMBytes, ABI, ...}
└── state: cstate:<id>:* — изначально пусто
CALL_CONTRACT tx
├── ABI validation: метод существует, число аргументов совпадает
├── pre-charge: tx.Fee + gasLimit × gasPrice
├── vm.Call(contractID, wasmBytes, method, argsJSON, gasLimit, hostEnv)
│ ├── compile (cached) + instrument (gas_tick в loop headers)
│ ├── register "env" host module (14 функций)
│ ├── [optional] wasi_snapshot_preview1 (для TinyGo контрактов)
│ └── fn.Call(ctx) → gasUsed, error
├── refund: (gasLimit - gasUsed) × gasPrice → обратно sender
└── logs: clog:<id>:<height>:<seq> → BadgerDB
```
**Gas модель:** каждый вызов функции (WASM или host) = 100 gas units.
`gasCost (µT) = gasUsed × gasPrice` (gasPrice управляется governance или константа 1 µT).
**Типы контрактов:**
- **Binary WASM** — написаны на Go через кодогенераторы (`contracts/*/gen/main.go`)
- **TinyGo WASM** — написаны на Go, компилируются с `tinygo -target wasip1`
---
## Экономика
**Supply:** Фиксированный. Genesis-блок минтит **21 000 000 T** на ключ node1. Последующей эмиссии нет.
**Unit:** µT (микро-токен). 1 T = 1 000 000 µT.
**Доходы валидаторов:** только комиссии из транзакций блока (`TotalFees`). Без блок-реварда.
**Комиссии:**
| Операция | Минимальная fee |
|---------|----------------|
| Все транзакции | 1 000 µT (MinFee) |
| CONTACT_REQUEST | tx.Amount → recipient (anti-spam) |
| DEPLOY_CONTRACT | 10 000 µT |
| CALL_CONTRACT | MinFee + gasUsed × gasPrice |
| RELAY_PROOF | sender → relay node (произвольно) |
**Governance:** gas_price, relay_fee и другие параметры можно менять on-chain через governance-контракт без хардфорка.
---
## Relay (E2E мессенджер)
**Шифрование:** NaCl box (X25519 Diffie-Hellman + XSalsa20 + Poly1305).
**Ключи:** каждый Identity имеет два ключа:
- Ed25519 (подпись транзакций, chain identity)
- X25519 (вывод из Ed25519 seed, шифрование сообщений)
**Поток сообщения:**
```
Alice node1 (relay) Bob
│ │ │
│── seal(msg, bob.X25519) ──▶ │ │
│ POST /relay/broadcast │ │
│ │── gossip envelope ──▶ │
│ │ store mailbox │
│ │ (TTL 7 days) │
│ │ │
│ │◀── GET /relay/inbox ──│
│ │ │── open(envelope)
│ │ │ → plaintext
```
**Anti-spam:**
- Первый контакт — платный (CONTACT_REQUEST tx, fee идёт получателю)
- Envelope: max 64 KB, max 500 envelopes на получателя (FIFO)
- RELAY_PROOF: подписанное доказательство доставки, fee снимается со sender и кредитуется relay
---
## Динамические валидаторы
Сет валидаторов хранится on-chain в `validator:<pubkey>`. Любой текущий валидатор может добавить или убрать другого (ADD_VALIDATOR / REMOVE_VALIDATOR tx). После commit такого блока PBFT-движок перезагружает сет без рестарта ноды.
**Ключевые файлы:**
```
blockchain/chain.go — state machine, applyTx, VMHostEnv
consensus/engine.go — PBFT, UpdateValidators()
vm/vm.go — wazero runtime, NewVM()
vm/host.go — host module "env" (14 функций)
vm/gas.go — gas counter, Remaining()
relay/mailbox.go — BadgerDB TTL mailbox
relay/crypto.go — NaCl seal/open
p2p/host.go — libp2p host, GossipSub
node/api_routes.go — HTTP API routing
```