科普 | 什麼是以太坊 P2P 網絡?

鏈傑未來 發佈 2020-01-24T08:01:38+00:00

集合E 中的邊指 p 可通過直接相連的路徑向 q 發送消息;也就是說,p 使用 q 的 pid 作為目的地址,在網絡之上向 q 發送消息。

此文旨在幫助你理解 P2P 網絡,並闡述一些以太坊的實現細節。P2P 技術利用終端設備的豐富資源,能夠緩解中心化系統的短板,而且從九十年代開始,這項技術就已經被 eMule,bitTorrent和Skype等知名軟體所採用。P2P 技術也是比特幣或者以太坊區塊鏈系統的核心組件。很多人都聽說過 P2P,但是不知道它到底是什麼。那就讓我們從了解什麼是 P2P 網絡開始吧。

什麼是 P2P網絡?

點對點(P2P)網絡是一種網絡覆蓋層(overlay network)——就是說,它是建立在公開網際網路之上的。從數學的角度來說,P2P 網絡可以被視作一個有向圖 G = (V,E),其中 V 是網絡中的對等節點集合,E 是對等節點所連成的邊的集合(也即節點間連接的集合)。每個對等節點 p 都有一個獨一無二的標識號 pid。集合 E 中的邊(p,q)指 p 可通過直接相連的路徑向 q 發送消息;也就是說,p 使用 q 的 pid 作為目的地址,在網絡之上向 q 發送消息。儘管在底層的 TCP/IP 網絡中,相似的 IP 地址可以轉譯為在地理位置上相互接近,但很少有這麼明確的直接關聯。

理想情況下,所有的對等節點間都應該有一條路徑相連。但因為每個節點對網絡拓撲和其他對等節點只有一個不完整的視圖,所以網絡覆蓋層需要中間節點將消息轉發至正確目的。圖的結構為每對節點提供了多條中間路徑,因此就算對等節點改變,也可通過圖的連通性提供網絡的恢復能力。對每個對等節點來說,圖的連通性通過與其他對等節點的鄰接關係來反映。當對等節點加入或者離開網絡,鄰接的對等節點可能會持有不正確的鄰接信息。因此使用網絡覆蓋層維護機制(Overlay maintenance mechanisms)保存更新的鄰接信息,使得所有節點間保持連通性。

P2P 網絡中的參與者向其他網絡參與者提供部分資源。不需要中心化的協調者,每個對等節點都可貢獻計算周期(CPU),磁碟存儲和網絡帶寬。傳統的 客戶端-伺服器 模型中,伺服器提供資源,客戶端使用資源;與之相對的,在 P2P 網絡中,對等節點既是網絡資源的供應者,也是消費者。因此,P2P 網絡可以很好地解決 客戶端-伺服器 模型下的一些短板,比如可擴展性單點故障

一般來說,P2P 網絡會有一個門檻,節點的資源貢獻高於這個門檻才能加入網絡。度量資源貢獻的標準應該是公平的,比如說,要求網絡中每個對等節點的平均貢獻應該在 P2P 系統總體平均值的統計範圍內等。資源貢獻應該是雙方互惠的。付出貢獻後可得到的利益,吸引著用戶加入 P2P 應用。

以太坊的 P2P 網絡是如何工作的?

以太坊的官方客戶端節點軟體 Geth,基於一種覆蓋層維護機制 (稱作 Kademlia 分布式哈希表)實現了對等節點發現協議(RLPx 節點發現協議)。雖然 Kademlia 是為了在 P2P 網絡中有效地定位和存儲內容而設計的,以太坊的 P2P 網絡只用它來發現新的對等節點。

Kademlia

以太坊網絡中,每個客戶端節點都配備有一個 enode ID,之後將此 ID 用 SHA3 算法散列為一個 256 位的值。Kademlia 使用 XOR 操作定義距離,因此兩個 256 位的數字之間的距離是他們的按位異或值(bitwise exclusive OR)。每個對等節點都擁有一個包含 256 個不同的桶(buckets)的數據結構,每個桶 i 中存儲與本節點距離在 2i-1 到 2i 之間的 16 個節點。為了發現一個新的對等節點,以太坊節點選擇自己作為目標 x,從桶中尋找到 16 個與目標 x 最近的節點,之後請求這 16 個節點,讓它們從自己的桶中各找出 16 個與目標 x 「更近」 的節點並返回,這樣以來,會得到至多 16×16 個新發現的節點。之後請求這 16×16 個新發現的節點中離目標 x 最近的 16 個節點,讓它們返回與 x 更近的 16 個節點。這個過程持續疊代,直到沒有新節點被發現。

-異或操作示意圖-

-bucket 與距離對應的示意圖-

對等節點間通信

Geth 使用 UDP 連接交換 P2P 網絡的信息。有 4 種類型的 UDP 消息。一條 *ping* 消息請求一條 *pong* 消息作為返回。此對消息用來判斷相鄰節點是否可響應。一條 *findnode* 消息請求一條 *neighbors* 消息(其中包含 16 個已經被響應節點知曉的節點列表)作為返回。當建立好對等節點的連接之後,Geth 節點通過加密和認證的 TCP 連接來交換區塊鏈信息。

數據結構

Geth 客戶端用兩種數據結構存儲其他節點的信息。第一種是稱作 db 的長期資料庫,它存儲在磁碟內,客戶端重啟之後數據也是持久存在的。db 中包含客戶端交互過的每個節點信息。db 的每條記錄包含節點 ID,IP 地址,TCP 埠,UDP 埠,(此客戶端)最後一次向(記錄中)節點發送 ping 的時間,最後一次從節點收到 pong 的時間,節點響應 findnode 消息的失敗次數。如果最後一次從一個節點收到 pong 消息的時間超過了一天,此節點將會被移出 db。

第二種數據結構是稱作 table 的短期資料庫。當客戶端重啟時 table 是空的。table 包含 256 個桶,每個桶存儲至多 16 條記錄。每條記錄存儲其他以太坊節點的信息——節點的 ID,IP 地址, TCP 埠和 UDP 埠。如果記錄中的某個節點對於 findnode 消息連續響應失敗,多於 4 次時將被移出 table。

當某個客戶端第一次啟動時,它的 db 是空的,只知道 6 個硬編碼的引導節點。隨後,當客戶端開始發現對等節點,客戶端依據上面描述的機制,將節點加入 db 和 table。

鄭重聲明:以上所有信息,不構成投資建議,僅供學習交流使用,幣市有風險,投資需謹慎!

關鍵字: