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
This commit is contained in:
vsecoder
2026-04-17 14:16:44 +03:00
commit 7e7393e4f8
196 changed files with 55947 additions and 0 deletions

207
docs/architecture.md Normal file
View File

@@ -0,0 +1,207 @@
# Архитектура 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
```