Протокол распространения данных gossip

Платформа Hyperledger Fabric позволяет оптимизировать производительность, безопасность и масштабируемость блокчейн-сетей, разделяя нагрузку между участниками выполнения транзакции (на стадии одобрения и записи) и узлами службы упорядочивания транзакций. Такое разделение операций в сети требует безопасного, надежного и масштабируемого протокола распространения данных для обеспечения их целостности и согласованности. Для выполнения этих требований в Fabric реализован протокол распространения данных gossip.

Протокол gossip

Одноранговые узлы используют протокол gossip для передачи данных реестра и канала с возможностью масштабирования. Обмен данными по протоколу gossip происходит непрерывно и каждый одноранговый узел в канале постоянно получает текущие и согласованные данные реестра от нескольких одноранговых узлов. Каждое сообщение, передаваемое по протоколу gossip, имеет подпись, что позволяет легко идентифицировать «византийских» участников и предотвратить распространение сообщений, которые они посылают. Одноранговые узлы, которые пропустили блоки из-за задержек, разрывов сети или других причин, в конечном счете синхронизируется до текущего состояния реестра путем запрашивания отсутствующих блоков у одноранговых узлов, у которых они есть в наличии.

Протокол распространения данных gossip выполняет три основные функции в сети Fabric:

  1. Управляет обнаружением одноранговых узлов и членством в каналах, постоянно определяя доступные одноранговые узлы, а также узлы, которые вышли из сети.
  2. Распространяет данные реестра среди всех одноранговых узлов в канале. Любой одноранговый узел с данными, не синхронизированный с остальными участниками канала, определяет отсутствующие блоки и автоматически синхронизируется, запрашивая нужные данные.
  3. Обеспечивает перенос данных на новые одноранговые узлы в сети путем репликации данных реестра с уже включенных одноранговых узлов.

При использовании протокола gossip данные распространяются в сообщениях, которые принимаются одними одноранговыми узлами от других одноранговых узлов в канале, а затем отправляются дальше определенному количеству случайно выбранных одноранговых узлов в канале, причем это количество является настраиваемым. Одноранговые узлы также могут отправлять запросы pull, а не ждать доставки сообщений. Этот цикл повторяется, в результате чего информация о членстве в канале, реестре и состоянии постоянно обновляется и синхронизируется. Для распространения новых блоков узел-лидер в канале запрашивает данные из службы упорядочения и инициирует распространение данных среди других одноранговых узлов своей собственной организации по протоколу gossip.

Выбор лидера

Механизм выбора узла-лидера используется для выбора одного однорангового узла в организации, который будет взаимодействовать со службой упорядочения и инициировать распределение новых блоков среди одноранговых узлов в рамках этой организации. Процедура выбора узла-лидера позволяет системе эффективно использовать пропускную способность службы упорядочения. Доступно два режима работы модуля выбора лидера:

  1. Статический — системный администратор вручную выбирает один одноранговый узел в организации в качестве лидера.
  2. Динамический — узлы самостоятельно выполняют процедуру выбора одного узла-лидера в организации.

Статический выбор лидера

Статический выбор позволяет вручную определить один или несколько узлов в организации в качестве лидера. Обратите внимание, что слишком большое количество одноранговых узлов, подключенных к службе упорядочения, может привести к неэффективному использованию пропускной способности сети. Чтобы включить режим статического выбора лидера, настройте следующие параметры в соответствующем разделе файла core.yaml:

peer:
    # Параметры конфигурации для протокола gossip
    gossip:
        useLeaderElection: false
        orgLeader: true

В качестве альтернативы эти параметры можно настроить и переопределить с помощью переменных среды:

export CORE_PEER_GOSSIP_USELEADERELECTION=false
export CORE_PEER_GOSSIP_ORGLEADER=true

Примечание

Следующий вариант конфигурации подразумевает, что одноранговый узел будет находится в режиме ожидания, т. е. одноранговый узел не будет пытаться стать ведущим узлом:

