《7天以太坊源码解读》— 第二天,节点是如何编译以及启动的

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

>>> geth 可执行文件怎么构建出来的?

上篇文章中讲,我们是通过 make all 构建出所有可执行文件。那么它到底做了些什么呢?

make是一个构建工具,它依据指定规则来构建目标,而构建什么目标以及如何构建目标都写在了 makefile 文件中(当然你也可以不叫makefile)

推荐大家阅读这篇文章 http://www.ruanyifeng.com/blog/2015/02/make.html ,学习 makefile 文件的编写

可以看到以太坊源码根目录存在一个makefile文件,通过上面的学习应该知道了 make all 到底做了什么

GORUN = env GO111MODULE=on go run
...
all:
    $(GORUN) build/ci.go install

make all执行的其实就是

env GO111MODULE=on go run build/ci.go install

意思是开启 golang 的 modules 特性,运行 build 文件夹下的 ci.go 文件,并传递参数 install

下面可以查看 ci.go 文件是如何运行的了。

首先找到 main 函数,往下开始分析代码。

传递的是install,所以找到 doInstall 函数

  1. 检查本机 golang 版本,如果版本不满足要求就直接退出,编译失败
  2. 检查指定的编译目标架构,如果未指定,默认是amd64,根据目标架构组装相应的命令选项以及参数

可以得到最终得到的编译命令是

go install -ldflags -X main.gitCommit=58cf5686eab9019cc01e202e846a6bbc70a3301d -X main.gitDate= -s -v ./...

就是编译根目录的所有包。

同理 make geth 最终的构建命令就是

go install -ldflags -X main.gitCommit=58cf5686eab9019cc01e202e846a6bbc70a3301d -X main.gitDate= -s -v ./cmd/geth

所以可以看出 ./cmd/geth 包就是 geth 的入口。我们就可以从这开始阅读源码了。

如果还有人不知道 go 可执行文件如何编译的,不知道go install的用法,可以网上学习,篇幅关系,这里不讲了。

>>> 节点是如何启动的?

现在从 cmd/geth/main.go 文件开始

  1. 通过 main 函数以及 init 函数对 geth 的各种参数以及选项进行配置,就是什么命令执行什么样的动作。如果没有指定子命令,默认执行 geth 函数中的代码。

上篇文章中的

./build/bin/geth --datadir=./private/ --mine --miner.threads=1 --etherbase=0x0000000000000000000000000000000000000003 --port 33303 --rpc --rpcport 8545 --rpcapi eth,web3,net,rpc,admin --ethash.dagdir ./private/tagdir/

就执行的是 geth 函数中的代码。接下来看 geth 函数

func geth(ctx *cli.Context) error {
    if args := ctx.Args(); len(args) > 0 {
        return fmt.Errorf("invalid command: %q", args[0])
    }
    prepare(ctx)
    node := makeFullNode(ctx)
    defer node.Close()
    startNode(ctx, node)
    node.Wait()
    return nil
}
  1. 配置内存缓存限额(配置go gc的回收百分比),并安装运行时指标收集系统
  2. 准备构建一个全节点。首先会注册一个Eth服务(以太坊中每个模块都被称作为一个服务),Eth服务中,如果指定了使用轻量协议(--light.serve设置如果大于0就是使用了,默认是0),则会开启一个LES(以太坊客户端的轻量级的子协议)服务器提供服务。
  3. 如果启用了Whisper协议(--shh选项),则注册Whisper服务。
  4. 如果启用了GraphQL功能,则注册一个GraphQL服务。
  5. 如果启用了ethstats功能,则注册ethstats服务。
  6. 启动全节点
  • 启动p2p服务器
  • 依次启动前面注册过的所有服务
  • 按需启动各种api端点服务器(HTTP、WS、RPC等)
  • 开启一个协程拦截终止命令(SIGINT和SIGTERM),用于优雅关闭退出
  • 解锁钱包账户(如果参数指定了的话),便于余额操作
  • 设置新建钱包、开启钱包、关闭钱包事件的处理器
  • 配置eth服务和les服务的与节点交互的rpc客户端
  • 订阅同步完成的事件。处理--exitwhensynced选项,同步完成就退出节点
  • 如果开启了挖矿,则启动挖矿
  1. 等待节点运行结束(关闭或异常退出)

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

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

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