【Filecoin相关】Filecoin源码分析—hello协议

【Filecoin相关】Filecoin源码分析---hello协议

【Filecoin相关】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,MinerBalance Address数据类型应该都是Cid struct,只是构造时属性不同(Version, Codec, Multihash type).

2.1 node创建到启动逻辑

Node中包含hello协议对象,在执行go-filecoin daemon执行时会daemon函数:创建node对象,并启动节点服务.

【Filecoin相关】Filecoin源码分析---hello协议

这里api是nodeAPI struct的对象,包含node对象,其数据成员daemon的数据成员是指向nodeAPI的指针,在查看daemonstart函数发现最终调用的就是nodestart函数.这里nodeAPInodeDaemon的关系是:nodeAPI包含成员daemon指向nodeDaemon,nodeDaemon的成员api指向nodeAPI.

 

【Filecoin相关】Filecoin源码分析---hello协议

数据结构nodeDaemon:

【Filecoin相关】Filecoin源码分析---hello协议

数据结构nodeAPI:

【Filecoin相关】Filecoin源码分析---hello协议

创建过程:

【Filecoin相关】Filecoin源码分析---hello协议

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

}

实例化structDefaultSyncer:

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

    // 用于过滤掉含有无效blockstipsets

badTipSets *badTipSetCache

// 公式协议接口

consensus consensus.Protocol

// 包装有效区块链的磁盘存储

    chainStore Store

}

start时启动hello服务:

【Filecoin相关】Filecoin源码分析---hello协议

syncCallBack即是区块同步的回调函数,次函数中实际的执行就是Syncer.HandleNewBlocks,先来看看Syncercreate过程:

 

接前面在New函数中先构造一个Config对象保存节点属性,然后调用成员函数Build完成其数据成员的初始化,

【Filecoin相关】Filecoin源码分析---hello协议

【Filecoin相关】Filecoin源码分析---hello协议

ChainStore实现了接口Store,是操作local chain store的接口,这个接口对于local chain store具有读写权限,目前只有syncer可以,与之对应,其余调用者只具有读权限,其接口为:ReadStore,Store的子集.这里的cstOnlinecstOffline基于BlockService接口封装的,提供了对block的检索和存储接口,因为chainStore是对本地的操作,所以创建是传的参数是cstOffine.

接下来再看hello.New()函数:

hello.New(node.Host(), node.ChainReader.GenesisCid(), syncCallBack, node.ChainReader.Head)

参数有:本地主机实例,local chain storegenesis cid,回调函数,和链头type TipSet map[string]*Tip,TipBlock:

【Filecoin相关】Filecoin源码分析---hello协议

New函数完成工作:

【Filecoin相关】Filecoin源码分析---hello协议

(1) 构造handle对象,数据成员有:

host,对应libp2p上的主机,这里是自己,创世区块cid,区块同步回调函数,获取链头TipSet的函数.

(2) 注册流处理回调函数,libp2p协议

const protocol = “/fil/hello/1.0.0”

(3) 注册网络状态改变通知处理器Notifiee,这里是hello自身因为其实现了Notifiee接口,如下图所示:

【Filecoin相关】Filecoin源码分析---hello协议

可以看出主要功能在Connected函数中,收到一个节点连接后,触发sayHello函数,发送Hello消息体.

hello服务逻辑处理:

(1) 当有Node连接到自己时会发送包含本节点信息的hello 消息给对方;

【Filecoin相关】Filecoin源码分析---hello协议

(2) 对端会回复一个包含对端节点信息的消息体过来

【Filecoin相关】Filecoin源码分析---hello协议

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楼
立即报名

【Filecoin相关】Filecoin源码分析---hello协议

【IPFS原力区】

总部位于上海,深耕IPFS社区发展与商业生态建设。

Force系列产品布局IPFS商业应用,贯通视频娱乐、文件共享、浏览器入口、数据加密管理等服务,为企业与个人的使用提供一站式服务。

旗下IPFS原力区是IPFS顶级价值生态社区,聚集了众多技术大咖和IPFS爱好者,通过持续输出全面、精细、优质的IPFS咨询和技术支持,将生态中的爱好者转化为IPFS支持者和参与者,推动IPFS生态的健康发展。

【Filecoin相关】Filecoin源码分析---hello协议

原文始发于微信公众号(IPFS原力区):【Filecoin相关】Filecoin源码分析—hello协议

原创文章,作者:admin,如若转载,请注明出处:https://blog.ipfsforce.com/472b6a0827/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

联系我们

135-8568-8154

在线咨询:点击这里给我发消息

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息