星云链源码分析一

· · 698 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

星云链开始函数在cmd/neb/main.go 下

main函数下使用github.com/urfave/cli进行命令行解析

app := cli.NewApp()

app.Action = neb

app.Name ="neb"

app.Run(os.Args)

具体可以去看这个包怎么使用

往下进入neb函数

func neb(ctx *cli.Context) error {

n, err := makeNeb(ctx)

select {

case <-runNeb(ctx, n):

return nil

}

这里只贴出主要函数

有两个主要函数

makeNeb

runNeb

先从makeNeb进去看一看

func makeNeb(ctx *cli.Context) (*neblet.Neblet, error){

这函数返回了一个neblet这个neblet就是星云链的一个实例

第一行conf := neblet.LoadConfig(config)

按照路径去加载星云链的核心配置

然后对一些配置的值进行修改 

networkConfig(ctx, conf.Network)

chainConfig(ctx, conf.Chain)

rpcConfig(ctx, conf.Rpc)

appConfig(ctx, conf.App)

statsConfig(ctx, conf.Stats)

最后根据配置返回一个星云链实例

n, err := neblet.New(conf)

}


接下来可以进入runNeb函数了

func runNeb(ctx *cli.Context, n *neblet.Neblet)chan bool {

c := make(chan os.Signal,1)

signal.Notify(c, os.Interrupt, syscall.SIGTERM)

// start net pprof if config.App.Pprof.HttpListen configured

  err := n.StartPprof(n.Config().App.Pprof.HttpListen)

if err != nil {

FatalF("start pprof failed:%s", err)

}

n.Setup()

n.Start()

quitCh := make(chan bool,1)

go func() {

<-c

n.Stop()

quitCh <-true

      return

  }()

return quitCh

}

这函数我把全部代码贴上来

第一行定义一个信号 长度为1 信号类型为os.Singal

接下来是打开prof端口

err := n.StartPprof(n.Config().App.Pprof.HttpListen)

以后就可以通过这个端口对软件的性能进行分析了、比如看起来很牛逼的go火焰图

接下来一个配置,一个开始跑程序的循环

n.Setup()

n.Start()

最后看到这个<-cgolang惯用伎俩

阻塞等待操作系统的命令。等到就执行n.stop()

go func() {

<-c

n.Stop()

现在就剩 setup和start函数

一个个来

进入setup()函数

有必要一个个解释一下

n.storage, err = storage.NewRocksStorage(n.config.Chain.Datadir)生成一个rocksdb实例。Golang框架很清晰,可以每一个部分拆开来看

n.netService, err = nebnet.NewNebService(n)生成一个网络服务实例。这个专门管网络传输的比如p2p网

n.nvm = nvm.NewNebulasVM()生成一个VM实例。目前只支持V8

if err := n.consensus.Setup(n);共识

if err := n.blockChain.Setup(n)链

n.syncService = nsync.NewService(n.blockChain, n.netService)

n.blockChain.SetSyncService(n.syncService)

同步

n.rpcServer = rpc.NewServer(n) RPC 

RPC

现在只讲大框架,将来再深入

轮到start()函数

进去的第一句是这个

if n.running {

logging.CLog().WithFields(logrus.Fields{

"err":"neblet is already running",

}).Fatal("Failed to start neblet.")

}

判断一下是否程序已经在运行了

if n.config.Stats.EnableMetrics {

metrics.Start(n)

}

Metric大部分用途是用来定时输出日志,根据配置文件判断是否打开

if err := n.netService.Start()

首先第一个运行的是p2p

f err := n.rpcServer.Start()

第二个运行的是rpc

if err := n.rpcServer.RunGateway()

其实这个也是和PRC有关。相对底层的调用都是RPC但是由于还要开放HTTP接口嘛。所以这里是RPC和HTTP之间的映射。

n.blockChain.Start()

n.blockChain.BlockPool().Start()

n.blockChain.TransactionPool().Start()

n.eventEmitter.Start()

n.syncService.Start()

这里说一下eventEmitte这个东西

这个叫消息发射器。星云链通过这个东西发送消息给感兴趣的subscribe

所谓的subscribe,就是对区块链消息感兴趣的客户端。比如RPC调用客户端

客户端可以通过ApiServeClient接口将自己的信息注册到消息发射器上。

顺便看一下syncservice服务

星云链在两种情况下启动区块同步,第一种是如果能在Blockpool接收到一个新区块,如果新区块在blockpool能找到父区块

但是在当前世界状态中找不到父区块。称之为一个gap值。当这个gap值达到一定程度、启动同步

这里所说的世界状态,是指当前区块的所有状态。以及以后涉及各种数据储存都用世界状态来表示。搞得看代码的人头晕眼花

chainConf := n.config.Chain

if chainConf.StartMine {

n.consensus.Start()

接下来这段代码判断是否挖矿,挖矿的话启动consensus

大概框架


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:

查看原文:星云链源码分析一

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

698 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传