Filecoin源码分析—hello协议

Chain Store主要持久化区块链信息,信息来源是hello服务.
1. 源码信息
1.1 package
hello
1.2 location
commands/daemon.go
protocol/hello
node/node.go
chain
2. 源码分析
常见数据结构:
Cid |
– str string |
+ Prefix() : Prefix |
+ Hash() : mh.Multihash |
+ string() : string |
+ … |
矿机ID,MessageID,Miner及Balance Address数据类型应该都是Cid struct,只是构造时属性不同(Version, Codec, Multihash type).
2.1 node创建到启动逻辑
Node中包含hello协议对象,在执行go-filecoin daemon执行时会daemon函数:创建node对象,并启动节点服务.
这里api是nodeAPI struct的对象,包含node对象,其数据成员daemon的数据成员是指向nodeAPI的指针,在查看daemon的start函数发现最终调用的就是node的start函数.这里nodeAPI与nodeDaemon的关系是:nodeAPI包含成员daemon指向nodeDaemon,nodeDaemon的成员api指向nodeAPI.
数据结构nodeDaemon:
数据结构nodeAPI:
创建过程:
2.2 hello创建到执行逻辑
Node struct中关联的数据结构:
// Node represents a full Filecoin node.
type Node struct {
…
ChainReader chain.ReadStore
// 同步服务:保证本地chain store的实时性和正确性
Syncer chain.Syncer
…
// hello协议
HelloSvc *hello.Handler
…
}
type Syncer interface {
HandleNewBlocks(ctx context.Context, blkCids []cid.Cid) error
}
实例化struct为DefaultSyncer:
type DefaultSyncer struct {
// 确保任意时刻只有一个协程在调HandleNewBlocks
mu sync.Mutex
// cstOnline is the online storage for fetching blocks. It should be connected to the network with bitswap.
cstOnline *hamt.CborIpldStore
// cstOffline is the node’s shared offline storage.
cstOffline *hamt.CborIpldStore
// 用于过滤掉含有无效blocks的tipsets
badTipSets *badTipSetCache
// 公式协议接口
consensus consensus.Protocol
// 包装有效区块链的磁盘存储
chainStore Store
}
start时启动hello服务:
syncCallBack即是区块同步的回调函数,次函数中实际的执行就是Syncer.HandleNewBlocks,先来看看Syncer的create过程:
接前面在New函数中先构造一个Config对象保存节点属性,然后调用成员函数Build完成其数据成员的初始化,
ChainStore实现了接口Store,是操作local chain store的接口,这个接口对于local chain store具有读写权限,目前只有syncer可以,与之对应,其余调用者只具有读权限,其接口为:ReadStore,是Store的子集.这里的cstOnline和cstOffline基于BlockService接口封装的,提供了对block的检索和存储接口,因为chainStore是对本地的操作,所以创建是传的参数是cstOffine.
接下来再看hello.New()函数:
hello.New(node.Host(), node.ChainReader.GenesisCid(), syncCallBack, node.ChainReader.Head)
参数有:本地主机实例,local chain store的genesis cid,回调函数,和链头type TipSet map[string]*Tip,Tip即Block:
New函数完成工作:
(1) 构造handle对象,数据成员有:
host,对应libp2p上的主机,这里是自己,创世区块cid,区块同步回调函数,获取链头TipSet的函数.
(2) 注册流处理回调函数,是libp2p协议
const protocol = “/fil/hello/1.0.0”
(3) 注册网络状态改变通知处理器Notifiee,这里是hello自身因为其实现了Notifiee接口,如下图所示:
可以看出主要功能在Connected函数中,收到一个节点连接后,触发sayHello函数,发送Hello消息体.
u hello服务逻辑处理:
(1) 当有Node连接到自己时会发送包含本节点信息的hello 消息给对方;
(2) 对端会回复一个包含对端节点信息的消息体过来
func (h *Handler) handleNewStream(s net.Stream) {
defer s.Close()
//获取远端节点实例
from := s.Conn().RemotePeer()
var hello Message
// 读取流信息到hello结构体中
if err := cbu.NewMsgReader(s).ReadMsg(&hello); err != nil {
log.Warningf(“bad hello message from peer %s: %s”, from, err)
return
}
// 调用processHelloMessage方法对接收到的消息进行处理
switch err := h.processHelloMessage(from, &hello); err {
// 如果创世区块不一样,关闭流连接退出,不予处理
case ErrBadGenesis:
log.Warningf(“genesis cid: %s does not match: %s, disconnecting from peer: %s”, &hello.GenesisHash, h.genesis, from)
s.Conn().Close() // nolint: errcheck
return
case nil: // ok, noop
default:
log.Error(err)
}
}
func (h *Handler) processHelloMessage(from peer.ID, msg *Message) error {
// 如果genesis区块不一样,报错
if !msg.GenesisHash.Equals(h.genesis) {
return ErrBadGenesis
}
// 调用区块同步方法,这里就会进入之前Syncer的逻辑里
h.chainSyncCB(from, msg.HeaviestTipSetCids, msg.HeaviestTipSetHeight)
return nil
}
最后看下genesisCid相关的代码:
var GenesisKey = datastore.NewKey(“/consensus/genesisCid”)
func readGenesisCid(ds datastore.Datastore) (cid.Cid, error) {
bb, err := ds.Get(chain.GenesisKey)
if err != nil {
return cid.Undef, errors.Wrap(err, “failed to read genesisKey”)
}
var c cid.Cid
err = json.Unmarshal(bb, &c)
if err != nil {
return cid.Undef, errors.Wrap(err, “failed to cast genesisCid”)
}
return c, nil
}
这个应该是区块链源块对应的key和cid,在第一次服务启动后,区块链同步到本地后才会有对应的value值,如果没法同步,则后续即使接到其他节点的区块也无法同步到本地。
【?活动通知】主题:Filecoin挖矿与BTC挖矿的对比
时间:2019年3月12日(周二)19:00 ~ 20:40地点:(上海.普陀)江宁路2000号 中期大厦12楼
总部位于上海,深耕IPFS社区发展与商业生态建设。
Force系列产品布局IPFS商业应用,贯通视频娱乐、文件共享、浏览器入口、数据加密管理等服务,为企业与个人的使用提供一站式服务。
旗下IPFS原力区是IPFS顶级价值生态社区,聚集了众多技术大咖和IPFS爱好者,通过持续输出全面、精细、优质的IPFS咨询和技术支持,将生态中的爱好者转化为IPFS支持者和参与者,推动IPFS生态的健康发展。

原创文章,作者:IPFS原力区,如若转载,请注明出处:https://ipfser.org/2019/03/14/filecoin-hello/
提示:投资有风险,入市须谨慎。本资讯不作为投资理财建议。