Глоссарий / Узлы и ПО
Заголовок сообщения
- Что такое заголовок сообщения?
- Заголовок сообщения в биткоине представляет собой фиксированный конверт из 24 байт, который оборачивает каждое одноранговое сообщение: стартовая строка сети, имя команды, длина полезной нагрузки и контрольная сумма.
Ничто в одноранговом протоколе не описывает само себя, поэтому эту работу выполняет конверт. Его четыре поля никогда не меняют размер и порядок, так что узел читает ровно 24 байта, узнает, сколько еще придет, и обрывает соединение с любым, кто заявляет больше 4 000 000 байт, которые принимает Bitcoin Core. Вы никогда его не увидите, но именно из-за некорректного заголовка соединение с пиром иногда пропадает без объяснений.
Как это работает
Четыре поля заголовка читаются в фиксированном порядке, и каждое определяет, что произойдет дальше.
Байты с 0 по 3 содержат стартовую строку, определяющую сеть. Байты с 4 по 15 содержат команду: имя в нижнем регистре ASCII, дополненное нулевыми байтами до двенадцати символов, поэтому у каждого типа сообщения в биткоине краткое имя, а cmpctblock с его десятью символами стоит близко к пределу. Байты с 16 по 19 содержат длину полезной нагрузки как беззнаковое целое в порядке little-endian. Байты с 20 по 23 содержат контрольную сумму: первые четыре байта двойного SHA-256, вычисленного по полезной нагрузке.
Именно размещение длины перед полезной нагрузкой и есть настоящая мера безопасности этой конструкции. Узел, прочитавший 24 байта, уже знает, не заявляет ли отправитель что-то абсурдное, а Bitcoin Core отклоняет все, что выше 4 000 000 байт, и отключается, не выделяя буфер и не ожидая данных, которые могут никогда не прийти. Если бы длина стояла после тела, пришлось бы полагаться на то, что отправитель остановится сам.
Контрольная сумма заслуживает меньшего доверия, чем обычно получает. Четыре байта хеша выявляют перевернутый бит на плохом канале и ничего не дают против пира, который лжет, поскольку враждебный отправитель просто вычисляет контрольную сумму по тому, что решил отправить. Целостность в биткоине обеспечивается проверкой содержимого по правилам консенсуса, а не этим полем.
В более новом программном обеспечении вся эта структура необязательна. Транспорт версии 2 из BIP324 шифрует соединение и заменяет открытый конверт запутанной разметкой длины плюс однобайтовым коротким идентификатором для самых частых типов сообщений, так что пассивный наблюдатель больше не может прочитать имена команд в трафике. Bitcoin Core поставил это как настройку по выбору в версии 26.0 и включил по умолчанию в более позднем выпуске.
Где это видно
Заголовки сообщений видны в перехвате пакетов и в собственной диагностике узла.
Запустите Bitcoin Core с -debug=net, и журнал будет записывать типы и размеры сообщений для каждого пира; это практический способ увидеть, что на самом деле делает соединение. Записи вида PROCESSMESSAGE: INVALID MESSAGESTART означают, что пир прислал байты, которые не начинались со стартовой строки этой сети; почти всегда это что-то неверно настроенное на другом конце, а не атака. Диссектор биткоина в Wireshark разбирает те же 24 байта, чтобы пометить каждый кадр.
Заголовок сообщения vs заголовок блока
Заголовок сообщения является транспортной упаковкой; заголовок блока представляет собой данные консенсуса, и общего у них только слово. Заголовок сообщения занимает 24 байта, существует только на время одной доставки и отбрасывается, как только полезная нагрузка прочитана. Заголовок блока занимает 80 байт, содержит версию, хеш предыдущего блока, корень Меркла, метку времени, целевую сложность и nonce, и хешируется, чтобы получить доказательство работы, навсегда закрепляющее этот блок. Один является адресной этикеткой на посылке; другой представляет собой то, что внутри.