Вики ZooBC
Безопасность и архитектура

Финальность и откат

Блок в ZooBC становится окончательным двумя путями. Как только он оказывается глубже 720 блоков (3 часов), ни один узел, идущий в ногу с сетью, не откатит его. А как только spine-блок, соподписанный двумя третями мест, называет его — или более поздний блок — своей контрольной точкой, ни один узел вообще не реорганизуется ниже него, какой бы вес ни заявляла конкурирующая ветвь. Узел, оказавшийся по неверную сторону этих пределов, там не остаётся: он объявляет себя застрявшим и восстанавливается из сети.

Откат в жёстких пределах

Узлы ZooBC следуют самой тяжёлой ветви (см. Выбор ветви и накопленная сложность). Когда узел узнаёт о более тяжёлой ветви, он откатывает свои недавние блоки до точки, где две ветви разошлись, а затем применяет блоки другой ветви, проверяя каждый. Откат восстанавливает каждую таблицу состояния до целевой высоты по версионированным строкам, включая coinbase удалённых блоков.

У этого отката есть жёсткий предел, max_rollback_height: 720 блоков в mainnet, 3 часа при 15 секундах на блок, и 60 блоков (15 минут) в devnet. Ветвь, для которой понадобился бы более глубокий откат, отклоняется, каким бы ни был её вес.

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

Случай 1: расхождение в пределах последних 720 блоков откатывается, и применяется более тяжёлая ветвь. Случай 2: расхождение глубже 720 отклоняется; узел, отрезанный дольше, становится застрявшим и восстанавливается из снимка spine-цепочки, как только пиры подтверждают более тяжёлую ветвь.
Случай 1: расхождение в пределах последних 720 блоков откатывается, и применяется более тяжёлая ветвь. Случай 2: расхождение глубже 720 отклоняется; узел, отрезанный дольше, становится застрявшим и восстанавливается из снимка spine-цепочки, как только пиры подтверждают более тяжёлую ветвь.

Нижняя граница контрольных точек

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

Ни одна реорганизация её не пересекает. Узел отклоняет форк, точка расхождения которого лежит ниже финализированной высоты, ещё до того, как загрузит хотя бы один блок, и отклоняет снова, если его когда-либо попросят удалить блоки ниже неё. Spine-блоку нужны соподписи двух третей зарегистрированных мест, и каждый подписант сначала сверяет его содержимое со своей собственной цепочкой, поэтому контрольная точка — это заявление реестра в целом. Каждый честный узел считает её окончательной, как только её сохраняет, не дожидаясь следующих spine-блоков.

Почему контрольная точка глубже предела отката

Здесь встречаются два числа. Узел может откатиться на 720 блоков. А контрольная точка spine-цепочки, как и снимок, который она называет, описывает цепочку на 760 блоков ниже вершины (main_snapshot_min_height).

Если бы контрольная точка была мельче предела отката, spine-цепочка могла бы закрепить блок, который законная реорганизация ещё могла бы заменить, и подписанная контрольная точка разошлась бы с цепочкой, которой следуют все. Поэтому построитель генезиса требует, чтобы main_snapshot_min_height превышал max_rollback_height как минимум на 20 блоков. В mainnet используется 760 против 720, запас в 40 блоков; devnet сохраняет ту же форму с 80 против 60. Каждый блок, который называет контрольная точка, уже находится за пределами любого допустимого отката.

Линейка назад от вершины: блоки от 0 до 720 ещё могут быть откачены, от 720 до 760 — запас не меньше 20, а на 760 контрольная точка и снимок отмечают окончательное. Devnet: откат 60, глубина 80.
Линейка назад от вершины: блоки от 0 до 720 ещё могут быть откачены, от 720 до 760 — запас не меньше 20, а на 760 контрольная точка и снимок отмечают окончательное. Devnet: откат 60, глубина 80.

Отрезанные узлы: застревание и восстановление

Узел, отрезанный дольше предела отката, может обнаружить, что остальная сеть последовала за более тяжёлой ветвью, до которой он не может дотянуться. Он не откатывается к ней, но и не продолжает в одиночку вечно.

Когда как минимум три зарегистрированных пира подтверждают более тяжёлую ветвь, лежащую вне досягаемости, узел объявляет себя застрявшим и прекращает создавать блоки на своей ветви. Собственный детектор застревания узла, локальное правило, кроме того, отслеживает 10 подряд неудачных разрешений форка на одной высоте, как минимум с 2 пирами, в течение как минимум 1 800 секунд (30 минут). При включённом auto_resync, что по умолчанию начиная с версии 0.5.8, застрявший узел отбрасывает свою локальную цепочку и восстанавливает её из сети, начиная с контрольных точек и снимков spine-цепочки (см. Снимки и быстрая синхронизация).

Отставший узел следует за реестром

Узел, вершина которого старше 7 200 секунд (2 часов), не доверяет первому попавшемуся пиру, утверждающему, что он впереди. Он следует вершине, о которой сообщают как минимум две трети выборки зарегистрированных пиров (не меньше ceil(2 × n / 3) из n пиров, где n не меньше 3).

В сравнении с вероятностной финальностью

В Proof of Work уверенность в блоке растёт с его глубиной, но никогда не становится полной; пользователи Bitcoin часто ждут шесть блоков, прежде чем считать платёж окончательным. ZooBC заменяет эту привычку правилами: жёсткий предел отката в 3 часа и соподписанная контрольная точка примерно раз в сутки, ниже которой история не меняется. Цена в том, что узел, отрезанный больше чем на 3 часа на ветви меньшинства, не может вернуться откатом; вместо этого он восстанавливается.

См. также