Глоссарий / Узлы и ПО
Синхронизация сначала по заголовкам
- Что такое синхронизация сначала по заголовкам?
- Синхронизация сначала по заголовкам представляет собой стратегию запуска, при которой узел скачивает и проверяет всю цепочку заголовков блоков по 80 байт, прежде чем запрашивать тела блоков, а затем загружает эти тела параллельно.
Разделение загрузки на два этапа делает первую синхронизацию практически выполнимой. Bitcoin Core работает так с версии 0.10.0, выпущенной в феврале 2015 года: загрузка блоков превратилась из одной упорядоченной очереди в задачу, распределяемую между всеми подключенными пирами. Если вы запускаете собственный узел, чтобы проверять собственный баланс, именно поэтому первоначальная синхронизация завершается за часы, а не за дни.
Как это работает
Синхронизация сначала по заголовкам начинается с того, что узел запрашивает у пиров заголовки, а не блоки.
Узел отправляет сообщение getheaders с локатором блоков, компактным списком хешей, который описывает, где он, по его мнению, сейчас находится. Пир отвечает сообщением headers, содержащим до 2000 заголовков по 80 байт каждый, поэтому один ответ покрывает примерно две недели цепочки. Для каждого заголовка узел проверяет, что тот указывает на родителя, который у него уже есть, и что его хеш соответствует сложности, заявленной в поле nBits, после чего снова запрашивает с новой вершины, пока ни у одного пира не остается ничего более нового.
Загрузка тел начинается только после того, как этот каркас построен. Поскольку узел уже знает хеш каждого нужного ему блока, он может запрашивать разные участки у нескольких пиров одновременно, а не стоять в очереди за одним соединением. Bitcoin Core ограничивает число запросов блоков, оставленных без ответа у одного пира, шестнадцатью в текущем коде, и отключает пира, который задерживает окно. Блоки, пришедшие раньше своих родителей, просто удерживаются, что положило конец старой практике хранить непроверенные данные на диске.
С заголовками связаны две меры предосторожности. Программа не примет цепочку, пока суммарное доказательство работы по имеющимся у нее заголовкам не превысит минимальную величину, зашитую в выпуск, так что пир не может заманить новый узел на дешевую боковую цепочку из легких блоков. Отдельно настройка assumevalid указывает хеш недавнего блока, поставляемый с каждой версией: подписи в блоках, погребенных под ним, повторно не проверяются, что снимает часы вычислений на эллиптических кривых, при этом каждое правило, зависящее от текущего состояния цепочки, по-прежнему соблюдается.
Где это видно
Синхронизация сначала по заголовкам проявляется как два счетчика, которые расходятся, пока узел догоняет цепочку.
Вызовите getblockchaininfo во время первой синхронизации, и поле headers будет намного опережать поле blocks, часто на сотни тысяч. Графический клиент говорит то же самое простыми словами: он может оценить время завершения только после того, как заголовки получены, потому что до этого он не знает, какой путь еще предстоит пройти. Наблюдение за тем, как эти два числа сближаются, и есть честный индикатор прогресса.
Легкое программное обеспечение намеренно останавливается после первой половины. SPV-кошелек, клиент компактных фильтров или узел Lightning, работающий без собственной серверной части цепочки, хранит только заголовки и надстраивает над ними доказательства Меркла или фильтры. Именно поэтому кошелек на смартфоне может проверять свою историю через мобильный интернет: заголовки малы и имеют фиксированный размер, а тела блоков не являются ни тем, ни другим.
Синхронизация сначала по заголовкам vs синхронизация сначала по блокам
Синхронизация сначала по заголовкам узнает форму цепочки, прежде чем скачивать ее содержимое, тогда как синхронизация сначала по блокам пыталась делать и то и другое сразу. Старый метод отправлял сообщение getblocks, получал сообщение inv не более чем с 500 хешами блоков и загружал их по одному у того пира, который ответил, так что одно медленное соединение тормозило все, что шло за ним. Все, что приходило не по порядку, не имело другого места, кроме пула ожидания в памяти, который атакующий мог заполнить мусором. Bitcoin Core не синхронизируется так с версии 0.10.0, хотя по-прежнему понимает эти сообщения, чтобы более старое программное обеспечение могло с ним взаимодействовать.