chore(release): clean up repo for v0.0.1 release
Excluded from release bundle:
- CONTEXT.md, CHANGELOG.md (agent/project working notes)
- client-app/ (React Native messenger — tracked separately)
- contracts/hello_go/ (unused standalone example)
Kept contracts/counter/ and contracts/name_registry/ as vm-test fixtures
(referenced by vm/vm_test.go; NOT production contracts).
Docs refactor:
- docs/README.md — new top-level index with cross-references
- docs/quickstart.md — rewrite around single-node as primary path
- docs/node/README.md — full rewrite, all CLI flags, schema table
- docs/api/README.md — add /api/well-known-version, /api/update-check
- docs/contracts/README.md — split native (Go) vs WASM (user-deployable)
- docs/update-system.md — new, full 5-layer update system design
- README.md — link into docs/, drop CHANGELOG/client-app references
Build-time version system (inherited from earlier commits this branch):
- node --version / client --version with ldflags-injected metadata
- /api/well-known-version with {build, protocol_version, features[]}
- Peer-version gossip on dchain/version/v1
- /api/update-check against Gitea release API
- deploy/single/update.sh with semver guard + 15-min systemd jitter
This commit is contained in:
@@ -1,219 +1,182 @@
|
||||
# Запуск ноды
|
||||
|
||||
## Быстрый старт (Docker)
|
||||
Три основных сценария — по возрастанию сложности.
|
||||
|
||||
| Сценарий | Где подробно |
|
||||
|----------|--------------|
|
||||
| **Одна нода локально (dev, genesis)** | [../quickstart.md](../quickstart.md) → Путь 1 |
|
||||
| **Одна нода с TLS и доменом (production personal)** | [../../deploy/single/README.md](../../deploy/single/README.md) |
|
||||
| **Multi-validator federation (3+ нод, PBFT quorum)** | [../../deploy/prod/README.md](../../deploy/prod/README.md) + [multi-server.md](multi-server.md) |
|
||||
|
||||
Этот документ — про native запуск (не через docker) и обзор всех флагов.
|
||||
|
||||
## Native build
|
||||
|
||||
Требования:
|
||||
- Go 1.24+
|
||||
- BadgerDB + libp2p встроены в бинарь (no-cgo, `CGO_ENABLED=0`)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/your/go-blockchain
|
||||
cd go-blockchain
|
||||
docker compose up -d
|
||||
go build -ldflags "-s -w \
|
||||
-X go-blockchain/node/version.Tag=$(git describe --tags --always --dirty) \
|
||||
-X go-blockchain/node/version.Commit=$(git rev-parse HEAD) \
|
||||
-X go-blockchain/node/version.Date=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
|
||||
-X go-blockchain/node/version.Dirty=$(git diff --quiet HEAD -- && echo false || echo true)" \
|
||||
-o node ./cmd/node
|
||||
|
||||
./node --version
|
||||
# dchain-node v0.0.1 (commit=abc1234 date=… dirty=false)
|
||||
```
|
||||
|
||||
Запускает 3 ноды: `node1` (8081), `node2` (8082), `node3` (8083).
|
||||
Ldflags не обязательны — без них версия будет "dev". Makefile в корне
|
||||
инкапсулирует это: `make build`.
|
||||
|
||||
Деплой контрактов:
|
||||
```bash
|
||||
docker exec node1 /scripts/deploy_contracts.sh
|
||||
```
|
||||
## Single node (genesis)
|
||||
|
||||
Explorer: http://localhost:8081
|
||||
|
||||
---
|
||||
|
||||
## Запуск вручную
|
||||
|
||||
### Требования
|
||||
|
||||
- Go 1.21+
|
||||
- BadgerDB (встроен)
|
||||
- libp2p (встроен)
|
||||
|
||||
### Сборка
|
||||
Сгенерировать ключ и поднять блок 0 с собой как единственным валидатором:
|
||||
|
||||
```bash
|
||||
cd go-blockchain
|
||||
go build ./cmd/node/
|
||||
go build ./cmd/client/
|
||||
```
|
||||
./node --version # проверка
|
||||
./client keygen --out node.json
|
||||
|
||||
### Genesis нода
|
||||
|
||||
```bash
|
||||
# Первый запуск — создать genesis
|
||||
./node \
|
||||
--key node1.json \
|
||||
--key node.json \
|
||||
--db ./data \
|
||||
--genesis \
|
||||
--validators "$(cat node1.json | jq -r .pub_key),$(cat node2.json | jq -r .pub_key),$(cat node3.json | jq -r .pub_key)" \
|
||||
--stats-addr :8081 \
|
||||
--listen /ip4/0.0.0.0/tcp/4001 \
|
||||
--db ./data/node1
|
||||
--stats-addr :8080
|
||||
```
|
||||
|
||||
### Peer нода
|
||||
После первого успешного запуска удалите `--genesis` (no-op, но шумит в логах).
|
||||
|
||||
## Join existing network
|
||||
|
||||
Зная URL хотя бы одной живой ноды:
|
||||
|
||||
```bash
|
||||
./node \
|
||||
--key node2.json \
|
||||
--peers /ip4/127.0.0.1/tcp/4001/p2p/<node1-peer-id> \
|
||||
--stats-addr :8082 \
|
||||
--listen /ip4/0.0.0.0/tcp/4002 \
|
||||
--db ./data/node2
|
||||
--key node.json \
|
||||
--db ./data \
|
||||
--join http://seed1.example.com:8080,http://seed2.example.com:8080 \
|
||||
--listen /ip4/0.0.0.0/tcp/4001 \
|
||||
--stats-addr :8080
|
||||
```
|
||||
|
||||
---
|
||||
Нода скачает `/api/network-info`, подхватит chain_id, genesis_hash, список
|
||||
валидаторов и peer multiaddrs. По умолчанию запускается как **observer**
|
||||
(применяет блоки, принимает tx, но не голосует). Чтобы стать валидатором,
|
||||
существующий валидатор должен подать `ADD_VALIDATOR` tx с multi-sig.
|
||||
|
||||
## Флаги командной строки
|
||||
## Все флаги
|
||||
|
||||
| Флаг | По умолчанию | Описание |
|
||||
|------|------------|---------|
|
||||
| `--key` | `node.json` | Файл Ed25519 + X25519 идентичности |
|
||||
| `--db` | `chaindata` | Директория BadgerDB |
|
||||
| `--listen` | `/ip4/0.0.0.0/tcp/4001` | libp2p адрес |
|
||||
| `--peers` | — | Bootstrap peer multiaddrs (через запятую) |
|
||||
| `--validators` | — | Pubkeys валидаторов (через запятую, только для `--genesis`) |
|
||||
| `--genesis` | false | Создать genesis блок при первом старте |
|
||||
| `--stats-addr` | `:8080` | HTTP API/Explorer порт |
|
||||
| `--wallet` | — | Payout кошелёк (hex pubkey) |
|
||||
| `--wallet-pass` | — | Пароль к кошельку |
|
||||
| `--heartbeat` | false | Отправлять heartbeat каждые 60 минут |
|
||||
| `--register-relay` | false | Зарегистрироваться как relay-провайдер |
|
||||
| `--relay-fee` | 0 | Fee за relay сообщение в µT |
|
||||
| `--relay-key` | `relay.json` | X25519 ключ для relay шифрования |
|
||||
| `--mailbox-db` | — | Директория для relay mailbox |
|
||||
| `--governance-contract` | — | ID governance контракта для динамических параметров |
|
||||
Каждый флаг имеет env fallback (`DCHAIN_<FLAG_NAME>` в UPPERCASE с
|
||||
заменой `-` на `_`).
|
||||
|
||||
---
|
||||
### Идентичность
|
||||
| Флаг | env | По умолчанию | Описание |
|
||||
|------|-----|--------------|----------|
|
||||
| `--key` | `DCHAIN_KEY` | `node.json` | Ed25519 + X25519 identity file |
|
||||
| `--db` | `DCHAIN_DB` | `chaindata` | BadgerDB directory |
|
||||
|
||||
## Docker Compose
|
||||
### Сеть
|
||||
| Флаг | env | По умолчанию | Описание |
|
||||
|------|-----|--------------|----------|
|
||||
| `--listen` | `DCHAIN_LISTEN` | `/ip4/0.0.0.0/tcp/4001` | libp2p listen multiaddr |
|
||||
| `--announce` | `DCHAIN_ANNOUNCE` | auto | Что анонсировать пирам (публичный IP!) |
|
||||
| `--peers` | `DCHAIN_PEERS` | — | Bootstrap peers (comma-sep multiaddrs) |
|
||||
| `--join` | `DCHAIN_JOIN` | — | Seed HTTP URLs для onboarding |
|
||||
|
||||
### docker-compose.yml структура
|
||||
### Консенсус
|
||||
| Флаг | env | По умолчанию | Описание |
|
||||
|------|-----|--------------|----------|
|
||||
| `--genesis` | `DCHAIN_GENESIS` | false | Создать block 0 при первом старте |
|
||||
| `--validators` | `DCHAIN_VALIDATORS` | — | Initial validator set (для `--genesis`) |
|
||||
| `--observer` | `DCHAIN_OBSERVER` | false | Observer mode (не голосовать) |
|
||||
| `--allow-genesis-mismatch` | — | false | Пропустить safety check (опасно) |
|
||||
|
||||
```yaml
|
||||
services:
|
||||
node1:
|
||||
build: .
|
||||
ports:
|
||||
- "8081:8080" # HTTP API
|
||||
- "4001:4001" # libp2p
|
||||
volumes:
|
||||
- node1_data:/chaindata
|
||||
- ./keys:/keys:ro
|
||||
command: >
|
||||
node
|
||||
--key /keys/node1.json
|
||||
--genesis
|
||||
--validators "$VALIDATORS"
|
||||
--stats-addr :8080
|
||||
--listen /ip4/0.0.0.0/tcp/4001
|
||||
--governance-contract "$GOV_ID"
|
||||
environment:
|
||||
- VALIDATORS=03...,04...,05...
|
||||
### Relay
|
||||
| Флаг | env | По умолчанию | Описание |
|
||||
|------|-----|--------------|----------|
|
||||
| `--register-relay` | `DCHAIN_REGISTER_RELAY` | false | Подать REGISTER_RELAY tx при старте |
|
||||
| `--relay-fee` | — | 1000 | Fee за relay envelope, µT |
|
||||
| `--relay-key` | — | `relay.json` | X25519 key для E2E шифрования envelope |
|
||||
| `--mailbox-db` | — | — | Badger dir для offline-получателей |
|
||||
|
||||
node2:
|
||||
build: .
|
||||
ports:
|
||||
- "8082:8080"
|
||||
command: >
|
||||
node
|
||||
--key /keys/node2.json
|
||||
--peers /dns4/node1/tcp/4001/p2p/$NODE1_PEER_ID
|
||||
--stats-addr :8080
|
||||
--listen /ip4/0.0.0.0/tcp/4001
|
||||
```
|
||||
### Governance / misc
|
||||
| Флаг | env | По умолчанию | Описание |
|
||||
|------|-----|--------------|----------|
|
||||
| `--governance-contract` | `DCHAIN_GOVERNANCE_CONTRACT` | — | ID governance контракта |
|
||||
| `--heartbeat` | — | false | Слать heartbeat tx каждые 60 мин |
|
||||
| `--log-format` | `DCHAIN_LOG_FORMAT` | `text` | `text` или `json` |
|
||||
|
||||
### Управление
|
||||
### HTTP / WebSocket / UI
|
||||
| Флаг | env | По умолчанию | Описание |
|
||||
|------|-----|--------------|----------|
|
||||
| `--stats-addr` | — | `:8080` | HTTP + WS listen address |
|
||||
| `--disable-ui` | `DCHAIN_DISABLE_UI` | false | Выключить блок-эксплорер HTML-страницы |
|
||||
| `--disable-swagger` | `DCHAIN_DISABLE_SWAGGER` | false | Выключить `/swagger` + `/swagger/openapi.json` |
|
||||
| `--api-token` | `DCHAIN_API_TOKEN` | — | Bearer token для submit (пусто = public) |
|
||||
| `--api-private` | `DCHAIN_API_PRIVATE` | false | Требовать token и для чтения |
|
||||
|
||||
```bash
|
||||
# Запустить
|
||||
docker compose up -d
|
||||
|
||||
# Логи
|
||||
docker compose logs -f node1
|
||||
|
||||
# Остановить
|
||||
docker compose down
|
||||
|
||||
# Сбросить данные
|
||||
docker compose down -v
|
||||
```
|
||||
|
||||
---
|
||||
### Update system
|
||||
| Флаг | env | По умолчанию | Описание |
|
||||
|------|-----|--------------|----------|
|
||||
| `--update-source-url` | `DCHAIN_UPDATE_SOURCE_URL` | — | Gitea `/api/v1/.../releases/latest` URL |
|
||||
| `--update-source-token` | `DCHAIN_UPDATE_SOURCE_TOKEN` | — | PAT для приватных repo |
|
||||
|
||||
## Файл ключа
|
||||
|
||||
Каждая нода использует один файл с обоими ключами:
|
||||
|
||||
```json
|
||||
{
|
||||
"pub_key": "03abcd...", // Ed25519 pubkey (hex, 66 символов)
|
||||
"priv_key": "...", // Ed25519 privkey (hex)
|
||||
"x25519_pub": "...", // X25519 pubkey для E2E relay (hex, 64 символа)
|
||||
"x25519_priv": "..." // X25519 privkey
|
||||
"pub_key": "26018d40...", // Ed25519 public (64 hex chars)
|
||||
"priv_key": "16aba1d2...", // Ed25519 private (128 hex chars, priv||pub)
|
||||
"x25519_pub": "baada10a...", // X25519 public для relay E2E
|
||||
"x25519_priv":"a814c191..." // X25519 private
|
||||
}
|
||||
```
|
||||
|
||||
Генерация:
|
||||
```bash
|
||||
client keygen --out node1.json
|
||||
`client keygen --out node.json` — создаёт валидный файл.
|
||||
|
||||
## Схема ключей BadgerDB
|
||||
|
||||
```
|
||||
height → uint64 (tip)
|
||||
block:<index> → JSON Block
|
||||
tx:<txid> → JSON TxRecord
|
||||
txchron:<block20d>:<seq04d> → tx_id (recent-tx index)
|
||||
balance:<pubkey> → uint64 (µT)
|
||||
stake:<pubkey> → uint64 (µT)
|
||||
id:<pubkey> → JSON RegisterKeyPayload
|
||||
chan:<channelID> → JSON CreateChannelPayload
|
||||
chan-member:<ch>:<pub> → ""
|
||||
contract:<contractID> → JSON ContractRecord
|
||||
cstate:<contractID>:<key> → bytes
|
||||
clog:<ct>:<block>:<seq> → JSON ContractLogEntry
|
||||
relay:<pubkey> → JSON RegisterRelayPayload
|
||||
validator:<pubkey> → "" (presence = active)
|
||||
schema:ver → uint32 (migration version)
|
||||
```
|
||||
|
||||
---
|
||||
## Метрики + healthcheck
|
||||
|
||||
## Мониторинг
|
||||
- **Healthcheck:** `curl http://localhost:8080/api/netstats` возвращает
|
||||
200 с JSON, если нода живая.
|
||||
- **Prometheus:** `GET /metrics` — см. [../api/README.md](../api/README.md).
|
||||
- **Время блока:** норма ~5 сек (константа в `consensus/pbft.go`).
|
||||
|
||||
### HTTP healthcheck
|
||||
## Сброс данных
|
||||
|
||||
```bash
|
||||
curl http://localhost:8081/api/netstats
|
||||
```
|
||||
# Native
|
||||
rm -rf ./data ./mailbox
|
||||
|
||||
### Logs
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
docker compose logs -f node1 | grep -E "block|error|warn"
|
||||
|
||||
# Прямой запуск
|
||||
./node ... 2>&1 | tee node.log
|
||||
```
|
||||
|
||||
### Метрики производительности
|
||||
|
||||
| Показатель | Норма |
|
||||
|-----------|------|
|
||||
| Время блока | ~3 с |
|
||||
| Блоков в минуту | ~20 |
|
||||
| PBFT фазы | prepare → commit → finalize |
|
||||
|
||||
---
|
||||
|
||||
## Структура данных BadgerDB
|
||||
|
||||
```
|
||||
balance:<pubkey> → uint64 (µT)
|
||||
identity:<pubkey> → JSON RegisterKeyPayload
|
||||
stake:<pubkey> → uint64 (µT)
|
||||
block:<index> → JSON Block
|
||||
tx:<txid> → JSON TxRecord
|
||||
txidx:<pubkey>:<block>:<seq> → txid (индекс по адресу)
|
||||
contract:<id> → JSON ContractRecord
|
||||
cstate:<id>:<key> → []byte (state контракта)
|
||||
clog:<id>:<seq> → JSON ContractLogEntry
|
||||
relay:<pubkey> → JSON RegisteredRelayInfo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Сброс и восстановление
|
||||
|
||||
```bash
|
||||
# Полный сброс
|
||||
docker compose down -v
|
||||
docker compose up -d
|
||||
|
||||
# Только данные одной ноды
|
||||
docker compose stop node1
|
||||
docker volume rm go-blockchain_node1_data
|
||||
docker compose up -d node1
|
||||
# Single-node container
|
||||
docker stop dchain && docker rm dchain
|
||||
docker volume rm dchain_data
|
||||
```
|
||||
|
||||
После сброса нужно заново задеплоить контракты и залинковать governance.
|
||||
После сброса нода начнёт с пустого стейта; c `--genesis` — создаст новый
|
||||
chain_id, с `--join` — синкается с сетью.
|
||||
|
||||
Reference in New Issue
Block a user