Отказоустойчивость и финальность
Гарантии BFT
Консенсус Savitri использует протокол голосования BFT (Byzantine Fault Tolerant) с кворумом 2f+1 (порог 67%).
Отказоустойчивость
| Всего нод (n) | Макс. Byzantine (f) | Требуемый кворум |
|---|---|---|
| 3 | 0 | 2 |
| 5 | 1 | 4 |
| 7 | 2 | 5 |
| 10 | 3 | 7 |
| 15 | 4 | 11 |
Формула: f = floor((n-1) / 3), кворум = 2f + 1
Безопасность
Блок финализируется только при получении Block Acceptance Certificate (BAC) с подписями от 2f+1 валидаторов. Это гарантирует:
- Ни один конфликтующий блок не может быть финализирован на той же высоте
- Нет откатов после выдачи BAC (детерминированная финальность, не вероятностная)
- Byzantinе-ноды не могут подделать сертификаты без участия в кворуме
Живость
Сеть может производить блоки, пока n - f честных нод онлайн:
- Ротация предложителя: после 50 блоков предложитель уступает место, предотвращая единую точку отказа
- Сторожевой таймер выборов: повторно запускает выборы при отсутствии прогресса блоков в течение 60 секунд
- Прогрессивное ослабление кворума: после 3+ последовательных неудач выборов минимальное число кандидатов снижается до 2
Структура DAG
BlockHeaders поддерживают многородительскую структуру DAG для параллельного производства блоков:
pub struct BlockHeader {
pub parent_hash: Vec<u8>, // основной родитель (обратно совместимо)
pub parent_hashes: Vec<Vec<u8>>, // дополнительные родители для DAG
// ...
}
Обнаружение конфликтов
ConflictDetector выявляет:
- Конфликты двойных трат: одно UTXO, ссылаемое в нескольких ветвях
- Конфликты состояния: конфликтующие переходы состояний
- Обнаружение форков: несколько блоков на одной высоте от разных предложителей
Разрешение конфликтов
При обнаружении конфликтов:
- Выбирается ветвь с более высокой совокупной оценкой PoU
- Конфликтующие транзакции откатываются
- Неконфликтующие транзакции из проигравшей ветви повторно применяются
Групповой консенсус
Формирование групп
Masternodes организуют lightnodes в группы:
- Сортировка lightnodes по PoU-оценке
- Назначение в группы размером
group_size(3 для разработки, 7 для продакшна) - Публикация назначений групп через gossipsub
- Детерминированные идентификаторы групп на основе эпохи (не системного времени)
Выборы внутри группы
В каждой группе:
- Члены обмениваются PoU-оценками
- Наивысшая PoU-оценка становится предложителем (тайбрейкер по peer_id)
- Требуется минимум
(total+1)/2кандидатов - После 3+ неудач: снижение до минимум 2 кандидатов
Принятие блоков
- Предложитель группы производит блок
- Члены группы верифицируют и подписывают
- BAC создаётся с 2f+1 подписями
- Masternodes верифицируют BAC и финализируют
Механизмы восстановления
Восстановление выборов
| Механизм | Триггер | Действие |
|---|---|---|
| Сторожевой таймер | Нет блока 60с | Повторный запуск PoU + выборы |
| Прогрессивное ослабление | 3+ неудачи | Снижение кворума до 2 |
| Ротация предложителя | 50 блоков | Уступить место, переизбрать |
| Немедленные перевыборы | Реинициализация группы | Запустить PoU + задачу выборов |
Восстановление узлов
| Механизм | Триггер | Действие |
|---|---|---|
| Keepalive gossipsub | Интервал 60с | Публикация PoU-оценки |
| Сторожевой таймер mesh | Нет mesh 60с | Переподключение к узлам группы |
| Отключение SlowPeer | Очередь переполнена | Отключить и переподключить |
| Сброс nonce | Локальный > storage + 200 | Сброс до storage nonce |
Восстановление группы
При реинициализации группы:
- PoU-оценки сохраняются для продолжающих членов
- Новые члены начинают с оценок по умолчанию
- Флаг
intra_group_startedсбрасывается - Немедленно запускаются PoU + выборы (без ожидания периодических таймеров)
Слэшинг (продакшн)
| Нарушение | Штраф | Период восстановления |
|---|---|---|
| Двойное голосование | 50% стейка | — |
| Простой | 10% стейка | Постепенно |
| Неверное предложение | 25% стейка | — |
Слэшинг отключён на devnet, включён на mainnet (config/production.toml).
Конфигурация консенсуса
| Параметр | Разработка | Продакшн |
|---|---|---|
| Тайм-аут | 15с | 10с |
| Макс. раундов | 5 | 10 |
| Порог кворума | 0.67 | 0.67 |
| BFT-оптимизации | Отключены | Включены |
| Слэшинг | Отключён | Включён |
| Время блока | 2с | 5с |
| Размер группы | 3 | 7 |