IPFS协议栈笔记

身份层:管理节点身份生成和验证

网络层:管理与其他节点的连接、使用多种底层网络协议

路由层:以分布式哈希表维护路由信息以定位特定的对等节点和对象。响应本地和远端节点发出的查询请求。

交换层:一种支持有效块分配的新型块交换协议BitSwap,模拟可信时场,弱化数据复制,防作弊

对象层:具有基于Merkle DAG所构建的对象层,具有内容寻址,防冗余特性

文件层:类似Git的版本化文件系统

命名层:具有自验特性的可变名称系统

 

身份层

标识IPFS网络的节点。在节点首次建立时,节点之间首先交换公钥,并且进行身份信息验证,比如:检查hash(other.PublicKey)的值是否等于other.NodeId的值。如果校验不通过,则用户信息不匹配,节点立即终止连接。

有两个优势:

根据需求选择最佳算法,随着功能的变化而演变。

 

网络层

IPFS网络堆栈的特点:

传输:IPFS兼容现有的主流传输协议,WebRTCDataChannels或uTP

可靠性:使用uTP和sctp来保障,这两种协议可以动态调整网络状态

可连接性:使用ICE等NAT穿越技术来实现广域网的可连接性

完整性:使用哈希校验检查数据完整性,IPFS所有数据块都有唯一的哈希

可验证性:使用数据发送者的公钥及HMAC消息认证码来检查消息的真实性

 

IPFS采用multiaddr的格式来表示目的地址和其使用的协议,以此来兼容和扩展未来可能出现的其他网络协议。

IPFS遵循覆盖网络的设计理念。首先虚拟出类似网关的IP地址,然后把数据包转发到Host物理服务器地址,最终通过路由和交换到达另一个HOST服务器的IP地址

路由层

路由层用于查找同伴节点的网络地址;专门用于服务特定对象的对等节点。IPFS数据结构基于S/Kadmlia和Coral技术的分布式松散哈希表。DSHT的接口位于libp2p模块中,IPFS路由实现了3中基本功能:内容路由、节点路由和节点存储.

交换层

IPFS中的BitSwap协议是协议实验的一项创新设计,利用信用机制在节点之间进行数据交换。BitSwap不局限于一个种子文件中的数据块。BitSwap协议中存在一个数据交换时场,包含各个节点想要获取的所有块数据,这些块来自文件系统中完全不相关的文件,同时这个市场是由IPFS网络中所有节点组成的。

BitSwap协议

BitSwap协议主要负责两件事情:向其他节点请求需要的数据块列表(want_list)和为其他节点提供已有的数据块列表(have_list)。当我们需要向其他节点请求数据或为其他节点提供数据块时,都会发送BitSwap message消息:want_list和对应数据块。

BitSwap系统重要模块:

需求管理器(Want-Manager):节点请求时在本地返回相应的结果或者发出合适的请求;

决策引擎(Desction-Engine):如何为其他节点分配资源,当接待你接收包含want_list的消息时,会被转发到决策引擎,引擎根据节点的BitSwap账单。

生命周期:

状态开放(Open):对等节点间开放待发送Bitswap账单状态,直到建立连接

数据发送(Sending):节点间发送want_list和数据块

连接关闭(Close):节点发送完成后断开连接

节点忽略(Ignored):超时、自定义和信用过分底等因素被忽略

 

BitSwap信用体系

BitSwap协议必须能够激励节点去乐于分享数据,即使这个节点暂时没有数据需求。IPFS根据节点的之间的数据收发建立了一个信用体系:有借有还,再借不难。

  • 发送给其他节点数据可以增加信用值
  • 从其他节点接受数据降低信用值

如果一个节点只接收数据而不分享数据,信用值就会降得很低而被其他节点忽略掉。简单来讲就是:你乐于分享数据,其它节点也乐于发送数据给你,如果你不愿意分享,那么其它节点也不愿意给你数据。

 

BitSwap策略

根据上面的信用体系,BitSwap可以采取不同的策略来实现,每一种策略都会对系统的整体性能产生不同的影响。策略的目标是:

  1. 节点数据交换的整体性能和效率最高
  2. 阻止“吃白食”(freeloaders)的现象。就是不能够只下载数据不上传数据
  3. 可以有效的防止一些攻击行为(比如:女巫攻击)
  4. 对信任节点建立宽松机制(lenient)

IPFS提供一个可参考的策略机制(实际的实现可以有所变化):

