Hyperledger Fabric 中 Gossip 數據傳播協議
https://hyperledger-fabric.readthedocs.io/zh_CN/latest/gossip.html
Hyperledger Fabric 通過將工作負載拆分爲交易執行(背書和提交)節點和交易排序節點的方式來優化區塊鏈網絡的性能、安全性和可擴展性。這樣對網絡的分割就需要一個安全、可靠和可擴展的數據傳播協議來保證數據的完整性和一致性。爲了滿足這個需求,Fabric 實現了 Gossip 數據傳播協議 。
Gossip 協議
Peer 節點通過 gossip 協議來傳播賬本和通道數據。Gossip 消息是持續的,通道中的每一個 Peer 節點不斷地從多個節點接收當前一致的賬本數據。每一個 gossip 消息都是帶有簽名的,因此拜占庭成員發送的僞造消息很容易就會被識別,並且非目標節點也不會接受與其無關的消息。Peer 節點會受到延遲、網絡分區或者其他原因影響而丟失區塊,這時節點會通過從其他擁有這些丟失區塊的節點處同步賬本。
基於 gossip 的數據傳播協議在 Fabric 網絡中有三個主要功能:
-
通過持續的識別可用的成員節點來管理節點發現和通道成員,還有檢測離線節點。
-
向通道中的所有節點傳播賬本數據。所有沒有和當前通道的數據同步的節點會識別丟失的區塊,並將正確的數據複製過來以使自己同步。
-
通過點對點的數據傳輸方式,使新節點以最快速度連接到網絡中並同步賬本數據。
Peer 節點基於 gossip 的數據廣播操作接收通道中其他的節點的信息,然後將這些信息隨機發送給通道上的一些其他節點,隨機發送的節點數量是一個可配置的常量。Peer 節點可以用“拉”的方式獲取信息而不用一直等待。這是一個重複的過程,以使通道中的成員、賬本和狀態信息同步並保持最新。在分發新區塊的時候,通道中 主 節點從排序服務拉取數據然後分發給它所在組織的節點。
主節點選舉
主節點的選舉機制用於在每一個組織中 選舉 出一個用於鏈接排序服務和開始分發新區塊的節點。主節點選舉使得系統可以有效地利用排序服務的帶寬。主節點選舉模型有兩種模式可供選擇:
-
靜態模式:系統管理員手動配置一個節點爲組織的主節點。
-
動態模式:組織中的節點自己選舉出一個主節點。
靜態主節點選舉
靜態主節點選舉允許你手動設置組織中的一個或多個節點節點爲主節點。請注意,太多的節點連接到排序服務可能會影響帶寬使用效率。要開啓靜態主節點選舉模式,需要配置 core.yaml
中的如下部分:
peer:
# Gossip related configuration
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
不要將 CORE_PEER_GOSSIP_USELEADERELECTION
和 CORE_PEER_GOSSIP_ORGLEADER
都設置爲 true,這將會導致錯誤。
使用靜態配置時,主節點失效或者崩潰都需要管理員進行處理。
動態主節點選舉
動態主節點選舉使組織中的節點可以 選舉 一個節點來連接排序服務並拉取新區塊。這個主節點由每個組織單獨選舉。
動態選舉出的主節點通過向其他節點發送 心跳 信息來證明自己處於存活狀態。如果一個或者更多的節點在一個段時間內沒有收到 心跳 信息,它們就會選舉出一個新的主節點。
在網絡比較差有多個網絡分區存在的情況下,組織中會存在多個主節點以保證組織中節點的正常工作。在網絡恢復正常之後,其中一個主節點會放棄領導權。在一個沒有網絡分區的穩定狀態下,會只有 唯一 一個活動的主節點和排序服務相連。
下邊的配置控制主節點 心跳 信息的發送頻率:
peer:
# Gossip related configuration
gossip:
election:
leaderAliveThreshold: 10s
開啓動態節點選舉,需要配置 core.yaml
中的以下參數:
peer:
# Gossip related configuration
gossip:
useLeaderElection: true
orgLeader: false
同樣,這些配置的參數可以通過環境變量覆蓋:
export CORE_PEER_GOSSIP_USELEADERELECTION=true
export CORE_PEER_GOSSIP_ORGLEADER=false
錨節點
gossip 利用錨節點來保證不同組織間的互相通信。
當提交了一個包含錨節點更新的配置區塊時,Peer 節點會連接到錨節點並獲取它所知道的所有節點信息。一個組織中至少有一個節點連接到了錨節點,錨節點就可以獲取通道中所有節點的信息。因爲 gossip 的通信是固定的,而且 Peer 節點總會被告知它們不知道的節點,所以可以建立起一個通道上成員的視圖。
例如,假設我們在一個通道有三個組織 A、B 和 C,組織 C 定義了錨節點 peer0.orgC。當 peer1.orgA 連接到 peer0.orgC 時,它將會告訴 peer0.orgC 有關 peer0.orgA 的信息。稍後等 peer1.orgB 連接到 peer0.orgC 時,後者也會告訴前者關於 peer0.orgA 的信息。在這之後,組織 A 和組織 B 可以開始直接交換成員信息而無需藉助 peer0.orgC 了。
由於組織間的通信依賴於 gossip,所以在通道配置中必須至少有一個錨節點。爲了系統的可用性和冗餘性,我們強烈建議每個組織都提供自己的一些錨節點。注意,錨節點不一定和主節點是同一個節點。
錨節點在通道配置文件 configtx.yaml
中配置,可以配置多個:
Organizations:
AnchorPeers:
- Host: 127.0.0.1
Port: 7051
外部和內部端點(endpoint)
爲了讓 gossip 高效地工作,Peer 節點需要包含其所在組織以及其他組織的端點信息。
當 Peer 節點啓動的時候,它會使用 core.yaml
文件中的 peer.gossip.bootstrap
來宣傳自己並交換成員信息,同時建立所屬組織中可用節點的視圖。
core.yaml
文件中的 peer.gossip.bootstrap
屬性用於在 一個組織內部 啓動 gossip。如果你要使用 gossip,通常要爲組織中的所有節點配置一組啓動節點(使用空格隔開的節點列表)。內部端點通常是由 Peer 節點自動計算的,或者在 core.yaml
中的 core.peer.address
指明。如果你要覆蓋該值,你可以設置環境變量 CORE_PEER_GOSSIP_ENDPOINT
。
啓動信息也同樣需要建立 跨組織 的通信。初始的跨組織啓動信息通過上面所說的“錨節點”設置提供。如果想讓其他組織知道你所在組織中的其他節點,你需要設置 core.yaml
文件中的 peer.gossip.externalendpoint
。如果沒有設置,節點的端點信息就不會廣播到其他組織的 Peer 節點。
這些屬性的設置如下:
export CORE_PEER_GOSSIP_BOOTSTRAP=<a list of peer endpoints within the peer's org>
export CORE_PEER_GOSSIP_EXTERNALENDPOINT=<the peer endpoint, as known outside the org>
Gossip 消息
在線的節點通過持續廣播“存活”消息來表明其處於可用狀態,每一條消息都包含了“公鑰基礎設施(PKI)” ID 和發送者的簽名。節點通過收集這些存活的消息來維護通道成員。如果沒有節點收到某個節點的存活信息,這個“死亡”的節點會被從通道成員關係中剔除。因爲“存活”的消息是經過簽名的,惡意節點無法假冒其他節點,因爲他們沒有根 CA 簽發的密鑰。
除了自動轉發接收到的消息之外,狀態協調進程還會在每個通道上的 Peer 節點之間同步 世界狀態。每個 Peer 節點都持續從通道中的其他節點拉取區塊,來修復他們缺失的狀態。因爲基於 gossip 的數據分發不需要固定的連接,所以該過程可以可靠地提供共享賬本的一致性和完整性,包括對節點崩潰的容忍。
因爲通道是隔離的,所以一個通道中的節點無法和其他通道通信或者共享信息。儘管節點可以加入多個通道,但是分區消息傳遞通過基於 Peer 節點所在通道的應用消息的路由策略,來防止區塊被分發到其他通道的 Peer 節點。
註解
- 通過 Peer 節點 TLS 層來處理點對點消息的安全性,不需要使用簽名。Peer 節點通過 CA 簽發的證書來授權。儘管沒有使用 TLS 證書,但在 gossip 層使用了經過授權的 Peer 節點證書。賬本區塊經過排序服務簽名,然後被分發到通道上的主節點。
- 通過 Peer 節點的成員服務提供者來管理授權。當 Peer 節點第一次連接到通道時,TLS 會話將與成員身份綁定。這就利用網絡和通道中成員的身份來驗證了與 Peer 節點相連的節點的身份。