上一篇文章我们说了一下 tendermint 的基本流程与共识,今天我们再说一下创世部分,这部分很简单,简单说就是生成了默认配置的文件并且根据配置进行创世。
这个是代码的 main 入口,在 commands 目录下是所有的命令文件。
package main
import (
"os"
"path/filepath"
"github.com/tendermint/tendermint/libs/cli"
cmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
cfg "github.com/tendermint/tendermint/config"
nm "github.com/tendermint/tendermint/node"
)
func main() {
// 添加所有命令
rootCmd := cmd.RootCmd
rootCmd.AddCommand(
cmd.GenValidatorCmd,
cmd.InitFilesCmd,
cmd.ProbeUpnpCmd,
cmd.LiteCmd,
cmd.ReplayCmd,
cmd.ReplayConsoleCmd,
cmd.ResetAllCmd,
cmd.ResetPrivValidatorCmd,
cmd.ShowValidatorCmd,
cmd.TestnetFilesCmd,
cmd.ShowNodeIDCmd,
cmd.GenNodeKeyCmd,
cmd.VersionCmd)
// NOTE:
// Users wishing to:
// * Use an external signer for their validators
// * Supply an in-proc abci app
// * Supply a genesis doc file from another source
// * Provide their own DB implementation
// can copy this file and use something other than the
// DefaultNewNode function
// 设置 NewNode 函数回调
nodeFunc := nm.DefaultNewNode
// Create & start node
rootCmd.AddCommand(cmd.NewRunNodeCmd(nodeFunc))
cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultTendermintDir)))
if err := cmd.Execute(); err != nil {
panic(err)
}
}
这是main.go的代码,里面很简单,设置一些命令,这里用到了一个框架 :https://github.com/spf13/cobra 感兴趣的可以看一下,挺好用的。
我们再看一下创世的命令,init。
package commands
import (
"fmt"
"github.com/spf13/cobra"
cfg "github.com/tendermint/tendermint/config"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
)
// InitFilesCmd initialises a fresh Tendermint Core instance.
var InitFilesCmd = &cobra.Command{
Use: "init",
Short: "Initialize Tendermint",
RunE: initFiles,
}
func initFiles(cmd *cobra.Command, args []string) error {
return initFilesWithConfig(config)
}
func initFilesWithConfig(config *cfg.Config) error {
// private validator
privValKeyFile := config.PrivValidatorKeyFile()
privValStateFile := config.PrivValidatorStateFile()
var pv *privval.FilePV
if cmn.FileExists(privValKeyFile) {
pv = privval.LoadFilePV(privValKeyFile, privValStateFile)
logger.Info("Found private validator", "keyFile", privValKeyFile,
"stateFile", privValStateFile)
} else {
pv = privval.GenFilePV(privValKeyFile, privValStateFile)
pv.Save()
logger.Info("Generated private validator", "keyFile", privValKeyFile,
"stateFile", privValStateFile)
}
nodeKeyFile := config.NodeKeyFile()
if cmn.FileExists(nodeKeyFile) {
logger.Info("Found node key", "path", nodeKeyFile)
} else {
if _, err := p2p.LoadOrGenNodeKey(nodeKeyFile); err != nil {
return err
}
logger.Info("Generated node key", "path", nodeKeyFile)
}
// genesis file
genFile := config.GenesisFile()
if cmn.FileExists(genFile) {
logger.Info("Found genesis file", "path", genFile)
} else {
genDoc := types.GenesisDoc{
ChainID: fmt.Sprintf("test-chain-%v", cmn.RandStr(6)),
GenesisTime: tmtime.Now(),
ConsensusParams: types.DefaultConsensusParams(),
}
key := pv.GetPubKey()
genDoc.Validators = []types.GenesisValidator{{
Address: key.Address(),
PubKey: key,
Power: 10,
}}
if err := genDoc.SaveAs(genFile); err != nil {
return err
}
logger.Info("Generated genesis file", "path", genFile)
}
return nil
}
这里面是对 init 命令的逻辑代码,在23行,我们有一个变量 config,这个就是对 tendermint 的默认配置,这个配置会写到一个文件中,在 linux 下会将此配置文件放在 /etc/tmcore/config/config.yaml。我们可以根据需求修改此配置文件。
我们再看一下默认配置的代码:
这里我就不把所有的代码拿过来了,我们看一下大体上的配置:
创世时最重要的就是创世的 json 数据,tendermint 解析这个数据进行创世,现在我们只用到了 init 命令,此时并不会开始创世,只是在 tendermint 这端保存创世时的信息,现在我们需要记住的就是,init 命令会保存一些创世的基本信息与配置,生成一些文件,后续创世以及正常的交易都会根据这些配置跑。之后我们会用 node 命令启动整个链,node命令会连接到我们的自己写的APP,下一篇文章我们再说 node命令,以及 tendermint 与 我们的 APP 的连接创世等。
留言与评论(共有 0 条评论) |