1511–12 марта 2013 года

Ночь, когда у Биткоина были две действительные истории

Новые и старые версии Bitcoin Core не согласовались в одном блоке. Разработчики и майнеры должны были решить за несколько часов, какую ветвь поддержать — и заплатили за это брошенной работой.

Вечером 11 марта 2013 года узлы Биткоина начали продолжать две версии одной истории. Новая версия Bitcoin 0.8 приняла блок 225 430 и строила цепочку дальше на его основе. Часть старых узлов с версией 0.7 отвергла его: обработка требовала больше блокировок базы данных, чем допускал практический предел Berkeley DB. Обе группы следовали своей программе и считали собственную ветвь действительной. Поначалу новую ветвь поддерживала большая часть мощности, собранной в майнинговых пулах. Простое ожидание скорее углубило бы раскол, чем устранило его. Разработчики, биржи и операторы пулов собрались в IRC. Без центрального штаба им нужно было найти путь, по которому достаточная часть сети смогла бы снова двигаться вместе.

01

Один блок, два вердикта

Блок 225 430 не был создан с целью разделить сеть. Однако он содержал больше входов транзакций, чем предыдущие блоки, и тем самым нагрузил базу данных таким образом, что выявил разницу между версиями. Bitcoin 0.8 использовал LevelDB и обработал блок. Версия 0.7 с Berkeley DB столкнулась с количеством блокировок и завершилась ошибкой.

Результат был опасно незаметным. Обе группы узлов соблюдали правила так, как их могла выполнить установленная у них программа. Новая ветвь не была мошеннической с точки зрения задуманных правил консенсуса, а старые узлы не подвергались атаке. Сеть разделилась из-за недокументированного практического ограничения одной технологии базы данных.

Майнеры с версией 0.8 строили над новым блоком. Майнеры с более старой версией продолжали от его предшественника. Как только обе ветви получили дополнительные блоки, платеж, подтвержденный на одной, не обязательно существовал на другой. Пользователь не мог безопасно полагаться на обычное количество подтверждений, пока не стало ясно, какую историю примет экономическое большинство.

Новейшая ветвь изначально несла примерно шестьдесят процентов производительности. В обычных обстоятельствах цепочка с большей накопленной работой получила бы преимущество. Однако здесь более старые узлы не могли принять новый блок без учёта его работы. Реорганизация сама не перекрывает блок, который местное программное обеспечение для проверки считает недействительным.

Инцидент так раскрыл предел простого правила "самый длинный цепочка побеждает". Точнее, побеждает цепочка с наибольшим трудом среди тех, которые узел впервые признает действительными. Когда узлы не соглашаются о действительности, самого хэшрейта недостаточно для мгновенного единения.

02

IRC как временная диспетчерская

Разработчики заметили проблему, когда начались различия в высоте и хэше отслеживаемых узлов. Общение сосредоточилось на IRC-канале, где было возможно сравнивать логи, производительность ветвей и реакции крупных пулов. Gavin Andresen позже в BIP 50 изложил хронологию и решения, принятые в течение ночи.

Не было выбора между чисто правильной и явно неправильной ветвью. Поддержка версии 0.8 сохранила бы цепочку с большей работой, но отрезала бы количество старых узлов. Возвращение к ветви 0.7 означало бы убедить новых майнеров отказаться от блоков, которые они уже легитимно выработали и за которые ожидали награду.

Практической причиной для возвращения стала совместимость. Версия 0.8 смогла принять меньшие блоки, созданные для старшей ветви, в то время как узлы 0.7 не смогли принять проблемный блок новой ветви. Если производительность перейдёт на ветвь, приемлемую для обеих групп, сеть может снова объединиться без немедленного принудительного обновления всех старых узлов.

Это решение не было приказом, который Андресен мог передать через протокол. Разработчики связались с операторами пулов и объяснили ситуацию. Биржам рекомендовали приостановить зачисление средств. Bitcoin.org опубликовал предупреждение и призвал крупные пулы вернуться к старой версии программы, чтобы сеть снова объединилась на совместимой ветви.

Эта координация была быстрой именно потому, что круг ключевых участников был ещё относительно мал, и люди знали друг друга из публичных каналов. Скорость помогла сети спасти себя от более длительного раскола, но одновременно показала социальные связи, на которых зависел ранний функционирование. Биткоин не имел начальника; однако были люди, чей телефонный звонок или сообщение могли переместить большую долю мощности.

Разговор на IRC не имел ни юридической силы, ни секретного административного ключа. Его значение состояло в том, что в одном месте он собрал людей с различными возможностями воздействия. Разработчики могли объяснить причину, пулы — перенаправить хешрейт, биржи — приостановить депозиты, а операторы узлов — сменить версию. Каждый шаг нес в себе собственный риск, и никто не мог гарантировать, что остальные подчинятся. Решение поддержать ветвь, совместимую с версией 0.7, поэтому не было техническим приказом из центра сети, а координированной ставкой на то, что именно этот путь быстрее всего восстановит общую историю с наименьшим воздействием на пользователей. Успех невозможно отделить от тогдашнего малого размера сообщества и выдавать за универсальную процедуру кризисного управления.

