From 486be46790070e0d3c2db4ae9d38d0aba890cd8b Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 5 Nov 2018 09:22:36 -0500 Subject: [PATCH 01/12] Update testnet to use canonical genesis time --- Gopkg.lock | 3 +- cmd/gaia/init/collect.go | 39 ++++++------ cmd/gaia/init/init.go | 55 ----------------- cmd/gaia/init/testnet.go | 126 ++++++++++++++++++++++++++++++--------- cmd/gaia/init/utils.go | 110 ++++++++++++++++++++++++++++++++++ 5 files changed, 229 insertions(+), 104 deletions(-) create mode 100644 cmd/gaia/init/utils.go diff --git a/Gopkg.lock b/Gopkg.lock index f9be7bd97a9e..5b4ab2469d17 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -165,13 +165,12 @@ version = "v1.2.0" [[projects]] - digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10" + digest = "1:ea40c24cdbacd054a6ae9de03e62c5f252479b96c716375aace5c120d68647c8" name = "github.com/hashicorp/hcl" packages = [ ".", "hcl/ast", "hcl/parser", - "hcl/printer", "hcl/scanner", "hcl/strconv", "hcl/token", diff --git a/cmd/gaia/init/collect.go b/cmd/gaia/init/collect.go index 34b65e560bce..97d9743a06c7 100644 --- a/cmd/gaia/init/collect.go +++ b/cmd/gaia/init/collect.go @@ -2,7 +2,6 @@ package init import ( "encoding/json" - "io/ioutil" "path/filepath" "github.com/cosmos/cosmos-sdk/client" @@ -12,7 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/tendermint/go-amino" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/cli" @@ -35,12 +33,13 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { RunE: func(_ *cobra.Command, _ []string) error { config := ctx.Config config.SetRoot(viper.GetString(cli.HomeFlag)) - name := viper.GetString(client.FlagName) + nodeID, valPubKey, err := InitializeNodeValidatorFiles(config) if err != nil { return err } + genDoc, err := loadGenesisDoc(cdc, config.GenesisFile()) if err != nil { return err @@ -59,12 +58,14 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { NodeID: nodeID, ValPubKey: valPubKey, } + appMessage, err := genAppStateFromConfig(cdc, config, initCfg, genDoc) if err != nil { return err } toPrint.AppMessage = appMessage + // print out some key information return displayInfo(cdc, toPrint) }, @@ -74,23 +75,29 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { return cmd } -func genAppStateFromConfig(cdc *codec.Codec, config *cfg.Config, initCfg initConfig, - genDoc types.GenesisDoc) (appState json.RawMessage, err error) { +func genAppStateFromConfig( + cdc *codec.Codec, config *cfg.Config, initCfg initConfig, genDoc types.GenesisDoc, +) (appState json.RawMessage, err error) { genFile := config.GenesisFile() - // process genesis transactions, else create default genesis.json - var appGenTxs []auth.StdTx - var persistentPeers string - var genTxs []json.RawMessage - var jsonRawTx json.RawMessage + var ( + appGenTxs []auth.StdTx + persistentPeers string + genTxs []json.RawMessage + jsonRawTx json.RawMessage + ) + // process genesis transactions, else create default genesis.json appGenTxs, persistentPeers, err = app.CollectStdTxs( - cdc, config.Moniker, initCfg.GenTxsDir, genDoc) + cdc, config.Moniker, initCfg.GenTxsDir, genDoc, + ) if err != nil { return } + genTxs = make([]json.RawMessage, len(appGenTxs)) config.P2P.PersistentPeers = persistentPeers + for i, stdTx := range appGenTxs { jsonRawTx, err = cdc.MarshalJSON(stdTx) if err != nil { @@ -100,6 +107,7 @@ func genAppStateFromConfig(cdc *codec.Codec, config *cfg.Config, initCfg initCon } cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config) + appState, err = app.GaiaAppGenStateJSON(cdc, genDoc, genTxs) if err != nil { return @@ -108,12 +116,3 @@ func genAppStateFromConfig(cdc *codec.Codec, config *cfg.Config, initCfg initCon err = WriteGenesisFile(genFile, initCfg.ChainID, nil, appState) return } - -func loadGenesisDoc(cdc *amino.Codec, genFile string) (genDoc types.GenesisDoc, err error) { - genContents, err := ioutil.ReadFile(genFile) - if err != nil { - return - } - err = cdc.UnmarshalJSON(genContents, &genDoc) - return -} diff --git a/cmd/gaia/init/init.go b/cmd/gaia/init/init.go index 0290ae4fb2bb..f2a815a5c30a 100644 --- a/cmd/gaia/init/init.go +++ b/cmd/gaia/init/init.go @@ -3,7 +3,6 @@ package init import ( "encoding/json" "fmt" - "github.com/tendermint/tendermint/privval" "os" "path/filepath" @@ -14,11 +13,8 @@ import ( "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/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/types" ) const ( @@ -97,54 +93,3 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob cmd.Flags().String(flagMoniker, "", "set the validator's moniker") return cmd } - -// InitializeNodeValidatorFiles creates private validator and p2p configuration files. -func InitializeNodeValidatorFiles(config *cfg.Config) (nodeID string, valPubKey crypto.PubKey, err error) { - nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) - if err != nil { - return - } - nodeID = string(nodeKey.ID()) - valPubKey = ReadOrCreatePrivValidator(config.PrivValidatorFile()) - return -} - -// WriteGenesisFile creates and writes the genesis configuration to disk. An -// error is returned if building or writing the configuration to file fails. -// nolint: unparam -func WriteGenesisFile(genesisFile, chainID string, validators []types.GenesisValidator, appState json.RawMessage) error { - genDoc := types.GenesisDoc{ - ChainID: chainID, - Validators: validators, - AppState: appState, - } - - if err := genDoc.ValidateAndComplete(); err != nil { - return err - } - - return genDoc.SaveAs(genesisFile) -} - -// read of create the private key file for this config -func ReadOrCreatePrivValidator(privValFile string) crypto.PubKey { - // private validator - var privValidator *privval.FilePV - if common.FileExists(privValFile) { - privValidator = privval.LoadFilePV(privValFile) - } else { - privValidator = privval.GenFilePV(privValFile) - privValidator.Save() - } - return privValidator.GetPubKey() -} - -func initializeEmptyGenesis(cdc *codec.Codec, genFile string, chainID string, - overwrite bool) (appState json.RawMessage, err error) { - if !overwrite && common.FileExists(genFile) { - err = fmt.Errorf("genesis.json file already exists: %v", genFile) - return - } - - return codec.MarshalJSONIndent(cdc, app.NewDefaultGenesisState()) -} diff --git a/cmd/gaia/init/testnet.go b/cmd/gaia/init/testnet.go index 5f729b0a4b7e..6fdc8c21e123 100644 --- a/cmd/gaia/init/testnet.go +++ b/cmd/gaia/init/testnet.go @@ -3,6 +3,10 @@ package init import ( "encoding/json" "fmt" + "net" + "os" + "path/filepath" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/codec" @@ -10,10 +14,6 @@ import ( "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/tendermint/tendermint/types" - "net" - "os" - "path/filepath" "github.com/cosmos/cosmos-sdk/server" "github.com/spf13/cobra" @@ -21,6 +21,8 @@ import ( cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" cmn "github.com/tendermint/tendermint/libs/common" + "github.com/tendermint/tendermint/types" + tmtime "github.com/tendermint/tendermint/types/time" ) var ( @@ -48,43 +50,51 @@ necessary files (private validator, genesis, config, etc.). Note, strict routability for addresses is turned off in the config file. Example: - - gaiad testnet --v 4 --o ./output --starting-ip-address 192.168.10.2 + gaiad testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2 `, RunE: func(_ *cobra.Command, _ []string) error { config := ctx.Config - return testnetWithConfig(config, cdc) + return initTestnet(config, cdc) }, } + cmd.Flags().Int(nValidators, 4, - "Number of validators to initialize the testnet with") + "Number of validators to initialize the testnet with", + ) cmd.Flags().StringP(outputDir, "o", "./mytestnet", - "Directory to store initialization data for the testnet") + "Directory to store initialization data for the testnet", + ) cmd.Flags().String(nodeDirPrefix, "node", - "Prefix the directory name for each node with (node results in node0, node1, ...)") + "Prefix the directory name for each node with (node results in node0, node1, ...)", + ) cmd.Flags().String(nodeDaemonHome, "gaiad", - "Home directory of the node's daemon configuration") + "Home directory of the node's daemon configuration", + ) cmd.Flags().String(nodeCliHome, "gaiacli", - "Home directory of the node's cli configuration") - + "Home directory of the node's cli configuration", + ) cmd.Flags().String(startingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)") + return cmd } -func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error { +func initTestnet(config *cfg.Config, cdc *codec.Codec) error { outDir := viper.GetString(outputDir) numValidators := viper.GetInt(nValidators) - // Generate genesis.json and config.toml chainID := "chain-" + cmn.RandStr(6) + monikers := make([]string, numValidators) nodeIDs := make([]string, numValidators) valPubKeys := make([]crypto.PubKey, numValidators) - // Generate private key, node ID, initial transaction - var accs []app.GenesisAccount - var genFiles []string + var ( + accs []app.GenesisAccount + genFiles []string + ) + + // generate private keys, node IDs, and initial transactions for i := 0; i < numValidators; i++ { nodeDirName := fmt.Sprintf("%s%d", viper.GetString(nodeDirPrefix), i) nodeDaemonHomeName := viper.GetString(nodeDaemonHome) @@ -92,6 +102,7 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error { nodeDir := filepath.Join(outDir, nodeDirName, nodeDaemonHomeName) clientDir := filepath.Join(outDir, nodeDirName, nodeCliHomeName) gentxsDir := filepath.Join(outDir, "gentxs") + config.SetRoot(nodeDir) err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm) @@ -108,24 +119,27 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error { monikers = append(monikers, nodeDirName) config.Moniker = nodeDirName + ip, err := getIP(i) if err != nil { _ = os.RemoveAll(outDir) return err } + nodeIDs[i], valPubKeys[i], err = InitializeNodeValidatorFiles(config) if err != nil { _ = os.RemoveAll(outDir) return err } - memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip) - // write genesis + memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip) genFiles = append(genFiles, config.GenesisFile()) buf := client.BufferStdin() prompt := fmt.Sprintf( - "Password for account '%s' (default %s):", nodeDirName, app.DefaultKeyPass) + "Password for account '%s' (default %s):", nodeDirName, app.DefaultKeyPass, + ) + keyPass, err := client.GetPassword(prompt, buf) if err != nil && keyPass != "" { // An error was returned that either failed to read the password from @@ -133,6 +147,7 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error { // length requirements. return err } + if keyPass == "" { keyPass = app.DefaultKeyPass } @@ -142,11 +157,14 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error { _ = os.RemoveAll(outDir) return err } + info := map[string]string{"secret": secret} + cliPrint, err := json.Marshal(info) if err != nil { return err } + // save private key seed words err = writeFile(fmt.Sprintf("%v.json", "key_seed"), clientDir, cliPrint) if err != nil { @@ -170,6 +188,7 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error { ) tx := auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, []auth.StdSignature{}, memo) txBldr := authtx.NewTxBuilderFromCLI().WithChainID(chainID).WithMemo(memo) + signedTx, err := txBldr.SignStdTx(nodeDirName, app.DefaultKeyPass, tx, false) if err != nil { _ = os.RemoveAll(outDir) @@ -182,7 +201,7 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error { return err } - // Gather gentxs folder + // gather gentxs folder err = writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBytes) if err != nil { _ = os.RemoveAll(outDir) @@ -190,26 +209,58 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error { } } - // Generate empty genesis.json + if err := initGenFiles(cdc, chainID, accs, genFiles); err != nil { + return err + } + + if err := collectGenFiles(cdc, config, chainID, monikers, nodeIDs, valPubKeys); err != nil { + return err + } + + fmt.Printf("Successfully initialized %v node directories\n", viper.GetInt(nValidators)) + return nil +} + +func initGenFiles( + cdc *codec.Codec, chainID string, accs []app.GenesisAccount, genFiles []string, +) error { + + numValidators := viper.GetInt(nValidators) appGenState := app.NewDefaultGenesisState() appGenState.Accounts = accs + appGenStateJSON, err := codec.MarshalJSONIndent(cdc, appGenState) if err != nil { return err } + genDoc := types.GenesisDoc{ ChainID: chainID, AppState: appGenStateJSON, Validators: nil, } - // Save all genesis.json files + // generate empty genesis files for each validator and save for i := 0; i < numValidators; i++ { if err := genDoc.SaveAs(genFiles[i]); err != nil { return err } } + return nil +} + +func collectGenFiles( + cdc *codec.Codec, config *cfg.Config, chainID string, + monikers, nodeIDs []string, valPubKeys []crypto.PubKey, +) error { + + outDir := viper.GetString(outputDir) + numValidators := viper.GetInt(nValidators) + + var appState json.RawMessage + genTime := tmtime.Now() + for i := 0; i < numValidators; i++ { nodeDirName := fmt.Sprintf("%s%d", viper.GetString(nodeDirPrefix), i) nodeDaemonHomeName := viper.GetString(nodeDaemonHome) @@ -217,10 +268,10 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error { gentxsDir := filepath.Join(outDir, "gentxs") moniker := monikers[i] config.Moniker = nodeDirName + config.SetRoot(nodeDir) nodeID, valPubKey := nodeIDs[i], valPubKeys[i] - // Run `init` and generate genesis.json and config.toml initCfg := initConfig{ ChainID: chainID, GenTxsDir: gentxsDir, @@ -228,21 +279,37 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error { NodeID: nodeID, ValPubKey: valPubKey, } + genDoc, err := loadGenesisDoc(cdc, config.GenesisFile()) if err != nil { return err } - if _, err := genAppStateFromConfig(cdc, config, initCfg, genDoc); err != nil { + + nodeAppState, err := genAppStateFromConfig(cdc, config, initCfg, genDoc) + if err != nil { + return err + } + + if appState == nil { + // set the canonical application state (they should not differ) + appState = nodeAppState + } + + genFile := config.GenesisFile() + + // overwrite each validator's genesis file to have a canonical genesis time + err = WriteGenesisFileWithTime(genFile, chainID, nil, appState, genTime) + if err != nil { return err } } - fmt.Printf("Successfully initialized %v node directories\n", viper.GetInt(nValidators)) return nil } func getIP(i int) (ip string, err error) { ip = viper.GetString(startingIPAddress) + if len(ip) == 0 { ip, err = server.ExternalIP() if err != nil { @@ -254,20 +321,24 @@ func getIP(i int) (ip string, err error) { return "", err } } + return ip, nil } func writeFile(name string, dir string, contents []byte) error { writePath := filepath.Join(dir) file := filepath.Join(writePath, name) + err := cmn.EnsureDir(writePath, 0700) if err != nil { return err } + err = cmn.WriteFile(file, contents, 0600) if err != nil { return err } + return nil } @@ -280,5 +351,6 @@ func calculateIP(ip string, i int) (string, error) { for j := 0; j < i; j++ { ipv4[3]++ } + return ipv4.String(), nil } diff --git a/cmd/gaia/init/utils.go b/cmd/gaia/init/utils.go new file mode 100644 index 000000000000..cbfac9ca2127 --- /dev/null +++ b/cmd/gaia/init/utils.go @@ -0,0 +1,110 @@ +package init + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "time" + + "github.com/cosmos/cosmos-sdk/cmd/gaia/app" + "github.com/cosmos/cosmos-sdk/codec" + amino "github.com/tendermint/go-amino" + cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/common" + "github.com/tendermint/tendermint/p2p" + "github.com/tendermint/tendermint/privval" + "github.com/tendermint/tendermint/types" +) + +// WriteGenesisFile creates and writes the genesis configuration to disk. An +// error is returned if building or writing the configuration to file fails. +func WriteGenesisFile( + genFile, chainID string, validators []types.GenesisValidator, appState json.RawMessage, +) error { + + genDoc := types.GenesisDoc{ + ChainID: chainID, + Validators: validators, + AppState: appState, + } + + if err := genDoc.ValidateAndComplete(); err != nil { + return err + } + + return genDoc.SaveAs(genFile) +} + +// WriteGenesisFileWithTime creates and writes the genesis configuration to disk. +// An error is returned if building or writing the configuration to file fails. +func WriteGenesisFileWithTime( + genFile, chainID string, validators []types.GenesisValidator, + appState json.RawMessage, genTime time.Time, +) error { + + genDoc := types.GenesisDoc{ + GenesisTime: genTime, + ChainID: chainID, + Validators: validators, + AppState: appState, + } + + if err := genDoc.ValidateAndComplete(); err != nil { + return err + } + + return genDoc.SaveAs(genFile) +} + +// read of create the private key file for this config +func ReadOrCreatePrivValidator(privValFile string) crypto.PubKey { + var privValidator *privval.FilePV + + if common.FileExists(privValFile) { + privValidator = privval.LoadFilePV(privValFile) + } else { + privValidator = privval.GenFilePV(privValFile) + privValidator.Save() + } + + return privValidator.GetPubKey() +} + +// InitializeNodeValidatorFiles creates private validator and p2p configuration files. +func InitializeNodeValidatorFiles( + config *cfg.Config) (nodeID string, valPubKey crypto.PubKey, err error, +) { + + nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) + if err != nil { + return + } + + nodeID = string(nodeKey.ID()) + valPubKey = ReadOrCreatePrivValidator(config.PrivValidatorFile()) + + return +} + +func loadGenesisDoc(cdc *amino.Codec, genFile string) (genDoc types.GenesisDoc, err error) { + genContents, err := ioutil.ReadFile(genFile) + if err != nil { + return + } + + err = cdc.UnmarshalJSON(genContents, &genDoc) + return +} + +func initializeEmptyGenesis( + cdc *codec.Codec, genFile string, chainID string, overwrite bool, +) (appState json.RawMessage, err error) { + + if !overwrite && common.FileExists(genFile) { + err = fmt.Errorf("genesis.json file already exists: %v", genFile) + return + } + + return codec.MarshalJSONIndent(cdc, app.NewDefaultGenesisState()) +} From 3379790b2f5cd4a94efd188a578f94bcc74fc54d Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 5 Nov 2018 09:28:04 -0500 Subject: [PATCH 02/12] Fix linting in genesis test --- cmd/gaia/app/genesis_test.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cmd/gaia/app/genesis_test.go b/cmd/gaia/app/genesis_test.go index 6c331856c345..579ad93a85d8 100644 --- a/cmd/gaia/app/genesis_test.go +++ b/cmd/gaia/app/genesis_test.go @@ -2,9 +2,10 @@ package app import ( "encoding/json" + "testing" + "github.com/tendermint/tendermint/crypto/secp256k1" tmtypes "github.com/tendermint/tendermint/types" - "testing" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" @@ -91,8 +92,10 @@ func TestGaiaAppGenState(t *testing.T) { func makeMsg(name string, pk crypto.PubKey) auth.StdTx { desc := stake.NewDescription(name, "", "", "") comm := stakeTypes.CommissionMsg{} - msg := stake.NewMsgCreateValidator(sdk.ValAddress(pk.Address()), pk, sdk.NewInt64Coin(bondDenom, - 50), desc, comm) + msg := stake.NewMsgCreateValidator( + sdk.ValAddress(pk.Address()), pk, + sdk.NewInt64Coin(bondDenom, 50), desc, comm, + ) return auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, nil, "") } From b8334c1d3521402cf66f4d102cdc564a4f4abd88 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 5 Nov 2018 09:29:05 -0500 Subject: [PATCH 03/12] Update dep lock --- Gopkg.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Gopkg.lock b/Gopkg.lock index 5b4ab2469d17..fafe6460658f 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -688,6 +688,7 @@ "github.com/tendermint/tendermint/rpc/lib/client", "github.com/tendermint/tendermint/rpc/lib/server", "github.com/tendermint/tendermint/types", + "github.com/tendermint/tendermint/types/time", "github.com/tendermint/tendermint/version", "github.com/zondax/ledger-goclient", "golang.org/x/crypto/bcrypt", From 2b297c4dc78004b203a17ec33ea03691f878f167 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 5 Nov 2018 09:30:13 -0500 Subject: [PATCH 04/12] Add pending log entry --- PENDING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PENDING.md b/PENDING.md index 11c13ea75f00..1fa2958e6352 100644 --- a/PENDING.md +++ b/PENDING.md @@ -62,7 +62,8 @@ BUG FIXES * Gaia CLI (`gaiacli`) * Gaia - - \#2670 [x/stake] fixed incorrent `IterateBondedValidators` and split into two functions: `IterateBondedValidators` and `IterateLastBlockConsValidators` + - \#2670 [x/stake] fixed incorrect `IterateBondedValidators` and split into two functions: `IterateBondedValidators` and `IterateLastBlockConsValidators` + - \#2691 Fix local testnet creation by using a single canonical genesis time * SDK - \#2625 [x/gov] fix AppendTag function usage error From 74c7dacd81e9582c769904476d5194bc3ac0d077 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 5 Nov 2018 10:28:12 -0500 Subject: [PATCH 05/12] Reduce usage of viper --- cmd/gaia/init/testnet.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/cmd/gaia/init/testnet.go b/cmd/gaia/init/testnet.go index 6fdc8c21e123..e446c4e14f2d 100644 --- a/cmd/gaia/init/testnet.go +++ b/cmd/gaia/init/testnet.go @@ -209,23 +209,26 @@ func initTestnet(config *cfg.Config, cdc *codec.Codec) error { } } - if err := initGenFiles(cdc, chainID, accs, genFiles); err != nil { + if err := initGenFiles(cdc, chainID, accs, genFiles, numValidators); err != nil { return err } - if err := collectGenFiles(cdc, config, chainID, monikers, nodeIDs, valPubKeys); err != nil { + err := collectGenFiles( + cdc, config, chainID, monikers, nodeIDs, valPubKeys, numValidators, outputDir, + ) + if err != nil { return err } - fmt.Printf("Successfully initialized %v node directories\n", viper.GetInt(nValidators)) + fmt.Printf("Successfully initialized %d node directories\n", numValidators) return nil } func initGenFiles( - cdc *codec.Codec, chainID string, accs []app.GenesisAccount, genFiles []string, + cdc *codec.Codec, chainID string, accs []app.GenesisAccount, + genFiles []string, numValidators int, ) error { - numValidators := viper.GetInt(nValidators) appGenState := app.NewDefaultGenesisState() appGenState.Accounts = accs @@ -253,19 +256,17 @@ func initGenFiles( func collectGenFiles( cdc *codec.Codec, config *cfg.Config, chainID string, monikers, nodeIDs []string, valPubKeys []crypto.PubKey, + numValidators int, outputDir string, ) error { - outDir := viper.GetString(outputDir) - numValidators := viper.GetInt(nValidators) - var appState json.RawMessage genTime := tmtime.Now() for i := 0; i < numValidators; i++ { nodeDirName := fmt.Sprintf("%s%d", viper.GetString(nodeDirPrefix), i) nodeDaemonHomeName := viper.GetString(nodeDaemonHome) - nodeDir := filepath.Join(outDir, nodeDirName, nodeDaemonHomeName) - gentxsDir := filepath.Join(outDir, "gentxs") + nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHomeName) + gentxsDir := filepath.Join(outputDir, "gentxs") moniker := monikers[i] config.Moniker = nodeDirName From 144907c48bf8ac09883475f216e3106cb283ecb4 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Mon, 5 Nov 2018 11:11:30 -0500 Subject: [PATCH 06/12] Revert viper changes and cleanup flag vars --- cmd/gaia/init/testnet.go | 60 +++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/cmd/gaia/init/testnet.go b/cmd/gaia/init/testnet.go index e446c4e14f2d..9105f1a7d535 100644 --- a/cmd/gaia/init/testnet.go +++ b/cmd/gaia/init/testnet.go @@ -26,13 +26,12 @@ import ( ) var ( - nodeDirPrefix = "node-dir-prefix" - nValidators = "v" - outputDir = "output-dir" - nodeDaemonHome = "node-daemon-home" - nodeCliHome = "node-cli-home" - - startingIPAddress = "starting-ip-address" + flagNodeDirPrefix = "node-dir-prefix" + flagNumValidators = "v" + flagOutputDir = "output-dir" + flagNodeDaemonHome = "node-daemon-home" + flagNodeCliHome = "node-cli-home" + flagStartingIPAddress = "starting-ip-address" ) const nodeDirPerm = 0755 @@ -58,30 +57,30 @@ Example: }, } - cmd.Flags().Int(nValidators, 4, + cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with", ) - cmd.Flags().StringP(outputDir, "o", "./mytestnet", + cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet", "Directory to store initialization data for the testnet", ) - cmd.Flags().String(nodeDirPrefix, "node", + cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)", ) - cmd.Flags().String(nodeDaemonHome, "gaiad", + cmd.Flags().String(flagNodeDaemonHome, "gaiad", "Home directory of the node's daemon configuration", ) - cmd.Flags().String(nodeCliHome, "gaiacli", + cmd.Flags().String(flagNodeCliHome, "gaiacli", "Home directory of the node's cli configuration", ) - cmd.Flags().String(startingIPAddress, "192.168.0.1", + cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)") return cmd } func initTestnet(config *cfg.Config, cdc *codec.Codec) error { - outDir := viper.GetString(outputDir) - numValidators := viper.GetInt(nValidators) + outDir := viper.GetString(flagOutputDir) + numValidators := viper.GetInt(flagNumValidators) chainID := "chain-" + cmn.RandStr(6) @@ -96,9 +95,9 @@ func initTestnet(config *cfg.Config, cdc *codec.Codec) error { // generate private keys, node IDs, and initial transactions for i := 0; i < numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", viper.GetString(nodeDirPrefix), i) - nodeDaemonHomeName := viper.GetString(nodeDaemonHome) - nodeCliHomeName := viper.GetString(nodeCliHome) + nodeDirName := fmt.Sprintf("%s%d", viper.GetString(flagNodeDirPrefix), i) + nodeDaemonHomeName := viper.GetString(flagNodeDaemonHome) + nodeCliHomeName := viper.GetString(flagNodeCliHome) nodeDir := filepath.Join(outDir, nodeDirName, nodeDaemonHomeName) clientDir := filepath.Join(outDir, nodeDirName, nodeCliHomeName) gentxsDir := filepath.Join(outDir, "gentxs") @@ -209,14 +208,11 @@ func initTestnet(config *cfg.Config, cdc *codec.Codec) error { } } - if err := initGenFiles(cdc, chainID, accs, genFiles, numValidators); err != nil { + if err := initGenFiles(cdc, chainID, accs, genFiles); err != nil { return err } - err := collectGenFiles( - cdc, config, chainID, monikers, nodeIDs, valPubKeys, numValidators, outputDir, - ) - if err != nil { + if err := collectGenFiles(cdc, config, chainID, monikers, nodeIDs, valPubKeys); err != nil { return err } @@ -225,10 +221,10 @@ func initTestnet(config *cfg.Config, cdc *codec.Codec) error { } func initGenFiles( - cdc *codec.Codec, chainID string, accs []app.GenesisAccount, - genFiles []string, numValidators int, + cdc *codec.Codec, chainID string, accs []app.GenesisAccount, genFiles []string, ) error { + numValidators := viper.GetInt(flagNumValidators) appGenState := app.NewDefaultGenesisState() appGenState.Accounts = accs @@ -256,17 +252,19 @@ func initGenFiles( func collectGenFiles( cdc *codec.Codec, config *cfg.Config, chainID string, monikers, nodeIDs []string, valPubKeys []crypto.PubKey, - numValidators int, outputDir string, ) error { + outDir := viper.GetString(flagOutputDir) + numValidators := viper.GetInt(flagNumValidators) + var appState json.RawMessage genTime := tmtime.Now() for i := 0; i < numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", viper.GetString(nodeDirPrefix), i) - nodeDaemonHomeName := viper.GetString(nodeDaemonHome) - nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHomeName) - gentxsDir := filepath.Join(outputDir, "gentxs") + nodeDirName := fmt.Sprintf("%s%d", viper.GetString(flagNodeDirPrefix), i) + nodeDaemonHomeName := viper.GetString(flagNodeDaemonHome) + nodeDir := filepath.Join(outDir, nodeDirName, nodeDaemonHomeName) + gentxsDir := filepath.Join(outDir, "gentxs") moniker := monikers[i] config.Moniker = nodeDirName @@ -309,7 +307,7 @@ func collectGenFiles( } func getIP(i int) (ip string, err error) { - ip = viper.GetString(startingIPAddress) + ip = viper.GetString(flagStartingIPAddress) if len(ip) == 0 { ip, err = server.ExternalIP() From 74997823cbb26e3e914a641aeb1827d8a52c2924 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 6 Nov 2018 09:44:04 -0500 Subject: [PATCH 07/12] Cleanup return values --- cmd/gaia/init/utils.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/cmd/gaia/init/utils.go b/cmd/gaia/init/utils.go index cbfac9ca2127..1738433705e7 100644 --- a/cmd/gaia/init/utils.go +++ b/cmd/gaia/init/utils.go @@ -78,32 +78,34 @@ func InitializeNodeValidatorFiles( nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile()) if err != nil { - return + return nodeID, valPubKey, err } nodeID = string(nodeKey.ID()) valPubKey = ReadOrCreatePrivValidator(config.PrivValidatorFile()) - return + return nodeID, valPubKey, nil } func loadGenesisDoc(cdc *amino.Codec, genFile string) (genDoc types.GenesisDoc, err error) { genContents, err := ioutil.ReadFile(genFile) if err != nil { - return + return genDoc, err } - err = cdc.UnmarshalJSON(genContents, &genDoc) - return + if err := cdc.UnmarshalJSON(genContents, &genDoc); err != nil { + return genDoc, err + } + + return genDoc, err } func initializeEmptyGenesis( - cdc *codec.Codec, genFile string, chainID string, overwrite bool, + cdc *codec.Codec, genFile, chainID string, overwrite bool, ) (appState json.RawMessage, err error) { if !overwrite && common.FileExists(genFile) { - err = fmt.Errorf("genesis.json file already exists: %v", genFile) - return + return nil, fmt.Errorf("genesis.json file already exists: %v", genFile) } return codec.MarshalJSONIndent(cdc, app.NewDefaultGenesisState()) From 9d4872264c5ed101c93bc2aa18578f5d92f68daf Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 6 Nov 2018 10:02:24 -0500 Subject: [PATCH 08/12] Address PR comments on viper usage --- cmd/gaia/init/testnet.go | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/cmd/gaia/init/testnet.go b/cmd/gaia/init/testnet.go index 9105f1a7d535..42d8332d27fb 100644 --- a/cmd/gaia/init/testnet.go +++ b/cmd/gaia/init/testnet.go @@ -119,7 +119,7 @@ func initTestnet(config *cfg.Config, cdc *codec.Codec) error { monikers = append(monikers, nodeDirName) config.Moniker = nodeDirName - ip, err := getIP(i) + ip, err := getIP(i, viper.GetString(flagStartingIPAddress)) if err != nil { _ = os.RemoveAll(outDir) return err @@ -208,11 +208,15 @@ func initTestnet(config *cfg.Config, cdc *codec.Codec) error { } } - if err := initGenFiles(cdc, chainID, accs, genFiles); err != nil { + if err := initGenFiles(cdc, chainID, accs, genFiles, numValidators); err != nil { return err } - if err := collectGenFiles(cdc, config, chainID, monikers, nodeIDs, valPubKeys); err != nil { + err := collectGenFiles( + cdc, config, chainID, monikers, nodeIDs, valPubKeys, numValidators, + outDir, viper.GetString(flagNodeDirPrefix), viper.GetString(flagNodeDaemonHome), + ) + if err != nil { return err } @@ -221,10 +225,10 @@ func initTestnet(config *cfg.Config, cdc *codec.Codec) error { } func initGenFiles( - cdc *codec.Codec, chainID string, accs []app.GenesisAccount, genFiles []string, + cdc *codec.Codec, chainID string, accs []app.GenesisAccount, + genFiles []string, numValidators int, ) error { - numValidators := viper.GetInt(flagNumValidators) appGenState := app.NewDefaultGenesisState() appGenState.Accounts = accs @@ -252,17 +256,14 @@ func initGenFiles( func collectGenFiles( cdc *codec.Codec, config *cfg.Config, chainID string, monikers, nodeIDs []string, valPubKeys []crypto.PubKey, + numValidators int, outDir, nodeDirPrefix, nodeDaemonHomeName string, ) error { - outDir := viper.GetString(flagOutputDir) - numValidators := viper.GetInt(flagNumValidators) - var appState json.RawMessage genTime := tmtime.Now() for i := 0; i < numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", viper.GetString(flagNodeDirPrefix), i) - nodeDaemonHomeName := viper.GetString(flagNodeDaemonHome) + nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) nodeDir := filepath.Join(outDir, nodeDirName, nodeDaemonHomeName) gentxsDir := filepath.Join(outDir, "gentxs") moniker := monikers[i] @@ -306,16 +307,19 @@ func collectGenFiles( return nil } -func getIP(i int) (ip string, err error) { - ip = viper.GetString(flagStartingIPAddress) +func getIP(i int, startingIPAddr string) (string, error) { + var ( + ip string + err error + ) - if len(ip) == 0 { + if len(startingIPAddr) == 0 { ip, err = server.ExternalIP() if err != nil { return "", err } } else { - ip, err = calculateIP(ip, i) + ip, err = calculateIP(startingIPAddr, i) if err != nil { return "", err } From 06c9d2f800701877c525be873a006b126782c7c4 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 6 Nov 2018 16:09:03 -0500 Subject: [PATCH 09/12] Attempt CI broken depedencies fix --- Gopkg.lock | 1 + Gopkg.toml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Gopkg.lock b/Gopkg.lock index fafe6460658f..65f93e50d732 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -501,6 +501,7 @@ ] pruneopts = "UT" revision = "ebee4377b15f2958b08994485375dd2ee8a649ac" + source = "https://github.com/tendermint/tendermint" [[projects]] digest = "1:7886f86064faff6f8d08a3eb0e8c773648ff5a2e27730831e2bfbf07467f6666" diff --git a/Gopkg.toml b/Gopkg.toml index a66574ea62f8..5f21cd098fee 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -36,7 +36,8 @@ [[override]] name = "github.com/tendermint/tendermint" - revision = "ebee4377b15f2958b08994485375dd2ee8a649ac" # TODO replace w/ 0.26.1 + revision = "ebee4377b15f2958b08994485375dd2ee8a649ac" # TODO: replace w/ tagged v0.26.1 + source = "https://github.com/tendermint/tendermint" # TODO: Remove once CI 'setup_dependencies' is fixed ## deps without releases: From b95a42f902e3bc7e21dcd09cee8ab05a76df7bc8 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 6 Nov 2018 16:17:56 -0500 Subject: [PATCH 10/12] Attempt CI broken depedencies fix...again --- Gopkg.lock | 4 ++-- Gopkg.toml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 65f93e50d732..b77c9130d38e 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -165,12 +165,13 @@ version = "v1.2.0" [[projects]] - digest = "1:ea40c24cdbacd054a6ae9de03e62c5f252479b96c716375aace5c120d68647c8" + digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10" name = "github.com/hashicorp/hcl" packages = [ ".", "hcl/ast", "hcl/parser", + "hcl/printer", "hcl/scanner", "hcl/strconv", "hcl/token", @@ -501,7 +502,6 @@ ] pruneopts = "UT" revision = "ebee4377b15f2958b08994485375dd2ee8a649ac" - source = "https://github.com/tendermint/tendermint" [[projects]] digest = "1:7886f86064faff6f8d08a3eb0e8c773648ff5a2e27730831e2bfbf07467f6666" diff --git a/Gopkg.toml b/Gopkg.toml index 5f21cd098fee..645ba13d6547 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -37,7 +37,6 @@ [[override]] name = "github.com/tendermint/tendermint" revision = "ebee4377b15f2958b08994485375dd2ee8a649ac" # TODO: replace w/ tagged v0.26.1 - source = "https://github.com/tendermint/tendermint" # TODO: Remove once CI 'setup_dependencies' is fixed ## deps without releases: From de046499abbe01ed49a8ac22ed125b88fde14505 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 6 Nov 2018 16:40:39 -0800 Subject: [PATCH 11/12] Fix TM dep --- Gopkg.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gopkg.toml b/Gopkg.toml index 645ba13d6547..797a7f1d257b 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -36,7 +36,7 @@ [[override]] name = "github.com/tendermint/tendermint" - revision = "ebee4377b15f2958b08994485375dd2ee8a649ac" # TODO: replace w/ tagged v0.26.1 + version = "v0.26.1" # TODO: replace w/ tagged v0.26.1 ## deps without releases: From 816bff86d2c82bd2119fccfb852cd2664a3396dc Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 6 Nov 2018 16:51:04 -0800 Subject: [PATCH 12/12] Update lockfile --- Gopkg.lock | 5 +++-- Gopkg.toml | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index b77c9130d38e..b25bae46137c 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -435,7 +435,7 @@ version = "v0.11.1" [[projects]] - digest = "1:92d7d1678577fd1a6f3348168cef87880bbc710ef5f4e9a1216f45c56567d734" + digest = "1:395820b381043b9d2204e181ddf0f9147397c4a7b8f5dc3162de4cfcddf4589a" name = "github.com/tendermint/tendermint" packages = [ "abci/client", @@ -501,7 +501,8 @@ "version", ] pruneopts = "UT" - revision = "ebee4377b15f2958b08994485375dd2ee8a649ac" + revision = "03e42d2e3866f01a00625f608e3bbfaeb30690de" + version = "v0.26.1-rc0" [[projects]] digest = "1:7886f86064faff6f8d08a3eb0e8c773648ff5a2e27730831e2bfbf07467f6666" diff --git a/Gopkg.toml b/Gopkg.toml index 797a7f1d257b..c7cd81ccc1dc 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -36,7 +36,7 @@ [[override]] name = "github.com/tendermint/tendermint" - version = "v0.26.1" # TODO: replace w/ tagged v0.26.1 + version = "v0.26.1-rc0" # TODO: replace w/ tagged v0.26.1 ## deps without releases: @@ -84,4 +84,3 @@ [prune] go-tests = true unused-packages = true -