根据上一节的内容, 内容提供者将自己存储的内容通过网络层发出, 内容的接收者接收到数据之后, 首先通过 Engine 的一个账单系统, 统计一下本节点与发送数据节点之间的数据交互统计, 然后查找一下 Engine 中缓存的 WantList 信息, 如果还有其它节点也在请求本节点刚刚接收到的数据, 则将该数据放入 peerRequestQueue 中去, 这样本节点也会马上成为内容的提供者.
随后本节点会将数据存储在本地的存储空间上, 这样既能够为本节点的访问者, 再次访问数据的时候提供数据缓存, 也能够成为其他节点的数据访问者提供数据的存储服务.
在数据交互层第一节中我们讲到, 访问数据的节点会 subscribe 一些列的 key, 这些 key 是要查找的数据对应的索引, 因此当我们接收到数据之后, 应该对这些订阅者广播一下最新接收到的数据, 步骤 4 就是 publish 这样的消息到相关的频道上.
当以上操作完成后, 本节点检查 Want Manager 队列中的数据, 如果接受到的数据被其他节点访问, 则会将数据提供给完了中的其它节点, 这是步骤 5 的工作内容. 本节点接收到数据之后, 会将 Want Manager 中关于该节点的请求从 Want List 中删除, 如果本节点是最初的数据请求发起者, 为了避免多个节点重复的发送同一份数据, 并在网络中传播, 在接受到数据之后应该发起 Cancel 命令, 通知其它节点不要再对本数据进行全网查找. Cancel 的逻辑与 GetBlock 相似. 有兴趣的同学可以自己研究一下就提的代码实现逻辑.
代码路径如下:
除了以上查找逻辑, 数据交换层的 Engine 还有一个功能, 就是根据本节点与其他节点的数据交换多少, 来决定是否继续为自己的邻居节点提供服务, 如果一个节点接受的数据很多, 贡献的数据很少, 那么它很可能被视为恶意节点, 被大家加入 Frozen 账号, 我们上一节介绍 PeerRequestQueue 的时候提到过这个 Map 结构. 数据首发的逻辑关系如下图.
第一个公式 r 表示发送的数据与接收的数据的比例关系.
第二个公式 P 表示继续给对方节点发送数据的概率
如果我们对方节点发送了很多数据, 但是从对方接收的数据很少, 那么 r 值会很大, 概率 P 就会变小, 即, 如果我们对对方贡献的数据多, 接收的数据少, 那么我们会认为对方有可能是攻击节点. 或者是恶意节点. 反之我们应该以更高的概率服务那些给我们提供更多服务的节点. 不过这一些列的引擎设计对于 Filecoin 这样的带激励的区块链架构方案没有太多参考价值, 因此本文没有展开详细的论述. 在 Filecoin 的设计原则这, 只要提供代币服务, 就可以享受更高的带宽和存储服务, 而服务的提供者为了获取更多的代币, 会非常欢迎这样的节点.
关于数据交换层, 我们仅仅以 GetBlocks 这个比较有代表性的接口, 来讲解整个的数据处理业务逻辑, 整个数据交换层需要解决的问题很多, 难度也是最大的, 在一个去中心化的存储体系里面, 你很难有效的通知其他节点, 数据是否有效以及存储的位置变化, 这将是 IPFS 面临的一大挑战.
来源: http://www.jianshu.com/p/0a175fb5c3e1