区块链
挖矿,比特币,EOS,以太坊

IPFS – 可快速索引的版本化的点对点文件系统(2)

136

3. IPFS设计
IPFS是一个分布式文件系统,它综合了以前的对等系统的成功想法,包括DHT,BitTorrent,Git和SFS。 IPFS的贡献是简化,发展和将成熟的技术连接成一个单一的内聚系统,大于其部分的总和。 IPFS提供了编写和部署应用程序的新平台,以及一个新的分发系统版本化大数据。 IPFS甚至可以演进网络本身。
IPFS是点对点的;没有节点是特权的。 IPFS节点将IPFS对象存储在本地存储中。节点彼此连接并传输对象。这些对象表示文件和其他数据结构。 IPFS协议分为一组负责不同功能的子协议:

1. 身份 – 管理节点身份生成和验证。描述在3.1节。
2.网络 – 管理与其他对等体的连接,使用各种底层网络协议。可配置的。详见3.2节。
3.路由 – 维护信息以定位特定的对等体和对象。响应本地和远程查询。默认为DHT,但可更换。在3.3节描述。
4.交换 – 一种支持有效块分配的新型块交换协议(BitSwap)。模拟市场,弱化数据复制。贸易策略可替换。描述在3.4节。
5.对象 – 具有链接的内容寻址不可更改对象的Merkle DAG。用于表示任意数据结构,例如文件层次和通信系统。详见第3.5节。
6.文件 – 由Git启发的版本化文件系统层次结构。详见3.6节。
7.命名 – 自我认证的可变名称系统。详见3.7节。
这些子系统不是独立的;它们是集成在一起,互相利用各自的属性。但是,分开描述它们是有用的,从下到上构建协议栈。符号:Go语言中指定了以下数据结构和功能

 

3.1 身份
节点由NodeId标识,这是使用S / Kademlia的静态加密难题[1]创建的公钥的密码散列。节点存储其公私钥(用密码加密)。用户可以在每次启动时自由地设置一个“新”节点身份,尽管这会损失积累的网络利益。激励节点保持不变。


首次连接时,对等体交换公钥,并检查:hash(other.PublicKey)等于other.NodeId。如果没有,则连接被终止
关于加密函数的注意事项:
IPFS不是将系统锁定到一组特定的功能选择,而是支持自我描述的值。哈希摘要值以多重哈希格式存储,其包括指定使用的哈希函数的头和以字节为单位的摘要长度。例如:


这允许系统(a)选择最佳功能用例(例如,更强的安全性与更快的性能),(b)随着功能选择的变化而演变。自描述值允许兼容使用不同的参数选择。

3.2 网络
IPFS节点与数百个其他节点进行定期通信网络中的节点,可能跨越广域网络。IPFS网络堆栈功能:

传输层: IPFS可以使用任何传输协议,并且最适合WebRTC DataChannels [?](用于浏览器连接)或uTP(LEDBAT [14])。
可靠性: 如果底层网络不提供可靠性,IPFS可使用uTP(LEDBAT [14])或SCTP [15]来提供可靠性。
可连接性:IPFS还可以使用ICE NAT穿墙打洞技术[13]。
完整性:可以使用哈希校验和来检查邮件的完整性。
可验证性:可以使用发送者的公钥使用HMAC来检查消息的真实性。

 

3.2.1对等节点寻址注意事项:
IPFS可以使用任何网络; 但它不承担对IP的获取以及不直接依赖于ip层。这允许在覆盖网络中使用IPFS。
IPFS将地址存储为多层地址,这个多层地址是由字节字符串组成的, 以便于给底层网络使用。多层地址提供了一种方式来表示地址及其协议,可以封装成好解析的格式。例如:

3.3 路由
IPFS节点需要一个路由系统, 这个路由系统可用于查找:(a)其他同伴的网络地址,(b)专门用于服务特定对象的对等节点。
IPFS使用基于S / Kademlia和Coral的DSHT,在2.1节中具体介绍过。在对象大小和使用模式方面, IPFS 类似于Coral[5] 和Mainline[16], 因此,IPFS DHT根据其大小对存储的值进行区分。小的值(等于或小于1KB)直接存储在DHT上。
对于更大的值,DHT只存储值索引,这个索引就是一个对等节点的NodeId, 该对等节点可以提供對该类型的值的具体服务。
DSHT的接口如下:

注意:不同的用例将要求基本不同的路由系统(例如广域网中使用DHT,局域网中使用静态HT)。因此,IPFS路由系统可以根据用户的需求替换的。只要使用上面的接口就可以了,系统都能继续正常运行。

3.4块交换 – BitSwap协议
IPFS 中的BitSwap协议受到BitTorrent 的启发,通过对等节点间交换数据块来分发数据的。像BT一样, 每个对等节点在下载的同时不断向其他对等节点上传已下载的数据。和BT协议不同的是, BitSwap 不局限于一个torrent文件中的数据块。BitSwap 协议中存在一个永久的市场。
这个市场包括各个节点想要获取的所有块数据。而不管这些块是哪些如.torrent文件中的一部分。这些快数据可能来自文件系统中完全不相关的文件。 这个市场是由所有的节点组成的。
虽然易货系统的概念意味着可以创建虚拟货币,但这将需要一个全局分类账本来跟踪货币的所有权和转移。这可以实施为BitSwap策略,并将在未来的论文中探讨。
在基本情况下,BitSwap节点必须以块的形式彼此提供直接的值。只有当跨节点的块的分布是互补的时候,各取所需的时候,这才会工作的很好。 通常情况并非如此,在某些情况下,节点必须为自己的块而工作。
在节点没有其对等节点所需的(或根本没有的)情况下,它会更低的优先级去寻找对等节点想要的块。这会激励节点去缓存和传播稀有片段, 即使节点对这些片段不感兴趣。

3.4.1 – BITSWAP 信用
这个协议必须带有激励机制, 去激励节点去seed 其他节点所需要的块,而它们本身是不需要这些块的。 因此, BitSwap的节点很积极去给对端节点发送块,期待获得报酬。但必须防止水蛭攻击(空负载节点从不共享块),一个简单的类似信用的系统解决了这些问题:
1, 对等节点间会追踪他们的平衡(通过字节认证的方式)。
2, 随着债务增加而概率降低,对等者概率的向债务人发送块。
注意的是,如果节点决定不发送到对等体,节点随后忽略对等体的ignore_cooldown超时。 这样可以防止发送者尝试多次发送(洪水攻击) (BitSwap默认是10秒)。

3.4.2 BITSWAP的策略
BitSwap 对等节点采用很多不同的策略,这些策略对整个数据块的交换执行力产生了不同的巨大影响。在BT 中, 标准策略是明确规定的(tit-for-tat),其他不同的策略也已经被实施,从BitTyrant [8](尽可能分享)到BitThief [8](利用一个漏洞,从不共享),到PropShare [8](按比例分享)。
BitSwap 对等体可以类似地实现一系列的策略(良好和恶意)。对于功能的选择,应该瞄准:

1.为整个交易和节点最大化交易能力。2.为了防止空负载节点利用和损害交易。3.高效抵制未知策略。4.对可信任的对等节点更宽容。

探索这些策略的空白是未来的事情。在实践中使用的一个选择性功能是sigmoid,根据负债比例进行缩放:
让负债比例在一个节点和它对等节点之间:

根据r,发送到负债节点的概率为:


正如你看到的图片1,当节点负债比例超过节点已建立信贷的两倍,发送到负债节点的概率就会急速下降。

负债比是信任的衡量标准:对于之前成功的互换过很多数据的节点会宽容债务,而对不信任不了解的节点会严格很多。
这个(a)给与那些创造很多节点的攻击者(sybill 攻击)一个障碍。(b)保护了之前成功交易节点之间的关系,即使这个节点暂时无法提供数据。(c)最终阻塞那些关系已经恶化的节点之间的通信,直到他们被再次证明。

3.4.3 BITSWAP 账本
BitSwap节点保存了一个记录与所有其他节点之间交易的账本。这个可以让节点追踪历史记录以及避免被篡改。当激活了一个链接,BitSwap节点就会互换它们账本信息。如果这些账本信息并不完全相同,分类账本将会重新初始化, 那些应计信贷和债务会丢失。
恶意节点会有意去失去“这些“账本, 从而期望清除自己的债务。节点是不太可能在失去了应计信托的情况下还能累积足够的债务去授权认证。伙伴节点可以自由的将其视为不当行为, 拒绝交易。