export CORE_PEER_GOSSIP_USELEADERELECTION=false
export CORE_PEER_GOSSIP_ORGLEADER=false
  1. Выбор значения true для CORE_PEER_GOSSIP_USELEADERELECTION и CORE_PEER_GOSSIP_ORGLEADER приведет к созданию неоднозначной конфигурации и возникновению ошибок.
  2. В случае статической конфигурации администратор организации отвечает за обеспечение высокой доступности ведущего узла в случае сбоев.

Динамический выбор лидера

Динамический выбор лидера позволяет одноранговым узлам в организации выбрать один узел, который будет подключаться к службе упорядочения и считывать новые блоки. Этот узел выбирается из числа одноранговых узлов в организации с помощью специальной автоматической процедуры.

Динамически выбранный узел-лидер отправляет сообщения heartbeat остальным одноранговым узлам для подтверждения своей работоспособности. Если один или несколько одноранговых узлов не получают сообщений heartbeat в течение установленного периода времени, они выбирают нового лидера.

В наихудшем сценарии нарушения связности сети в организации будет несколько активных лидеров, чтобы гарантировать отказоустойчивость и доступность, позволяя одноранговым узлам продолжать работу. После устранения нарушения связности сети, один из узлов-лидеров перестанет выполнять эту роль. В нормальном состоянии сети будет использоваться только один активный узел-лидер, подключенный к службе упорядочения.

Следующая конфигурация контролирует частоту сообщений heartbeat ведущего узла:

peer:
    # Параметры конфигурации для протокола gossip
    gossip:
        election:
            leaderAliveThreshold: 10s

Для включения динамического выбора ведущего узла необходимо настроить следующие параметры в файле core.yaml:

peer:
    # Параметры конфигурации для протокола gossip
    gossip:
        useLeaderElection: true
        orgLeader: false

В качестве альтернативы эти параметры можно настроить и переопределить с помощью переменных среды:

export CORE_PEER_GOSSIP_USELEADERELECTION=true
export CORE_PEER_GOSSIP_ORGLEADER=false

Якорные узлы

В рамках протоколе gossip якорные узлы позволяют одноранговым узлам разных организаций иметь представление друг о друге.

При записи нового блока конфигурации, содержащего обновление якорных узлов, одноранговые узлы обращаются к якорным узлам и узнают обо всех одноранговых узлах, известных якорным узлам. Как только хотя бы один одноранговый узел из каждой организации связывается с якорным узлом, якорный узел узнает о всех одноранговых узлах в канале. Поскольку передача сообщений по протоколу gossip происходит непрерывно и поскольку одноранговые узлы всегда запрашивают информацию о существовании неизвестных узлов, в канале может быть быстро получено представление о количестве членов.

Например, предположим, что в канале присутствуют три организации — A, B, C, а также один якорный узел — peer0.orgC, определенный для организации C. Когда узел peer1.orgA (организации A) связывается с узлом peer0.orgC, он сообщает ему о существовании узла peer0.orgA. И, также, когда узел peer1.orgB связывается с peer0.orgC, последний сообщает первому о существовании узла peer0.orgA. С этого момента организации A и B начнут обмениваться информацией о членстве напрямую без какой-либо помощи со стороны узла peer0.orgC.

Поскольку обмен данными между организациями базируется на протоколе gossip, в конфигурации канала должен быть указан хотя бы один якорный узел. Настоятельно рекомендуется, чтобы каждая организация предоставляла свой собственный набор якорных узлов для обеспечения высокой доступности и избыточности. Обратите внимание, что якорный узел не обязательно должен быть лидером.

Внешние и внутренние конечные точки

Для эффективной передачи данных по протоколу gossip одноранговые узлы должны иметь возможность получать информацию о конечных точках от одноранговых узлов собственной организации, а также узлов других организаций.

При загрузке однорангового узла в его файле core.yaml используется свойство peer.gossip.bootstrap для оповещения и обмена информацией о членстве, что позволяет узлам получать представление обо всех доступных узлах в своей организации.

