Консенсус
NeuroChain використовує Malachite (Informal Systems) — Tendermint BFT у вигляді бібліотеки Rust, вбудованої в ноду. Блок остаточний, щойно валідатори з понад 2/3 стейку дали за нього precommit: жодних форків, на які треба чекати, і жодних підтверджень, які треба рахувати.
| Властивість | Значення |
|---|---|
| Алгоритм | Tendermint BFT: propose → prevote → precommit |
| Сила голосу | Стейк валідатора, в uNRO |
| Поріг коміту | Понад 2/3 усієї сили голосу |
| Стійкість до збоїв | До f несправних валідаторів із 3f + 1 |
| Підписи голосів і пропозицій | ML-DSA-65 (постквантовий) |
| Остаточність | Одразу після коміту |
Одна висота крок за кроком
- Propose. Пропозер для
(height, round)складає блок із mempool: список транзакцій, їхній корінь Мерклаtx_rootіprev_state_root— корінь стану, якого він досяг після попереднього блоку. - Перевірка. Кожен інший валідатор звіряє транзакції з
tx_rootі порівнюєprev_state_rootзі своїм коренем для попередньої висоти. Розбіжність означає, що стан однієї зі сторін розійшовся; валідатор відмовляється голосувати і пише в журналSTATE DIVERGENCE. - Prevote, precommit. Валідатори голосують за блок або за nil, якщо він недійсний чи не надійшов вчасно.
- Коміт. Коли є precommit понад 2/3 сили голосу, блок ухвалено. Кожен валідатор застосовує його транзакції, ділить комісії, на висотах виплат нараховує винагороди й обчислює новий корінь стану — усе детерміновано, тож кожна чесна нода отримує той самий корінь.
- Без кворуму вчасно висота переходить у наступний раунд з новим пропозером і довшими тайм-аутами.
Тайм-аути раундів — стандартні для Malachite. Темп між блоками задається для кожної ноди:
| Змінна | За замовчуванням | Значення |
|---|---|---|
NEUROCHAIN_BLOCK_MS | 200 | Мінімальна пауза перед пропозицією блоку з транзакціями |
NEUROCHAIN_EMPTY_BLOCK_MS | 2000 | Мінімальна пауза перед порожнім блоком, щоб простояча мережа не шуміла |
Хто пропонує
Пропозер обирається лише за стейком і детерміновано, тож кожна нода отримує ту саму відповідь:
- Беруться активні валідатори та їхні стейки; усі стейки ділять на найбільший спільний дільник, щоб важили лише пропорції.
SHA3-256("neuro-proposer|" ‖ height ‖ round)дає число, рівномірно розподілене по всій вазі.- Валідатори проходяться по черзі; пропонує той, у чий діапазон ваги потрапило число.
Валідатор з удвічі більшим стейком пропонує вдвічі частіше. Зміна раунду дає нове число, тож валідатор, що лежить, пропускається. Якщо ні в кого не лишилось стейку, вибір переходить на почергове, щоб мережа йшла далі.
Набір валідаторів
Валідатор бере участь у консенсусі, коли виконано все з переліченого:
- Його адреса закінчується на
.node, і його консенсусний публічний ключ ML-DSA-65 записано в мережі. - Його стейк щонайменше
min_stake(за замовчуванням 10 000 NRO). - Він не оштрафований і не в jail.
- У шардованій мережі він належить до цього шарду.
Набір щоразу виводиться зі стану мережі, тож зміни стейку, штрафи й нові реєстрації набувають сили через транзакції, які застосував кожен валідатор.
Для справжньої візантійської стійкості протоколу потрібно щонайменше 7 валідаторів (f = 2). Нода з меншою кількістю попереджає про це під час старту; GET /health показує validator_count, bft_quorum (кількість 2f + 1 для поточного набору) і bft_ready. Для тестових мереж мінімум змінює NEUROCHAIN_MIN_VALIDATORS.
Де AI може і не може діяти
Доказ безпеки Tendermint спирається на те, що сила голосу — це стейк. AI ніколи не повинен її змінювати.
| Дозволено? | Стан | |
|---|---|---|
| Змінити силу голосу або поріг 2/3 | Ніколи | Гарантовано: голоси рахує Malachite за стейком |
| Вивести валідатора (jail, slash → сила голосу 0) | Так — лише виведення, ніколи додаткова вага | Працює, спрацьовує на доказ подвійного підпису |
| Зміщувати вибір пропозера за довірою | Так, у принципі | Не діє: пропозер обирається лише за стейком |
ConsensusAI обчислює для кожного валідатора оцінку довіри за його недавньою участю. Зараз ця оцінка показується, але не використовується: її видно в GET /api/v1/validators і в журналі рішень оракула для кожного блоку. З вибору пропозера її прибрано, бо кожна нода рахувала участь зі свого погляду; після простою ці погляди розходились, ноди не погоджувались, хто може пропонувати, і вже не сходились. Повернути довіру у вибір пропозера можна лише на даних про участь, які самі узгоджені в консенсусі (коміт попереднього блоку, переданий у наступному).
Slashing і jail
Підпис двох різних голосів для тієї самої висоти й раунду — доказове порушення. Коли такий доказ подано й перевірено в консенсусі:
| Наслідок | За замовчуванням | Параметр управління |
|---|---|---|
| Штраф зі стейку | 5% від min_stake (не більше стейку валідатора) | slash_fraction_double_sign_bps = 500 |
| Винагорода тому, хто повідомив | 1% штрафу | slash_reward_fraction_bps = 100 |
| Решта | спалюється | — |
| Jail (сила голосу 0) | 10 000 блоків | jail_blocks (змінна NEUROCHAIN_JAIL_BLOCKS) |
Кожен доказ застосовується один раз. Після строку jail валідатор автоматично повертається в набір, якщо його стейк і далі щонайменше min_stake. Штрафи — у GET /api/v1/slashing/history.
Перезапуск і наздоганяння
- Перезапуск. Malachite веде журнал попереднього запису. Перезапущений валідатор програє його і може ухвалити висоту, яку вже закомітив; нода розпізнає блок як застосований і продовжує роботу, а не зупиняється.
- Наздоганяння. Нода, що була офлайн, запитує в пірів пропущені ухвалені блоки — кожен із сертифікатом коміту й повним списком транзакцій — і застосовує їх по черзі так, ніби брала участь. Піри тримають для цього останні 10 000 ухвалених блоків (
NEUROCHAIN_SYNC_HISTORY_BLOCKS). Нода, що відстала більше, лишається помітно позаду, а не копіює записи блоків, які не застосувала; стара синхронізація записів блоків тепер лише порівнює корені стану для блоків, які нода вже має. - Нова нода. Може стартувати з підписаного знімка стану, а не програвати все від генезису — див. Запуск ноди.
Шардинг експериментально
Мережу можна поділити на шарди, кожен зі своїм екземпляром Malachite, своїми валідаторами і своєю висотою:
- Акаунт або валідатор належить шарду
FNV-1a(адреса) mod n_shards. - Нода обслуговує шард із
NEUROCHAIN_SHARD_ID; кількість шардів —NEUROCHAIN_SHARDS. БезNEUROCHAIN_SHARD_IDнода працює з одним шардом і міжшардових переказів немає. - Переказ в інший шард — двофазний коміт: шард-джерело блокує суму; шард-призначення зараховує її після перевірки доказу Меркла про списання; якщо цього не сталося за 10 блоків (
RELAY_TIMEOUT_BLOCKS), джерело повертає суму відправнику.
Як тестується. Модульні тести ноди покривають розподіл за шардами, фільтрацію mempool і голосів за шардом, шлях блокування → зарахування та повернення за тайм-аутом (test_cross_shard_2pc_commit, test_cross_shard_2pc_timeout_refund, запуск — cargo test -p neurochain-node). Мережеві прогони з кількома валідаторами поки були з одним шардом; прогону з кількома шардами й кількома валідаторами на шард ще не було. Експлуатація — у розділі IBC v2 і шардинг.
Перевірте самі
curl -s "$NODE_RPC/health" # висота, раунд, піри, validator_count, bft_quorum, bft_ready
curl -s "$NODE_RPC/api/v1/validators" # стейк, оцінка довіри, запропоновані блоки, голоси
curl -s "$NODE_RPC/api/v1/blocks?limit=1" # останній блок: пропозер, tx_root, state_root