节点可以自由的保留分布式账本历史,这不需要正确的操作,因为只有当前的分类账本条目是有用的。节点也可以根据需要自由收集分布式帐本,从不太有用的分布式帐开始:老(其他对等节点可能不存在)和小。

3.4.4 BITSWAP 详解
BitSwap 节点有以下简单的协议。


对等连接的生命周期草图:
1.Open: 对等节点间发送ledgers 直到他们同意。2.Sending: 对等节点间交换want_lists 和blocks。3.Close: 对等节点断开链接。4.Ignored: (特殊)对等体被忽略(等待时间的超时)如果节点采用防止发送策略。
Peer.open(NodeId, Ledger).
当发生链接的时候,节点会初始化链接的账本,要么保存一个份链接过去的账本,要么创建一个新的被清零的账本。然后,发送一个携带账本的open信息给对等节点。
接收到一个open信息之后,对等节点可以选择是否接受此链接。如果,根据接收者的账本,发送者是一个不可信的代理(传输低于零或者有很大的未偿还的债务),接收者可能会选择忽略这个请求。忽略请求是ignore_cooldown超时来概率性实现的,为了让错误能够有时间改正和攻击者被挫败。
如果链接成功,接收者用本地账本来初始化一个Peer对象以及设置last_seen时间戳。然后,它会将接受到的账本与自己的账本进行比较。如果两个账本完全一样,那么这个链接就被Open,如果账本并不完全一致,那么此节点会创建一个新的被清零的账本并且会发送此账本。
Peer.send_want_list(WantList)
当链接已经Open的时候,节点会广发它们的want_list给所有已经链接的对等节点。这个是在(a)open链接后(b)随机间歇超时后(c)want_list改变后(d)接收到一个新的块之后完成的。
当接收到一个want_list之后,节点会存储它。然后,会检查自己是否拥有任何它想要的块。如果有,会根据上面提到的BitSwap策略来将want_list所需要的块发送出去。
Peer.send_block(Block)
发送一个块是直接了当的。节点只是传输数据块。当接收到了所有数据的时候,接收者会计算多重hash校验和来验证它是否是自己所需数据,然后发送确认信息。
在完成一个正确的块传输之后,接受者会将此块从need_list一到have_list,最后接收者和发送者都会更新它们的账本来反映出传输的额外数据字节数。
如果一个传输验证失败了,发送者要么会出故障要么会攻击接收者,接收者可以选择拒绝后面的交易。注意,BitSwap是期望能够在一个可靠的传输通道上进行操作的,所以传输错误(可能会引起一个对诚实发送者错误的惩罚)是期望在数据发送给BitSwap之前能够被捕捉到。
Peer.close(Bool)
传给close最后的一个参数,代表close链接是否是发送者的意愿。如果参数值为false,接收者可能会立即重新open链接,这避免链过早的close链接。
一个对等节点close链接发生在下面两种情况下:
silence_wait超时已经过期,并且没有接收到来自于对等节点的任何信息(BitSwap默认使用30秒),节点会发送Peer.close(false)。
在节点退出和BitSwap关闭的时候,节点会发送Peer.close(true).
接收到close消息之后,接收者和发送者会断开链接,清除所有被存储的状态。账本可能会被保存下来为了以后的便利,当然,只有在被认为账本以后会有用时才会被保存下来。
注意点:
非open信息在一个不活跃的连接上应该是被忽略的。在发送send_block信息时,接收者应该检查这个块,看它是否是自己所需的,并且是否是正确的,如果是,就使用此块。总之,所有不规则的信息都会让接收者触发一个close(false)信息并且强制性的重初始化此链接。

3.5 Merkle DAG对象
DHT和BitSwap允许IPFS构造一个庞大的点对点系统用来快速稳定的分发和存储。最主要的是,IPFS建造了一个Merkle DAG,一个无回路有向图,对象之间的links都是hash加密嵌入在源目标中。这是Git数据结构的一种推广。Merkle DAGS给IPFS提供了很多有用的属性,包括:
1.内容可寻址:所有内容都是被多重hash校验和来唯一识别的,包括links。
2.防止篡改:所有的内容都用它的校验和来验证。如果数据被篡改或损坏,IPFS会检测到。
3.重复数据删除:所有的对象都拥有相同的内容并只存储一次。这对于索引对象非常有用,比如git的tree和commits,或者数据的公共部分。
IPFS对象的格式是:


IPFS Merkle DAG是存储数据非常灵活的一种方式。只要求对象引用是(a)内容可寻址的,(b)用上面的格式编码。IPFS允许应用完全的掌控数据域;应用可以使用任何自定义格式的数据,即使数据IPFS都无法理解。单独的内部对象link表允许IPFS做:
用对象的形式列出所有对象引用,例如:

解决字符串路经查找,例如foo/bar/baz。给出一个对象,IPFS会解析第一个路经成分进行hash放入到对象的link表中,再获取路径的第二个组成部分,一直如此重复下去。因此,任何数据格式的字符串路经都可以在Merkle DAG中使用。
*递归性的解决所有对象引用:

原始数据结构公共link结构是IPFS构建任意数据结构的必要组成部分。可以很容易看出Git的对象模型是如何套用DAG的。一些其他潜在的数据结构:
(a)键值存储(b)传统关系型数据(c)数据三倍存储(d) 文档发布系统(e)通信平台(f)加密货币区块。

这些系统都可以套用IPFS Merkle DAG,这使这些系统更复杂的应用可以使用IPFS作为传输协议。

3.5.1 路经
IPFS对象可以遍历一个字符串路经。路经格式与传统UNIX文件系统以及Web一致。Merkle DAG的links使遍历变得很容易。全称路经在IPFS中的格式是:


/ipfs前缀允许只要在挂载点不冲突(挂载点名称当然是可配置的)的情况下挂载到一个已存在的系统上。第二个路经组成部分(第一个是IPFS)是一个对象的hash。通常都是这种情况,因为没有全局的根。
一个根对象可能会有一个不可能完成的任务,就是在分布式环境(可能还断开链接)中处理百万对象的一致性。因此,我们用地址可寻址来模拟根。通过的hash所有的对象都是可访问的。这意思是说,给一个路经对象/bar/baz,最后一个对象可以可以被所有的访问的:

3.5.2 本地对象
IPFS客户端需要一个本地存储器,一个外部系统可以为IPFS管理的对象存储以及检索本地原始数据。存储器的类型根据节点使用案例不同而不同。
在大多数情况下,这个存储器只是硬盘空间的一部分(不是被本地的文件系统使用键值存储如leveldb来管理,就是直接被IPFS客户端管理),在其他的情况下,例如非持久性缓存,存储器就是RAM的一部分。
最终,所有的块在IPFS中都是能够获取的到的,块都存储在了一些节点的本地存储器中。当用户请求一个对象时,这个对象会被查找到并下载下来存储到本地,至少也是暂时的存储在本地。这为一些可配置时间量提供了快速的查找。

3.5.3对象锁定
希望确保特定对象生存的节点可以锁定此对象。这保证此特定对象被保存在了节点的本地存储器上。也可以递归的进行锁定所有相关的派生对象。这使所有被指定的对象都保存在本地存储器上。
这对长久保存文件特别有用,包括引用。这也同样让IPFS成为一个links是永久的Web,且对象可以确保其他被指定对象的生存。

3.5.4 发布对象
IPFS是全球分布的。它设计为允许成千上万的用户文件可以共同的存在的。DHT使用内容哈希寻址技术,使发布对象是公平的,安全的,完全分布式的。任何人都可以发布对象,只需要将对象的key加入到DHT中,并且以对象是对等节点的方式加入进去,然后把路径给其他的用户。
要注意的是,对象本质上是不可改变的,就像在Git中一样。新版本的哈希值不同,因此是新对象。跟踪版本则是额外版本对象的工作。

3.5.5 对象级别的加密
IPFS是具备可以处理对象级别加密操作的。一个已加密的或者已签名的对象包装在一个特殊的框架里,此框架允许加密和验证原始字节。


加密操作改变了对象的哈希值,定义一个不同的新的对象。IPFS自动的验证签名以及使用用户指定的钥匙链解密数据。加密数据的links也同样的被保护着,没有解密秘钥就无法遍历对象。
也存在着一种现象,可能父对象使用了一个秘钥进行了加密,而子对象使用了另一个秘钥进行加密或者根本没有加密。这可以保证links共享对象安全。

赞(0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址