區塊鏈底層網絡調研

背景

在做區塊鏈項目時,大多落地金融機構,網絡開通比較麻煩。現有區塊鏈底層平臺組成聯盟鏈要求鏈上組織機構網絡都需要打通,這裏相對底層網絡進行一些優化,初步想法是通過一些路由節點或是超級節點進行路由,也就是P2P網絡中混合式架構。這裏調研常見的區塊鏈網絡架構。

比特幣網絡架構

擴展比特幣網絡(extended bitcoin network):指代所有包含比特幣P2P協議、礦池挖礦協議、Stratum協議以及其他連接比特幣系統組件相關協議的整體網絡結構。

比特幣節點

節點具有錢包、挖礦、路由、完整區塊鏈數據庫功能

節點分類

全節點:這個全指的是擁有完整的區塊鏈副本,全節點可以不借助其他節點就可以完成校驗交易

輕量節點:只保留一部分區塊鏈交易(與自己相關的區塊鏈),採用“簡易支付驗證(SPV)”的方式來完成交易驗證,以及網絡路由

比特幣網絡核心客戶端:錢包、礦工、完整區塊鏈數據庫、網絡路由

獨立礦工節點:具有完整區塊鏈數據,獨立挖礦,網絡路由

礦池服務器,一般礦池協議採用stratum協議

比特幣網絡

區塊傳播機制

1、節點A收到一個block,對其進行驗證,驗證通過後,會將其廣播給其連接的節點;

2、節點A向其連接的節點發送inv的消息,inv消息包含節點A驗證過的區塊的相關信息;

3、節點B收到inv消息,如果之前沒有接收過這個區塊,則向節點A發送一個getdata消息,要求得到交易記錄,以及區塊的具體信息;節點A只有在收到getdata消息後,纔會把區塊block的具體信息發送給節點B。

當礦工挖到新區塊後,區塊按上述方法傳播到全網中。新區塊並不是同時向所有節點廣播,而只能向其附近的、建立連接的節點進行廣播。比特幣網絡中,每個節點與至少其他P個節點保持連接,如果連接數低於P,那麼節點就會從它已知的地址中隨機選擇地址並試圖與其建立連接。如果連接的數量超過P,後續來自於其他節點的連接請求一般也並不會被拒絕。目前比特幣網絡中,平均每個節點有32個開放的連接,比特幣協議中默認P=8。

新產生的區塊必須要使得其被至少50%節點認證並接受。也就是其他節點對新區塊進行哈希的過程,對隨機數nounce的確可以使得哈希函數小於目標哈希,只有當新區塊加入父區塊且在此基礎上繼續產生6個區塊後,才認爲該新區塊是在主鏈上的。

關於區塊分叉問題在之前文章中分析過,因爲涉及到交易最終是否被確認,區塊是否能上主鏈,在這裏再簡單講一下。兩個節點可能同時挖到區塊,例如一個節點挖到區塊X,同時另一個節點挖到區塊Y,並進行全網廣播。此時如果節點A先收到區塊X並且驗證成功,節點A將基於區塊X,尋找下一個新的區塊。而先收到區塊Y的節點B,在驗證區塊Y也是正確的區塊後,將會基於區塊Y上面尋找下一個新區塊。這時區塊鏈上出現了一個“分叉”,即出現了兩條鏈:一條是X,另一條是Y。

出現兩條鏈後,這時就看兩條鏈挖到下一區塊的速度。如果節點A比節點B更快找到下一個新區塊Z,由於節點A是基於區塊X上尋找新區塊的,因此,原來的兩條鏈分別變成X+Z和Y,這時由於X+Z這條鏈比Y鏈更長,那些原來在Y基礎上挖礦的礦工們,就會放棄Y,並轉而在X+Z這條鏈上繼續挖礦,因此X+Z這條鏈就成爲“主鏈”,而區塊Y則成爲“孤塊”。

儘管有礦工挖到了區塊Y,但是由於區塊Y是孤塊,並沒有被加入到主鏈中去,因此,儘管挖到區塊Y的曠工得到了比特幣獎勵,但是該比特幣獎勵是"unspendable“的狀態,無法使用,也就意味着不會獲得比特幣獎勵,其包含的所有交易記錄也不會被確認,將返回到交易池中“待確認”。而挖到區塊X的礦工,得到了比特幣獎勵,經過六個區塊的驗證後,被確認在主鏈上了,也就意味着將獲得比特幣獎勵,這時其包含的所有交易記錄也將會得到確認,並從交易池Pool中刪去。

