kademlia演算法學習 區塊鏈P2P網路設計

2021-09-17 03:08:23 字數 2577 閱讀 7700

如今很多p2p網路的實現都採用dht的方式實現查詢,其中kademlia(簡稱kad)演算法由於其簡單性、靈活性、安全性成為主流的實現方式。下面我們就來詳細分析這個應用於位元幣和以太坊p2p網路中的kad演算法。

kad網路中每個節點都有乙個160bit的id值作為標誌符,key也是乙個160bit的標誌符,每乙個加入kad網路的節點都會被分配乙個160bit的節點id(node id),這個id值是隨機產生的。同時對的資料就存放在id值距離key值最近的若干個節點上。

kad演算法乙個精妙之處在於它採用異或操作來計算節點之間的距離。通過異或操作,我們可以得到該距離演算法有一下特點:

所以,這裡所說的距離是邏輯上的距離,與地理位置無關,所以有可能兩個節點之間計算得到的邏輯距離很近,但實際上地理上的距離卻很遠。

例如:節點a的id(011)和節點b的id(101)距離:011 ⊕ 101 = 110 = 4+2 = 6。

當我們把所有節點id都按照上述步驟操作後,會發現,這些節點形成一顆二叉樹。

節點110的視角

每乙個節點都可以從自己的視角來對二叉樹進行拆分。

拆分規則是從根節點開始,把不包含自己的子樹拆分出來,然後在剩下的子樹再拆分不包含自己的下一層子樹,以此類推,直到最後只剩下自己。如上圖所示,以節點id為6(110)為視角進行拆分,可以得到3個子樹(灰色圓圈)。而以節點101為視角拆分,則可以得到如下二叉樹。

節點101的視角

kad預設的雜湊值空間是m=160(雜湊值有160bit),所以拆分以後的子樹最多有160個。而考慮到實際網路中節點個數遠遠沒有2^160個,所以子樹的個數明顯小於160個。

對於每個節點,當按照自己的視角對二叉樹進行拆分以後,會得到n個子樹。對於每個子樹,如果都分別知道裡面1個節點,那麼就可以利用這n個節點進行遞迴路由,從而可以達到整個二叉樹的任何乙個節點。

假設每個節點id是n bits。每個節點按照自己視角拆分完子樹後,一共可以得到n個子樹。上面說了,只要知道每個子樹裡的乙個節點就可以實現所有節點的遍歷。但是,在實際使用過程中,考慮到健壯性(每個節點可能推出或者宕機),只知道乙個節點是不夠的,需要之多多幾個節點才比較保險。

k桶在這裡實際上就是路由表。每個節點按照自己視角拆分完子樹後,可以得到n個子樹,那麼就需要維護n個路由表(對應n個k-桶)。

kad演算法中就使用了k-桶的概念來儲存其他鄰近節點的狀態資訊(節點id、ip和埠),如下圖,對於160bit的節點id,就有160個k-桶,對於每乙個k-桶i,它會儲存與自己距離在區間[2^i, 2^(i+1)) 範圍內的k個節點的資訊,如下圖所示。每個k-桶i中儲存有k個其他節點資訊,在bittorrent中k取8。當然每乙個k-桶i不可能把所有相關的節點都儲存,這樣表根本儲存不下。它是距離自己越近的節點儲存的越多,離自己越遠儲存的越少(只取距離自己最近的k個節點),如下圖所示。

同時每個k-桶中存放的位置是根據上次看到的時間順序排列,最早訪問的放在頭部,最新訪問的放在尾部。

主要有以下3種

任何節點都可以發起find_node(查詢節點)的請求,從而重新整理k-桶中的節點資訊

當收到其他節點傳送過來的請求(如:find_node、find_value),會把對方的節點id加入到某個k-桶中

當乙個節點id要被用來更新對應的k-桶,其具體步驟如下:

這種機制提高了kad網路的穩定性並降少了網路維護成本(減少構建路由表),同時這種機制能在一定程度上防禦ddos攻擊,因為只有老節點失效後,kad才會更新k-桶,這就避免了通過新節點加入來泛洪路由資訊。

kad演算法一共有4中訊息型別:

store 通知乙個節點儲存鍵值對,以便以後查詢使用

find_node 返回對方節點桶中離請求鍵值最近的 k 個節點

find_value 與 find_node 一樣,不過當請求的接收者存有請求者所請求的key值的時候,它將返回相應value

備註:每個發起請求的rpc訊息都會包含乙個傳送者加入的隨機值,這個可以確保在接收到訊息響應的時候可以根前面傳送過的訊息匹配。

節點查詢可以同步進行也可以非同步進行,同時查詢的併發數量一般為3。

當節點要查詢資料對時,和定位節點的過程類似。

如果上述find_value最終找到value值,則資料對會快取在沒有返回value值的最近節點上,這樣下次再查詢相同的key值時就可以加快查詢速度。

當節點收到乙個的資料時,它的儲存過程如下:

乙個新節點想要加入kad網路,其步驟如下:

節點a在自我定位建立路由表的同時,也使得其他節點能夠使用節點a的id來更新他們的路由表。這過程讓節點a獲得詳細路由表的同時,也讓其他節點知道a節點的加入。

區塊鏈 區塊鏈雜湊演算法

雜湊演算法是區塊鏈中保證交易資訊不被篡改的單向密碼機制。雜湊演算法接收一段明文後,以一種不可逆的方式將其轉化為一段長度較短 位數固定的雜湊資料。它有兩個特點 加密過程不可逆,意味著我們無法通過輸出的雜湊資料倒推原本的明文是什麼 輸入的明文與輸出的雜湊資料一一對應,任何乙個輸入資訊的變化,都必將導致最...

區塊鏈演算法

交易記錄就是這個樣子的 賬本可以理解為一組交易記錄,乙個下列結構稱之為乙個區塊hash值 賬本的摘要,序號 記賬時間 交易記錄1 交易記錄2 指向下乙個區塊的指標 第乙個區塊 hash 賬本 hash值 後續區塊 hash 前乙個賬本的hash值,新賬本 新的hash值 產生新的乙個區塊 區塊使用鍊...

區塊鏈學習

區塊鏈是乙個分布式賬本,一種通過去中心化 去信任的方式集體維護乙個可靠資料庫的技術方案。2.1 數字簽名 使用數字簽名驗證交易物件身份。2.2 時間戳 位元幣網路採取從 5 個以上節點獲取時間,然後取中間值的方式作為時間戳。2.3 merkle tree 用於校驗資料完整性的二叉樹,葉子節點儲存交易...