Свойство peer.gossip.bootstrap в файле core.yaml однорангового узла используется для распространения данных по протоколу gossip внутри организации. При использовании протокола gossip все одноранговые узлы в организации обычно настраиваются таким образом, чтобы они указывали на исходный набор одноранговых узлов начальной загрузки (такие одноранговые узлы указываются через пробел). Внутренняя конечная точка обычно автоматически вычисляется самим узлом или просто передается явно в свойстве core.peer.address файла core.yaml. При необходимости изменения этого значения, можно экспортировать CORE_PEER_GOSSIP_ENDPOINT в качестве переменной среды.

Информация начальной загрузки также требуется для установления обмена данными между организациями. Исходная информация начальной загрузки передается между организациями с помощью якорных узлов, как описано выше. Если необходимо, чтобы другие одноранговые узлы в организации были известны другим организациям, следует указать значение для свойства peer.gossip.externalendpoint в файле core.yaml для конкретного однорангового узла. Если значение этого свойства не указано, информация о конечной точке однорангового узла не будет транслироваться одноранговым узлам других организаций.

Чтобы установить эти свойства, введите:

export CORE_PEER_GOSSIP_BOOTSTRAP=<список конечных точек однорангового узла в пределах организации этого однорангового узла>
export CORE_PEER_GOSSIP_EXTERNALENDPOINT=<конечная точка однорангового узла, известная за пределами организации>

Обмен сообщениями посредством протокола gossip

Одноранговые узлы демонстрируют свою доступность, непрерывно транслируя сообщения «alive», каждое из которых содержит идентификатор инфраструктуры открытых ключей (PKI) и подпись отправителя. Одноранговые узлы поддерживают актуальную информацию о членстве в канале, собирая эти сообщения. Если ни один узел не получает эти сообщения от определенного однорангового узла, такой «мертвый» узел в конечном итоге лишается членства в канале. Поскольку сообщения «alive» имеют криптографическую подпись, узлы с фальшивыми данными никогда не смогут выдать себя за другие одноранговые узлы, поскольку у них отсутствует соответствующий ключ подписи, выданный корневым удостоверяющим центром.

Помимо автоматической пересылки полученных сообщений, процесс согласования состояния синхронизирует глобальное состояние между одноранговыми узлами в каждом канале. Каждый одноранговый узел постоянно получает блоки от других одноранговых узлов в канале, чтобы скорректировать свое состояние в случае выявления расхождений. Поскольку для распространения данных по протоколу gossip не требуется фиксированное соединение, этот процесс позволяет добиться высокой степени согласованности и целостности данных в общем реестре, а также повышенной устойчивости к сбоям узлов.

Поскольку каналы являются отдельными «подсетями», одноранговые узлы в одном канале не могут отправлять сообщения или обмениваться информацией с членами любого другого канала. И хотя любой одноранговый узел может являться членом нескольких каналов, разделенный обмен сообщениями предотвращает распространение блоков среди одноранговых узлов, которые не входят в состав членов канала, путем применения правил маршрутизации сообщений на основе подписок одноранговых узлов на каналы.

Примечание

1. Безопасность двухточечных обменов сообщениями обеспечивается TLS-шифрованием на уровне одноранговым узлов и не требует подписи. Одноранговые узлы аутентифицируются с помощью своих сертификатов, которые выдаются удостоверяющим центром. TLS-сертификаты также используются, однако на уровне протокола gossip аутентификация производится с помощью сертификатов одноранговых узлов. Блоки реестра подписываются службой упорядочения и затем доставляются узлам-лидерам в канале.

2. Аутентификация одноранговых узлов контролируется провайдером службы членства. При подключении однорангового узла к каналу в первый раз сессия TLS привязывается к идентификатору членства. По сути, это аутентифицирует подключающихся одноранговых узлов с соблюдением членства в сети и канале.