Сетевой уровень
Последнее обновление страницы: 2 марта 2026 г.
Ethereum - это одноуровневая сеть с тысячами узлов, которые должны быть в состоянии общаться друг с другом с помощью стандартизированных протоколов. "Сетевой уровень" - это набор протоколов, который позволяет этим узлам находить друг друга и обмениваться информацией. Это включает в себя информацию о "беседе" (один ко многим коммуникациям) по сети, а также обмен запросами и ответами между конкретными узлами (один к одной коммуникации). Каждый узел должен соблюдать определенные сетевые правила, чтобы убедиться, что они посылают и получают правильную информацию.
Клиентское программное обеспечение состоит из двух частей (клиентов исполнения и клиентов консенсуса), у каждой из которых есть свой собственный сетевой стек. Помимо общения с другими узлами Ethereum клиенты должны взаимодействовать друг с другом. На этой странице приведено вступительное объяснение протоколов, обеспечивающих эту связь.
Клиенты исполнения распространяют транзакции по одноранговой сети уровня исполнения. Это требует зашифрованной связи между аутентифицированными узлами. Когда валидатор выбран для предложения блока, транзакции из локального пула транзакций узла передаются клиентам консенсуса через локальное RPC-соединение и упаковываются в блоки Beacon. Затем клиенты консенсуса распространяют блоки Beacon по своей p2p-сети. Для этого требуются две отдельные p2p-сети: одна соединяет клиентов исполнения для распространения транзакций, а другая — клиентов консенсуса для распространения блоков.
Предварительные условия
Некоторые знания об узлах и клиентах Ethereum будут полезны для понимания этой страницы.
Уровень исполнения
Сетевые протоколы уровня исполнения разделены на два стека:
-
стек обнаружения: создан на основе UDP и позволяет новому узлу находить другие узлы для подключения
-
стек DevP2P: работает поверх TCP и позволяет узлам обмениваться информацией
Оба стека работают параллельно. Стек обнаружения добавляет новых участников в сеть, а стек DevP2P обеспечивает их взаимодействие.
Обнаружение
Обнаружение — это процесс поиска других узлов в сети. Этот процесс запускается с помощью небольшого набора начальных узлов (bootnodes) — узлов, чьи адреса жестко закодированы (opens in a new tab) в клиенте, чтобы их можно было немедленно найти и подключить клиента к другим узлам. Эти начальные узлы существуют только для того, чтобы представить новый узел набору других узлов — это их единственная цель, они не участвуют в обычных задачах клиента, таких как синхронизация цепи, и они используются только при самом первом запуске клиента.
Протокол, используемый для взаимодействия узлов с начальными узлами, представляет собой модифицированную форму Kademlia (opens in a new tab), которая использует распределенную хеш-таблицу (opens in a new tab) для обмена списками узлов. Каждый узел имеет версию этой таблицы, содержащую информацию, необходимую для подключения к ближайшим узлам. Эта «близость» не является географической: расстояние определяется сходством идентификатора узла. Таблица каждого узла регулярно обновляется в целях безопасности. Например, в протоколе обнаружения Discv5 (opens in a new tab) узлы также могут отправлять «объявления», в которых отображаются подпротоколы, поддерживаемые клиентом, что позволяет узлам договариваться о протоколах, которые они оба могут использовать для связи.
Обнаружение начинается с игры в PING-PONG. Успешный PING-PONG «связывает» новый узел с начальным узлом. Первоначальное сообщение, которое предупреждает начальный узел о появлении нового узла в сети, — это PING. Этот PING включает в себя хешированную информацию о новом узле, начальном узле и временную метку истечения срока действия. Начальный узел получает PING и возвращает PONG, содержащий хеш PING. Если хеши PING и PONG совпадают, соединение между новым узлом и начальным узлом проверяется, и считается, что они «связаны».
После связывания новый узел может отправить запрос FIND-NEIGHBOURS начальному узлу. Данные, возвращаемые начальным узлом, включают список других узлов, к которым может подключиться новый узел. Если узлы не связаны, запрос FIND-NEIGHBOURS завершится неудачно, и новый узел не сможет войти в сеть.
Как только новый узел получает список соседей от начального узла, он начинает обмен PING-PONG с каждым из них. Успешные обмены PING-PONG связывают новый узел с его соседями, обеспечивая обмен сообщениями.
1запуск клиента --> подключение к начальному узлу --> связывание с начальным узлом --> поиск соседей --> связывание с соседямиКлиенты исполнения в настоящее время используют протокол обнаружения Discv4 (opens in a new tab), и ведется активная работа по переходу на протокол Discv5 (opens in a new tab).
ENR: Записи узлов Ethereum
Запись узла Ethereum (ENR) — это объект, содержащий три основных элемента: подпись (хеш содержимого записи, созданный в соответствии с некоторой согласованной схемой идентификации), порядковый номер, который отслеживает изменения в записи, и произвольный список пар «ключ-значение». Это перспективный формат, который упрощает обмен идентифицирующей информацией между новыми узлами и является предпочтительным форматом сетевого адреса для узлов Ethereum.
Почему обнаружение построено на UDP?
UDP не поддерживает проверку ошибок, повторную отправку неудачных пакетов или динамическое открытие и закрытие соединений — вместо этого он просто отправляет непрерывный поток информации цели, независимо от того, успешно ли он получен. Эта минимальная функциональность также приводит к минимальным накладным расходам, что делает этот вид соединения очень быстрым. Для обнаружения, когда узел просто хочет заявить о своем присутствии, чтобы затем установить формальное соединение с другим узлом, UDP достаточно. Однако для остальной части сетевого стека UDP не подходит. Обмен информацией между узлами довольно сложен и поэтому требует более полнофункционального протокола, который может поддерживать повторную отправку, проверку ошибок и т. д. Дополнительные накладные расходы, связанные с TCP, стоят дополнительной функциональности. Поэтому большая часть P2P-стека работает поверх TCP.
DevP2P
DevP2P сам по себе представляет собой целый стек протоколов, которые Ethereum реализует для создания и поддержания одноранговой сети. После того как новые узлы входят в сеть, их взаимодействие регулируется протоколами стека DevP2P (opens in a new tab). Все они работают поверх TCP и включают транспортный протокол RLPx, проводной протокол и несколько подпротоколов. RLPx (opens in a new tab) — это протокол, управляющий инициацией, аутентификацией и поддержанием сеансов между узлами. RLPx кодирует сообщения с использованием RLP (Recursive Length Prefix), что является очень эффективным с точки зрения занимаемого пространства методом кодирования данных в минимальную структуру для отправки между узлами.
Сеанс RLPx между двумя узлами начинается с первоначального криптографического рукопожатия. Это включает в себя отправку узлом сообщения аутентификации, которое затем проверяется другим узлом. При успешной проверке другой узел генерирует сообщение с подтверждением аутентификации для возврата узлу-инициатору. Это процесс обмена ключами, который позволяет узлам обмениваться данными конфиденциально и безопасно. Успешное криптографическое рукопожатие затем заставляет оба узла отправить друг другу сообщение «hello» «по каналу связи». Проводной протокол инициируется успешным обменом сообщениями «hello».
Сообщения «hello» содержат:
- версию протокола
- ID клиента
- порт
- ID узла
- список поддерживаемых подпротоколов
Это информация, необходимая для успешного взаимодействия, поскольку она определяет, какие возможности являются общими для обоих узлов, и настраивает связь. Существует процесс согласования подпротоколов, в ходе которого сравниваются списки подпротоколов, поддерживаемых каждым узлом, и те, которые являются общими для обоих узлов, могут использоваться в сеансе.
Наряду с сообщениями «hello» проводной протокол также может отправлять сообщение «disconnect», которое предупреждает другой узел о том, что соединение будет закрыто. Проводной протокол также включает сообщения PING и PONG, которые периодически отправляются для поддержания сеанса открытым. Таким образом, обмены по протоколам RLPx и проводному протоколу закладывают основы для связи между узлами, обеспечивая каркас для обмена полезной информацией в соответствии с конкретным подпротоколом.
Подпротоколы
Проводной протокол
После подключения узлов и запуска сеанса RLPx проводной протокол определяет, как узлы обмениваются данными. Изначально проводной протокол определял три основные задачи: синхронизация цепи, распространение блоков и обмен транзакциями. Однако, когда Ethereum перешел на proof-of-stake, распространение блоков и синхронизация цепи стали частью уровня консенсуса. Обмен транзакциями по-прежнему входит в компетенцию клиентов исполнения. Обмен транзакциями означает обмен ожидающими транзакциями между узлами, чтобы сборщики блоков могли выбрать некоторые из них для включения в следующий блок. Подробная информация об этих задачах доступна здесь (opens in a new tab). Клиенты, поддерживающие эти подпротоколы, предоставляют к ним доступ через JSON-RPC.
les (легкий подпротокол Ethereum)
Это минимальный протокол для синхронизации легких клиентов. Традиционно этот протокол использовался редко, потому что полные узлы должны обслуживать данные для легких клиентов без стимулирования. Поведение по умолчанию клиентов исполнения не предполагает обслуживание данных легких клиентов по протоколу les. Более подробную информацию можно найти в спецификации (opens in a new tab) les.
Snap
Протокол snap (opens in a new tab) — это необязательное расширение, которое позволяет узлам обмениваться снимками недавних состояний, что позволяет им проверять данные учетных записей и хранилища без необходимости загружать промежуточные узлы дерева Меркла.
Wit (протокол свидетелей)
Протокол свидетелей (wit) (opens in a new tab) — это необязательное расширение, которое позволяет обмениваться свидетелями состояния между узлами, помогая синхронизировать клиентов с вершиной цепи.
Whisper
Whisper был протоколом, целью которого была доставка защищенных сообщений между узлами без записи какой-либо информации в блокчейн. Он был частью проводного протокола DevP2P, но теперь устарел. Существуют и другие связанные проекты (opens in a new tab) с похожими целями.
Уровень консенсуса
Клиенты консенсуса участвуют в отдельной одноранговой сети с другой спецификацией. Клиентам консенсуса необходимо участвовать в распространении блоков, чтобы они могли получать новые блоки от других узлов и транслировать их, когда наступает их очередь предлагать блок. Подобно уровню исполнения, это сначала требует протокола обнаружения, чтобы узел мог находить другие узлы и устанавливать безопасные сеансы для обмена блоками, аттестациями и т. д.
Обнаружение
Подобно клиентам исполнения, клиенты консенсуса используют discv5 (opens in a new tab) поверх UDP для поиска других узлов. Реализация discv5 на уровне консенсуса отличается от реализации на уровне клиентов исполнения только тем, что она включает адаптер, подключающий discv5 к стеку libP2P (opens in a new tab), что делает DevP2P устаревшим. Сеансы RLPx уровня исполнения устарели в пользу рукопожатия защищенного канала libP2P.
ENR
ENR для узлов консенсуса включает публичный ключ узла, IP-адрес, порты UDP и TCP и два специфичных для консенсуса поля: битовое поле подсети аттестации и ключ eth2. Первое упрощает узлам поиск других узлов, участвующих в конкретных подсетях распространения аттестаций. Ключ eth2 содержит информацию о том, какую версию форка Ethereum использует узел, обеспечивая подключение узлов к правильной сети Ethereum.
libP2P
Стек libP2P поддерживает все коммуникации после обнаружения. Клиенты могут подключаться и прослушивать IPv4 и/или IPv6, как определено в их ENR. Протоколы на уровне libP2P можно подразделить на домены gossip и req/resp.
Gossip
Домен gossip включает всю информацию, которая должна быстро распространяться по сети. Сюда входят блоки Beacon, доказательства, аттестации, выходы и слэшинги. Это передается с использованием libP2P gossipsub v1 и зависит от различных метаданных, хранящихся локально на каждом узле, включая максимальный размер полезной нагрузки gossip для приема и передачи. Подробная информация о домене gossip доступна здесь (opens in a new tab).
Запрос-ответ
Домен запроса-ответа содержит протоколы для клиентов, запрашивающих конкретную информацию у других узлов. Примеры включают запрос определенных блоков Beacon, соответствующих определенным корневым хешам или находящихся в диапазоне слотов. Ответы всегда возвращаются в виде байтов, закодированных с помощью SSZ и сжатых с помощью snappy.
Почему клиент консенсуса предпочитает SSZ, а не RLP?
SSZ расшифровывается как простая сериализация (simple serialization). Он использует фиксированные смещения, которые позволяют легко декодировать отдельные части закодированного сообщения без необходимости декодировать всю структуру, что очень полезно для клиента консенсуса, поскольку он может эффективно извлекать определенные фрагменты информации из закодированных сообщений. Он также специально разработан для интеграции с протоколами Меркла, с соответствующим повышением эффективности для мерклизации. Поскольку все хеши на уровне консенсуса являются корнями Меркла, это приводит к значительному улучшению. SSZ также гарантирует уникальное представление значений.
Подключение клиентов исполнения и консенсуса
Клиенты консенсуса и исполнения работают параллельно. Они должны быть соединены, чтобы клиент консенсуса мог давать инструкции клиенту исполнения, а клиент исполнения мог передавать пакеты транзакций клиенту консенсуса для включения в блоки Beacon. Связь между двумя клиентами может быть достигнута с помощью локального RPC-соединения. API, известный как 'Engine-API' (opens in a new tab), определяет инструкции, передаваемые между двумя клиентами. Поскольку оба клиента находятся за единой сетевой идентификацией, они совместно используют ENR (запись узла Ethereum), которая содержит отдельный ключ для каждого клиента (ключ eth1 и ключ eth2).
Ниже приведено краткое описание потока управления с указанием соответствующего сетевого стека в скобках.
Когда клиент консенсуса не является производителем блока:
- Клиент консенсуса получает блок по протоколу распространения блоков (консенсус p2p)
- Клиент консенсуса предварительно проверяет блок, т. е. убеждается, что он получен от действительного отправителя с правильными метаданными
- Транзакции в блоке отправляются на уровень исполнения в качестве полезной нагрузки исполнения (локальное RPC-соединение)
- Уровень исполнения выполняет транзакции и проверяет состояние в заголовке блока (т. е. проверяет совпадение хешей)
- Уровень исполнения передает данные проверки обратно на уровень консенсуса, теперь блок считается проверенным (локальное RPC-соединение)
- Уровень консенсуса добавляет блок в начало своего блокчейна и аттестует его, транслируя аттестацию по сети (консенсус p2p)
Когда клиент консенсуса является производителем блока:
- Клиент консенсуса получает уведомление о том, что он является следующим производителем блока (консенсус p2p)
- Уровень консенсуса вызывает метод
create blockв клиенте исполнения (локальный RPC) - Уровень исполнения обращается к мемпулу транзакций, который был заполнен по протоколу распространения транзакций (исполнение p2p)
- Клиент исполнения объединяет транзакции в блок, выполняет транзакции и генерирует хеш блока
- Клиент консенсуса получает транзакции и хеш блока от клиента исполнения и добавляет их в блок Beacon (локальный RPC)
- Клиент консенсуса транслирует блок по протоколу распространения блоков (консенсус p2p)
- Другие клиенты получают предложенный блок по протоколу распространения блоков и проверяют его, как описано выше (консенсус p2p)
После того как блок был аттестован достаточным количеством валидаторов, он добавляется в начало цепи, подтверждается и в конечном итоге финализируется.
Схема сетевого уровня для клиентов консенсуса и исполнения, с ethresear.ch (opens in a new tab)
Дополнительные материалы
DevP2P (opens in a new tab)\nLibP2p (opens in a new tab)\nСпецификации сети уровня консенсуса (opens in a new tab)\nот Kademlia к discv5 (opens in a new tab)\nстатья о Kademlia (opens in a new tab)\nвведение в p2p Ethereum (opens in a new tab)\nвзаимосвязь eth1/eth2 (opens in a new tab)\nвидео о Слиянии и деталях клиента eth2 (opens in a new tab)

