Биткоин-сеть. Размеры сети
Пока что мы говорили о возможностях к публикации транзакций и помещению их в блокчейн, как будто они происходят по волшебству. На самом деле всё происходит через биткоин-сеть. Это р2р-сеть, и в неё использованы многие идеи, реализованные в других р2р- сетях, созданных для совсем других целях. В биткоин-сети все узлы равны. Нет никакой иерархии, нет никаких специальных или главных узлов.
Работает она по ТСР и имеет случайную топологию, где каждый узел связан с другими случайными узлами. Новые узлы могут подключаться когда угодно. Вообще можно скачать биткоин-клиент хоть сейчас, вписать свой компьютер как узел, и у него будут такие же права и возможности, как и у любого другого узла в сети.
Со временем сеть меняется, и происходит потому, что узлы появляются и исчезают. Нет ясного и понятного способа покинуть сеть - вместо этого, если от узла давно ничего не слышно (обычно это три часа) - другие узлы начинают о нём забывать. Таким образом, сеть изящно справляется с отключаемыми узлами. Вспомните, что они подключаются случайным образом, и никакой географической топологией тут и не пахнет. Предположим, что вы запускаете новый узел и желаете подключиться к сети. Вы начинаете с простого сообщения, отправляемого на известный вам узел.
Это обычно называется сид-узлом, и есть несколько способов просмотреть списки сид-узлов для подключения. Вы отправляете особое сообщение, в котором говорится "Дайте адреса в сети, о которых вы знаете", и процесс можно повторять, сколько угодно. Затем вы выбираете те, к которым желаете подключиться, и после этого станете полнофункциональной частью биткоин-сети. Есть несколько этапов с элементами случайности, и идеальный исход - это пиринг со случайным набором узлов. Для подключения к сети вам нужно знать только как связаться с одним узлом, который там уже есть.
Для чего нужна эта сеть? Для поддержки блокчейна, разумеется. Для публикации транзакции нужно, чтоб об этом знала вся сеть. Это происходит по простому фладинг-алгоритму, иногда называемого "сарафанным протоколом" (gossip protocol). Если Алиса хочет заплатить Бобу, её клиент создаёт, а узел транслирует эту транзакцию всем узлам, с которым он связан. Каждый узел проводит серию проверок на предмет принятия данных, а затем ретранслирует транзакцию остальным сопряжённым с ним узлам.
Узлы, получившие данные о транзакции, помещают их в пул транзакций, о которых им известно, но которые ещё не попали в блокчейн. Если узел получает данные транзакции, которые уже в пуле, он не транслирует её дальше - это обеспечивает конечность работы сарафанного протокола и защищает транзакции от вечного циркулирования по сети. Вспомним, что каждая транзакция имеет уникальный идентификатор в виде собственного хэша, поэтому в пуле её легко найти.
Как узлы решают, распространять ли данные, когда получают информацию о новой транзакции? Есть четыре проверки. Первая и самая главная - валидация транзакции (она должна соответствовать блокцепи). Узлы пропускают скрипт для каждого предшествующего выхода на высвобождение и удостоверяются, что он возвращает true. Вторая проверка - на двойное расходование. Узел не станет транслировать уже виденную транзакцию - и это третья проверка. И, наконец, четвёртая, по умолчанию - узлы принимают и ретранслируют только стандартные скрипты, записанные в белом списке.
Все эти проверки проводятся на всякий случай - хорошо ведущие себя узлы проводят их для сохранения нормального состояния работы сети, но нигде не записано правило, что узлы обязаны выполнять всё это. Поскольку это р2р-сеть, к которой может присоединиться любой, всегда есть шанс, что узел будет пропускать двойные расходования, нестандартные или откровенно недействительные транзакции - поэтому каждый из узлов проводит проверку самостоятельно.
Поскольку сеть не совсем прозрачна, есть вероятность, что узлы в итоге не сойдутся во мнении относительно транзакций в пуле. Это становится особенно интересно и важно, если есть попытка провести двойной расход. Скажем, Алиса пытается заплатить одними и теми же биткоинами Бобу и Чарли, и отправляет две транзакции почти одновременно. Некоторые узлы услышат о транзакции от Алисы Бобу, а другие - от Алисы Чарли раньше, чем о другой. Когда узел получает данные о любой из них, он добавит её в пул, а вторую будет рассматривать как двойную трату. Узел прекратит трансляцию последней и не станет добавлять её в пул. В итоге какое-то время у узлов будут разные данные о том, какая транзакция должна попасть в блок. Это называется состоянием состязания.
Хорошая новость - всё это совершенно нормально. Тот, кто майнит следующий блок, разобьёт паритет и решит, какая из этих транзакций будет записана в блок. Допустим, что повезло транзакции от Алисы Чарли. Когда узлы, верящие в транзакцию от Алисы Бобу узнают об этом, они выведут эту транзакцию из пулов, поскольку это будет двойным расходованием. Когда об этом же узнают узлы, верящие в транзакцию от Алисы Чарли, они выведут её из пула, потому что она уже попала в блокчейн.
Поэтому никаких несовпадений больше не будет. Поскольку узлы по умолчанию верят в то, что услышат первым, имеет значение топология сети. Если две конфликтующие транзакции или блока объявляются в разных местах сети, они оба будут распространяться в противоположных направлениях, и всё будет зависеть от того, какой узел ближе к какой волне данных.
Конечно, это предполагает, что каждый узел применяет эту логику - однако нет центрального органа, который обязывал бы их делать это, поэтому они могут использовать любую другую логику. Этот вопрос мы снова поднимем в главе 5, когда будем обсуждать, почему в частности майнеры могут склоняться к использованию другой логики, чем та, что задана по умолчанию.
До этого мы обсуждали в основном распространение транзакций. Логика объявления новых блоков, когда майнеры их находят, почти аналогична той, по которой распространяется новая транзакция, и всё это может оказаться в состоянии состязания. Если два валидных блока смайнены одновременно, то в итоговый блокчейн может быть включён только один из них. В итоге это зависит от того, на каких узлах он расположен, а тот, который проигрывает, оказывается заброшенным.
Валидация блока гораздо сложнее, чем в случае транзакций. Вдобавок к валидации заголовка и проверке приемлемости диапазона значения хэша, узлы должны подтвердить каждую транзакцию в блоке. Наконец, узел перенаправит блок, только если он находится на самой длинной ветви блокчейна, который фактически имеет древовидную структуру. Это предотвращает накопление форков.
Но, как и в случае транзакций, узлы могут применять логику по собственному усмотрению - транслировать невалидные блоки, или блоки, которые идут от более ранних точек в блокчейне. Это создаст форк, но это не страшно. Протокол рассчитан на то, чтобы выдержать подобное.
Рис. 3.9. Время распространения блока. На графике показано среднее время, необходимое для достижения различного процента от общего числа узлов сети
На графике 3.9 показано среднее время продвижения новых блоков по каждому узлу в сети. Три линии показывают время продвижения на 25, 50 и 75 процентах. Как видно, оно в целом пропорционально размеру блока, так как полоса пропускания сети довольно узка. Более крупные блоки распространяются по большинству узлов в сети дольше 30 секунд — так что протокол в целом не слишком эффективен.
В интернете полминуты — это довольно долго. В проекте биткоина простая сеть с небольшими конструкциями, где узлы равны и могут входить и выходить из сети, сочли более важным, чем эффективность, поэтому блоку может понадобиться пройти через множество узлов, прежде чем он достигнет самых отдалённых частей сети. Если бы сеть была организована наоборот, путь между узлами мог бы быть устроен гораздо короче.
Размеры сети. Измерить размеры сети довольно сложно — она динамична, а центрального органа в ней нет. В разных исследованиях даны разные оценки. С одной стороны, утверждают, что в определённые моменты в качестве узла работал миллион IP. С другой стороны говорят о постоянной связи между 5-10 тысячами узлов, которые проводят полную валидацию всех получаемых транзакций.
Это может показаться неожиданно низким числом, однако на момент написания нет данных о том, растёт или падает число узлов на самом деле Требования по хранению. Полностью валидирующие узлы должны всегда оставаться на связи, чтобы получать все данные. Чем дольше узел отключён, тем больше ему придётся узнать после подключения.
Такие узлы часто должны хранить весь блокчейн и нуждаются в хорошей связи для обеспечения возможности узнавать о новых транзакциях и передавать их дальше. Требования по хранению сейчас ограничиваются несколькими десятками гигабайт (см. рис. 3.10), что вполне в пределах возможностей среднего домашнего компьютера.
Рис. 3.10. Размер блокчейна. Полностью валидирующие узлы должны хранить весь блокчейн, размер которого на конец 2014 составляет более 26 Гб
Наконец, полностью валидирующие узлы должны поддерживать весь набор неизрасходованных выходов по транзакциям, то есть — коинов, которые доступны для расхода. В идеале они должны храниться в ОЗУ, чтобы при появлении данных о новой возможной транзакции в сети узел мог быстро выходы, на которые она претендует, запустить скрипты, проверить валидность подписей и добавить транзакцию в пул. К середине 2014 в блокчейне было более 44 миллионов транзакций, из которых 12 были неизрасходованными. К счастью, этого всё равно слишком мало, чтобы заполнить собой гигабайт оперативной памяти при эффективной структуре данных.
Лёгкие узлы. В отличие от полностью валидирующих узлов, лёгкие узлы, также известные, как тонкие клиенты или SPV-клиенты (от simple payment verification - простое подтверждение платежа), хранят не весь блокчейн, но только его фрагменты, необходимые им для верификации отдельных транзакций, под которые они настроены. Фактически большинство узлов сети битокина именно такие. Если вы, например, используете программу-кошелёк, она, как правило, включает в себя лёгкий узел. Узел загружает заголовки блоков и транзакции, которые соответствуют выплатам по вашим адресам. Лёгкий узел не имеет того же уровня безопасности, что и полностью валидирующий.
Поскольку он оперирует лишь заголовками, то проверяет он только то, насколько сложно было смайнить блоки, но не валидность каждой включённой в него транзакции, поскольку он не имеет в своём распоряжении истории транзакций и не знает набора неизрасходванных выходов. Такие узлы могут подтверждать только те транзакции, которые касаются их непосредственно, и потому полагаются на полностью валидирующие узлы в вопросе подтверждения остальных транзакций.
Это не самый плохой компромисс в смысле безопасности. Предполагается, что всегда есть полностью валидирующие узлы, которые выполняют самую чёрную работу, и если майнеры станут заниматься этим блоком, что очень недёшево, они наверняка подстрахуются не один раз. Экономия средств для лёгкого узла очевидна. Заголовки блоков занимают 0,001 часть всего блокчейна. Вместо того, чтобы хранить десятки гигов, хранятся лишь десятки мегабайт. Таким образом даже смартфон может работать как лёгкий узел.
Поскольку биткоин основан на открытом протоколе, в идеале может быть много разных вариантов применения, которые плавно друг с другом взаимодействуют Если в одном из них завёлся баг, едва ли он навредит всей сети. Протокол уже успешно перевнедрялся - есть имплементации на С++ и Go, и некоторые сейчас разрабатывают другие версии. Однако, большая часть узлов в сети по факту оперирует биткоин-библиотекой, написанной на С++, которая обслуживается разработчиками ядра биткоина, и некоторые из них работают на устаревших версиях, которые давно не обновлялись. Как бы там ни было, большинство в той или иной форме используют один и тот же клиент.
Дата добавления: 2023-05-18; просмотров: 382;