В среде биткойн-пользователей появляется всё больше смущения относительно природы процессов, лежащих в основе внесения изменений в протокол Биткойна. В прошлой заметке я описал процесс внесения изменений в кодовую базу Bitcoin Core. В этой статье я зайду ещё дальше в сложности процесса, стоящего в основе изменений в правилах консенсуса, проверяющих, чтобы все находились на одном блокчейне и видели те же кошельки и истории транзакций.
Когда разные узлы оказываются на разных цепях, это называется форк консенсуса или разделение цепи. Замечу, что такой типа форка весьма отличается от форка кодовой базы (обычно производится простым клонированием чужого репозитория). Большинство форков кодовой базы (в случае их корректного проведения) не приведут к ситуации, в которой узлы оказываются на двух разных цепях, если обратное не задумывалось специально, как в случае с альткойнами.
Когда разные группы узлов оказываются на разных цепочках, преднамеренно или же в результате атаки, такой случай называется нарушение консенсуса. Качество неизменности целиком полагается на устойчивость сети к нарушениям консенсуса.
До сих пор большинство изменений в кодовую базу Биткойна не имели влияния на правила консенсуса.
Некоторые изменения касались просто передвижения кода туда-сюда или переименования сущностей чтобы всё подчистить, также процесс известен как “рефакторинг”. Хорошим примером подобного изменения служит удаление файлов main.h и main.cpp, предложенное Мэттом Коралло.
Другие изменения включают оптимизацию определённых операций для того, чтобы или ускорить их, или занизить другие требования к ресурсам, например к пространству или памяти. Примеры подобных изменений включают представленную Питером Уиллем headers-first синхронизацию (“сначала заголовки”), которая значительно уменьшила изначальное время синхронизации во время установки полного узла, а также использование библиотеки шифрования secp256k1 (её основной автор – тоже Уилль), которая значительно ускоряет проверку подписи ECDSA, позволяя существенно сократить время на подтверждение транзакций и блоков, и сейчас она даже возможно более протестированная и более безопасная, чем библиотека OpenSSL, которую она заменила.
Примеры выше оказали значительное позитивное влияние на софт, но практически не повлияли на совместимость с другими узлами.
Когда предлагается изменение, затрагивающее совместимость узлов, обычно требуется BIP (Bitcoin Improvement Proposal). Краткое описание процесса внесения Предложения по Изменения Биткойна может быть найдено здесь, вместе со всеми BIP-ами.
Для того, чтобы классифицировать и приоритизировать BIP-ы по их влиянию на совместимость, я написал и выложил BIP123, который сейчас уже внедрён. Это относящийся к процессам BIP требует от любого BIP-а, влияющего на совместимость, определить, на какой из четырёх разных уровней он влияет: консенсус, сервисы пиров, API/RPC, и приложения.
Все уровни кроме уровня консенсуса позволяют внедрять в себя опциональные новые возможности, а также удалять возможности, в которых отпала необходимость, используя техники, представляющие совершенно нулевой риск фрагментирования сети или разделения цепи.
Уровень консенсуса самый трудный в плане изменений, так как именно он определяет правила, отвечающие за распознавание, является ли определённый блок (и таким образом, определённый блокчейн) подлинным (“валидным”). Сюда входят проверки на правильное форматирование данных, ограничения по размерам, проверка, не является ли награда за блок слишком большой, проверка, что все потраченные монеты на самом деле существуют, проверка подписей транзакций и так далее. Любые изменения в этих правилах могут спровоцировать разделение цепей.
Изменения в правила консенсуса обычно разделены на две категории: хард-форки, и софт-форки. По определению, хард-форки утрачивают или устраняют существующие правила в то время как софт-форки лишь укрепляют или добавляют новые правила. Это может показаться неочевидным, но это разделение имеет некоторые серьёзные случаи применения.
Так как хард-форки утрачивают или уничтожают существующие правила, блоки, которые были бы отвергнуты старыми правилами, теперь принимаются узлами, использующими новые правила. Примеры включают повышение награды за блок, повышение максимального размера блока, изменение формата заголовка блока (block header), или изменение функции Proof-of-Work. Узлы, которые не обновляют свои правила, будут отвергать эти блоки и продолжат следовать только тем цепям, которые применяют старые правила. Это означает, что пока все узлы не будут обновлены, мы получим разделение цепи.
С Биткойном ещё никогда не проводили хард-форка. Или, по крайней мере, так думают, так как в основном достаточно сложно убедиться в отсутствии недокументированных действий (некоторые могут назвать это багом) в библиотеке баз данных, приведших к отвержению рядом узлов блока, который должен был быть верным. Данный инцидент был разрешён намеренным отвержением этого блока и заменой библиотеки в поздних версиях софта той, которая (как мы надеемся) не имеет такого рода уязвимостей.
Софт-форки лишь укрепляют или добавляют новые правила. Примеры включают уменьшение наград за блоки, уменьшение базового максимального размера блока, повторное использование неиспользованных опкодов (“операционных кодов”) некоторыми способами для создания новых, или добавление новых данных в блок и включение хеша в OP_RETURN параметр выходной транзакции, игнорируемой более старыми узлами. Последний пример – механизм, использующийся в SegWit, к которому мы вернёмся позже, чтобы создать дополнительное пространство в блоке без необходимости проведения хард-форка.
При помощи софт-форков, в противоположность хард-форкам, старые узлы будут продолжать принимать новые блоки, так как все проверки на подлинность всё ещё в силе. Более новый софт также включит в себя новые способы проверки подлинности, а значит блоки, что проходят проверку на старом софте, могут не пройти её на новом. Важное замечание по софт-форкам состоит в том, что пока большинство хеширующей мощности поддерживает новые правила, все узлы будут продолжать концентрироваться вокруг единственной цепочки. Это совершенно не случай хард-форков.
И хард-форки и софт-форки требуют усилия по координации для проведения мягкого перехода и избегания или смягчения разделений цепи. Хард-форки по умолчанию разделяют сеть, за исключением того случая, если все узлы в сети обновят свой софт к тому моменту, как правила изменятся. Давайте, чтобы было понятнее…. вообразите логистические сложности и философские проблемы, возникающие относительно принуждения всех пользователей (разработчиков приложения) принять изменения или весьма реальный риск потенциального провоцирования нарушения консенсуса.
Софт-форки позволяют использовать куда более гладкие механизмы разворачивания, не требующие от всех узлов одновременного обновления, и предоставляющие намного больше механизмов смягчения для предотвращения разделений цепи. Более того, тип софт-форков, использовавшихся в Биткойне, был специально разработан так, чтобы быть обратно совместимым и защищать ожидаемое поведение предыдущих версий софта. Это значит, что вы можете снова запустить старый кошелёк, о котором вы давно забыли, который валяется на каком-нибудь старом жёстком диске, и он всё ещё будет работать так, как ожидается! Вы будете в состоянии отправлять и получать биткойны, таким же способом, как делали это всегда.
Процесс перехода на новые правила консенсуса называется активацией. Введение Сатоши 1 Мб ограничения на размер блока в сентябре 2010 года является примером софт форка. Он установил жесткий порог на определённой высоте блока. Любой блок, который после этого превысил бы данный лимит, автоматически отвергался. Это был очень небрежный механизм активации. Но в то время сеть была достаточно маленькой, и ставки были настолько малы, что координация была относительно простой и непротиворечивой.
Позднее стали использовать новый механизм активации, использовавший вместо высоты блока временную отметку. Были выпущены два софт форка, использующие этот механизм: BIP16 (P2SH), позволивший совершать транзакции мультиподписи; и BIP30, требующий от всех транзакций иметь уникальный идентификатор.
Затем появился BIP34, требующий, чтобы высота блока отображалась в coinbase данных транзакции, что ввело новый механизм активации, ласково названный ISM, или ЯСБ (ЯвляетсяСуперБольшинством), из-за имени функции C++, призванной проверять, необходима ли активация. Это был первый механизм, который использовал активацию вычислительной мощностью, или майнерскую активацию, или то, что теперь называется MASF (Miner Activated Soft Fork).
Изначальный замысел был в том, что версия блока будет вписываться, начиная с единицы во время каждой такой активации. От блоков новой версии требуется внедрение дополнительного правила: как только 75% блоков из последних 1000 блоков станут принадлежать этой новой версии. Затем, как только значение достигнет 95%, блоки с более ранним номером версии будут автоматически отвергаться.
Этот механизм продолжали использовать в BIP65 (CHECKLOCKTIMEVERIFY) и в BIP66 (Прямые DER подписи). Тем не менее, стали очевидны значительные ограничения этого механизма. В особенности, так как каждое внедрение софт форка увеличивало версию блока на 1, софт-форки могут быть развёрнуты лишь по одному за раз – и до того, как был активирован предыдущий софт-форк, невозможно было активировать другой. Если бы какая либо активация терпела фиаско по конкретной причине, это предотвратило бы развёртывание и активацию последующих софт-форков.
Это привело к разработке BIP9 (Version bits), механизм активации софт-форков, который позволил параллельное развёртывание софт-форков, а также активацию с использованием разных значений в поле “версия” заголовка блока для каждого софт-форка, вместо увеличения номера версии. Как только прошла активация, значение уже не должно быть выставлено и поле может использоваться для будущих активаций. В теории, это позволило бы развернуть до 29 софт-форков одновременно и независимо их активировать. Всё по-прежнему зависит от сигналирования хеширующей мощностью (путём установления значения версии).
Причина, по которой ISM и BIP9 полагаются на сигналирование вычислительными мощностями, состоит в том, что, несмотря на отсутствие требования к узлам обновляться одновременно, майнерам придётся обновляться, чтобы применить новые правила, и убедиться, что они не закончили процедуру майнингом блоков, которые будут отвергнуты узлами, принявшими новые правила. Использование сигналирования майнерами позволило умно координировать процесс – до тех пор, пока супербольшинство майнеров использовали новые правила, риск любого разделения цепи может быть легко устранён. Показатель в 95% был выбран просто для того, чтобы быть “на безопасной стороне”. Тут никогда не подразумевалось голосования. Идея состояла в том, что софт-форки должны обсуждаться и одобряться перед развёртыванием, чтобы убедиться, что они снискали достаточно поддержки со стороны экосистемы. BIP9 в основном стал решением проблемы координации транзита, по максимуму избегавшим внесения изменений в сеть.
Тем не менее, активация BIP66 не прошла полностью гладко, так как несмотря на активное сигналирование со стороны многих майнеров, многие из них на самом деле не применяли новые правила. Это привело к тому, что некоторые майнеры начали выстраивать цепь поверх цепи, которую отвергали узлы, уже внедрившие BIP66. Эти блоки на постоянной основе отвергались сетью, а майнеры, продолжавшие добычу поверх этой цепи – потеряли свои вознаграждения. Это известно под названием “майнинг без подтверждения”, и это общепризнанно вредная практика.
BIP9 впервые использовали для активации пакета софт форков BIP68/BIP112/BIP113, добавившего опкод CHECKSEQUENCEVERIFY, позволяющий устанавливать блокировки по времени. Это развёртывание и активация прошли гладко. Затем появился следующий софт форк, предназначавшийся для активации с использованием BIP9, BIP141 (SegWit), и именно в этом месте… вещи начали распадаться на части… и всё уже никогда не станет таким, как прежде.
Несмотря на невероятное количество данных, распространённых в сообществе и индустрии, этот конкретный софт-форк стал сильно политизированным в результате недопонимания а также того, что можно назвать расхождением интересов, которое открыто не обсуждалось и которое осознали как раз перед развёртыванием софт форка. В частности, несмотря на предупреждение со стороны операторов самых больших пулов, что они будут сигналировать в его поддержку, когда BIP был на самом деле выпущен, достаточно заметное количество хеширующих мощностей отказались делать это. Несколько майнинговых пулов начали провоцировать опасность использованием более старых версий софта Биткойна, несовместимых на уровне консенсуса, и начали выдвигать требования к внесению изменений, которые, если честно, ввергли в ужас большинство разработчиков.
С точки зрения ретроспективы стало понятно, что на майнерскую активацию софт-форков не стоит полагаться, если существует расхождение интересов между майнерами и пользователями. В общем случае, это проверенный и протестированный механизм, который, если правильно исполнен, известен гладкостью своей работы. Однако, в случае противостояния он попросту не работает. BIP9 даёт маленькому количеству вычислительной мощности право вето против активации софт форка, вне зависимости от того, насколько он популярен среди остальных пользователей и индустрии.
Помните, что 95% подразумевалось в качестве порога безопасности, а не голосования. Этот порог был выбран преднамеренно. По правде сказать, даже объема в 60% было бы вполне достаточно, чтобы убедиться в отсутствии постоянного разделения цепи, тем не менее, порог в 95% предназначен для существенного уменьшения количества брошенных блоков (орфанов), и потенциал для временного разделения цепи, существующий на протяжении более чем нескольких блоков.
И помните, что перед появлением активации майнерами Биткойн полагался на временную отметку и высоту блока в процессе активации, зависящем от экономически важных узлов, обновляющих свой софт в качестве поощрения майнерам последовать за ними. Этот тип механизма получил название UASF, или Активируемый Пользователями Софт Форк.
Так что, с учётом уроков прошлого, кажется, что комбинация MASF и UASF будет необходима для будущих актов развёртывания и правильных действий в отношении этих негативных сценариев. Не похоже, что BIP9 снова когда-либо будет использован.
К сожалению, BIP141 (SegWit) уже был развёрнут с использованием механизма BIP9, и во время написания этого поста работает на более чем 80% узлов, согласно данным Люка Джуниора. Повторение процесса развертки с использованием новых механизмов активации – длинный процесс, преисполненный трудностей. Это значит, что пользовательская активация может быть реально проведена в течении короткого промежутка времени, если пользователи будут использовать софт, требующий от майнеров сигналирования в поддержку.
Вот что привело к разработке BIP148 и BIP149 участником Shaolin Fry. Оба могут считаться пользовательскими механизмами активации, но они весьма различны. BIP148 требует, чтобы майнеры стали сигналировать в поддержку BIP141 1 августа 2017 года до тех пор, пока активация не будет завершена; он намного более агрессивен, чем BIP149, который ожидает развёртывания BIP9 в ноябре 2017 года, и заново разворачивает его с использованием BIP8, модификации BIP9, которая позволяет майнерам сигналить, но устанавливает жёсткие временные рамки относительно даты активации. BIP149 может означать, что BIP141 (SegWit) не активируется до конца 2018 года.
Пожалуйста, обратите внимание, что ни BIP148, ни BIP149 не требует от майнеров поддержки SegWit транзакций или включения их в свои блоки! Они просто делают так, чтобы другие майнеры не могли остановить своих коллег в плане их поддержки.
Учитывая проблемы масштабирования, которые испытывает сеть, и существенные улучшения в технологии платёжных каналов, зависящей от правильной работы BIP141 (SegWit), я верю, что текущий конфликт между пользователями и несколькими майнерами требует быстрого решения. BIP141 уже успешно активирован на других блокчейнах, включая Litecoin, чья цена сильно возросла после активации.
Используя BIP148 и настаивая на том, чтобы используемые кошельки и биржи поддерживали его, вы выставляете жёсткие временные рамки для активации. Майнеры должны или активировать в июле, или начать сигналировать начиная с 1 августа до тех пор, пока не завершится процесс. Майнерам придётся позволить другим майнерам находить блоки SegWit, а также позволить пользователям использовать софт с SegWit функционалом. Если они не сделают этого, их блоки не будут приниматься экономическим большинством, и таким образом, они будут не в состоянии продавать намайненные биткойны или собирать их в качестве комиссий, которые захотят платить пользователи и компании, поддерживающие SegWit.
Существует несколько вероятных сценариев, которые могут произойти с учётом того, что несколько майнеров всё ещё настаивают на блокировке SegWit – но все они весьма затратны для таких майнеров, в то время как майнинг на цепочке с SegWit будет оставаться высоко прибыльным. Так как BIP148 является софт-форком, как только он наберет достаточно вычислительной мощности себе в поддержку, вся сеть сконцентриуется вокруг неё как самой длинной валидной цепи и экосистема сможет продолжать строиться на основе последних инноваций в протоколе. Мы наконец-то покончим с шумом и продолжим заниматься бизнесом по строительству будущего!
Источник