Как стать автором
Обновить

Особенности обновлений узлов децентрализованных блокчейн-систем

Время на прочтение4 мин
Количество просмотров1.4K
Вопросы управления изменениями сами по себе достаточно сложны. Но при обновлении программного обеспечения распределенной систем, узлы которых принадлежат различным зонам ответственности, какими являются большинство блокчейн-систем возникают специфические не интуитивные проблемы, про которые иногда забывают даже опытные разработчики. Эта статья написана в некотором смысле как шпаргалка, что бы самому реже про эти тонкости забывать

Блокчейн представляет из себя распределенную базу данных со множеством реплик. У каждой реплики (узла) свой владелец, который принимает решение провести обновление или нет.
Как можно догадаться база данных организована в виде цепочки блоков, в каждом блоке собран набор транзакций (операций по изменению состояния БД). Отдельные транзакции создаются пользователями блокчейна и передаются узлам сети, которые и объединяют их в блоки.
Создавший блок узел (обычно называемый майнером или генератором) рассылает его другим узлам, которые проверяют его правильность, после чего присоединяют его к своей цепочке и обновляют состояние БД. Правильность блока определяется правильностью включенных в него транзакций, а так же правом узла его выпустить (определяется «алгоритмом консенсуса»). Когда несколько узлов создали разные блоки консенсус определяет, какая цепочка лучше, и следующие блоки должны присоединяться к ней. Как правило, лучшей признается цепочка, генераторы которой обладали большим количеством ресурсов — вычислительной мощности или количеством токенов.

Если разные узлы используют разное программное обеспечение, они могут признавать правильными или неправильными разные блоки, из-за чего сеть может распасться на отдельные сегменты с несовместимыми состояниями базы данных.

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

Простейший случай — новая версия запрещает некоторые блоки, которые были разрешены старой, не разрешает ни чего нового и не изменяет алгоритмов обработки. Если большинство, достаточное для генерации лучшей цепочки, одновременно перейдет на новую версию, то необновленные узлы продолжат принимать блоки, созданные обновленными узлами, а если сами создадут неправильный блок, который будет отвергнут большинством, вынуждены будут перейти на лучшую цепочку. Это часто называют soft fork, то есть мягкое, временное разделение сети. Но владельцы узлов живут в разных часовых поясах и не всегда возможно одновременно выполнить обновление. Появляется зазор, в который может некоррекный блок попасть в блокчейн и не дать большинству прийти к консенсусу по поводу лучшей цепочки. Если запрет не очень существенный, его можно привязать к «высоте» (номеру блока в цепочке).

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

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

Второй случай — обновление может разрешить некоторые блоки, которые были запрещены старой версией. Например, такими обновлениями будут введение новых операций, расширение виртуальной машины смарт-контрактов. Как не странно, это более сложный случай. Когда большинство обновилось и начало производить новые блоки, не обновившееся меньшинство не сможет принять лучшую цепочку и продолжит майнить свою. Таким образом сеть распадется на две, что плохо скажется на использовании ресурсов, надежности и, наиболее важно, доверии пользователей, которым придется выбирать, к узлам какой половины обращаться. Что бы решить эту проблему, в таких обновлениях задействуется консенсус. Новая возможность становится доступна не сразу, а только после того, как за нее проголосуют большинство узлов в сети. Пока идет голосование, владельцы узлов получают возможность обновиться. После успешного голосования необновившие узлы теряют возможность подключиться к общей сети. Такая ситуация именуется hard fork, то есть жесткое, необратимое деление сети.

Иногда удобно совместить оба подхода. При обнаружении ошибок проще и быстрее запретить транзакции, которые могут ее использовать, а потом, отдельным обновлением, исправить ошибку и разрешить использование некоторых транзакций.

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

Раз обновление такое сложное, возникает желание производить его как можно реже. Особенно хочется не делать ошибок, тем более что скорее всего удалить ошибочный код не получится. Я надеюсь, это будет серьезным стимулом внедрения формальных методов и использовать надежные технологии, но пока проблемы обычно решаются на уровне бизнес-процессов управления проектом.
Теги:
Хабы:
+1
Комментарии0

Публикации

Изменить настройки темы

Истории

Работа

Ближайшие события