IPFS 中的 BitSwap 協(xié)議

簡介

BitSwap 是 IPFS 網(wǎng)絡(luò)中定義數(shù)據(jù)塊交換方式的協(xié)議,它是一個一種基于統(tǒng)一格式的消息對等協(xié)議,有別于 request/response 方式。簡單來說就是,在 IPFS 中,請求和響應(yīng)的消息都使用同一類型的消息包。由于在 IPFS 網(wǎng)絡(luò)中,所有的 Peers 都是對等節(jié)點,不存在 BitTorrent 中那樣的 Tracker 服務(wù)器,所以通信方式更加簡單。

BitSwap 協(xié)議還定義了如何請求數(shù)據(jù)、如何發(fā)送數(shù)據(jù)以及向誰發(fā)送數(shù)據(jù)等策略,每個節(jié)點都可以有自己的策略,作為數(shù)據(jù)交換的核心模塊,BitSwap 使用一些預(yù)定義的激勵機制來促進(jìn)網(wǎng)絡(luò)中數(shù)據(jù)的流動,通過一個點對點之間的傳輸記錄賬本來達(dá)到互惠的目的。

IPFS 網(wǎng)絡(luò)中使用 Bitswap 協(xié)議獲取數(shù)據(jù)塊一個最大的特點是,請求的數(shù)據(jù)塊是跨文件的,這個是跟 BitTorrent 最大的區(qū)別所在,因為在 BitTorrent 中,塊請求都是基于文件的,一個 Peer Swarm 都是對同一個文件(目錄)進(jìn)行數(shù)據(jù)傳輸。而在 IPFS 中,由于數(shù)據(jù)請求是基于塊的,任何類型的數(shù)據(jù)塊,只要其哈希值一樣,都可以拿為己用,一個 Peer Swarm 對應(yīng)的是整個 IPFS 網(wǎng)絡(luò)中的數(shù)據(jù),因此所有的數(shù)據(jù)塊都可以被用來使用,實現(xiàn)真正的跨文件數(shù)據(jù)交換。這不僅大大減少了數(shù)據(jù)的冗余,還大大提高的塊檢索的效率。顯然,BitSwap 的效率比 BitTorrent 更高。

基于上,BitSwap 協(xié)議定義了 Message, Networking, Decision Engine 以及 WantList 等主要模塊。

1. Message Protocol

IPFS 中使用 Protocol Buffer 對消息進(jìn)行編碼,Peers 之間通信的消息分為兩種,一種是 WantList 用于描述請求,第二種是 Block 用于表示傳遞的塊數(shù)據(jù)。
WantList 中包含了 blockCid, priority, cancel, full 等字段用于描述要請求的 Block 索引,優(yōu)先級以及是否是完整請求等信息。

我們知道,在 IPFS 中,文件被分為若干 Chunks,也叫 Blocks,Block 是 IPFS 網(wǎng)絡(luò)中最基本的數(shù)據(jù)操作單位。每個 Block 使用一個 CID 標(biāo)識符來索引,CID 是一個自描述的索引結(jié)構(gòu)體,它集成了對 Block 編碼所使用 codec, length, hash 等信息,可以唯一標(biāo)識一個 Block。因此,要想從 Peer 下載一個 Block,只需在告訴它 CID 即可,收到 Block 時我們也可以容易進(jìn)行驗證。

實際上,由于 IPFS 中使用了 Multicodec 自適應(yīng)編碼協(xié)議,因此消息發(fā)送前還會添加 multicodec 前綴,這樣,就使得消息的格式范圍大大增加了,而不僅僅是 Protobuf。比如 JSON, Cbor 等都可以支持!更加強大的是,IPFS 還定義了一套 Multistream 作為網(wǎng)絡(luò)流的格式協(xié)議,因此它甚至還能支持協(xié)議的不同版本。

2. Networking

Networking 模塊定義了消息發(fā)送和處理,查找 Block Providers,Announce Keys,Session 管理,路由等組件。