03

Пулы часто жертвуют своей добычей

Решающий шаг сделали два оператора: Michael Marsee, известный как Eleuthria и руководивший BTCGuild, и Marek Palatinus из Slush Pool. Оба вернулись с версии 0.8 на 0.7 и направили вычислительную мощность на старую ветвь. Это помогло изменить соотношение накопленной работы между двумя историями.

Не было бесплатным жестом в таблице. Блоки, добытые на брошенной ветви при реорганизации, перестали быть частью основной цепи, поэтому их награды не должны были остаться тратными. BIP 50 прямо напоминает, что пулы пожертвовали значительные деньги, чтобы сеть вернулась на общую ветвь.

Как только старшая ветвь вырвалась вперед, обновленные узлы 0.8 могли принять ее и переорганизовать свою историю. Старые узлы уже были на ней. Разделение завершилось не тем, что одна версия удаленно переписала другую, а тем, что достаточно много майнеров создало больше работы над точкой, которую могли проверить обе.

Во время инцидента произошло как минимум одно крупное двойное расходование, которое было описано как эксперимент, а не запланированная атака. Событие всё же показало реальное риск: транзакция могла быть подтверждена на ветви, которая будет позже брошена. Рекомендация остановить вклады не была паникой; она защищала сервисы от бухгалтерских остатков, основанных на временной истории.

В этот момент пулы не владели сетью. Они могли влиять на порядок блоков мощностью, которую им доверили майнеры, но не могли заставить каждый полный узел принять любые правила. Их успех зависел от узкой цели: создать ветвь, которую старые и новые узлы считали бы действительной, и обеспечить ей максимальную работу.

04

Разбор инцидента вместо мифа о победе

Гэвин Андресен позже описал инцидент в BIP 50. Документ не утверждает, что сеть работала безупречно. Он объясняет причину, ход событий, потерю блоков, двойную трату и меры, позволяющие раньше обнаруживать подобные расхождения. Благодаря опубликованному разбору опыт кризисной ночи не остался только в памяти её участников. Учиться на нём смогли и другие разработчики.

Одним из уроков было то, что консенсус не включает только правила, написанные в комментарии или документации. Практическое поведение широко используемой программы может стать ограничением сети, даже если никто не намеревался, чтобы оно имело денежное значение. Миграция базы данных поэтому не должна рассматриваться как чисто внутреннее изменение, если оно может изменить принятие блока.

Другим уроком стало необходимость более тщательной координации апгрейдов и тестирования блоков gần граничных значений производительности. Версия 0.8 принесла улучшения производительности, но разница проявила себя только в реальной сети. После инцидента разработчики ввели временные ограничения и подготовили путь, который позволил позже безопасно отказаться от старых зависимостей.

Эта история иногда используется как доказательство того, что Bitcoinом управляет несколько разработчиков, а в других случаях как доказательство того, что он автоматически незничителен. Ни одна из этих сокращенных версий не соответствует действительности. Люди смогли срочно координировать исправление, но для этого им потребовалось сотрудничество пулов, бирж и операторов узлов. Программное обеспечение принимало решения на каждом компьютере отдельно, и общий результат возник только в результате их совместного действия.

Ночь с 11 на 12 марта завершилась возвращением к одной основной цепочке. Но расхождения не исчезли сами собой. Одни участники заметили проблему, другие приостановили сервисы, а майнеры пожертвовали уже выполненной работой ради совместимой истории. Биткоин преодолел раскол благодаря сочетанию правил, экономических потерь и готовности людей признать, что на этот раз уступить должна новая программа.

Ценность BIP 50 в том, что он не закрывает тему заявлением о победе децентрализации. Документ фиксирует конкретную причину, хронологию, потерянную работу и шаги, намеченные для предотвращения похожих неожиданностей. Неприятный сбой становится основой для дальнейших тестов. При этом остаётся вопрос: сколько неписаных предположений скрывается между двумя версиями программы, которые мы считаем совместимыми? Консенсус — это больше, чем перечень правил на бумаге. Независимые реализации и узлы должны приходить к одному результату даже в граничных случаях. Важность этого согласия особенно ясно видна, когда оно нарушается.

Atlas

Люди и понятия в Атласе

FORK13March 2013 Chain SplitGAVINGavin AndresenSLUSHМарек «Slush» ПалатинусPOOLMining PoolNODEFull NodeRULESПравила консенсусаREORGReorg
  1. 01
    BIP 50 — Посмертный анализ ветвления цепи марта 2013

    Основной технический отчет о причине, хэш-рейте, координации BTCGuild и Slush Pool, двойном расходовании и исправлении.

  2. 02
    Bitcoin.org — 11/12 март 2013 Информация о цепочечном разветвлении

    Современные общественные предупреждения для торговцев и пользователей во время разделения сети.

  3. 03
    Bitcoin Core — версия 0.8.0 заметки к выпуску

    Контекст новой базы данных и изменений версии, на которой проявилась неожиданная несовместимость.

Следующая история · 16Trezor: ключи от Биткоина в карманном компьютере