Распределённые системы

Византийская отказоустойчивость

Цели урока

  • Понимать разницу между Byzantine и crash faults и почему Raft/Paxos не защищают от первых
  • Знать теорему 3f+1 и уметь вычислить нужное число узлов
  • Понимать три фазы PBFT и зачем каждая из них нужна
  • Знать где применяется BFT на практике и когда он избыточен

Предварительные знания

  • Принципы работы Raft/Paxos (crash fault tolerance)
  • Понятие кворума и majority voting
  • Базовое понимание криптографических подписей

Ethereum DAO hack 2016: 60 млн долларов украдено не через взлом сети, а через Byzantine поведение контракта - узлы делали именно то, что написано в коде, но результат был катастрофическим. Paxos/Raft бессильны когда узлы врут.

  • **Bitcoin (PoW)** - вероятностный BFT для публичной сети без доверия: 51% честных узлов гарантируют консенсус
  • **Hyperledger Fabric** - PBFT для межбанковских расчётов где участники - конкуренты
  • **Boeing 777** - triple-modular redundancy для защиты от radiation-induced bit flips (hardware Byzantine)
  • **SpaceX Falcon 9** - 3 Flight Management Computers с Byzantine-tolerant voting
  • **Facebook Diem/Libra** - HotStuff BFT как основа LibraBFT с O(N) view change

Лэмпорт и задача предателей

В 1982 году Лэмпорт, Шостак и Пиз опубликовали статью «Byzantine Generals Problem» - название придумал Лэмпорт как аналогию для труднообъяснимой проблемы. До этого проблему называли «Interactive Consistency Problem», что звучало менее запоминающе. Статья оказалась настолько влиятельной, что термин «Byzantine fault» вошёл в стандартный словарь distributed systems и используется в официальных авиационных стандартах DO-178C.

Задача византийских генералов

**Июнь 2016. Ethereum DAO смарт-контракт держит 150 млн долларов. Атакующий находит уязвимость и рекурсивно вызывает withdraw 1800 раз подряд - каждый раз получая 50 ETH до того как баланс обнуляется. Украдено 60 млн долларов.** Это не баг сети - узлы Ethereum корректно выполнили код. Это Byzantine fault на уровне логики: узел делал именно то, что написано, но намеренно деструктивно.

Лэмпорт, Шостак и Пиз в 1982 году формализовали эту проблему через военную метафору. N генералов осаждают город и должны договориться: АТАКОВАТЬ или ОТСТУПИТЬ. Общение - только через гонцов. Часть генералов - предатели, которые активно мешают консенсусу.

**Byzantine fault** - узел ведёт себя произвольно: врёт о полученных сообщениях, отправляет разные данные разным получателям, сговаривается с другими предателями. Принципиальное отличие от crash fault: молчащий узел - предсказуем, лгущий - нет.

Тип сбояПоведение узлаАлгоритм защиты
Crash (CFT)Узел упал и молчит - предсказуемоRaft, Paxos - нужно 2f+1 узлов
OmissionУзел теряет часть сообщений - молчаRaft с таймаутами
Byzantine (BFT)Узел врёт, шлёт противоречия, сговариваетсяPBFT, HotStuff - нужно 3f+1 узлов

**Paxos/Raft не защищают от Byzantine faults.** Оба алгоритма предполагают модель crash-stop: узел либо работает корректно, либо молчит. Один злонамеренный узел может сломать Raft-кластер: он может отвечать разным репликам разными данными и нарушить инвариант.

Проблема генералов иллюстрирует суть: при трёх генералах и одном предателе честные не могут достичь консенсуса. Если командующий-предатель посылает генералу A приказ АТАКА, а генералу B - ОТСТУПЛЕНИЕ, то A и B видят конфликт, но не знают кто из них получил ложный приказ.

Если использовать Raft с большим кластером, он защитит от взломанных узлов

Raft защищает только от crash faults. Один скомпрометированный узел в Raft-кластере может нарушить safety.

Raft требует 2f+1 узлов для f crash-отказов. Но алгоритм не верифицирует честность узлов - он просто подсчитывает голоса большинства. Byzantine узел голосует за неправильное значение, и кворум может принять ложное решение.

Чем Byzantine fault принципиально отличается от crash fault?

Теорема 3f+1: минимум узлов для Byzantine consensus

**Фундаментальный результат Лэмпорта, Шостака и Пиза (1982):** для достижения Byzantine consensus при наличии f злонамеренных узлов необходимо минимум 3f+1 узлов суммарно. Это математически доказанная нижняя граница - обойти её невозможно без дополнительных допущений.

**Интуиция за 3f+1:** при f Byzantine-узлах и f молчащих узлах (имитируют crash) остаётся f+1 честных голосов. Кворум составляет 2f+1. Из них как минимум f+1 - честные. Этого достаточно чтобы перевесить f предателей. Итого: f (Byzantine) + f (молчащие) + f+1 (честные) = 3f+1.

f (предателей)Нужно узлов (3f+1)Кворум (2f+1)Мин. честных в кворуме
1432
2753
31074
10312111

Почему 3 узла недостаточно для f=1: предположим командующий - предатель. Он посылает генералу G1 приказ АТАКА, генералу G2 - ОТСТУПЛЕНИЕ. G1 и G2 обмениваются сообщениями. G1 говорит G2: «я получил АТАКА». G2 говорит G1: «я получил ОТСТУПЛЕНИЕ». Оба видят конфликт, но оба утверждения одинаково достоверны - нет способа определить кто из трёх (Commander, G1, G2) является предателем.

При 4 узлах (3f+1 при f=1) аналогичный сценарий разрешается: кворум из 3 узлов будет содержать не менее 2 честных. Два честных узла согласуются между собой, перевешивая одного предателя.

Теорему 3f+1 можно обойти умной криптографией или надёжным железом

3f+1 - информационно-теоретическая нижняя граница, не зависящая от реализации

Доказательство Лэмпорта работает в модели без шифрования (устных сообщений). С аутентификацией (письменные сообщения - подписи) нижняя граница снижается до 2f+1, но это другая, более сильная модель угроз.

Банк строит систему подтверждения транзакций из 7 нод. Сколько Byzantine-узлов можно терпеть?

PBFT: первый практичный BFT-алгоритм

**Castro и Liskov, MIT, 1999. PBFT (Practical Byzantine Fault Tolerance) - первый алгоритм, который сделал BFT практически применимым.** До PBFT теоретические BFT-протоколы были слишком медленными для реального использования. PBFT показал overhead всего 3% по сравнению с non-BFT системами при малых кластерах.

Три фазы PBFT

**Pre-prepare:** Primary получает запрос клиента, назначает ему sequence number n и рассылает всем репликам. **Prepare:** каждая реплика, получив Pre-prepare, рассылает Prepare всем остальным. Состояние prepared достигается когда собрано 2f Prepare-сообщений. **Commit:** после prepared каждый шлёт Commit всем. После 2f+1 Commit - операция выполняется и клиент получает Reply.

**View Change:** если реплика не получает Pre-prepare вовремя - подозревает Primary. Отправляет VIEW-CHANGE с доказательствами. Новый Primary (view+1 mod N) собирает 2f VIEW-CHANGE и рассылает NEW-VIEW. Дорого: O(N^2) сообщений. Злонамеренный Primary может намеренно триггерить view changes, замедляя систему.

МетрикаCrash-tolerant (Raft)BFT (PBFT)BFT (HotStuff)
Узлов для f отказов2f+13f+13f+1
Сообщений на операциюO(N)O(N^2)O(N)
Раунды233
КриптографияНе нужнаMAC/подписиThreshold signatures
View changeO(N)O(N^2)O(N)

Почему клиент PBFT ждёт f+1 одинаковых ответов, а не одного?

BFT на практике: когда нужен и сколько стоит

**HotStuff (Facebook/Meta, 2018) решил главную проблему PBFT: O(N^2) сообщения при view change.** Ключевая идея - threshold signatures (пороговые подписи): вместо того чтобы лидер рассылал всем N^2 сообщений, каждая реплика шлёт подпись лидеру, лидер агрегирует в одну подпись и делает один broadcast. View change: O(N) вместо O(N^2). HotStuff используется в Diem/Libra и является основой LibraBFT.

ОбластьПримерПочему BFT, не Raft
Public blockchainBitcoin, EthereumУзлы принадлежат незнакомым людям, нет доверия
Permissioned blockchainHyperledger FabricКонсорциум организаций - конкуренты в одной сети
Финансовые расчётыSWIFT, межбанкЗащита от инсайдеров и взломанных узлов
Авиация/КосмосBoeing 777, SpaceXРадиация может flip bits - hardware Byzantine
Critical infrastructureЭнергосетиAPT-атаки на управляющие узлы

**Большинству систем BFT не нужен.** Если все узлы под контролем одной организации - Raft достаточен и на порядок быстрее. BFT нужен когда участники не доверяют друг другу (разные организации, public network) или когда hardware failure может привести к Byzantine поведению (space, nuclear).

Практический выбор: внутренние системы (микросервисы, базы данных компании) - Raft или Paxos. Multi-org системы где участники конкурируют или не доверяют друг другу - BFT. Public blockchains используют вероятностный BFT (Bitcoin PoW, Ethereum PoS) который жертвует finality ради масштабируемости.

BFT нужен только для блокчейнов и криптовалют

BFT нужен везде где узлы контролируются разными недоверяющими сторонами или где hardware может дать Byzantine отказы

Авионика Boeing 777 использует triple-modular redundancy - классический BFT для hardware faults (радиация, битые биты). SpaceX Falcon 9 имеет 3 Flight Management Computers голосующих большинством. Это BFT задолго до блокчейна.

Стартап строит систему для расчётов между 5 банками-конкурентами. Raft или PBFT?

Вопросы для размышления

  • Большинство production-систем используют Raft/Paxos без BFT. Какие конкретные условия в архитектуре компании сигнализировали бы о необходимости перехода на BFT-протокол?

Связанные уроки

  • dist-09-raft — Raft is the crash-fault baseline; BFT extends it
  • dist-08-paxos — Classic Paxos assumes crash faults only
  • ds-03-consensus — BFT consensus is a harder variant of the consensus problem
  • dist-12-consistency — BFT changes the impossibility boundaries for consistency
  • crypto-28-digital-signatures
Византийская отказоустойчивость

0

1

Войти