傳播速度

從前面區塊傳播的機制可以發現,某節點挖到新區塊後,其發現新區塊的時間、以及向外面傳播該新區塊的速度,影響該新區塊最終是否能加入主鏈。

根據相關統計研究,2015年,當時全世界的節點大概爲6000個,因此,當一個新挖出的區塊被至少3000個節點(50%的節點)接受時,該區塊就有較大的可能性加入主鏈。區塊的傳播速度與區塊的大小有着明顯的關係。例如,要傳播至3k個節點,一個700Kb+的區塊大約要花15秒,而一個200-300Kb的區塊則只需要6秒。對於一個8MB大小的區塊來說,要傳播至網絡中3k各節點,需要花100多秒。當礦工新挖出一個區塊,當要傳播至3k個節點,每個礦工平均花費10秒左右。

一般這個傳播速度遠小於挖出新區塊的速度,一般挖到一個新區塊時間爲十分鐘左右。

以太坊網絡架構

比特幣主網的P2P網絡是無結構的,而以太坊使用P2P網絡是有結構的,採用分佈式哈希表(DHT)技術,可以實現在分佈式環境下快速而又準確地路由、定位數據的問題。以太坊通過Kademlia(簡稱Kad)算法來實現。

Kad 網絡

網絡節點有一個nodeID,會映射到一個二叉前綴樹,

映射規則:

將 nodeID 以二進制形式表示,然後從高到低對每一位的 0 或 1 依次處理;
二進制的第 n 位對應二叉樹的第 n 層;
如果該位是 0,進入左子樹,是 1 則進入右子樹(反過來也可);
全部位都處理完後,這個 nodeID, 就對應了二叉樹上的某個葉子節點。
二叉前綴樹
利用異或來計算節點之間的邏輯距離,在這種二叉樹結構下,對每個節點來說,離它越近的節點異或距離也是越近的。接着,可以按照離自己異或距離的遠近,對整顆二叉樹進行拆分。

拆分規則

從根節點開始,將不包括自己的那顆子樹拆分出來,然後在包含自己的子樹中,把不包括自己的下一層子樹再拆分出來,以此類推,直到只剩下自己。以上圖的 110 節點爲例,可將其拆分成如圖陰影所示的除 110 節點之外的三顆子樹。

K-Buket

完成子樹拆分後,只要知道每個子樹裏面的其中一個節點,就可以進行遞歸路由實現整顆二叉樹所有節點的遍歷。但在實際場景下,由於節點是動態變化的,所以一般不會只知道每個子樹的一個節點,而是需要知道多個節點。因此,Kad 中有一個叫 K-桶(K-bucket)的概念,每個桶會記錄每顆子樹裏所知道的多個節點。

其實,一個子樹對應一個K-桶也就是就是一張路由表,如果拆分出來有 m 顆子樹,那對應節點就需要維護 m 個路由表,所有的K-bucket組合一起就是網絡的完整路由表。每個節點都會各自維護自己的 m 個 K-桶,每個 K-桶裏記錄的節點信息一般會包括 NodeID、IP、Endpoint、與 Target 節點(即維護該 K-桶的節點)的異或距離等信息。

以太坊中的K值是16,也就是說每個K桶包含16個節點,nodeID爲256位,所以一共有256個k桶。K桶中記錄了節點的NodeId,distance,endpoint,ip等信息,按照與target節點的距離進行排序。也就是每個節點維護256個K桶,也就是256個子路由表,也就是256個劃分的子樹,所有的k桶合起來也就是一個節點的路由表。

還是以nodeID爲110的節點爲例,共有3個k桶,如下圖:
k-bucket

節點路由維護

在以太坊的 Kad 網絡中,節點之間的通信是基於 UDP ,有4 個主要的通信協議,用於K-Bucket刷新,新節點加入等操作:

  • Ping:用於探測一個節點是否在線
  • Pong:用於響應 Ping 命令
  • FindNode:用於查找與 Target 節點異或距離最近的其他節點
  • Neighbours:用於響應 FindNode 命令,會返回一或多個節點

fabric網絡架構

不同於上面兩種公鏈的P2P網絡架構,fabric主要用於聯盟鏈,要求同一channel內節點要互通。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章