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

10 KiB
Raw Blame History

Архитектура 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