1)Message Stream
在 IPFS 網(wǎng)絡(luò)中,消息都是被打包成 Multistream 流進(jìn)行傳輸?shù)?,Peer 接收到一個 Stream 之后,會先對其解碼成對應(yīng)的消息格式,然后根據(jù)消息內(nèi)容的要求決定是響應(yīng)請求還是接收塊數(shù)據(jù)。
如果 Decision Engine 決定響應(yīng) WantList 請求,那么 BitSwap 會從本地的塊數(shù)據(jù)庫中取出塊數(shù)據(jù),往 Peer Request Queue 中添加一個任務(wù),把塊數(shù)據(jù)發(fā)送給對方。

2)Provider
當(dāng)前節(jié)點想要下載一個數(shù)據(jù)塊,本地塊數(shù)據(jù)庫中未找到時,就會調(diào)用 BitSwap 的網(wǎng)絡(luò)模塊(DHT)查找 Providers,一旦找到,就會連接它并向其發(fā)送 WantList 請求,
如果收到了塊數(shù)據(jù),那么會把存入本地的塊數(shù)據(jù)庫。更新本地的 WantList 以及傳輸記錄賬本,更新 Session 等一些列操作。

  1. Announce
    Announce 操作是本地節(jié)點作為 Key Provider 進(jìn)行的。在 IPFS 網(wǎng)絡(luò)中,Block 是用 Key 來標(biāo)識的(即 Cid Prefix),因此,每當(dāng)本地新增一個 Block 數(shù)據(jù)是,provide worker 會異步的向網(wǎng)絡(luò)中進(jìn)行 Announce 操作,以聲明自己擁有某個塊。這樣,當(dāng)其他 Peer 想要下載時,就可以根據(jù) DHT Table 方便的找到要連接的 Providers。

4)Session
Session 管理 Peers 之間的連接,包括 Peers 的請求狀態(tài)(優(yōu)先級,是否已取消?等),以及 Peer 存活狀態(tài)等等信息。

3. Decision Engine

Decision Engine 是 BitSwap 協(xié)議的信用管理模塊。它管理一個請求隊列,使用一個賬本來記錄節(jié)點之間的傳輸記錄,并以此決定是否響應(yīng)對端的下載請求。
之所以建立一個信用賬本,主要是為了以下目的:

  • 提高節(jié)點之間數(shù)據(jù)交換的效率
  • 防止 freerider
  • 防止一些攻擊行為(比如:女巫攻擊)
  • 對信任的節(jié)點建立寬松機制

需要注意的是,信用記錄是兩個節(jié)點之間的,分為 Credit 和 Debt 兩部分,比如,節(jié)點 A 向節(jié)點 B 發(fā)送過數(shù)據(jù),那么 A 就擁有對 B 的 Credit,相反,B 欠了 A 的 Debt。如果 A 對 B 擁有的 Credit 超過 Debt,那么下次其向 B 發(fā)出 WantList 請求塊數(shù)據(jù)的時候,B 就會立刻反饋數(shù)據(jù)??偟膩碚f,A 的 Credit 減去其 Debt 就是凈值,IPFS 中使用負(fù)債率(debt ratio,r)來表示。

負(fù)債率的公式是:

debtRatio = bytes_sent/(bytes_recv + 1)

節(jié)點根據(jù)負(fù)債率來計算出這個節(jié)點的發(fā)送率 P (send|r) = 1? 1/(1+exp(6?3r))

根據(jù)這兩個函數(shù)可以發(fā)現(xiàn),當(dāng)負(fù)債率達(dá)到某一個值的時候負(fù)債率會急劇下降。

這個模型表達(dá)的意義:如果一個節(jié)點只接受數(shù)據(jù)不分享數(shù)據(jù),別人發(fā)送給它數(shù)據(jù)的概率會越來越低(到達(dá)某一個值后就會急劇降低接近0),如果節(jié)點持續(xù)保持分享數(shù)據(jù),別的節(jié)點向你發(fā)送數(shù)據(jù)的概率就會越來越大。