每个节点根据和其他节点的收发数据,计算负债率(debt ratio,r) r = bytes_sent / (bytes_recv + 1) 节点根据负债率计算出来和这个节点的数据发送率(P) P (send|r) = 1− 1/(1+exp(6−3r))

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

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

 

BitSwap账单

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

 

对象层

基于分布式哈希表DHT和BitSwap技术,IPFS期望构造一个庞大的点对点系统,用于快速、稳健地存储和分发数据块。

IPFS使用Merkle DAG技术构建了一个有向无环图数据结构,用于存储对象数据。这也是Git使用的数据结构,Merkle DAG为IPFS提供了很多有用的属性,包括:

1、内容可寻址:所有内容由多重哈希校验并唯一标识。

2、防止篡改:所有内容都通过哈希校验,如果数据被篡改,IPFS网络将能检测到。

3、重复数据删除:相同内容有相同哈希,只存储一次,对索引对象特别有用。


本地对象

IPFS客户端需要一个本地存储器,一个外部系统可以为IPFS管理的对象存储以及检索本地原始数据。存储器的类型根据节点使用案例而已,在大多数情况下,这个存储器只是硬盘空间的一部分(不是被本地的leveldb来管理,就是直接被IPFS客户端管理),在其他的情况下,例如非持久性缓存,存储器就是RAM的一部分。

对象锁定

希望对某个对象数据进行长期存储的节点可以执行锁定操作。以此保证此对象被保存在了该节点的本地存储器上,同时也可以递归地锁定所有相关的派生对象,这对长期存储完整的对象文件特别有用。

发布对象

IPFS是全球分布的文件系统,DHT使用内容哈希寻址技术,使发布对象是公平的,安全的,完全分布式的。任何人都可以发布对象,只需要将对象的Key加入到DHT中,并且对象是通过P2P传输的方式加入进去,然后把访问路径给其他的用户。

 

加密操作改变了对象的哈希值,定义了一个不同新的对象结构,IPFS自动的验证签名机制,用户自定义的私钥加解密数据都为对象数据提供了安全保证。同时,加密数据的链式关系也同样被保护着,因为没有解密密钥就无法遍历整个链式对象结构。

 

文件层

PFS定义了一组对象,用于在Merkle DAG之上对版本化文件系统进行建模。这个对象模型类似于著名版本控制软件Git的数据结构:

  • 块(block):一个可变大小的数据块。
  • 列表(list):一个块或其他列表的集合。
  • 树(tree):块,列表或其他树的集合。
  • 提交(commit):树的版本历史记录中的快照。

文件对象:BLOB

  blob对象包含一个可寻址的数据单元,表示一个文件,当文件比较小,不需要切片时,就以Blob对象的形式存储在IPFS网络之中,如下所示:

 

{
    "data":"some data here", //blobs 无links
}

文件对象:LIST

  list对象由多个连接在一起的Blob组成,通常存储的是一个大文件。从某种意义上说,list的功能更适合数据互相连接的文件系统。由于list可以包含其他list,所以可能形成包括链接列表和平衡树在内的拓扑结构,如下:

 

{
    "data":["blob","list","blob"],  //lists有一个对象类型的数组作为数据
    "links":[
        {
            "hash":"XLYkgq61DYaq8Nhkcqy7LcnSA7dSHQ78x",
            "size":189458
        },
        {
            "hash":"XLHBNsgoepUDKL8dkd9Hesa5io9sdxi7n",
            "size":19442
        },
        {
            "hash":"XLWVQKJII8v7dggkfdhHSFlkaw9yjs7dj",
            "size":5286
        } // 在links中lists是没有名字的
    ]
}

文件对象:TREE

  在IPFS中,Tree对象与Git的tree类似,代表一个目录,或者一个名字到哈希值的映射表,哈希值表示blob,list,其他的tree,或commit,结构如下:

 

{
    "data":["blob","list","blob"], // trees有一个对象类型的数组作为数据
    "links":[
        {
            "hash":"XLYkgq61DYaq8Nhkcqy7LcnSA7dSHQ78x",
            "name":"less",
            "size":189458
        },
        {
            "hash":"XLHBNsgoepUDKL8dkd9Hesa5io9sdxi7n",
            "name":"script",
            "size":19442
        },
        {
            "hash":"XLWVQKJII8v7dggkfdhHSFlkaw9yjs7dj",
            "name":"template",
            "size":5286
        } // trees是没有名字的
    ]
}

