Корректировка сложности – это великое, но, тем не менее, недооцененное нововведение, обеспечивающее бесперебойную работу Биткоина.
Перевод трэда Алекса Вальтца
Корректировка сложности – это великое, но, тем не менее, недооцененное нововведение, обеспечивающее бесперебойную работу Биткоина.
Помимо того, что она обеспечивает предсказуемость предложения Биткоина, она также является..:
- фундаментальным механизмом, обеспечивающим безопасность сети
- саморегулирующимся механизм
- важнейшим компонентом консенсуса
С момента своего появления Биткоин корректировал свою сложность 373 раза.
В течение первого года работы сети сложность не увеличивалась, первое значительное изменение произошло первого января 2010 года, на высоте блока 32,256.
Самые большие изменения сложности составили:
- вверх - 302% на высоте блока 68,544
- вниз - 27% на высоте блока 689,472
Сложность биткоин-майнинга показывает, насколько сложно найти хэш, который обеспечит попадание блока в цепочку. При текущей сложности 30,977,051,760,460 1 из каждых 13,315,579,227,696,403,823,071,581 хэшей SHA256 будет генерировать действительный блок. Действительный блок – это тот блок, хэш которого ниже определенной цели.
Майнинг – это случайный и непредсказуемый процесс. Более того, майнеры могут присоединяться к сети и покидать ее в любое время. Оба эти фактора могут влиять на скорость появления блоков. Сложность регулирует скорость добавления новых блоков в блокчейн.
Корректировка сложности достигает следующих целей:
- Поддерживает постоянство эмиссии новых биткоинов.
- Обеспечивает дальнейшее согласование стимулов майнеров с пользователями и честность первых.
Давайте чуть подробнее остановимся на втором пункте:
Майнеры хэшируют все данные блока вместе с нонсом (случайным числом) до тех пор, пока не найдут хэш блока, который меньше определенной цели. Существует прямая зависимость между целью и сложностью: чем меньше цель, тем сложнее майнить.
Подробнее о биткоин-майнинге можно узнать из одноименной главы книги Яна Прицкера “Изобретаем Биткоин”.
Значение целевого числа хранится в блоке в поле Bits в сжатом формате. Тот факт, что само значение целевого числа хэшируется с остальными данными блока, делает сложность защищенной от подделки. Сложность обычно представляется в десятичном формате.
Целевое число = Максимальная цель / Сложность
Максимальная цель – это цель при сложности равной 1 (минимально возможной сложности). Это значение было выбрано Сатоши. И Максимальная цель, и сложность = 1 были закодированы им в генезис-блоке:
Сложность, равная 420 означает, что потребуется на 420 попыток больше (в среднем), чтобы найти подходящий хэш, чем при самой простой сложности 1. Как уже упоминалось, генезис-блок был намайнен при сложности 1. С тех пор каждые 2016 блоков сложность пересчитывается.
Когда блок добывается, майнер также должен добавить к нему временнýю метку. Эта временнáя метка каждый раз используется для пересчета сложности. Мы стремимся к тому, чтобы новый блок находился каждые 10 минут, поэтому после 2016 блоков мы проверяем, сколько времени в среднем проходило между появлением блоков.
Ожидаемое время: 2016 блоков x 10 минут = 20,160 минут.
Если блоки генерировались быстрее, допустим, каждые 8 минут, то мы получим 2016 x 8 = 16,128, то 20,160 / 16,128 = 1.25.
Новая сложность = 1.25 × Старая сложность
Хэшрейт не известен. Мы лишь знаем, насколько быстро генерируются блоки и используем временные метки в блоках, чтобы оценить хэшрейт сети. Это нельзя назвать точной наукой.
Но и сами временные метки не являются точной наукой.
Как уже говорилось, нам нужен некий эталон времени, чтобы убедиться, что мы корректируем сеть таким образом, что блок будет находиться каждые 10 минут. Когда блок добывается, майнер добавляет время внутрь блока. Но что если его часы сбились или он лжет?
Подробнее о том, как Биткоин узнает который сейчас час – в статье “Биткоин – это время”.
— Зачем майнерам врать? Чтобы получить больше монет!
Позвольте пояснить:
В интересах майнера говорить, что на производство блоков ушло больше времени. Это приведет к понижению сложности при следующей корректировке.
Более низкая сложность → легче добывать монеты.
Для смягчения негативных эффектов этой атаки у Биткоина есть 3 правила:
- Правило MedianPast Time – узел не примет блок, если его временнáя метка не превышает медиану предыдущих 11 блоков.
Это правило консенсуса.
Если оно не выполняется, блоки отклоняются.
https://github.com/bitcoin/bitcoin/blob/4daadce36cfe9baa63c4d7d70de027add03a00df/src/chain.h#L259
- Правило времени будущего блока – временнáя метка не может превышать 2 часа относительно медианного времени, предоставленного пирами узла.
Здесь используется MAX_FUTURE_BLOCK_TIME.
Это правило политики.
Блоки из будущего могут стать действительными в будущем.
https://github.com/bitcoin/bitcoin/blob/4daadce36cfe9baa63c4d7d70de027add03a00df/src/chain.h#L22
- Максимально допустимый разрыв между временем, предоставляемым узлами, и локальными системными часами составляет 90 минут.
Это правило локального клиента.
https://github.com/bitcoin/bitcoin/blob/4daadce36cfe9baa63c4d7d70de027add03a00df/src/chain.h#L38n
- Первое правило гарантирует, что блокчейн продвигается вперед.
- Второе правило гарантирует, что цепочка не продвинется слишком далеко.
- Третье правило является дополнительной защитой.
Самое главное, эти правила говорят нам о том, что управлять временем в Биткоине очень сложно и не всегда можно добиться точных результатов.
Несмотря на то, что сложность корректируется каждые 2016 блоков, она учитывает только 2015 блоков.
Причиной тому ошибка “off-by-1”, допущенная Сатоши.
Она все еще присутствует в коде сегодня, так как ее исправление может привести к хард-форку. Вместо того чтобы проверять, сколько времени прошло между последними блоками каждого периода в 2016 блоков, код сравнивает время между 1-м и 2016-м блоком каждого периода. Как следствие, целевое время добычи блока на самом деле составляет не 10 минут, а 10.005 минут. Эти 0.03 секунды не играют большого значения, но ошибка приводит к появлению двух очень странных вещей.
Вы можете ожидать, что интервал корректировки будет равен двум неделям / 2015 блокам, но все еще более запутанно. Если хэшрейт биткоина абсолютно постоянен, а блоки имеют точные временные метки, сложность будет меняться раз в 2 недели, 20 минут и 1.191658 секунды.
Питер Вюлле высказывался на эту тему в этом трэде.
2-й эффект – это Атака Искажения Времени.
Учитывая правила, упомянутые в выше:
- Временная метка блока > медианы предыдущих 11 блоков
- Временная метка блока < сейчас + некоторый буфер
В рамках этих правил майнер может солгать, что ему потребовалось больше времени на генерацию блоков.
Правило off-by-1 заставляет последний блок текущего периода не пересекаться с первым блоком нового периода. Атакующий может делать это бесконечно и довести сложность до 1. Однако такая атака будет очень заметна и потребует координации действий майнеров.
Помимо временных ограничений, сложность не может изменяться более чем в 4 раза. Это кажется довольно необычным ограничением, но оно служит важной цели.
https://github.com/bitcoin/bitcoin/blob/master/src/pow.cpp#L54
Это правило дополнительно защищает от упомянутой атаки. Также можно изолировать узел от сети и отправлять ему блоки с ложными метками времени. Узел будет обманут, снизив свою сложность, и атакующему будет легче создавать ложные блоки.
Почему каждые 2016 блоков?
2 недели / 10 минут = 2016
Почему не меньше 2016?
Это позволило бы проводить аналогичные изолирующие атаки, как объяснялось выше. Атакующий может изолировать узел и посылать ему блоки с меньшей сложностью. Чтобы увенчаться успехом, любые подобные атаки должны продолжаться в течение 2 недель.
Чтобы дать вам представление о том, насколько высока сложность биткоин-майнинга сегодня, обратимся к следующему примеру:
Мой компьютер Apple M1 Max работает со скоростью 5,8 Мегахэшей в секунду. Мне потребуется 727 миллионов лет, чтобы найти блок при нынешней сложности. Theymos в 2010 году сгенерировал 5 блоков на процессоре Pentium (в 1000 раз медленнее сегодняшних моделей) за один день.
Напоследок я хочу поделиться с вами этим постом в bitcointalk от 2010 года, сделанным Сатоши, когда увеличение сложности с 1 до 1.82 было довольно серьезным достижением: