Перейти к содержимому
buybitcoinsmart

Глоссарий / Справочник разработчика

MSG_WITNESS_BLOCK

Что такое MSG_WITNESS_BLOCK?
Тип инвентаря с данными свидетеля (witness block) описывает, как узел, поддерживающий segwit, запрашивает блок в расширенной сериализации, со всеми подписями на месте, а не удаленными.

Определено в BIP-144.

Два узла могут хранить один и тот же блок и расходиться в том, сколько в нем байт. MSG_WITNESS_BLOCK имеет код 0x40000002, это обычный запрос блока с добавленным битом свидетеля, и он существует с тех пор, как segregated witness активировался в блоке 481 824 24 августа 2017 года. Если вы запускаете собственный узел, именно этот запрос загружает подписи, которые нужны вашей машине, прежде чем она начнет доверять цепочке.

Как это работает

Bitcoin Core хранит два способа записи одного и того же блока и выбирает между ними в зависимости от того, кто запрашивает.

Флаг свидетеля представляет собой один старший бит, 0x40000000. Добавьте его к типу инвентаря блока, который равен 2, и получите 0x40000002. BIP144 ввел и этот флаг, и служебный бит NODE_WITNESS со значением 8, который узел сообщает в своем сообщении version, чтобы указать, что может отдавать более полные данные. Флаг появляется только в запросе getdata. Объявления передаются как обычные инвентари блоков, потому что объявление представляет собой всего лишь хеш, а хеш в обоих случаях одинаков.

Именно из-за этого последнего пункта две сериализации вообще могут сосуществовать. Заголовок блока фиксирует корень Меркла, построенный из txid, а txid вычисляется по транзакции без ее свидетеля. Удалите все подписи, и хеш блока все равно даст тот же самый идентификатор размером 32 байта. Данные свидетеля фиксируются отдельно, в выходе транзакции coinbase, скрипт которого занимает не менее 38 байт и начинается с четырехбайтового тега 0xaa21a9ed, за которым следует корень Меркла свидетеля размером 32 байта.

Разница сильнее всего проявляется в размере. Ограничение на блок составляет 4 000 000 единиц веса, которые считаются как утроенный размер без данных свидетеля плюс полный размер, что позволяет блоку, нагруженному данными свидетеля, приближаться к 4 МБ в сети. Блок 774 628, добытый 1 февраля 2023 года, составил примерно 3,96 МБ, и почти все это одна надпись (inscription), размещенная в пространстве свидетеля. Примените эту формулу веса в обратном порядке, и у блока такого размера в его форме без данных свидетеля почти ничего не останется. Старый пир, запросивший устаревшую (legacy) сериализацию, получил бы скелет и ничего из полезной нагрузки, и именно поэтому такие пиры считаются неспособными проверять текущие блоки.

Где это видно

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

Запустите bitcoind с категорией отладки net, и строки getdata будут проходить перед вами на протяжении всей начальной загрузки блоков, и каждая из них помечена флагом свидетеля, потому что современный узел загружает блоки только у пиров, поддерживающих данные свидетеля. RPC-вызов getpeerinfo разбивает отправленные и полученные байты по типам сообщений, поэтому легко заметить, как трафик блоков доминирует в синхронизации. Bitcoin Core 23.0 добавил getblockfrompeer, который запрашивает у одного указанного пира один конкретный блок по хешу и получает форму с данными свидетеля.

Обрезанные (pruned) узлы усложняют картину. Узел, работающий с включенной обрезкой, минимально допустимое значение которой составляет 550 МиБ, объявляет NODE_NETWORK_LIMITED и отдает только последние 288 блоков, примерно двое суток истории. Запросите у него что-то более старое, и ничего не придет.

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

MSG_WITNESS_BLOCK vs MSG_BLOCK

MSG_BLOCK запрашивает тот же блок с удаленными подписями, и теперь это устаревший (legacy) запрос. Оба типа называют блок одним и тем же хешем, и на оба отвечают сообщением block. Разница в том, присутствуют ли байт-маркер, байт-флаг и стеки свидетеля внутри каждой транзакции. Узел, который запрашивает MSG_BLOCK для недавнего блока, не может проверить в нем ни одной segwit-траты, поэтому Bitcoin Core оставляет эту форму для пиров, которые никогда не сообщали NODE_WITNESS.

Не путать с

Часто задаваемые вопросы

Почему у блока два разных размера?

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

Читайте далее

Связанные термины

Еще в разделе «Справочник разработчика»

Читать эту страницу на английском