初始化工作
Geth 的 main()
函数非常的简洁,通过 app.Run()
来启动程序
[./cmd/geth/main.go]
func main() {
if err := app.Run(os.Args); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
其简洁是得力于 Geth 使用了 gopkg.in/urfave/cli.v1
扩展包,该扩展包用于管理程序的启动,以及命令行解析,其中 app
是该扩展包的一个实例。
在 Go 语言中,在有 init()
函数的情况下,会默认先调用 init()
函数,然后再调用 main()
函数;Geth 几乎在 ./cmd/geth/main.go#init()
中完成了所有的初始化操作:设置程序的子命令集,设置程序入口函数等,下面看下 init()
函数片段:
[./cmd/geth/main.go]
func init() {
// Initialize the CLI app and start Geth
app.Action = geth
app.HideVersion = true // we have a command to print the version
app.Copyright = "Copyright 2013-2018 The go-ethereum Authors"
app.Commands = []cli.Command{
// See chaincmd.go:
initCommand,
importCommand,
exportCommand,
importPreimagesCommand,
...
}
...
}
在以上代码中,预设了 app
实例的值,其中 app.Action = geth
作为 app.Run()
调用的默认函数,而 app.Commands
保存了子命令实例,通过匹配命令行参数可以调用不同的函数(而不调用 app.Action
),使用 Geth 不同的功能,如:开启带控制台的 Geth、使用 Geth 创造创世块等。
节点启动流程
无论是通过 geth()
函数还是其他的命令行参数启动节点,节点的启动流程大致都是相同的,这里以 geth()
为例:
[./cmd/geth/main.go]
func geth(ctx *cli.Context) error {
node := makeFullNode(ctx)
startNode(ctx, node)
node.Wait()
return nil
}
其中 makeFullNode()
函数将返回一个节点实例,然后通过 startNode()
启动。在 Geth 中,每一个功能模块都被视为一个服务,每一个服务的正常运行驱动着 Geth 的各项功能;makeFullNode()
通过解析命令行参数,注册指定的服务。以下是 makeFullNode()
代码片段:
[./cmd/geth/config.go]
func makeFullNode(ctx *cli.Context) *node.Node {
stack, cfg := makeConfigNode(ctx)
utils.RegisterEthService(stack, &cfg.Eth)
if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) {
utils.RegisterDashboardService(stack, &cfg.Dashboard, gitCommit)
}
...
// Add the Ethereum Stats daemon if requested.
if cfg.Ethstats.URL != "" {
utils.RegisterEthStatsService(stack, cfg.Ethstats.URL)
}
return stack
}
然后通过 startNode()
启动各项服务并运行节点。以下是 Geth 启动流程图:
每个服务正常运行,相互协作,构成了 Geth:
通过 main()
函数的调用,最终启动了 p2p 网络,这一小节对网络架构做详细的分析。
三层架构 以太坊是去中心化的数字货币系统,天然适用 p2p 通信架构,并且在其上还支持了多种协议。在以太坊中,p2p 作为通信链路,用于负载上层协议的传输,可以将其分为三层结构:
TCP/IP
中的网络层及以下的封装。p2p 通信链路层 从最下层开始逐步分析,第三层是由 Go 语言所封装的网络 IO 层,这里就跳过了,直接分析 p2p 通信链路层。p2p 通信链路层主要做了三项工作:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。