В точном смысле Orphan Block — блок, непосредственный предшественник которого неизвестен конкретному узлу. В более свободном употреблении так иногда называют Stale Block вне активной цепочки. Ни одно обозначение само не означает мошенничества или дефектного блока: сначала нужно понять, какие данные есть у узла и какой смысл имеется в виду.
Предыдущий блок иногда называют родительским. Для настоящего Orphan Block узел Яны его не знает и не может закончить проверку связи. У Stale Block родитель может быть известен, а весь блок — действителен; просто узел следует другой ветви как активной истории. Bitcoin Developer Guide явно различает эти значения. Увидев orphan в обозревателе блоков, Яна сначала выясняет, отсутствует ли предшественник или блок лишь не остался в основной цепочке. [1]
Разница видна и в Bitcoin Core — программе для работы узла, который проверяет блоки и транзакции по правилам Bitcoin. В Bitcoin Core 29 функция AcceptBlockHeader ищет предшественника по hashPrevBlock, ссылке на его идентифицирующий отпечаток. Если записи в индексе нет, она возвращает prev-blk-not-found. Если родитель известен и помечен недействительным, результат — bad-prevblk. Первое означает «мне не хватает контекста», второе — «ты продолжаешь недействительный блок». Получение отсутствующего предшественника позволяет провести следующие проверки, но само по себе ещё не гарантирует принятия целого блока. [2]
У блока есть заголовок — короткий набор данных для идентификации и связи — и тело с транзакциями. Bitcoin Core 0.10.0 ввёл синхронизацию headers-first: сначала получают и проверяют заголовки, затем блоки можно загружать параллельно. Поэтому узел Яны может знать заголовок предшественника, ещё не имея всего блока на диске. Отсутствующее тело блока — не то же самое, что неизвестный предшественник; иначе обычная загрузка могла бы показаться загадочной неисправностью. [3]
Команда getchaintips в Bitcoin Core 29 показывает Яне, какие концы ветвей знает её узел. active обозначает активную цепочку, valid-fork — полностью проверенную неактивную ветвь. valid-headers означает, что блоки доступны, но не прошли полной проверки; headers-only — что некоторых блоков нет. invalid отмечает ветвь с недействительным блоком. Это не перечень одинаковых проблем. Даже выражение orphaned branches в справке не отменяет этих различий. [4]
Представим два разных блока A и B на высоте 900000. Это наш собственный пример, а не описание конкретного события. Высота — позиция в цепочке, поэтому у конкурирующих блоков она может быть одинаковой. Яна различает их по hash, идентифицирующему отпечатку блока, и previousblockhash, ссылке на предшественника. При выборе между действительными ветвями решает накопленная работа, а не одна высота. Интерфейс RPC для передачи команд программе называет её chainwork: суммарная ожидаемая работа, соответствующая сложностям блоков. [1] [5]
Когда Яна запрашивает через getblock блок вне основной цепочки, Bitcoin Core 29 может вернуть confirmations = -1. Это специальная отметка состояния, а не обычное число подтверждений. Это не обратный отсчёт и не отрицательная глубина реорганизации. Значение также не доказывает отсутствия предшественника. Его нужно читать вместе с идентичностью блока и состоянием ветви; кроме того, узел Яны может не иметь всех блоков, когда-либо увиденных другими участниками. [5]
Награда за блок создаётся особой первой транзакцией coinbase, не связанной с одноимённой биржей. Выход транзакции — это запись определённой суммы в биткоинах и условий, которые нужно выполнить, чтобы её потратить. В Bitcoin Core 29 COINBASE_MATURITY равна 100: выход, созданный на высоте H, впервые можно потратить в действительном блоке на высоте H+100. Важна разница высот, а не прошедшие минуты. Но это условие ожидания не заменяет включения в активную цепочку. Пока блок с наградой остаётся на неактивной ветви, его выхода нет в активном наборе UTXO, учёте ещё не потраченных выходов. Новые блоки в другом месте сами эти деньги не возвращают. [6] [7] [1] [8]
Яна сохраняет hash блока, его предшественника, состояние ветви и версию программы. Добавляет ответы getchaintips и getblock и время их получения. Его она записывает отдельно от поля time в заголовке: время в блоке не равно моменту, когда её компьютер его наблюдал. Запись помогает сравнивать дальнейшие наблюдения, но сама не доказывает атаки, конкретного сбоя сети или глобальной доли orphan-блоков. Прежде всего она описывает состояние одного узла в определённый момент. [4] [5]
Для полной картины прочитайте эту статью вместе с Stale Block, Reorg, Block Propagation, Proof of Work, Bitcoin. На эту статью также ссылаются Stale Block.