-
Notifications
You must be signed in to change notification settings - Fork 40
/
init.go
163 lines (145 loc) · 5.49 KB
/
init.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
Why we overwrite the Init/Testnet functions in cosmos-sdk:
1. Cosmos moved init/testnet cmds to the gaia packages which we never and should not imports.
2. Cosmos has a different init/testnet workflow from ours. Also, the init cmd has some bugs.
3. After overwrite, the code is cleaner and easier to maintain.
*/
package init
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authtx "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/spf13/cobra"
"github.com/spf13/viper"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/libs/common"
"github.com/bnb-chain/node/app"
"github.com/bnb-chain/node/common/types"
"github.com/bnb-chain/node/common/utils"
"github.com/bnb-chain/node/wire"
)
const (
flagOverwrite = "overwrite"
flagClientHome = "home-client"
//nolint:deadcode,varcheck
flagOverwriteKey = "overwrite-key"
flagMoniker = "moniker"
flagAccPrefix = "acc-prefix"
)
type printInfo struct {
Moniker string `json:"moniker"`
ChainID string `json:"chain_id"`
NodeID string `json:"node_id"`
PubKey string `json:"pub_key"`
AppMessage json.RawMessage `json:"app_message"`
}
// nolint: errcheck
func displayInfo(cdc *codec.Codec, info printInfo) error {
out, err := codec.MarshalJSONIndent(cdc, info)
if err != nil {
return err
}
fmt.Fprintf(os.Stdout, "%s\n", string(out))
return nil
}
// get cmd to initialize all files for tendermint and application
// nolint
func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cobra.Command {
cmd := &cobra.Command{
Use: "init",
Short: "Initialize private validator, p2p, genesis, and application configuration files",
Long: `Initialize validators's and node's configuration files.
Note that only node's configuration files will be written if the flag --skip-genesis is
enabled, and the genesis file will not be generated.
`,
Args: cobra.NoArgs,
RunE: func(_ *cobra.Command, _ []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(cli.HomeFlag))
chainID := viper.GetString(client.FlagChainID)
if chainID == "" {
chainID = fmt.Sprintf("test-chain-%v", common.RandStr(6))
}
nodeID, pubKey := InitializeNodeValidatorFiles(config)
config.Moniker = viper.GetString(flagMoniker)
if config.Moniker == "" {
config.Moniker = viper.GetString(client.FlagName)
}
if config.Moniker == "" {
return errors.New("must specify --name (validator moniker)")
}
valOperAddr, secret := CreateValOperAccount(viper.GetString(flagClientHome), config.Moniker)
memo := fmt.Sprintf("%s@%s:26656", nodeID, "127.0.0.1")
genTx := PrepareCreateValidatorTx(cdc, chainID, config.Moniker, memo, valOperAddr, pubKey)
appState, err := appInit.AppGenState(cdc, []json.RawMessage{genTx})
if err != nil {
return err
}
genFile := config.GenesisFile()
if !viper.GetBool(flagOverwrite) && common.FileExists(genFile) {
return fmt.Errorf("genesis.json file already exists: %v", genFile)
}
ExportGenesisFileWithTime(genFile, chainID, nil, appState, utils.Now())
WriteConfigFile(config)
bech32ifyPubKey, err := sdk.Bech32ifyConsPub(pubKey)
if err != nil {
return err
}
toPrint := printInfo{
ChainID: chainID,
Moniker: config.Moniker,
NodeID: nodeID,
PubKey: bech32ifyPubKey,
AppMessage: makeAppMessage(cdc, secret),
}
return displayInfo(cdc, toPrint)
},
}
cmd.Flags().StringVar(&app.DefaultKeyPass, "kpass", "12345678", "defaultKeyPass for client keystore")
cmd.Flags().StringP(flagClientHome, "c", app.DefaultCLIHome, "client's home directory")
cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the genesis.json file")
cmd.Flags().String(client.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(flagMoniker, "", "overrides --name flag and set the validator's moniker to a different value; ignored if it runs without the --with-txs flag")
cmd.Flags().StringVar(&app.ServerContext.Bech32PrefixAccAddr, flagAccPrefix, "bnb", "bech32 prefix for AccAddress")
app.ServerContext.BindPFlag("addr.bech32PrefixAccAddr", cmd.Flags().Lookup(flagAccPrefix))
cmd.MarkFlagRequired(flagMoniker)
return cmd
}
func PrepareCreateValidatorTx(cdc *codec.Codec, chainId, name, memo string,
valOperAddr sdk.ValAddress, valPubKey crypto.PubKey) json.RawMessage {
msg := stake.MsgCreateValidatorProposal{
MsgCreateValidator: stake.NewMsgCreateValidator(
valOperAddr,
valPubKey,
sdk.NewCoin(types.NativeTokenSymbol, 90000e8),
stake.NewDescription(name, "", "", ""),
stake.NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
),
}
tx := auth.NewStdTx([]sdk.Msg{msg}, []auth.StdSignature{}, memo, auth.DefaultSource, nil)
txBldr := authtx.NewTxBuilderFromCLI().WithChainID(chainId).WithMemo(memo)
signedTx, err := txBldr.SignStdTx(name, app.DefaultKeyPass, tx, false)
if err != nil {
panic(err)
}
txBytes, err := wire.MarshalJSONIndent(cdc, signedTx)
if err != nil {
panic(err)
}
return txBytes
}
func WriteConfigFile(config *cfg.Config) {
configFilePath := filepath.Join(config.RootDir, "config", "config.toml")
cfg.WriteConfigFile(configFilePath, config)
}