目录
跳转到: 1 filecoin 概念
跳转到: 2 filecoin 通用语言理解
跳转到: 3 filecoin 开发网络使用
4 filecoin 源码顶层架构分析
4.1 题外话 -- 关于竞争力
4.2 filecoin 顶层架构概览及分析思路
4.2.1 分析思路
4.2.2 filecoin 顶层架构概览
4.3 网络层
4.4 协议层
4.5 REST/CMD
4.6 内部 API 层
4.7 core 服务层
4 filecoin 源码顶层架构分析
4.1 题外话 -- 关于竞争力
网络技术的高速发展带领我们进入了知识大爆炸, 技术快速跃迁的时代, 5G 已经开始走向商业落地, 网络速率的再次跃迁给我们带来了无限的想象空间, 全息投影, 即时翻译, 远程医疗, 人工智能等等会更加成熟落地? 路由器在个人家庭中的角色可能会发生变化? IOT 万物互联的时代将会真正到来? 区块链的 TPS 提升? 高速网络下的云应用, 大数据会出现什么新的玩法?
笔者想说的是, 整个世界都在急速变化, 在波涛汹涌的竞争浪潮之中, 如何保持自己的竞争力. 我偶尔会问同事, 朋友, 你与刚毕业的大学生相比, 优势在哪里?
笔者认为如下两点才是在这个高速时代的真正竞争力, 个人如此, 公司团队亦如此.
高效的学习能力
高维的思维能力
以上为笔者观点, 也欢迎大家探讨. 在分析具体架构之前, 笔者在 4.2.1 中分享了自己的分析思路, 我认为这也许也值得分享.
4.2 filecoin 源码顶层架构概览及分析思路
4.2.1 分析思路
终于进入到源码分析环节了, 其实回顾一下前面三章, filecoin 的概念及通用语言可以总结为 filecoin 的本质, 分析源码的过程归根接底还是理解设计者的意图, 第三章 filecoin 开发网络的实战使用对于笔者来说也是为了更清晰地对 filecoin 本质及设计意图进行深入理解.
分析总思路为: 抓住本质分析, 理解设计者意图
自上而下逐层分析, 从抽象到具体
自下而上反向总结, 从具体到抽象
分析过程分为三大步骤
第一步, 理解 filecoin 本质及设计目的 (前面三章)
第二步, 理解 filecoin 的顶层架构设计 (本章), 反向加深对 filecoin 本质的理解
第三步, 各层的具体源码分析 (后面章节), 反向加深对 filecoin 本质的理解
详细参见下图
filecoin_arch.PNG
在顶层源码中分为 go-filecon 和 rust-fil-proofs. 分别为主框架和存储证明部分, 本文主要分析 go-filecoin 源码的顶层框架.
4.2.2 filecoin 顶层架构概览
4.2.2.1 架构图
┌─────────────────────────────────────┐
│ │
Network │ network (gossipsub, bitswap, etc.) │ | | \/
│ │ |_| /\
└─────▲────────────▲────────────▲─────┘
│ │ │ ┌────────────────────────────┐
┌─────▼────┐ ┌─────▼─────┐ ┌────▼─────┐ │ │
│ │ │ │ │ │ │ Commands / REST API │
Protocols │ Storage │ │ Mining │ │Retrieval │ │ │
│ Protocol │ │ Protocol │ │ Protocol │ └────────────────────────────┘
│ │ │ │ │ │ │
└──────────┘ └───────────┘ └──────────┘ │
│ │ │ │
└──────────┬─┴─────────────┴───────────┐ │
▼ ▼ ▼
┌────────────────────────────────┐ ┌───────────────────┬─────────────────┐
Internal │ Core API │ │ Porcelain │ Plumbing │
API │ │ ├───────────────────┘ │
└────────────────────────────────┘ └─────────────────────────────────────┘
│ │
┌─────────┴────┬──────────────┬──────────────┬─┴────────────┐
▼ ▼ ▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐
│ │ │ │ │ │ │ │ │ │
Core │ Message │ │ Chain │ │ Processor │ │ Block │ │ Wallet │
│ Pool │ │ Store │ │ │ │ Service │ │ │
│ │ │ │ │ │ │ │ │ │
└────────────┘ └────────────┘ └────────────┘ └────────────┘ └────────────┘
官方给出的如上架构概览图是小于实际源码的, 但是不影响理解.
官方的 spec 项目中, 有较多文档说明已经滞后于源码, 其引用的源码有些已经从 go-filecoin 源码中消失了, 想深入分析的朋友建议可以结合源码和文档同步进行看.
本文后面的章节中, 只会简述各个层的设计目的, 每一层的具体源码分析, 将放到后面章节分享给大家.
4.2.2.2 IPFS 与 filecoin 在技术架构层面的关系
ipfsandfilecoin.PNG
IPFS 与 filecoin 同样采用 IPLD 结构, 数据结构是互通的, 简而言之, 在 IPFS 之上存储的数据, filecoin 可以读取. filecoin 存储的未密封数据, IPFS 也是可以读取的.
IPFS 与 filecoin 网络部分均复用 libp2p 部分.
filecoin 复用了大量 IPFS 组件, 比如 CID,IPLD,bitswap 等等.
4.3 网络层
网络层的实现依赖协议实验室的 libp2p 项目, 如果不熟悉的可以先简单记住如下要点, 后面笔者考虑视情况补充 IPFS/libp2p 的相关分享.
libp2p 的网络层实现了节点之间的联通性问题, 包括节点发现, NAT 穿透, pubsub,relay 等.
libp2p 的路由层的主要目的, 包括节点路由, 内容路由, DHT 键值存储.
multistream 需要理解, filecoin 的协议层之协议定义就是基于 mulitistream 的.
filecoin 网络层的目的
处理请求信息, 回复响应信息, 包括存储订单处理, 检索请求处理, 区块同步等等.
4.4 协议层
协议层主要处理应用级的逻辑, 状态切换等, 具体会通过 API 层调用具体的 core 服务进行处理.
4.4.1 hello 握手协议
协议名称: /fil/hello/1.0.0
目的:
本节点上线, 向其他节点发起 hello 握手请求, 进而进行区块同步.
响应其他新上线的节点 hello 握手请求, 触发其进行区块同步.
4.4.2 存储协议
4.4.2.1 存储矿工
协议名称:/fil/storage/mk/1.0.0, /fil/storage/qry/1.0.0
目的:
接受客户发起的订单交易请求, 查询订单请求, 会提交对应处理状态到区块链上 (包括清单处理成功或失败; 密封成功或者失败等等).
更新本地的密封或者订单状态.
4.4.2.2 存储客户
采用上述的 / fil/storage/mk/1.0.0, /fil/storage/qry/1.0.0 协议, 建立 multistream, 向矿工发起交易或者查询交易状态.
4.4.3 检索协议
4.4.3.1 检索矿工
协议名称:/fil/retrieval/free/0.0.0
目的:
接受客户的检索请求, 并响应处理
注意: 目前仅仅支持 free 检索, 白皮书所描述的完整检索功能尚未实现.
4.4.3.2 检索客户
采用上述的 / fil/retrieval/free/0.0.0 协议, 建立 multistream, 向矿工发起检索请求.
4.4.4 心跳协议
协议名称: fil/heartbeat/1.0.0
目的:
启动之后向指定节点发起心跳.
如前面 3.2.1 章节中的设置 Nick Name, 以及激活极点, 都属于心跳协议实现的.
4.5 REST/CMD
这个应该不用多解释, 提供cmd或者REST接口供用户操作具体节点. 第三章中的开发网络使用基本都是使用的 CMD 方式.
4.6 内部 API 层
4.6.1 node 对象
filecoin 的 node 节点是一个上帝对象, 从下面 Node 的结构可以看出, 基本贯穿了 filecoin 的整个业务.
为了解决耦合性问题, 尤其是后续轻节点的实现, 官方已经开始将原有的 API 包, 往 plumbing 包以及 porcelain 包迁移, 这样做的目的是让系统具备更好的解耦性, 以满足更灵活的需求.
plumbing 和 porcelain 模式也是借鉴 Git 的思维.
▼+Node : struct
- [fields]
- +AddNewlyMinedBlock : newBlockFunc
- +BlockSub : ps.Subscription
- +Blockstore : bstore.Blockstore
- +Bootstrapper : *filnet.Bootstrapper
- +ChainReader : chain.ReadStore
- +Consensus : consensus.Protocol
- +Exchange : exchange.Interface
- +HeaviestTipSetCh : chan interface{}
- +HeaviestTipSetHandled : func()
- +HelloSvc : *hello.Handler
- +MessageSub : ps.Subscription
- +MiningScheduler : mining.Scheduler
- +MsgPool : *core.MessagePool
- +OfflineMode : bool
- +OnlineStore : *hamt.CborIpldStore
- +PeerHost : host.Host
- +Ping : *ping.PingService
- +PorcelainAPI : *porcelain.API
- +PowerTable : consensus.PowerTableView
- +Repo : repo.Repo
- +RetrievalClient : *retrieval.Client
- +RetrievalMiner : *retrieval.Miner
- +Router : routing.IpfsRouting
- +StorageMiner : *storage.Miner
- +StorageMinerClient : *storage.Client
- +Syncer : chain.Syncer
- +Wallet : *wallet.Wallet
- -blockTime : time.Duration
- -blockservice : bserv.BlockService
- -cancelMining : context.CancelFunc
- -cancelSubscriptionsCtx : context.CancelFunc
- -cborStore : *hamt.CborIpldStore
- -host : host.Host
- -lookup : lookup.PeerLookupService
- -mining
- -miningCtx : context.Context
- -miningDoneWg : *sync.WaitGroup
- -sectorBuilder : sectorbuilder.SectorBuilder
- [methods]
- +BlockHeight() : *types.BlockHeight, error
- +BlockService() : bserv.BlockService
- +CborStore() : *hamt.CborIpldStore
- +ChainReadStore() : chain.ReadStore
- +CreateMiner(ctx context.Context, accountAddr address.Address, gasPrice types.AttoFIL, gasLimit types.GasUnits, pledge uint64, pid libp2ppeer.ID, collateral *types.AttoFIL) : *address.Address, error
- +GetBlockTime() : time.Duration
- +Host() : host.Host
- +Lookup() : lookup.PeerLookupService
- +MiningSignerAddress() : address.Address
- +MiningTimes() : time.Duration, time.Duration
- +NewAddress() : address.Address, error
- +SectorBuilder() : sectorbuilder.SectorBuilder
- +SetBlockTime(blockTime time.Duration)
- +Start(ctx context.Context) : error
- +StartMining(ctx context.Context) : error
- +Stop(ctx context.Context)
- +StopMining(ctx context.Context)
- -addNewlyMinedBlock(ctx context.Context, b *types.Block)
- -cancelSubscriptions()
- -getLastUsedSectorID(ctx context.Context, minerAddr address.Address) : uint64, error
- -getMinerActorPubKey() : []byte, error
- -handleNewHeaviestTipSet(ctx context.Context, head types.TipSet)
- -handleNewMiningOutput(miningOutCh chan mining.Output)
- -handleSubscription(ctx context.Context, f pubSubProcessorFunc, fname string, s ps.Subscription, sname string)
- -isMining() : bool
- -miningAddress() : address.Address, error
- -miningOwnerAddress(ctx context.Context, miningAddr address.Address) : address.Address, error
- -saveMinerConfig(minerAddr address.Address, signerAddr address.Address) : error
- -setIsMining(isMining bool)
- -setupMining(ctx context.Context) : error
- [functions]
- +New(ctx context.Context, opts ...ConfigOpt) : *Node, error
4.6.2 API 包
这基本上是早期实现的 API 接口, 对应 4.2.2.1 中的 Core API, 严重依赖于 Node, 耦合性大. 现在在逐步迁移. 感兴趣可以参照如下源码逐层深入去看.
- package: API
- location: API/API.go
- type API interface {
- Actor() Actor
- Address() Address
- Client() Client
- Daemon() Daemon
- Dag() Dag
- ID() ID
- Log() Log
- Miner() Miner
- Mining() Mining
- Paych() Paych
- Ping() Ping
- RetrievalClient() RetrievalClient
- Swarm() Swarm
- Version() Version
- }
4.6.3 plumbing 和 porcelain 包
plumbing API 简而言之, 是实现底层的公共 API, 其不依赖于 Node 的实现.
而 porcelain API 则是在 plumbing API 之上, 更偏应用级的调用, 同样不依赖于 Node 实现.
源码分别参见 go-filecoin 目录下,./plumbing 和./porcelain.
4.7 core 服务层
关于核心业务调度以及业务持久化的底层处理基本都在这一层, 包含但不限于如下服务.
4.7.1 Message pool
消息池主要保存还未上链的消息.
4.7.2 Chain store
链存储主要持久化链信息, 注意同步区块的逻辑是在协议层的 hello 协议所出发的.
4.7.3 Processor
处理事务消息如何驱动状态转换.
4.7.4 Block service
负责 IPLD 数据的内容寻址, 包括区块链等.
4.7.5 Wallet
钱包管理.
来源: http://www.jianshu.com/p/9bb00c3bfca2