# Запуск ноди

> Запуск ноди NeuroChain — збірка з вихідного коду (спершу контракти), запуск однієї тестової ноди чи мережі з кількох валідаторів, Docker Compose, структура даних, ключі, знімки стану, моніторинг через Prometheus і Grafana, резервне копіювання й відновлення.

Source: https://docs.nro.world/uk/operate/node

## Вимоги

- Rust (stable) з ціллю `wasm32-unknown-unknown`
- Інструментарій C++ і `clang` (RocksDB збирається з вихідного коду)
- Node.js 18+ для gateway
- Кілька ГБ диска для збірки

## Збірка

Нода вбудовує два системні контракти, тож збирайте їх **першими**:

```bash
cd neurochain
rustup target add wasm32-unknown-unknown

for c in nrc20 ncert; do
  (cd contracts/$c && RUSTFLAGS="-C link-arg=--allow-undefined" \
     cargo build --release --target wasm32-unknown-unknown)
done

cargo build -p neurochain-node --bin neurochain        # → target/debug/neurochain
```

Без кроку з контрактами збірка ноди падає з `couldn't read …/nrc20.wasm`. Прапорець `--allow-undefined` дозволяє host-імпортам контрактів лінкуватися з поточним Rust; нові контракти можуть натомість оголошувати `#[link(wasm_import_module = "env")]` (див. [NeuroWASM](/uk/neurowasm/#a-minimal-contract)).

Перша збірка триває кілька хвилин (RocksDB); наступні — секунди. Для всього, крім локального тестування, використовуйте `--release`.

## Одна локальна нода

```bash
CHAIN_ENV=testnet \
NEUROCHAIN_DATA_DIR=./data \
NEUROCHAIN_MODELS_DIR=./models \
NEUROCHAIN_P2P_PORT=30333 \
NEUROCHAIN_RPC_PORT=9933 \
NEUROCHAIN_NODE_ADDR=localhost:30333 \
NEUROCHAIN_MIN_VALIDATORS=1 \
RUST_LOG=neurochain=info \
./target/debug/neurochain
```

- `CHAIN_ENV=testnet` вмикає кран і пом'якшує перевірку підписів для розробки. Для будь-чого справжнього не задавайте його (правила mainnet).
- Без `NEUROCHAIN_GENESIS_VALIDATORS` нода робить себе єдиним валідатором (`neuro:node-1.node`) і одразу починає виробляти блоки.
- `NEUROCHAIN_MIN_VALIDATORS=1` прибирає попередження про те, що валідаторів менше 7.

Перевірте:

```bash
curl -s http://localhost:9933/health
# {"status":"ok","height":6,"validator_count":1,"bft_quorum":1,"bft_ready":false,…}
```

Потім запустіть [gateway](./gateway).

## Мережа з кількох валідаторів {#a-multi-validator-network}

Кожен валідатор має стартувати з **того самого генезису**, у якому перелічено всіх валідаторів з їхніми публічними ключами консенсусу. Для локальної мережі репозиторій це автоматизує:

```bash
cd neurochain
scripts/net-test/net-test.sh keys 4    # створити 4 ключі валідаторів, записати спільний набір генезису
scripts/net-test/net-test.sh up 4      # запустити їх (спершу нода 1, решта підключаються до неї)
scripts/net-test/net-test.sh check     # висоти збігаються, блоки виробляються, спонсорований газ узгоджений
scripts/net-test/net-test.sh down
```

Скрипт використовує RPC-порти від 9941, P2P-порти від 30341 і дані в `.net-test/`, тож звичайної ноди з `./data` не зачіпає.

Вручну:

1. **Створіть ключ кожного валідатора.** Запустіть кожну ноду один раз з власними `NEUROCHAIN_DATA_DIR`, `NEUROCHAIN_NODE_ADDR` і портами. Вона запише ключ у `<data dir>/shard0/bft_key.bin` і виведе в журнал:
   ```
   Consensus validator … — ML-DSA-65 pubkey (put in NEUROCHAIN_GENESIS_VALIDATORS): 6e80bab8…
   ```
   Зупиніть її і видаліть `<data dir>/shard0/state_rdb` та `<data dir>/shard0/wal`. **`bft_key.bin` збережіть.**
2. **Запишіть набір генезису** — однакове значення для кожної ноди:
   ```
   NEUROCHAIN_GENESIS_VALIDATORS='neuro:val1.node|host1:30333|1000000|0.9|<pubkey1>,neuro:val2.node|host2:30333|1000000|0.9|<pubkey2>,…'
   ```
   Поля: адреса валідатора, його P2P-адреса (має дорівнювати `NEUROCHAIN_NODE_ADDR` цієї ноди), стейк у NRO, початковий trust (лише для звітів), публічний ключ ML-DSA-65. Запис без публічного ключа не входить у консенсус.
3. **Запустіть** першу ноду, потім інші з `NEUROCHAIN_BOOTSTRAP=host1:30333`. Якщо валідаторів менше 7, задайте `NEUROCHAIN_MIN_VALIDATORS` рівним їхній кількості.

Повідомлення консенсусу йдуть тим самим P2P-портом; окремого порту консенсусу немає. Нода розпізнає, який вона валідатор, зіставляючи `NEUROCHAIN_NODE_ADDR` з P2P-адресою в наборі генезису.

::: tip Набір генезису ніколи не змінюється
Валідатори, що приєднуються пізніше, реєструють `.node` і стейкають (див. [Стейкінг](/uk/learn/staking)); вони не змінюють `NEUROCHAIN_GENESIS_VALIDATORS`. Нода, запущена з іншим набором генезису чи балансом, відхиляє блоки інших і пише в журнал `STATE DIVERGENCE`.
:::

## Docker Compose

З кореня репозиторію:

```bash
cp .env.example .env        # відредагуйте за потреби
docker compose up -d        # нода, gateway, вебзастосунок
docker compose --profile monitoring up -d   # плюс Prometheus і Grafana
```

Образи збирають контракти й ноду поетапно. Дані ноди — в томі `node1-data`; файли AI-моделей монтуються лише для читання з `neurochain/models`.

## Папка даних

| Шлях | Вміст |
|------|-------|
| `<data dir>/shard<N>/bft_key.bin` | Ключ консенсусу й підпису ноди — **зробіть резервну копію, нікому не передавайте** |
| `<data dir>/shard<N>/state_rdb/` | Стан мережі шарда N у RocksDB |
| `<data dir>/shard<N>/wal/` | Журнал попереднього запису консенсусу, відтворюється після перезапуску |

## Старт зі знімка стану

Нова нода може не відтворювати історію, а завантажити підписаний знімок стану з працюючої ноди:

```bash
NEUROCHAIN_CHECKPOINT_URL=http://trusted-node:9933 ./target/debug/neurochain
```

З порожньою папкою даних нода отримує `/api/v1/state/snapshot`, застосовує його й наздоганяє з цієї висоти. Знімок розкриває всі баланси й стейки; захистіть ендпоінт через `NEUROCHAIN_SNAPSHOT_TOKEN` (клієнти тоді надсилають `Authorization: Bearer <token>`).

## Доступність і TLS

- За правилами mainnet RPC слухає `localhost`, з `CHAIN_ENV=testnet` — `0.0.0.0`; щоб обрати, задайте `NEUROCHAIN_RPC_HOST`.
- Задайте `NEUROCHAIN_TLS_CERT` і `NEUROCHAIN_TLS_KEY` (шляхи до PEM), щоб обслуговувати RPC через HTTPS.
- Перед користувачами ставте gateway, а не ноду.
- `NEUROCHAIN_INTERNAL_TOKEN` захищає внутрішні ендпоінти (запис у журнал оракула, експорт даних для AI) заголовком `X-Internal-Token`.

## Моніторинг

`GET /metrics` віддає метрики Prometheus:

| Метрика | Значення |
|---------|----------|
| `nc_block_height`, `nc_bft_round` | Просування мережі |
| `nc_bft_validators_active`, `nc_bft_quorum_size` | Набір валідаторів |
| `nc_peer_count`, `nc_mempool_size`, `nc_tx_total` | Мережа й навантаження |
| `nc_total_staked`, `nc_base_fee`, `nc_fees_burned` | Економіка (суми в uNRO) |
| `nc_deploy_rejected_total{rule_id}` | Розгортання, відхилені VMGuardian, за правилами |
| `nc_model_active_count`, `nc_model_voting_count`, `nc_model_version{…}`, `nc_model_confirms_needed`, `nc_model_voting_deadline_remaining_blocks` | Реєстр AI-моделей |
| `nc_sentinel_flagged_total{category}`, `nc_sentinel_held_total`, `nc_sentinel_released_total{how}` | Sentinel |

У `monitoring/` лежать конфігурація збору Prometheus і готова панель Grafana зі сповіщеннями про великий мемпул, менше 2 пірів і сплеск відхилених розгортань.

## Резервне копіювання й відновлення

```bash
./scripts/backup.sh [data_dir] [backup_dir]     # копія на льоту; нода продовжує працювати
./scripts/restore.sh <backup_dir> [data_dir]    # спершу зупиніть ноду
```

Резервні копії містять `bft_key.bin` — зберігайте їх так само надійно, як сам ключ.

## Корисні рядки журналу

| Рядок | Значення |
|-------|----------|
| `consensus decided, committing height=…` | Блок фіналізовано |
| `Below minimum: n/7 active validators` | Валідаторів менше, ніж `NEUROCHAIN_MIN_VALIDATORS` |
| `STATE DIVERGENCE` | Стан цієї ноди відрізняється від стану пропонувальника; вона не голосує, доки це не вирішено |
| `genesis validator(s) missing ML-DSA pubkey` | Запис у наборі генезису не має публічного ключа і виключений |

Усі змінні: [Змінні середовища](./env).
