Section1.1 start & configure
摘要
geth指令启动的入口定义在cmd/geth. 通过init函数初始化了启动的函数入口以及启动前和结束后的动作. 程序的实际入口为cmd/geth/main.go
中定义的func geth()
, 程序首先初始化node
, 然后启动, 之后注册EthService
, 注册过程生成了一个eth
, eth
会生成一个engine
, 在生成engine
的过程中会选择共识机制, 并调用共识机制的生成函数. 以后的其他关于共识机制的对象皆在engine
的基础上生成.
正文
cmd/geth
是一个可执行pkg(即包含main函数的pkg), 编译生成名为geth
可执行文件. 使用go install -v ./...
或go install -v ./cmd/geth
编译, 该文件会出现在$GOPATH/bin
下. 使用make
编译不会, geth-pbft不使用make
.
cmd/geth/main.go
cmd/geth/main.go
func init()
func init()
该函数在包初始化时调用, 先于func main()
执行.
main.go
包含全局变量app
, 使用func utils.NewApp()
初始化. func utils.NewApp()
定义在cmd/utils/flags.go
中, 函数内部不包含特殊的配置信息.
app
是使用"gopkg.in/urfave/cli.v1"
管理的, 其内部机制尚未深究.
在init()
定义了app.Flags
, app.Before
, app.After
. 其中, Flags包含了geth包含的各种子命令, 在./*cmd.go
中定义, 每个command包含了Action
, Description
等信息. 例如chaincmd.go
中定义的initCommand
, 描述了初始化chain命令的信息.
app.Before
应该是定义执行app.Action
主体之前的动作, 包含了CPU信息, 调用了utils.SetupNetwork(ctx)
.
app.After
定义了程序结束后的后续处理动作.
在func init()
中, 执行了app.Action = geth
, 将app.Action
定义为func geth()
.
func geth(ctx *cli.Context) error
func geth(ctx *cli.Context) error
cmd/geth/main.go
中定义了func geth()
. 如下:
在func main()
中, 执行了app.Run(os.Args)
. 即, 在命令行中键入geth
后, 经过几次跳转之后会运行func geth()
. 主要的配置信息从func geth()
开始. 我们将func geth()
视作事实上的程序入口.
func geth()
通过func makeFullNode(ctx *cli.Context) *node.Node
获得node
实例, 该函数在config.go
中定义. 其后通过func startNode(ctx *cli.Context, stack *node.Node)
启动.
func startNode(ctx *cli.Context, stack *node.Node)
func startNode(ctx *cli.Context, stack *node.Node)
startNode boots up the system node and all registered protocols, after which it unlocks any requested accounts, and starts the RPC/IPC interfaces and the miner.
首先调用了cmd/utils/cmd.go
中定义的func StartNode(stack *node.Node)
, 该函数只是注册中断信号等. 其后, 该函数配置了account, wallet, rpc(Remote Procedure Call)等信息, 暂不关心. 最后根据配置信息判断是否开始挖矿, 配置GasPrice, 并启动相关线程.
cmd/geth/config.go
cmd/geth/config.go
func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig)
func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig)
该函数内初始化eth
, shh
, node
的初始配置.
其内设置了EthStatsURL
, 作用尚未清楚.
func makeFullNode(ctx *cli.Context) *node.Node
func makeFullNode(ctx *cli.Context) *node.Node
如上述, 该函数会被cmd/geth/main.go
中的func geth()
调用.
首先通过调用了func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig)
, 进行了配置, 获得节点实例. 其后执行utils.RegisterEthService(stack, &cfg.Eth)
, 开始具体eth的配置. 其内便包含了共识机制的设置, 在cmd/utils/flags.go
中进行了实现.
cmd/utils/flags.go
cmd/utils/flags.go
func RegisterEthService(stack *node.Node, cfg *eth.Config)
func RegisterEthService(stack *node.Node, cfg *eth.Config)
该函数根据SyncMode
是否为downloader.LightSync
判断使用light client或std client. 若使用标准客户端, 会进一步执行fullNode, err := eth.New(ctx, cfg)
来生成节点, 共识机制的配置主要从eth.New()
开始, 该函数在eth/backend.go
中定义.
eth/backend.go
eth/backend.go
内部对协议各个细节进行了定义, 关于共识机制的尤其需要关注eth.engine
, 该值由CreateConsensusEngine(ctx, config, chainConfig, chainDb)
定义.
CreateConsensusEngine(ctx, config, chainConfig, chainDb)
CreateConsensusEngine(ctx, config, chainConfig, chainDb)
可以看到, 这里根据config
内的参数选择共识机制, 并调用相关函数获得实例. ethash.NewFaker()
等在consensus/ethash
内部定义, 已经进入了共识机制内部.
Last updated
Was this helpful?