文件对象:COMMIT

  IPFS中,commit对象代表任何对象在版本历史记录中的一个快照,它与Git的commit也非常类似,但它可以指向任何类型的对象。

版本控制

  commit对象代表着一个对象在历史版本中的一个特定快照。两个不同的commit之间相互比较对象数据,可以揭露出两个不同版本文件系统的区别。IPFS可以实现Git版本控制工具的所有功能,同时也可以兼容Git。

文件系统路径

  Merkle DAG可以看到,可以使用字符串路径API遍历IPFS对象在系统上的文件路径地址。

将文件分割成LIST和BLOB

  版本控制和分发大文件最主要的挑战:找到一个正确的方法来将它们分隔成独立的块。与其认为IPFS可以为每个不同类型的文件提供正确的分隔方法,不如说IPFS提供了以下的几个可选选择:

  • 使用Rabin Fingerprints指纹算法来定义比较合适的块边界。
  • 使用rsync和rolling-checksum算法,来检测块在版本之间的改变。
  • 允许用户设定文件大小而调整数据块的分割策略。

路径查找性能

  基于路径的访问需要遍历整个对象图,检索每个对象需要在DHT中查找它的Key值,连接到对等点并检索对应的数据块。这是一笔相当大的性能开销,特别是在查找的路径具有多个路径时。IPFS充分考虑了这一点,并设计了如下的方式来缓解:

  • 树缓存(tree cache):由于所有的对象都是哈希寻址的,可以被无限的缓存,另外,tree一般比较小,所以比起blob,IPFS会优先缓存tree。
  • 扁平树(flattened trees):对于任何给定的tree,一个特殊的扁平树可以构建一个链表,所有对象都可以从这个tree中访问得到。在扁平树中name就是一个从原始tree分离的路径,用斜线分隔。

命名层

       采用DAG的方式生成了一个可以追踪对象的历史记录;但是存在一个问题:当数据对象的内容更新后,同时发生改变的还有内容地址的名称。需要设计一个在易变环境中保持固定名称的方案。

自验证签名

       在加密环境下、在全局命名空间中,构建可自行认证名称的方式,模式如下:

       NodeId = hash(node.PubKey),生成IPFS节点信息

       给每个用户分配一个可变的命名空间,由之前生成的节点ID信息作为地址名称,在此路径下:/ipns/

       一个用户可以在此路径下发布一个用自己私钥签名的对象。比如:

      /ipns/XLF2ip4ii9x0wejs23HD2swlddVmas8kd0Ax/ 。

      当其他用户获取对象时,他们可以检测签名是否与公钥和节点信息匹配,从而验证用户发布对象的真实性,达到可变状态的获取。

人类友好名称

  IPNS是重新命名地址名称的好方式,但对人类来说,却不是十分友好和记忆,因此,IPFS使用下面的技术来增加IPNS的用户良好度。

1.对等节点链接

  遵循自验证文件系统(SFS)的设计理念,用户可以将其他用户节点的对象直接链接到自己的命名空间下,这有利于创建一个更信任的网络:

# Alice links 到 Bob 上
ipfs link /<alice-pk-hash>/friends/bob /<bob-pk-hash>
# Eve links 到 Alice 上
ipfs link /<eve-pk-hash>/friends/alice /<alice-pk-hash>
# Eve 也可以访问Bob
/<eve-pk-hash>/friends/alice/friends/bob
# 访问Verisign认证域
/<verisign-pk-hash>/foo.com

2.DNS TXT IPNS记录

  在现有的DNS系统中添加TXT记录,这样能够通过域名访问IPFS网络中的文件对象:

# DNS TXT 记录
ipfs.benet.ai. TXT "ipfs=XLF2ip4jD3U..."
# 表现为符号链接
ln -s /ipns/XLF2ip4jD3U... /ipns/fs.benet.ai

# IPFS也支持可读标识符Proquint,可以将二进制编码翻译成可读文件的方法,如下:
# proquint语句
/ipns/dahih-dolij-sozuk-vosah-luvar-fuluh
# 分解为相应的下面形式
/ipns/KhWwNprxYVxKqpDZ

除此之外,IPFS还提供短地址的命名服务,类似我们现在看到的DNS和WebURL链接:

# 用户可以从下面获取一个link
/ipns/shorten.er/foobar
# 然后放到自己的命名空间
/ipns/XLF2ipQ4JD3Udex6xKbgeHrhemUtaA9Vm

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值