星云链开始函数在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
大概框架
有疑问加站长微信联系(非本文作者)