IPFS源码阅读(二)
使用IPFS中重要的就是要知道怎样存和获取数据,以及数据的交换。本文重点介绍下Add操作,就是IPFS添加文件时涉及到的相关代码。当前的IPFS版本是v0.13.0-rc1,我实际是看的master分支。
入口文件Add
Add函数位于core/coreapi/unixfs.go文件中
里面可以看到重要的几点
Chunker默认大小是256kb,用"size-262144"表示
使用Balanced Merkle DAG
组件之间的关系:DAGService包含了BlockService组件,而BlockService组合了GCBlockstore组件,然后GCBlockstroe包含BaseBlocks和GCLocker两个组件,最后BaseBlocks组合了最原始的blockstore组件
Add执行过程大概如下:初始化settings,然后使用api.baseBlocks, api.blockstore初始化GCBlockstore,接着初始化DAGService
然后创建一个adder,调用AddAllAndPin
addFile
传入路径和文件, 调用adder.add生成Merkle DAG并返回root, 接着调用adder.addNode把root节点添加到MFS中(MFS具体内容看我前一遍文章),这又是通过调用mfs.PutNode方法来实现的。
PutNode(r *Root, path string, nd ipld.Node)
通过path查找root节点应该存放的目录,然后调用directory.AddChild,这个函数
会继续调用dagService.Add完成文件实际存储(最终调用的是flatfs的Put函数)
调用unixfsDir.AddChild吧根节点存放到Merkle DAG中
后续流程
根据需要是否pin文件
总结
在寻找存放文件的实际Put函数时,很是头疼,IPFS的部分代码设计还是不错的,比如模块化和接口抽象,但实际也没那么好,代码调用层次过深(包括参数传递)
另外GO语言也比较灵活,写不好就有比较乱的感觉。
附录
实际文件存放目录: ~/.ipfs/blocks
想看Merkle DAG是什么样子的,可以参考这个工具: https://dag.ipfs.io/
ipfs filestore
IPFS中的filestore作用类似于Git中的LFS,主要用于存储大文件,在blockstore只存储大文件的dag root,在FileManager存放文件的metadata, 避免大文件充斥blockstore,节省blockstore的空间。
DAG中叶子节点的数据结构ipld.Node
DAG中有Link数据结构如下
// Link represents an IPFS Merkle DAG Link between Nodes.
type Link struct {
// utf string name. should be unique per object
Name string // utf8
// cumulative size of target object
Size uint64
// multihash of the target object
Cid cid.Cid
}