Decision Engine 會記錄下來和其他節(jié)點通信的賬單(數(shù)據(jù)收發(fā)),可以保持節(jié)點間數(shù)據(jù)交換的歷史和防止篡改。當(dāng)兩個節(jié)點之間建立連接的時候,BitSwap 會相互交換賬單信息,如果賬單不匹配,則清除重新記賬。惡意節(jié)點可能會故意“丟失”賬單,以希望清除掉自己的債務(wù)。其它交互節(jié)點會把這些都記下來,如果總是發(fā)生,節(jié)點就會被拒絕。

這套信用系統(tǒng)跟 BitTorrent 和 Emule 的信用系統(tǒng)是類似的,Tit-for-Tat,其信用記錄都是基于傳輸節(jié)點雙方的,并不是全局共享的,也就是說,即使你往某個節(jié)點傳輸了大量的數(shù)據(jù),如果你想要的數(shù)據(jù)不在那個節(jié)點上,你也無法根據(jù)你的貢獻(xiàn)度從整個 IPFS 網(wǎng)絡(luò)受益。

為此,IPFS 的團(tuán)隊開發(fā)了一個全新的 Filecoin 項目,它就是構(gòu)建與整個 IPFS 網(wǎng)絡(luò)之上的激勵層。后續(xù)文章再介紹。

4. WantManager

WantManager 模塊主要是管理 WantList 請求的,它是一個實現(xiàn)模塊。WantList 是核心數(shù)據(jù)結(jié)構(gòu),通過管理一個消息隊列,一旦有新的 WantList Entry 添加,就會觸發(fā)消息隊列的工作線程,從而往指定的 Peer 發(fā)送數(shù)據(jù)塊。WantManager 提供了一些機制來保證數(shù)據(jù)塊的分發(fā),比如發(fā)送失敗時會等待一定間隔后進(jìn)行重發(fā) Rebroadcast,通過 WantList Gauge 監(jiān)控發(fā)送過程,完成數(shù)據(jù)下載之后的請求取消等。

實驗

假如我們想要下載一個 Video 文件,我們知道它的哈希是:Qmdsrpg2oXZTWGjat98VgpFQb5u1Vdw5Gun2rgQ2Xhxa2t,因此,在啟動 ipfs daemon 之后,我們執(zhí)行:

$ ipfs get Qmdsrpg2oXZTWGjat98VgpFQb5u1Vdw5Gun2rgQ2Xhxa2t

這時候,IPFS 的 WantManager 會計算出 WantList,搜尋網(wǎng)絡(luò)中的 Peers 并下載相應(yīng)的 Block。
我們可以通過下列命令查看 WantList。

$ ipfs bitswap wantlist
QmYEqofNsPNQEa7yNx93KgDycmrzbFkr5oc3NMKXMxx5ff
QmUmDEBm9a8MYyqRdb3YQnoqPmqAo4cEWdKQErirFJdSWD
QmY5VJPbsRZzFCTMrFBx2qtZiyyeLhsjBysyfC1fx2gE9S
QmdbzYgyhqUNCNL8xU2HTSKwao1ck2Gmi5U1ygjQuJd92b
QmbZDe5Dcv9mJr8fiqp5aJL2cbyu64tgzwCS2Vy4P3krCL
QmRjzMzVeYRE5b6tDF3sTXMV1sTffno92uL3WwuFavBrWQ
...

找到我們擁有 Debt 的節(jié)點列表

QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3
QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z
QmUh2KnjAvgEbJFSd5JZws4CNvt6LbC4C1sRpBgCbZQiqD
Qmc9pBLfKSwWboKHMvmKx1P7Z738CojuUXkPA1dsPrvSw2
...

選擇一個并查看我們是否從該節(jié)點下載過數(shù)據(jù)

$ ipfs bitswap ledger QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3
Ledger for <peer.ID SoLMeW>
Debt ratio: 0.000000
Exchanges:  11
Bytes sent: 0
Bytes received: 2883738

全文完!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容