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
4.0 KiB
Governance интеграция
Нода может использовать governance-контракт для динамического управления параметрами (gas_price и другими) без перезапуска.
Принцип работы
Governance contract (on-chain)
state: param:gas_price = "5"
param:relay_fee = "200"
...
Node (blockchain/chain.go)
GetEffectiveGasPrice() → читает BadgerDB напрямую
GetGovParam(key) → cstate:<govID>:param:<key>
Нода читает параметры напрямую из BadgerDB без вызова VM — это быстро и дёшево.
Привязка governance
При запуске ноды (флаг)
./node \
--key node1.json \
--governance-contract a1b2c3d4e5f60001 \
...
В рантайме (без перезапуска)
curl -X POST http://localhost:8081/api/governance/link \
-H "Content-Type: application/json" \
-d '{"governance": "a1b2c3d4e5f60001"}'
Response:
{"status": "ok", "governance": "a1b2c3d4e5f60001"}
Изменение вступает в силу немедленно — следующий CALL_CONTRACT уже будет использовать новый governance.
Через deploy-скрипт (автоматически)
scripts/deploy_contracts.sh автоматически вызывает link_governance на всех нодах после деплоя:
link_governance() {
for NODE in http://node1:8080 http://node2:8080 http://node3:8080; do
curl -sX POST "$NODE/api/governance/link" \
-H "Content-Type: application/json" \
-d "{\"governance\":\"$GOV_ID\"}"
done
}
Управляемые параметры
| Ключ | Тип | По умолчанию | Описание |
|---|---|---|---|
gas_price |
uint64 (строка) | 1 | µT за 1 gas unit |
Дополнительные параметры можно хранить в governance для читающих их контрактов (например, messenger_entry_fee, relay_fee_override, etc.) — нода их не читает, но они доступны через inter-contract вызовы.
Изменение gas_price
# 1. Любой предлагает новое значение
client call-contract --method propose \
--arg gas_price --arg 5 \
--contract $GOV_ID --key key.json \
--gas 10000 --node http://node1:8080
# 2. Admin утверждает
client call-contract --method approve \
--arg gas_price \
--contract $GOV_ID --key /keys/node1.json \
--gas 10000 --node http://node1:8080
# 3. Проверить текущее значение
curl "http://localhost:8081/api/contracts/$GOV_ID/state/param:gas_price"
После approve — изменение вступает в силу немедленно на всех нодах которые привязали этот governance.
Передача роли admin
# Передать admin другому валидатору
client call-contract --method set_admin \
--arg $NEW_ADMIN_PUBKEY \
--contract $GOV_ID --key /keys/node1.json \
--gas 10000 --node http://node1:8080
Отвязать governance
Если нужно вернуться к значениям по умолчанию:
curl -X POST http://localhost:8081/api/governance/link \
-H "Content-Type: application/json" \
-d '{"governance": ""}'
После этого нода будет использовать встроенные константы (GasPrice = 1 µT/gas).
Проверка привязки
Прямого API для проверки текущего govContractID нет. Косвенно: если gas_price изменился через governance и применился — привязка работает.
# Установить gas_price = 1 через governance
# Затем вызвать контракт с --gas 1000 и проверить fee = 1000 µT