IPFS 中的 BitSwap 协议

简介

BitSwap 是 IPFS 网络中定义数据块交换方式的协议,它是一个一种基于统一格式的消息对等协议,有别于 request/response 方式。简单来说就是,在 IPFS 中,请求和响应的消息都使用同一类型的消息包。由于在 IPFS 网络中,所有的 Peers 都是对等节点,不存在 BitTorrent 中那样的 Tracker 服务器,所以通信方式更加简单。

BitSwap 协议还定义了如何请求数据、如何发送数据以及向谁发送数据等策略,每个节点都可以有自己的策略,作为数据交换的核心模块,BitSwap 使用一些预定义的激励机制来促进网络中数据的流动,通过一个点对点之间的传输记录账本来达到互惠的目的。

IPFS 网络中使用 Bitswap 协议获取数据块一个最大的特点是,请求的数据块是跨文件的,这个是跟 BitTorrent 最大的区别所在,因为在 BitTorrent 中,块请求都是基于文件的,一个 Peer Swarm 都是对同一个文件(目录)进行数据传输。而在 IPFS 中,由于数据请求是基于块的,任何类型的数据块,只要其哈希值一样,都可以拿为己用,一个 Peer Swarm 对应的是整个 IPFS 网络中的数据,因此所有的数据块都可以被用来使用,实现真正的跨文件数据交换。这不仅大大减少了数据的冗余,还大大提高的块检索的效率。显然,BitSwap 的效率比 BitTorrent 更高。

基于上,BitSwap 协议定义了 Message, Networking, Decision Engine 以及 WantList 等主要模块。

1. Message Protocol

IPFS 中使用 Protocol Buffer 对消息进行编码,Peers 之间通信的消息分为两种,一种是 WantList 用于描述请求,第二种是 Block 用于表示传递的块数据。
WantList 中包含了 blockCid, priority, cancel, full 等字段用于描述要请求的 Block 索引,优先级以及是否是完整请求等信息。

我们知道,在 IPFS 中,文件被分为若干 Chunks,也叫 Blocks,Block 是 IPFS 网络中最基本的数据操作单位。每个 Block 使用一个 CID 标识符来索引,CID 是一个自描述的索引结构体,它集成了对 Block 编码所使用 codec, length, hash 等信息,可以唯一标识一个 Block。因此,要想从 Peer 下载一个 Block,只需在告诉它 CID 即可,收到 Block 时我们也可以容易进行验证。

实际上,由于 IPFS 中使用了 Multicodec 自适应编码协议,因此消息发送前还会添加 multicodec 前缀,这样,就使得消息的格式范围大大增加了,而不仅仅是 Protobuf。比如 JSON, Cbor 等都可以支持!更加强大的是,IPFS 还定义了一套 Multistream 作为网络流的格式协议,因此它甚至还能支持协议的不同版本。

2. Networking

Networking 模块定义了消息发送和处理,查找 Block Providers,Announce Keys,Session 管理,路由等组件。

1)Message Stream
在 IPFS 网络中,消息都是被打包成 Multistream 流进行传输的,Peer 接收到一个 Stream 之后,会先对其解码成对应的消息格式,然后根据消息内容的要求决定是响应请求还是接收块数据。
如果 Decision Engine 决定响应 WantList 请求,那么 BitSwap 会从本地的块数据库中取出块数据,往 Peer Request Queue 中添加一个任务,把块数据发送给对方。

2)Provider
当前节点想要下载一个数据块,本地块数据库中未找到时,就会调用 BitSwap 的网络模块(DHT)查找 Providers,一旦找到,就会连接它并向其发送 WantList 请求,
如果收到了块数据,那么会把存入本地的块数据库。更新本地的 WantList 以及传输记录账本,更新 Session 等一些列操作。

  1. Announce
    Announce 操作是本地节点作为 Key Provider 进行的。在 IPFS 网络中,Block 是用 Key 来标识的(即 Cid Prefix),因此,每当本地新增一个 Block 数据是,provide worker 会异步的向网络中进行 Announce 操作,以声明自己拥有某个块。这样,当其他 Peer 想要下载时,就可以根据 DHT Table 方便的找到要连接的 Providers。

