Compact Blocks — способ передавать блоки Bitcoin по BIP 152 с меньшим количеством повторяемых данных. Сам блок не уменьшается, а правила не смягчаются: получатель должен восстановить всё содержимое и проверить его перед принятием.
Анна хочет отправить Петру новый блок, но многие транзакции у него уже есть. Блок объединяет транзакции в пакет, добавляемый в общую историю. Посылать все — значит повторять данные. Механизм Compact Blocks передаёт заголовок и список коротких меток для поиска знакомых транзакций. Заголовок — короткая часть блока с основными сведениями, в том числе ссылкой на предыдущий блок и контрольным отпечатком транзакций. Для технического читателя: метки имеют длину 48 бит, то есть 6 байт, и получаются усечением результата функции SipHash-2-4. Её параметры выводятся из заголовка и дополнительного числа для этой передачи, называемого nonce. Поэтому метка не является постоянным именем транзакции для всей сети Bitcoin. [1] [2] [7]
Список заменяет не всё. Анна отправляет выбранные транзакции полностью вместе с их позициями в блоке. Обычный пример — Coinbase Transaction, первая транзакция блока, назначающая награду за майнинг; к одноимённой бирже она отношения не имеет. Она создаётся именно для этого блока, поэтому среди ожидающих транзакций Петра её обычно нет. Полные записи и короткие метки дополняют друг друга при восстановлении. [1] [2]
Mempool Петра — местный набор транзакций, известных его узлу, но ещё не подтверждённых в принятой цепочке. Для доступных транзакций он вычисляет такие же короткие метки и ищет совпадения со списком Анны. Он не предполагает, что у всех одинаковый набор. Поскольку метка иногда соответствует нескольким транзакциям, само совпадение ещё не доказывает окончательно, что содержимое верно. [1] [2]
Если позиции пусты или неоднозначны, Пётр запрашивает конкретные транзакции по их позициям. Запрос называется getblocktxn, ответ с транзакциями — blocktxn. Названия можно не запоминать: важно запросить реальные данные, а не угадывать содержимое. Дополнительный запрос и ответ требуют времени. Если восстановление не удаётся, можно скачать блок целиком. [1] [3]
Пётр должен восстановить точные транзакции в правильном порядке и проверить их связь с заголовком. Merkle Tree сводит транзакции к контрольному отпечатку и помогает проверять такую связь. Однако правильная сборка не заменяет проверки правил. Full Node — это программа, с помощью которой Пётр самостоятельно проверяет правила Bitcoin, например право расходовать средства и размер награды. Цифровая подпись подтверждает разрешение на платёж с помощью закрытого ключа — секретного числового значения, не раскрывая сам ключ. Компактная передача не делает исключений для недействительного блока. [1] [8]
Соседние узлы договариваются о режиме через sendcmpct. В быстром варианте сообщение cmpctblock с данными для восстановления сразу объявляет новый блок. После обязательных предварительных проверок отправитель может передавать его до завершения всех проверок транзакций. В частности, нужно проверить связь с проверенной цепочкой, Proof of Work как доказательство вычислительной работы и связь заголовка с транзакциями. Получатель всё равно полностью проверяет блок перед принятием в свою историю. [1] [4]
Другой вариант сначала объявляет уже проверенный блок через inv или headers. Пётр запрашивает компактные данные, если они нужны. Так можно избежать ненужной передачи блока, уже полученного другим путём, ценой дополнительного шага обмена. Оба режима могут экономить данные по сравнению с повторной отправкой всех транзакций. Разница в моменте отправки и необходимости предварительного запроса, а не в требованиях к действительности блока. [1] [7]
У двух разных транзакций может быть одинаковая короткая метка. Это называется коллизией. Как у двух людей с одинаковыми инициалами: сокращения уже недостаточно, чтобы различить их. В зависимости от места проблемы программа запрашивает дополнительные данные или скачивает полный блок. Коллизия не взламывает подписи Bitcoin и не превращает недействительный блок в действительный. Проверять нужно реальное содержимое, а не просто совпадение коротких меток. [1] [2]
Версия 2 компактного протокола поддерживает SegWit, отделяющий подписи и другие проверочные данные в часть witness. Она использует wtxid, идентификатор с учётом этих данных, вместо txid, который их не учитывает. Полные транзакции передаются с необходимыми данными witness по BIP 144. Их не отбрасывают, чтобы посылка выглядела меньше. Версия протокола передачи также не является номером версии самого блока. [1] [6]
Если Анна и Пётр знают много общих транзакций, блок передаётся с гораздо меньшим количеством повторных данных. Это помогает и домашнему соединению при внезапном поступлении блока. При малом пересечении наборов дополнительные запросы уменьшают экономию. Главная цель — сократить передаваемые данные; быстрая доставка является возможной выгодой, а не обещанием нулевого ожидания или фиксированного размера сообщения. Нового предела размера блоков Bitcoin это не вводит. [5] [7]
Для полной картины прочитайте эту статью вместе с Block Propagation, Initial Block Download, Eclipse Attack, vByte, Bitcoin, Coinbase-транзакция. На эту статью также ссылаются Stale Block, Eclipse Attack, Selfish Mining, Block Propagation.