mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +00:00
remove old init package
This commit is contained in:
parent
cfbd4e92aa
commit
566c0258a6
145
init/collect.go
145
init/collect.go
@ -1,145 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
// DONTCOVER
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"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/types"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
|
||||||
"github.com/kava-labs/kava/app"
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
flagGenTxDir = "gentx-dir"
|
|
||||||
)
|
|
||||||
|
|
||||||
type initConfig struct {
|
|
||||||
ChainID string
|
|
||||||
GenTxsDir string
|
|
||||||
Name string
|
|
||||||
NodeID string
|
|
||||||
ValPubKey crypto.PubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint
|
|
||||||
func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
|
||||||
cmd := &cobra.Command{
|
|
||||||
Use: "collect-gentxs",
|
|
||||||
Short: "Collect genesis txs and output a genesis.json file",
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
genTxsDir := viper.GetString(flagGenTxDir)
|
|
||||||
if genTxsDir == "" {
|
|
||||||
genTxsDir = filepath.Join(config.RootDir, "config", "gentx")
|
|
||||||
}
|
|
||||||
|
|
||||||
toPrint := newPrintInfo(config.Moniker, genDoc.ChainID, nodeID, genTxsDir, json.RawMessage(""))
|
|
||||||
initCfg := newInitConfig(genDoc.ChainID, genTxsDir, name, nodeID, 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)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().String(cli.HomeFlag, app.DefaultNodeHome, "node's home directory")
|
|
||||||
cmd.Flags().String(flagGenTxDir, "",
|
|
||||||
"override default \"gentx\" directory from which collect and execute "+
|
|
||||||
"genesis transactions; default [--home]/config/gentx/")
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func genAppStateFromConfig(
|
|
||||||
cdc *codec.Codec, config *cfg.Config, initCfg initConfig, genDoc types.GenesisDoc,
|
|
||||||
) (appState json.RawMessage, err error) {
|
|
||||||
|
|
||||||
genFile := config.GenesisFile()
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
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 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
genTxs[i] = jsonRawTx
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
|
|
||||||
|
|
||||||
appState, err = app.AppGenStateJSON(cdc, genDoc, genTxs)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ExportGenesisFile(genFile, initCfg.ChainID, nil, appState)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func newInitConfig(chainID, genTxsDir, name, nodeID string,
|
|
||||||
valPubKey crypto.PubKey) initConfig {
|
|
||||||
|
|
||||||
return initConfig{
|
|
||||||
ChainID: chainID,
|
|
||||||
GenTxsDir: genTxsDir,
|
|
||||||
Name: name,
|
|
||||||
NodeID: nodeID,
|
|
||||||
ValPubKey: valPubKey,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newPrintInfo(moniker, chainID, nodeID, genTxsDir string,
|
|
||||||
appMessage json.RawMessage) printInfo {
|
|
||||||
|
|
||||||
return printInfo{
|
|
||||||
Moniker: moniker,
|
|
||||||
ChainID: chainID,
|
|
||||||
NodeID: nodeID,
|
|
||||||
GenTxsDir: genTxsDir,
|
|
||||||
AppMessage: appMessage,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,141 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"github.com/tendermint/tendermint/libs/cli"
|
|
||||||
"github.com/tendermint/tendermint/libs/common"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
|
||||||
"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"
|
|
||||||
"github.com/kava-labs/kava/app"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddGenesisAccountCmd returns add-genesis-account cobra Command.
|
|
||||||
func AddGenesisAccountCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
|
||||||
cmd := &cobra.Command{
|
|
||||||
Use: "add-genesis-account [address_or_key_name] [coin][,[coin]]",
|
|
||||||
Short: "Add genesis account to genesis.json",
|
|
||||||
Args: cobra.ExactArgs(2),
|
|
||||||
RunE: func(_ *cobra.Command, args []string) error {
|
|
||||||
config := ctx.Config
|
|
||||||
config.SetRoot(viper.GetString(cli.HomeFlag))
|
|
||||||
|
|
||||||
addr, err := sdk.AccAddressFromBech32(args[0])
|
|
||||||
if err != nil {
|
|
||||||
kb, err := keys.NewKeyBaseFromDir(viper.GetString(flagClientHome))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err := kb.Get(args[0])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
addr = info.GetAddress()
|
|
||||||
}
|
|
||||||
|
|
||||||
coins, err := sdk.ParseCoins(args[1])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
vestingStart := viper.GetInt64(flagVestingStart)
|
|
||||||
vestingEnd := viper.GetInt64(flagVestingEnd)
|
|
||||||
vestingAmt, err := sdk.ParseCoins(viper.GetString(flagVestingAmt))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
genFile := config.GenesisFile()
|
|
||||||
if !common.FileExists(genFile) {
|
|
||||||
return fmt.Errorf("%s does not exist, run `kvd init` first", genFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
genDoc, err := LoadGenesisDoc(cdc, genFile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var appState app.GenesisState
|
|
||||||
if err = cdc.UnmarshalJSON(genDoc.AppState, &appState); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
appState, err = addGenesisAccount(cdc, appState, addr, coins, vestingAmt, vestingStart, vestingEnd)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
appStateJSON, err := cdc.MarshalJSON(appState)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ExportGenesisFile(genFile, genDoc.ChainID, nil, appStateJSON)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().String(cli.HomeFlag, app.DefaultNodeHome, "node's home directory")
|
|
||||||
cmd.Flags().String(flagClientHome, app.DefaultCLIHome, "client's home directory")
|
|
||||||
cmd.Flags().String(flagVestingAmt, "", "amount of coins for vesting accounts")
|
|
||||||
cmd.Flags().Uint64(flagVestingStart, 0, "schedule start time (unix epoch) for vesting accounts")
|
|
||||||
cmd.Flags().Uint64(flagVestingEnd, 0, "schedule end time (unix epoch) for vesting accounts")
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func addGenesisAccount(
|
|
||||||
cdc *codec.Codec, appState app.GenesisState, addr sdk.AccAddress,
|
|
||||||
coins, vestingAmt sdk.Coins, vestingStart, vestingEnd int64,
|
|
||||||
) (app.GenesisState, error) {
|
|
||||||
|
|
||||||
for _, stateAcc := range appState.Accounts {
|
|
||||||
if stateAcc.Address.Equals(addr) {
|
|
||||||
return appState, fmt.Errorf("the application state already contains account %v", addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
acc := auth.NewBaseAccountWithAddress(addr)
|
|
||||||
acc.Coins = coins
|
|
||||||
|
|
||||||
if !vestingAmt.IsZero() {
|
|
||||||
var vacc auth.VestingAccount
|
|
||||||
|
|
||||||
bvacc := &auth.BaseVestingAccount{
|
|
||||||
BaseAccount: &acc,
|
|
||||||
OriginalVesting: vestingAmt,
|
|
||||||
EndTime: vestingEnd,
|
|
||||||
}
|
|
||||||
|
|
||||||
if bvacc.OriginalVesting.IsAllGT(acc.Coins) {
|
|
||||||
return appState, fmt.Errorf("vesting amount cannot be greater than total amount")
|
|
||||||
}
|
|
||||||
if vestingStart >= vestingEnd {
|
|
||||||
return appState, fmt.Errorf("vesting start time must before end time")
|
|
||||||
}
|
|
||||||
|
|
||||||
if vestingStart != 0 {
|
|
||||||
vacc = &auth.ContinuousVestingAccount{
|
|
||||||
BaseVestingAccount: bvacc,
|
|
||||||
StartTime: vestingStart,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
vacc = &auth.DelayedVestingAccount{
|
|
||||||
BaseVestingAccount: bvacc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
appState.Accounts = append(appState.Accounts, app.NewGenesisAccountI(vacc))
|
|
||||||
} else {
|
|
||||||
appState.Accounts = append(appState.Accounts, app.NewGenesisAccount(&acc))
|
|
||||||
}
|
|
||||||
|
|
||||||
return appState, nil
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
|
||||||
|
|
||||||
"github.com/kava-labs/kava/app"
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAddGenesisAccount(t *testing.T) {
|
|
||||||
cdc := codec.New()
|
|
||||||
addr1 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
|
|
||||||
type args struct {
|
|
||||||
appState app.GenesisState
|
|
||||||
addr sdk.AccAddress
|
|
||||||
coins sdk.Coins
|
|
||||||
vestingAmt sdk.Coins
|
|
||||||
vestingStart int64
|
|
||||||
vestingEnd int64
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"valid account",
|
|
||||||
args{
|
|
||||||
app.GenesisState{},
|
|
||||||
addr1,
|
|
||||||
sdk.NewCoins(),
|
|
||||||
sdk.NewCoins(),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"dup account",
|
|
||||||
args{
|
|
||||||
app.GenesisState{Accounts: []app.GenesisAccount{{Address: addr1}}},
|
|
||||||
addr1,
|
|
||||||
sdk.NewCoins(),
|
|
||||||
sdk.NewCoins(),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"invalid vesting amount",
|
|
||||||
args{
|
|
||||||
app.GenesisState{},
|
|
||||||
addr1,
|
|
||||||
sdk.NewCoins(sdk.NewInt64Coin("stake", 50)),
|
|
||||||
sdk.NewCoins(sdk.NewInt64Coin("stake", 100)),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"invalid vesting times",
|
|
||||||
args{
|
|
||||||
app.GenesisState{},
|
|
||||||
addr1,
|
|
||||||
sdk.NewCoins(sdk.NewInt64Coin("stake", 50)),
|
|
||||||
sdk.NewCoins(sdk.NewInt64Coin("stake", 50)),
|
|
||||||
1654668078,
|
|
||||||
1554668078,
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
_, err := addGenesisAccount(
|
|
||||||
cdc, tt.args.appState, tt.args.addr, tt.args.coins,
|
|
||||||
tt.args.vestingAmt, tt.args.vestingStart, tt.args.vestingEnd,
|
|
||||||
)
|
|
||||||
require.Equal(t, tt.wantErr, (err != nil))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
312
init/gentx.go
312
init/gentx.go
@ -1,312 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
// DONTCOVER
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
|
||||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
|
||||||
"github.com/tendermint/tendermint/libs/common"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/context"
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
kbkeys "github.com/cosmos/cosmos-sdk/crypto/keys"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
|
||||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking/client/cli"
|
|
||||||
"github.com/kava-labs/kava/app"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
defaultTokens = sdk.TokensFromTendermintPower(100)
|
|
||||||
defaultAmount = defaultTokens.String() + sdk.DefaultBondDenom
|
|
||||||
defaultCommissionRate = "0.1"
|
|
||||||
defaultCommissionMaxRate = "0.2"
|
|
||||||
defaultCommissionMaxChangeRate = "0.01"
|
|
||||||
defaultMinSelfDelegation = "1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GenTxCmd builds the kvd gentx command.
|
|
||||||
// nolint: errcheck
|
|
||||||
func GenTxCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
|
||||||
cmd := &cobra.Command{
|
|
||||||
Use: "gentx",
|
|
||||||
Short: "Generate a genesis tx carrying a self delegation",
|
|
||||||
Args: cobra.NoArgs,
|
|
||||||
Long: fmt.Sprintf(`This command is an alias of the 'kvd tx create-validator' command'.
|
|
||||||
|
|
||||||
It creates a genesis piece carrying a self delegation with the
|
|
||||||
following delegation and commission default parameters:
|
|
||||||
|
|
||||||
delegation amount: %s
|
|
||||||
commission rate: %s
|
|
||||||
commission max rate: %s
|
|
||||||
commission max change rate: %s
|
|
||||||
minimum self delegation: %s
|
|
||||||
`, defaultAmount, defaultCommissionRate, defaultCommissionMaxRate, defaultCommissionMaxChangeRate, defaultMinSelfDelegation),
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
|
|
||||||
config := ctx.Config
|
|
||||||
config.SetRoot(viper.GetString(tmcli.HomeFlag))
|
|
||||||
nodeID, valPubKey, err := InitializeNodeValidatorFiles(ctx.Config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read --nodeID, if empty take it from priv_validator.json
|
|
||||||
if nodeIDString := viper.GetString(cli.FlagNodeID); nodeIDString != "" {
|
|
||||||
nodeID = nodeIDString
|
|
||||||
}
|
|
||||||
|
|
||||||
ip := viper.GetString(cli.FlagIP)
|
|
||||||
if ip == "" {
|
|
||||||
fmt.Fprintf(os.Stderr, "couldn't retrieve an external IP; "+
|
|
||||||
"the tx's memo field will be unset")
|
|
||||||
}
|
|
||||||
|
|
||||||
genDoc, err := LoadGenesisDoc(cdc, config.GenesisFile())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
genesisState := app.GenesisState{}
|
|
||||||
if err = cdc.UnmarshalJSON(genDoc.AppState, &genesisState); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = app.ValidateGenesisState(genesisState); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
kb, err := keys.NewKeyBaseFromDir(viper.GetString(flagClientHome))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
name := viper.GetString(client.FlagName)
|
|
||||||
key, err := kb.Get(name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read --pubkey, if empty take it from priv_validator.json
|
|
||||||
if valPubKeyString := viper.GetString(cli.FlagPubKey); valPubKeyString != "" {
|
|
||||||
valPubKey, err = sdk.GetConsPubKeyBech32(valPubKeyString)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
website := viper.GetString(cli.FlagWebsite)
|
|
||||||
details := viper.GetString(cli.FlagDetails)
|
|
||||||
identity := viper.GetString(cli.FlagIdentity)
|
|
||||||
|
|
||||||
// Set flags for creating gentx
|
|
||||||
prepareFlagsForTxCreateValidator(config, nodeID, ip, genDoc.ChainID, valPubKey, website, details, identity)
|
|
||||||
|
|
||||||
// Fetch the amount of coins staked
|
|
||||||
amount := viper.GetString(cli.FlagAmount)
|
|
||||||
coins, err := sdk.ParseCoins(amount)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = accountInGenesis(genesisState, key.GetAddress(), coins)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
|
|
||||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
|
||||||
|
|
||||||
// XXX: Set the generate-only flag here after the CLI context has
|
|
||||||
// been created. This allows the from name/key to be correctly populated.
|
|
||||||
//
|
|
||||||
// TODO: Consider removing the manual setting of generate-only in
|
|
||||||
// favor of a 'gentx' flag in the create-validator command.
|
|
||||||
viper.Set(client.FlagGenerateOnly, true)
|
|
||||||
|
|
||||||
// create a 'create-validator' message
|
|
||||||
txBldr, msg, err := cli.BuildCreateValidatorMsg(cliCtx, txBldr)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err := txBldr.Keybase().Get(name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.GetType() == kbkeys.TypeOffline || info.GetType() == kbkeys.TypeMulti {
|
|
||||||
fmt.Println("Offline key passed in. Use `kvcli tx sign` command to sign:")
|
|
||||||
return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// write the unsigned transaction to the buffer
|
|
||||||
w := bytes.NewBuffer([]byte{})
|
|
||||||
cliCtx = cliCtx.WithOutput(w)
|
|
||||||
|
|
||||||
if err = utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, true); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the transaction
|
|
||||||
stdTx, err := readUnsignedGenTxFile(cdc, w)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// sign the transaction and write it to the output file
|
|
||||||
signedTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, false, true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch output file name
|
|
||||||
outputDocument := viper.GetString(client.FlagOutputDocument)
|
|
||||||
if outputDocument == "" {
|
|
||||||
outputDocument, err = makeOutputFilepath(config.RootDir, nodeID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := writeSignedGenTx(cdc, outputDocument, signedTx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "Genesis transaction written to %q\n", outputDocument)
|
|
||||||
return nil
|
|
||||||
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
ip, _ := server.ExternalIP()
|
|
||||||
|
|
||||||
cmd.Flags().String(tmcli.HomeFlag, app.DefaultNodeHome, "node's home directory")
|
|
||||||
cmd.Flags().String(flagClientHome, app.DefaultCLIHome, "client's home directory")
|
|
||||||
cmd.Flags().String(client.FlagName, "", "name of private key with which to sign the gentx")
|
|
||||||
cmd.Flags().String(client.FlagOutputDocument, "",
|
|
||||||
"write the genesis transaction JSON document to the given file instead of the default location")
|
|
||||||
cmd.Flags().String(cli.FlagIP, ip, "The node's public IP")
|
|
||||||
cmd.Flags().String(cli.FlagNodeID, "", "The node's NodeID")
|
|
||||||
cmd.Flags().String(cli.FlagWebsite, "", "The validator's (optional) website")
|
|
||||||
cmd.Flags().String(cli.FlagDetails, "", "The validator's (optional) details")
|
|
||||||
cmd.Flags().String(cli.FlagIdentity, "", "The (optional) identity signature (ex. UPort or Keybase)")
|
|
||||||
cmd.Flags().AddFlagSet(cli.FsCommissionCreate)
|
|
||||||
cmd.Flags().AddFlagSet(cli.FsMinSelfDelegation)
|
|
||||||
cmd.Flags().AddFlagSet(cli.FsAmount)
|
|
||||||
cmd.Flags().AddFlagSet(cli.FsPk)
|
|
||||||
cmd.MarkFlagRequired(client.FlagName)
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func accountInGenesis(genesisState app.GenesisState, key sdk.AccAddress, coins sdk.Coins) error {
|
|
||||||
accountIsInGenesis := false
|
|
||||||
bondDenom := genesisState.StakingData.Params.BondDenom
|
|
||||||
|
|
||||||
// Check if the account is in genesis
|
|
||||||
for _, acc := range genesisState.Accounts {
|
|
||||||
// Ensure that account is in genesis
|
|
||||||
if acc.Address.Equals(key) {
|
|
||||||
|
|
||||||
// Ensure account contains enough funds of default bond denom
|
|
||||||
if coins.AmountOf(bondDenom).GT(acc.Coins.AmountOf(bondDenom)) {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"account %v is in genesis, but it only has %v%v available to stake, not %v%v",
|
|
||||||
key.String(), acc.Coins.AmountOf(bondDenom), bondDenom, coins.AmountOf(bondDenom), bondDenom,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
accountIsInGenesis = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if accountIsInGenesis {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Errorf("account %s in not in the app_state.accounts array of genesis.json", key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func prepareFlagsForTxCreateValidator(
|
|
||||||
config *cfg.Config, nodeID, ip, chainID string, valPubKey crypto.PubKey, website, details, identity string,
|
|
||||||
) {
|
|
||||||
viper.Set(tmcli.HomeFlag, viper.GetString(flagClientHome))
|
|
||||||
viper.Set(client.FlagChainID, chainID)
|
|
||||||
viper.Set(client.FlagFrom, viper.GetString(client.FlagName))
|
|
||||||
viper.Set(cli.FlagNodeID, nodeID)
|
|
||||||
viper.Set(cli.FlagIP, ip)
|
|
||||||
viper.Set(cli.FlagPubKey, sdk.MustBech32ifyConsPub(valPubKey))
|
|
||||||
viper.Set(cli.FlagMoniker, config.Moniker)
|
|
||||||
viper.Set(cli.FlagWebsite, website)
|
|
||||||
viper.Set(cli.FlagDetails, details)
|
|
||||||
viper.Set(cli.FlagIdentity, identity)
|
|
||||||
|
|
||||||
if config.Moniker == "" {
|
|
||||||
viper.Set(cli.FlagMoniker, viper.GetString(client.FlagName))
|
|
||||||
}
|
|
||||||
if viper.GetString(cli.FlagAmount) == "" {
|
|
||||||
viper.Set(cli.FlagAmount, defaultAmount)
|
|
||||||
}
|
|
||||||
if viper.GetString(cli.FlagCommissionRate) == "" {
|
|
||||||
viper.Set(cli.FlagCommissionRate, defaultCommissionRate)
|
|
||||||
}
|
|
||||||
if viper.GetString(cli.FlagCommissionMaxRate) == "" {
|
|
||||||
viper.Set(cli.FlagCommissionMaxRate, defaultCommissionMaxRate)
|
|
||||||
}
|
|
||||||
if viper.GetString(cli.FlagCommissionMaxChangeRate) == "" {
|
|
||||||
viper.Set(cli.FlagCommissionMaxChangeRate, defaultCommissionMaxChangeRate)
|
|
||||||
}
|
|
||||||
if viper.GetString(cli.FlagMinSelfDelegation) == "" {
|
|
||||||
viper.Set(cli.FlagMinSelfDelegation, defaultMinSelfDelegation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeOutputFilepath(rootDir, nodeID string) (string, error) {
|
|
||||||
writePath := filepath.Join(rootDir, "config", "gentx")
|
|
||||||
if err := common.EnsureDir(writePath, 0700); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return filepath.Join(writePath, fmt.Sprintf("gentx-%v.json", nodeID)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readUnsignedGenTxFile(cdc *codec.Codec, r io.Reader) (auth.StdTx, error) {
|
|
||||||
var stdTx auth.StdTx
|
|
||||||
bytes, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return stdTx, err
|
|
||||||
}
|
|
||||||
err = cdc.UnmarshalJSON(bytes, &stdTx)
|
|
||||||
return stdTx, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// nolint: errcheck
|
|
||||||
func writeSignedGenTx(cdc *codec.Codec, outputDocument string, tx auth.StdTx) error {
|
|
||||||
outputFile, err := os.OpenFile(outputDocument, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer outputFile.Close()
|
|
||||||
json, err := cdc.MarshalJSON(tx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = fmt.Fprintf(outputFile, "%s\n", json)
|
|
||||||
return err
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/staking/client/cli"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_prepareFlagsForTxCreateValidator(t *testing.T) {
|
|
||||||
defer server.SetupViper(t)()
|
|
||||||
defer setupClientHome(t)()
|
|
||||||
config, err := tcmd.ParseConfig()
|
|
||||||
require.Nil(t, err)
|
|
||||||
logger := log.NewNopLogger()
|
|
||||||
ctx := server.NewContext(config, logger)
|
|
||||||
|
|
||||||
valPubKey, _ := sdk.GetConsPubKeyBech32("cosmosvalconspub1zcjduepq7jsrkl9fgqk0wj3ahmfr8pgxj6vakj2wzn656s8pehh0zhv2w5as5gd80a")
|
|
||||||
|
|
||||||
type args struct {
|
|
||||||
config *cfg.Config
|
|
||||||
nodeID string
|
|
||||||
ip string
|
|
||||||
chainID string
|
|
||||||
valPubKey crypto.PubKey
|
|
||||||
website string
|
|
||||||
details string
|
|
||||||
identity string
|
|
||||||
}
|
|
||||||
|
|
||||||
type extraParams struct {
|
|
||||||
amount string
|
|
||||||
commissionRate string
|
|
||||||
commissionMaxRate string
|
|
||||||
commissionMaxChangeRate string
|
|
||||||
minSelfDelegation string
|
|
||||||
}
|
|
||||||
|
|
||||||
type testcase struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
}
|
|
||||||
|
|
||||||
runTest := func(t *testing.T, tt testcase, params extraParams) {
|
|
||||||
prepareFlagsForTxCreateValidator(tt.args.config, tt.args.nodeID, tt.args.ip, tt.args.chainID, tt.args.valPubKey, tt.args.website, tt.args.details, tt.args.identity)
|
|
||||||
require.Equal(t, tt.args.website, viper.GetString(cli.FlagWebsite))
|
|
||||||
require.Equal(t, tt.args.details, viper.GetString(cli.FlagDetails))
|
|
||||||
require.Equal(t, tt.args.identity, viper.GetString(cli.FlagIdentity))
|
|
||||||
require.Equal(t, params.amount, viper.GetString(cli.FlagAmount))
|
|
||||||
require.Equal(t, params.commissionRate, viper.GetString(cli.FlagCommissionRate))
|
|
||||||
require.Equal(t, params.commissionMaxRate, viper.GetString(cli.FlagCommissionMaxRate))
|
|
||||||
require.Equal(t, params.commissionMaxChangeRate, viper.GetString(cli.FlagCommissionMaxChangeRate))
|
|
||||||
require.Equal(t, params.minSelfDelegation, viper.GetString(cli.FlagMinSelfDelegation))
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []testcase{
|
|
||||||
{"No parameters", args{ctx.Config, "X", "0.0.0.0", "chainId", valPubKey, "", "", ""}},
|
|
||||||
{"Optional parameters fed", args{ctx.Config, "X", "0.0.0.0", "chainId", valPubKey, "cosmos.network", "details", "identity"}},
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultParams := extraParams{defaultAmount, defaultCommissionRate, defaultCommissionMaxRate, defaultCommissionMaxChangeRate, defaultMinSelfDelegation}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
t.Run(tt.name, func(t *testing.T) { runTest(t, tt, defaultParams) })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override default params
|
|
||||||
params := extraParams{"5stake", "1.0", "1.0", "1.0", "1.0"}
|
|
||||||
viper.Set(cli.FlagAmount, params.amount)
|
|
||||||
viper.Set(cli.FlagCommissionRate, params.commissionRate)
|
|
||||||
viper.Set(cli.FlagCommissionMaxRate, params.commissionMaxRate)
|
|
||||||
viper.Set(cli.FlagCommissionMaxChangeRate, params.commissionMaxChangeRate)
|
|
||||||
viper.Set(cli.FlagMinSelfDelegation, params.minSelfDelegation)
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) { runTest(t, tt, params) })
|
|
||||||
}
|
|
||||||
}
|
|
95
init/init.go
95
init/init.go
@ -1,95 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
cfg "github.com/tendermint/tendermint/config"
|
|
||||||
"github.com/tendermint/tendermint/libs/cli"
|
|
||||||
"github.com/tendermint/tendermint/libs/common"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
|
||||||
"github.com/kava-labs/kava/app"
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
flagOverwrite = "overwrite"
|
|
||||||
flagClientHome = "home-client"
|
|
||||||
flagVestingStart = "vesting-start-time"
|
|
||||||
flagVestingEnd = "vesting-end-time"
|
|
||||||
flagVestingAmt = "vesting-amount"
|
|
||||||
)
|
|
||||||
|
|
||||||
type printInfo struct {
|
|
||||||
Moniker string `json:"moniker"`
|
|
||||||
ChainID string `json:"chain_id"`
|
|
||||||
NodeID string `json:"node_id"`
|
|
||||||
GenTxsDir string `json:"gentxs_dir"`
|
|
||||||
AppMessage json.RawMessage `json:"app_message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func displayInfo(cdc *codec.Codec, info printInfo) error {
|
|
||||||
out, err := codec.MarshalJSONIndent(cdc, info)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", string(out)) // nolint: errcheck
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitCmd returns a command that initializes all files needed for Tendermint
|
|
||||||
// and the respective application.
|
|
||||||
func InitCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { // nolint: golint
|
|
||||||
cmd := &cobra.Command{
|
|
||||||
Use: "init [moniker]",
|
|
||||||
Short: "Initialize private validator, p2p, genesis, and application configuration files",
|
|
||||||
Long: `Initialize validators's and node's configuration files.`,
|
|
||||||
Args: cobra.ExactArgs(1),
|
|
||||||
RunE: func(_ *cobra.Command, args []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, _, err := InitializeNodeValidatorFiles(config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
config.Moniker = args[0]
|
|
||||||
|
|
||||||
var appState json.RawMessage
|
|
||||||
genFile := config.GenesisFile()
|
|
||||||
|
|
||||||
if appState, err = initializeEmptyGenesis(cdc, genFile, chainID,
|
|
||||||
viper.GetBool(flagOverwrite)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = ExportGenesisFile(genFile, chainID, nil, appState); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
toPrint := newPrintInfo(config.Moniker, chainID, nodeID, "", appState)
|
|
||||||
|
|
||||||
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
|
|
||||||
return displayInfo(cdc, toPrint)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().String(cli.HomeFlag, app.DefaultNodeHome, "node'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")
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
@ -1,136 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
|
||||||
"github.com/kava-labs/kava/app"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server/mock"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
abciServer "github.com/tendermint/tendermint/abci/server"
|
|
||||||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
|
||||||
"github.com/tendermint/tendermint/libs/cli"
|
|
||||||
"github.com/tendermint/tendermint/libs/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestInitCmd(t *testing.T) {
|
|
||||||
defer server.SetupViper(t)()
|
|
||||||
defer setupClientHome(t)()
|
|
||||||
|
|
||||||
logger := log.NewNopLogger()
|
|
||||||
cfg, err := tcmd.ParseConfig()
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
ctx := server.NewContext(cfg, logger)
|
|
||||||
cdc := app.MakeCodec()
|
|
||||||
cmd := InitCmd(ctx, cdc)
|
|
||||||
|
|
||||||
require.NoError(t, cmd.RunE(nil, []string{"kavanode-test"}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupClientHome(t *testing.T) func() {
|
|
||||||
clientDir, err := ioutil.TempDir("", "mock-sdk-cmd")
|
|
||||||
require.Nil(t, err)
|
|
||||||
viper.Set(flagClientHome, clientDir)
|
|
||||||
return func() {
|
|
||||||
if err := os.RemoveAll(clientDir); err != nil {
|
|
||||||
// TODO: Handle with #870
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEmptyState(t *testing.T) {
|
|
||||||
defer server.SetupViper(t)()
|
|
||||||
defer setupClientHome(t)()
|
|
||||||
|
|
||||||
logger := log.NewNopLogger()
|
|
||||||
cfg, err := tcmd.ParseConfig()
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
ctx := server.NewContext(cfg, logger)
|
|
||||||
cdc := app.MakeCodec()
|
|
||||||
|
|
||||||
cmd := InitCmd(ctx, cdc)
|
|
||||||
require.NoError(t, cmd.RunE(nil, []string{"kavanode-test"}))
|
|
||||||
|
|
||||||
old := os.Stdout
|
|
||||||
r, w, _ := os.Pipe()
|
|
||||||
os.Stdout = w
|
|
||||||
cmd = server.ExportCmd(ctx, cdc, nil)
|
|
||||||
|
|
||||||
err = cmd.RunE(nil, nil)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
outC := make(chan string)
|
|
||||||
go func() {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
io.Copy(&buf, r)
|
|
||||||
outC <- buf.String()
|
|
||||||
}()
|
|
||||||
|
|
||||||
w.Close()
|
|
||||||
os.Stdout = old
|
|
||||||
out := <-outC
|
|
||||||
require.Contains(t, out, "genesis_time")
|
|
||||||
require.Contains(t, out, "chain_id")
|
|
||||||
require.Contains(t, out, "consensus_params")
|
|
||||||
require.Contains(t, out, "validators")
|
|
||||||
require.Contains(t, out, "app_hash")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStartStandAlone(t *testing.T) {
|
|
||||||
home, err := ioutil.TempDir("", "mock-sdk-cmd")
|
|
||||||
require.Nil(t, err)
|
|
||||||
defer func() {
|
|
||||||
os.RemoveAll(home)
|
|
||||||
}()
|
|
||||||
viper.Set(cli.HomeFlag, home)
|
|
||||||
defer setupClientHome(t)()
|
|
||||||
|
|
||||||
logger := log.NewNopLogger()
|
|
||||||
cfg, err := tcmd.ParseConfig()
|
|
||||||
require.Nil(t, err)
|
|
||||||
ctx := server.NewContext(cfg, logger)
|
|
||||||
cdc := app.MakeCodec()
|
|
||||||
initCmd := InitCmd(ctx, cdc)
|
|
||||||
require.NoError(t, initCmd.RunE(nil, []string{"kavanode-test"}))
|
|
||||||
|
|
||||||
app, err := mock.NewApp(home, logger)
|
|
||||||
require.Nil(t, err)
|
|
||||||
svrAddr, _, err := server.FreeTCPAddr()
|
|
||||||
require.Nil(t, err)
|
|
||||||
svr, err := abciServer.NewServer(svrAddr, "socket", app)
|
|
||||||
require.Nil(t, err, "error creating listener")
|
|
||||||
svr.SetLogger(logger.With("module", "abci-server"))
|
|
||||||
svr.Start()
|
|
||||||
|
|
||||||
timer := time.NewTimer(time.Duration(2) * time.Second)
|
|
||||||
select {
|
|
||||||
case <-timer.C:
|
|
||||||
svr.Stop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInitNodeValidatorFiles(t *testing.T) {
|
|
||||||
home, err := ioutil.TempDir("", "mock-sdk-cmd")
|
|
||||||
require.Nil(t, err)
|
|
||||||
defer func() {
|
|
||||||
os.RemoveAll(home)
|
|
||||||
}()
|
|
||||||
viper.Set(cli.HomeFlag, home)
|
|
||||||
viper.Set(client.FlagName, "moniker")
|
|
||||||
cfg, err := tcmd.ParseConfig()
|
|
||||||
require.Nil(t, err)
|
|
||||||
nodeID, valPubKey, err := InitializeNodeValidatorFiles(cfg)
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.NotEqual(t, "", nodeID)
|
|
||||||
require.NotEqual(t, 0, len(valPubKey.Bytes()))
|
|
||||||
}
|
|
385
init/testnet.go
385
init/testnet.go
@ -1,385 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
// DONTCOVER
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
srvconfig "github.com/cosmos/cosmos-sdk/server/config"
|
|
||||||
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/staking"
|
|
||||||
"github.com/kava-labs/kava/app"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
tmconfig "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"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
flagNodeDirPrefix = "node-dir-prefix"
|
|
||||||
flagNumValidators = "v"
|
|
||||||
flagOutputDir = "output-dir"
|
|
||||||
flagNodeDaemonHome = "node-daemon-home"
|
|
||||||
flagNodeCliHome = "node-cli-home"
|
|
||||||
flagStartingIPAddress = "starting-ip-address"
|
|
||||||
)
|
|
||||||
|
|
||||||
const nodeDirPerm = 0755
|
|
||||||
|
|
||||||
// get cmd to initialize all files for tendermint testnet and application
|
|
||||||
func TestnetFilesCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
|
||||||
Use: "testnet",
|
|
||||||
Short: "Initialize files for a testnet",
|
|
||||||
Long: `testnet will create "v" number of directories and populate each with
|
|
||||||
necessary files (private validator, genesis, config, etc.).
|
|
||||||
|
|
||||||
Note, strict routability for addresses is turned off in the config file.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
kvd testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2
|
|
||||||
`,
|
|
||||||
RunE: func(_ *cobra.Command, _ []string) error {
|
|
||||||
config := ctx.Config
|
|
||||||
return initTestnet(config, cdc)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().Int(flagNumValidators, 4,
|
|
||||||
"Number of validators to initialize the testnet with",
|
|
||||||
)
|
|
||||||
cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet",
|
|
||||||
"Directory to store initialization data for the testnet",
|
|
||||||
)
|
|
||||||
cmd.Flags().String(flagNodeDirPrefix, "node",
|
|
||||||
"Prefix the directory name for each node with (node results in node0, node1, ...)",
|
|
||||||
)
|
|
||||||
cmd.Flags().String(flagNodeDaemonHome, "kvd",
|
|
||||||
"Home directory of the node's daemon configuration",
|
|
||||||
)
|
|
||||||
cmd.Flags().String(flagNodeCliHome, "kvcli",
|
|
||||||
"Home directory of the node's cli configuration",
|
|
||||||
)
|
|
||||||
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, ...)")
|
|
||||||
|
|
||||||
cmd.Flags().String(
|
|
||||||
client.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created",
|
|
||||||
)
|
|
||||||
cmd.Flags().String(
|
|
||||||
server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom),
|
|
||||||
"Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)",
|
|
||||||
)
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func initTestnet(config *tmconfig.Config, cdc *codec.Codec) error {
|
|
||||||
var chainID string
|
|
||||||
|
|
||||||
outDir := viper.GetString(flagOutputDir)
|
|
||||||
numValidators := viper.GetInt(flagNumValidators)
|
|
||||||
|
|
||||||
chainID = viper.GetString(client.FlagChainID)
|
|
||||||
if chainID == "" {
|
|
||||||
chainID = "chain-" + cmn.RandStr(6)
|
|
||||||
}
|
|
||||||
|
|
||||||
monikers := make([]string, numValidators)
|
|
||||||
nodeIDs := make([]string, numValidators)
|
|
||||||
valPubKeys := make([]crypto.PubKey, numValidators)
|
|
||||||
|
|
||||||
appConfig := srvconfig.DefaultConfig()
|
|
||||||
appConfig.MinGasPrices = viper.GetString(server.FlagMinGasPrices)
|
|
||||||
|
|
||||||
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(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")
|
|
||||||
|
|
||||||
config.SetRoot(nodeDir)
|
|
||||||
|
|
||||||
err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm)
|
|
||||||
if err != nil {
|
|
||||||
_ = os.RemoveAll(outDir)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.MkdirAll(clientDir, nodeDirPerm)
|
|
||||||
if err != nil {
|
|
||||||
_ = os.RemoveAll(outDir)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
monikers = append(monikers, nodeDirName)
|
|
||||||
config.Moniker = nodeDirName
|
|
||||||
|
|
||||||
ip, err := getIP(i, viper.GetString(flagStartingIPAddress))
|
|
||||||
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)
|
|
||||||
genFiles = append(genFiles, config.GenesisFile())
|
|
||||||
|
|
||||||
buf := client.BufferStdin()
|
|
||||||
prompt := fmt.Sprintf(
|
|
||||||
"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
|
|
||||||
// STDIN or the given password is not empty but failed to meet minimum
|
|
||||||
// length requirements.
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if keyPass == "" {
|
|
||||||
keyPass = app.DefaultKeyPass
|
|
||||||
}
|
|
||||||
|
|
||||||
addr, secret, err := server.GenerateSaveCoinKey(clientDir, nodeDirName, keyPass, true)
|
|
||||||
if err != nil {
|
|
||||||
_ = 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 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
accTokens := sdk.TokensFromTendermintPower(1000)
|
|
||||||
accStakingTokens := sdk.TokensFromTendermintPower(500)
|
|
||||||
accs = append(accs, app.GenesisAccount{
|
|
||||||
Address: addr,
|
|
||||||
Coins: sdk.Coins{
|
|
||||||
sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), accTokens),
|
|
||||||
sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
valTokens := sdk.TokensFromTendermintPower(100)
|
|
||||||
msg := staking.NewMsgCreateValidator(
|
|
||||||
sdk.ValAddress(addr),
|
|
||||||
valPubKeys[i],
|
|
||||||
sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
|
|
||||||
staking.NewDescription(nodeDirName, "", "", ""),
|
|
||||||
staking.NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
|
|
||||||
sdk.OneInt(),
|
|
||||||
)
|
|
||||||
kb, err := keys.NewKeyBaseFromDir(clientDir)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
tx := auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, []auth.StdSignature{}, memo)
|
|
||||||
txBldr := authtx.NewTxBuilderFromCLI().WithChainID(chainID).WithMemo(memo).WithKeybase(kb)
|
|
||||||
|
|
||||||
signedTx, err := txBldr.SignStdTx(nodeDirName, app.DefaultKeyPass, tx, false)
|
|
||||||
if err != nil {
|
|
||||||
_ = os.RemoveAll(outDir)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
txBytes, err := cdc.MarshalJSON(signedTx)
|
|
||||||
if err != nil {
|
|
||||||
_ = os.RemoveAll(outDir)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// gather gentxs folder
|
|
||||||
err = writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBytes)
|
|
||||||
if err != nil {
|
|
||||||
_ = os.RemoveAll(outDir)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
appConfigFilePath := filepath.Join(nodeDir, "config/kvd.toml")
|
|
||||||
srvconfig.WriteConfigFile(appConfigFilePath, appConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := initGenFiles(cdc, chainID, accs, genFiles, numValidators); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err := collectGenFiles(
|
|
||||||
cdc, config, chainID, monikers, nodeIDs, valPubKeys, numValidators,
|
|
||||||
outDir, viper.GetString(flagNodeDirPrefix), viper.GetString(flagNodeDaemonHome),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Successfully initialized %d node directories\n", numValidators)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func initGenFiles(
|
|
||||||
cdc *codec.Codec, chainID string, accs []app.GenesisAccount,
|
|
||||||
genFiles []string, numValidators int,
|
|
||||||
) error {
|
|
||||||
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 *tmconfig.Config, chainID string,
|
|
||||||
monikers, nodeIDs []string, valPubKeys []crypto.PubKey,
|
|
||||||
numValidators int, outDir, nodeDirPrefix, nodeDaemonHomeName string,
|
|
||||||
) error {
|
|
||||||
|
|
||||||
var appState json.RawMessage
|
|
||||||
genTime := tmtime.Now()
|
|
||||||
|
|
||||||
for i := 0; i < numValidators; i++ {
|
|
||||||
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
|
|
||||||
nodeDir := filepath.Join(outDir, nodeDirName, nodeDaemonHomeName)
|
|
||||||
gentxsDir := filepath.Join(outDir, "gentxs")
|
|
||||||
moniker := monikers[i]
|
|
||||||
config.Moniker = nodeDirName
|
|
||||||
|
|
||||||
config.SetRoot(nodeDir)
|
|
||||||
|
|
||||||
nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
|
|
||||||
initCfg := newInitConfig(chainID, gentxsDir, moniker, nodeID, valPubKey)
|
|
||||||
|
|
||||||
genDoc, err := LoadGenesisDoc(cdc, config.GenesisFile())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getIP(i int, startingIPAddr string) (string, error) {
|
|
||||||
var (
|
|
||||||
ip string
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(startingIPAddr) == 0 {
|
|
||||||
ip, err = server.ExternalIP()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ip, err = calculateIP(startingIPAddr, i)
|
|
||||||
if err != nil {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func calculateIP(ip string, i int) (string, error) {
|
|
||||||
ipv4 := net.ParseIP(ip).To4()
|
|
||||||
if ipv4 == nil {
|
|
||||||
return "", fmt.Errorf("%v: non ipv4 address", ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
for j := 0; j < i; j++ {
|
|
||||||
ipv4[3]++
|
|
||||||
}
|
|
||||||
|
|
||||||
return ipv4.String(), nil
|
|
||||||
}
|
|
114
init/utils.go
114
init/utils.go
@ -1,114 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
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"
|
|
||||||
|
|
||||||
"github.com/kava-labs/kava/app"
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ExportGenesisFile creates and writes the genesis configuration to disk. An
|
|
||||||
// error is returned if building or writing the configuration to file fails.
|
|
||||||
func ExportGenesisFile(
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExportGenesisFileWithTime creates and writes the genesis configuration to disk.
|
|
||||||
// An error is returned if building or writing the configuration to file fails.
|
|
||||||
func ExportGenesisFileWithTime(
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, valPubKey, err
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeID = string(nodeKey.ID())
|
|
||||||
server.UpgradeOldPrivValFile(config)
|
|
||||||
|
|
||||||
pvKeyFile := config.PrivValidatorKeyFile()
|
|
||||||
if err := common.EnsureDir(filepath.Dir(pvKeyFile), 0777); err != nil {
|
|
||||||
return nodeID, valPubKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
pvStateFile := config.PrivValidatorStateFile()
|
|
||||||
if err := common.EnsureDir(filepath.Dir(pvStateFile), 0777); err != nil {
|
|
||||||
return nodeID, valPubKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
valPubKey = privval.LoadOrGenFilePV(pvKeyFile, pvStateFile).GetPubKey()
|
|
||||||
|
|
||||||
return nodeID, valPubKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadGenesisDoc reads and unmarshals GenesisDoc from the given file.
|
|
||||||
func LoadGenesisDoc(cdc *amino.Codec, genFile string) (genDoc types.GenesisDoc, err error) {
|
|
||||||
genContents, err := ioutil.ReadFile(genFile)
|
|
||||||
if err != nil {
|
|
||||||
return genDoc, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := cdc.UnmarshalJSON(genContents, &genDoc); err != nil {
|
|
||||||
return genDoc, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return genDoc, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func initializeEmptyGenesis(
|
|
||||||
cdc *codec.Codec, genFile, chainID string, overwrite bool,
|
|
||||||
) (appState json.RawMessage, err error) {
|
|
||||||
|
|
||||||
if !overwrite && common.FileExists(genFile) {
|
|
||||||
return nil, fmt.Errorf("genesis.json file already exists: %v", genFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
return codec.MarshalJSONIndent(cdc, app.NewDefaultGenesisState())
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
"github.com/cosmos/cosmos-sdk/tests"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestExportGenesisFileWithTime(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
dir, cleanup := tests.NewTestCaseDir(t)
|
|
||||||
defer cleanup()
|
|
||||||
|
|
||||||
fname := filepath.Join(dir, "genesis.json")
|
|
||||||
require.NoError(t, ExportGenesisFileWithTime(fname, "test", nil, json.RawMessage(""), time.Now()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLoadGenesisDoc(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
dir, cleanup := tests.NewTestCaseDir(t)
|
|
||||||
defer cleanup()
|
|
||||||
|
|
||||||
fname := filepath.Join(dir, "genesis.json")
|
|
||||||
require.NoError(t, ExportGenesisFileWithTime(fname, "test", nil, json.RawMessage(""), time.Now()))
|
|
||||||
|
|
||||||
_, err := LoadGenesisDoc(codec.Cdc, fname)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Non-existing file
|
|
||||||
_, err = LoadGenesisDoc(codec.Cdc, "non-existing-file")
|
|
||||||
require.Error(t, err)
|
|
||||||
|
|
||||||
malformedFilename := filepath.Join(dir, "malformed")
|
|
||||||
malformedFile, err := os.Create(malformedFilename)
|
|
||||||
require.NoError(t, err)
|
|
||||||
fmt.Fprint(malformedFile, "invalidjson")
|
|
||||||
malformedFile.Close()
|
|
||||||
// Non-existing file
|
|
||||||
_, err = LoadGenesisDoc(codec.Cdc, malformedFilename)
|
|
||||||
require.Error(t, err)
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package init
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
"github.com/cosmos/cosmos-sdk/server"
|
|
||||||
"github.com/kava-labs/kava/app"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/tendermint/tendermint/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Validate genesis command takes
|
|
||||||
func ValidateGenesisCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
|
||||||
return &cobra.Command{
|
|
||||||
Use: "validate-genesis [file]",
|
|
||||||
Args: cobra.RangeArgs(0, 1),
|
|
||||||
Short: "validates the genesis file at the default location or at the location passed as an arg",
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
|
||||||
|
|
||||||
// Load default if passed no args, otherwise load passed file
|
|
||||||
var genesis string
|
|
||||||
if len(args) == 0 {
|
|
||||||
genesis = ctx.Config.GenesisFile()
|
|
||||||
} else {
|
|
||||||
genesis = args[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
//nolint
|
|
||||||
fmt.Fprintf(os.Stderr, "validating genesis file at %s\n", genesis)
|
|
||||||
|
|
||||||
var genDoc types.GenesisDoc
|
|
||||||
if genDoc, err = LoadGenesisDoc(cdc, genesis); err != nil {
|
|
||||||
return fmt.Errorf("Error loading genesis doc from %s: %s", genesis, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
var genstate app.GenesisState
|
|
||||||
if err = cdc.UnmarshalJSON(genDoc.AppState, &genstate); err != nil {
|
|
||||||
return fmt.Errorf("Error unmarshaling genesis doc %s: %s", genesis, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = app.ValidateGenesisState(genstate); err != nil {
|
|
||||||
return fmt.Errorf("Error validating genesis file %s: %s", genesis, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("File at %s is a valid genesis file for kvd\n", genesis)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user