4)Session
Session 管理 Peers 之间的连接,包括 Peers 的请求状态(优先级,是否已取消?等),以及 Peer 存活状态等等信息。

3. Decision Engine

Decision Engine 是 BitSwap 协议的信用管理模块。它管理一个请求队列,使用一个账本来记录节点之间的传输记录,并以此决定是否响应对端的下载请求。
之所以建立一个信用账本,主要是为了以下目的:

  • 提高节点之间数据交换的效率
  • 防止 freerider
  • 防止一些攻击行为(比如:女巫攻击)
  • 对信任的节点建立宽松机制

需要注意的是,信用记录是两个节点之间的,分为 Credit 和 Debt 两部分,比如,节点 A 向节点 B 发送过数据,那么 A 就拥有对 B 的 Credit,相反,B 欠了 A 的 Debt。如果 A 对 B 拥有的 Credit 超过 Debt,那么下次其向 B 发出 WantList 请求块数据的时候,B 就会立刻反馈数据。总的来说,A 的 Credit 减去其 Debt 就是净值,IPFS 中使用负债率(debt ratio,r)来表示。

负债率的公式是:

debtRatio = bytes_sent/(bytes_recv + 1)

节点根据负债率来计算出这个节点的发送率 P (send|r) = 1− 1/(1+exp(6−3r))

根据这两个函数可以发现,当负债率达到某一个值的时候负债率会急剧下降。

这个模型表达的意义:如果一个节点只接受数据不分享数据,别人发送给它数据的概率会越来越低(到达某一个值后就会急剧降低接近0),如果节点持续保持分享数据,别的节点向你发送数据的概率就会越来越大。

Decision Engine 会记录下来和其他节点通信的账单(数据收发),可以保持节点间数据交换的历史和防止篡改。当两个节点之间建立连接的时候,BitSwap 会相互交换账单信息,如果账单不匹配,则清除重新记账。恶意节点可能会故意“丢失”账单,以希望清除掉自己的债务。其它交互节点会把这些都记下来,如果总是发生,节点就会被拒绝。

这套信用系统跟 BitTorrent 和 Emule 的信用系统是类似的,Tit-for-Tat,其信用记录都是基于传输节点双方的,并不是全局共享的,也就是说,即使你往某个节点传输了大量的数据,如果你想要的数据不在那个节点上,你也无法根据你的贡献度从整个 IPFS 网络受益。

为此,IPFS 的团队开发了一个全新的 Filecoin 项目,它就是构建与整个 IPFS 网络之上的激励层。后续文章再介绍。

4. WantManager

WantManager 模块主要是管理 WantList 请求的,它是一个实现模块。WantList 是核心数据结构,通过管理一个消息队列,一旦有新的 WantList Entry 添加,就会触发消息队列的工作线程,从而往指定的 Peer 发送数据块。WantManager 提供了一些机制来保证数据块的分发,比如发送失败时会等待一定间隔后进行重发 Rebroadcast,通过 WantList Gauge 监控发送过程,完成数据下载之后的请求取消等。

实验

假如我们想要下载一个 Video 文件,我们知道它的哈希是:Qmdsrpg2oXZTWGjat98VgpFQb5u1Vdw5Gun2rgQ2Xhxa2t,因此,在启动 ipfs daemon 之后,我们执行:

$ ipfs get Qmdsrpg2oXZTWGjat98VgpFQb5u1Vdw5Gun2rgQ2Xhxa2t

这时候,IPFS 的 WantManager 会计算出 WantList,搜寻网络中的 Peers 并下载相应的 Block。
我们可以通过下列命令查看 WantList。

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

找到我们拥有 Debt 的节点列表

QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3
QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z
QmUh2KnjAvgEbJFSd5JZws4CNvt6LbC4C1sRpBgCbZQiqD
Qmc9pBLfKSwWboKHMvmKx1P7Z738CojuUXkPA1dsPrvSw2
...

选择一个并查看我们是否从该节点下载过数据

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

全文完!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容