Merge branch 'develop' into sunny/get_all_delegations_validator_querier

This commit is contained in:
Christopher Goes
2018-11-05 11:56:32 +01:00
102 changed files with 1302 additions and 922 deletions
+11 -8
View File
@@ -109,7 +109,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
app.cdc,
app.keyParams, app.tkeyParams,
)
app.stakeKeeper = stake.NewKeeper(
stakeKeeper := stake.NewKeeper(
app.cdc,
app.keyStake, app.tkeyStake,
app.bankKeeper, app.paramsKeeper.Subspace(stake.DefaultParamspace),
@@ -117,30 +117,32 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
)
app.mintKeeper = mint.NewKeeper(app.cdc, app.keyMint,
app.paramsKeeper.Subspace(mint.DefaultParamspace),
app.stakeKeeper, app.feeCollectionKeeper,
&stakeKeeper, app.feeCollectionKeeper,
)
app.distrKeeper = distr.NewKeeper(
app.cdc,
app.keyDistr,
app.paramsKeeper.Subspace(distr.DefaultParamspace),
app.bankKeeper, app.stakeKeeper, app.feeCollectionKeeper,
app.bankKeeper, &stakeKeeper, app.feeCollectionKeeper,
app.RegisterCodespace(stake.DefaultCodespace),
)
app.slashingKeeper = slashing.NewKeeper(
app.cdc,
app.keySlashing,
app.stakeKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamspace),
&stakeKeeper, app.paramsKeeper.Subspace(slashing.DefaultParamspace),
app.RegisterCodespace(slashing.DefaultCodespace),
)
app.govKeeper = gov.NewKeeper(
app.cdc,
app.keyGov,
app.paramsKeeper, app.paramsKeeper.Subspace(gov.DefaultParamspace), app.bankKeeper, app.stakeKeeper,
app.paramsKeeper, app.paramsKeeper.Subspace(gov.DefaultParamspace), app.bankKeeper, &stakeKeeper,
app.RegisterCodespace(gov.DefaultCodespace),
)
// register the staking hooks
app.stakeKeeper = app.stakeKeeper.WithHooks(
// NOTE: stakeKeeper above are passed by reference,
// so that it can be modified like below:
app.stakeKeeper = *stakeKeeper.SetHooks(
NewHooks(app.distrKeeper.Hooks(), app.slashingKeeper.Hooks()))
// register message routes
@@ -259,7 +261,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
if err != nil {
panic(err)
}
bz := app.cdc.MustMarshalBinary(tx)
bz := app.cdc.MustMarshalBinaryLengthPrefixed(tx)
res := app.BaseApp.DeliverTx(bz)
if !res.IsOK() {
panic(res.Log)
@@ -273,7 +275,8 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
// sanity check
if len(req.Validators) > 0 {
if len(req.Validators) != len(validators) {
panic(fmt.Errorf("len(RequestInitChain.Validators) != len(validators) (%d != %d) ", len(req.Validators), len(validators)))
panic(fmt.Errorf("len(RequestInitChain.Validators) != len(validators) (%d != %d)",
len(req.Validators), len(validators)))
}
sort.Sort(abci.ValidatorUpdates(req.Validators))
sort.Sort(abci.ValidatorUpdates(validators))
+96 -70
View File
@@ -26,6 +26,7 @@ var (
// bonded tokens given to genesis validators/accounts
freeFermionVal = int64(100)
freeFermionsAcc = sdk.NewInt(150)
bondDenom = "steak"
)
// State to Unmarshal
@@ -90,58 +91,60 @@ func GaiaAppInit() server.AppInit {
// Create the core parameters for genesis initialization for gaia
// note that the pubkey input is this machines pubkey
func GaiaAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (genesisState GenesisState, err error) {
if len(appGenTxs) == 0 {
err = errors.New("must provide at least genesis transaction")
return
func GaiaAppGenState(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
genesisState GenesisState, err error) {
if err = cdc.UnmarshalJSON(genDoc.AppState, &genesisState); err != nil {
return genesisState, err
}
// start with the default staking genesis state
stakeData := stake.DefaultGenesisState()
slashingData := slashing.DefaultGenesisState()
// get genesis flag account information
genaccs := make([]GenesisAccount, len(appGenTxs))
// if there are no gen txs to be processed, return the default empty state
if len(appGenTxs) == 0 {
return genesisState, errors.New("there must be at least one genesis tx")
}
stakeData := genesisState.StakeData
for i, genTx := range appGenTxs {
var tx auth.StdTx
err = cdc.UnmarshalJSON(genTx, &tx)
if err != nil {
return
if err := cdc.UnmarshalJSON(genTx, &tx); err != nil {
return genesisState, err
}
msgs := tx.GetMsgs()
if len(msgs) != 1 {
err = errors.New("must provide genesis StdTx with exactly 1 CreateValidator message")
return
return genesisState, errors.New(
"must provide genesis StdTx with exactly 1 CreateValidator message")
}
if _, ok := msgs[0].(stake.MsgCreateValidator); !ok {
return genesisState, fmt.Errorf(
"Genesis transaction %v does not contain a MsgCreateValidator", i)
}
msg := msgs[0].(stake.MsgCreateValidator)
// create the genesis account, give'm few steaks and a buncha token with there name
genaccs[i] = genesisAccountFromMsgCreateValidator(msg, freeFermionsAcc)
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
}
// create the final app state
genesisState = GenesisState{
Accounts: genaccs,
StakeData: stakeData,
for _, acc := range genesisState.Accounts {
// create the genesis account, give'm few steaks and a buncha token with there name
for _, coin := range acc.Coins {
if coin.Denom == bondDenom {
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.
Add(sdk.NewDecFromInt(coin.Amount)) // increase the supply
}
}
}
genesisState.StakeData = stakeData
genesisState.GenTxs = appGenTxs
return genesisState, nil
}
// NewDefaultGenesisState generates the default state for gaia.
func NewDefaultGenesisState() GenesisState {
return GenesisState{
Accounts: nil,
StakeData: stake.DefaultGenesisState(),
MintData: mint.DefaultGenesisState(),
DistrData: distr.DefaultGenesisState(),
GovData: gov.DefaultGenesisState(),
SlashingData: slashingData,
GenTxs: appGenTxs,
SlashingData: slashing.DefaultGenesisState(),
GenTxs: nil,
}
return
}
func genesisAccountFromMsgCreateValidator(msg stake.MsgCreateValidator, amount sdk.Int) GenesisAccount {
accAuth := auth.NewBaseAccountWithAddress(sdk.AccAddress(msg.ValidatorAddr))
accAuth.Coins = []sdk.Coin{
{msg.Description.Moniker + "Token", sdk.NewInt(1000)},
{"steak", amount},
}
return NewGenesisAccount(&accAuth)
}
// GaiaValidateGenesisState ensures that the genesis state obeys the expected invariants
@@ -175,27 +178,43 @@ func validateGenesisStateAccounts(accs []GenesisAccount) (err error) {
}
// GaiaAppGenState but with JSON
func GaiaAppGenStateJSON(cdc *codec.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
func GaiaAppGenStateJSON(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
appState json.RawMessage, err error) {
// create the final app state
genesisState, err := GaiaAppGenState(cdc, appGenTxs)
genesisState, err := GaiaAppGenState(cdc, genDoc, appGenTxs)
if err != nil {
return nil, err
}
appState, err = codec.MarshalJSONIndent(cdc, genesisState)
return
return codec.MarshalJSONIndent(cdc, genesisState)
}
// CollectStdTxs processes and validates application's genesis StdTxs and returns the list of validators,
// appGenTxs, and persistent peers required to generate genesis.json.
func CollectStdTxs(moniker string, genTxsDir string, cdc *codec.Codec) (
validators []tmtypes.GenesisValidator, appGenTxs []auth.StdTx, persistentPeers string, err error) {
// CollectStdTxs processes and validates application's genesis StdTxs and returns
// the list of appGenTxs, and persistent peers required to generate genesis.json.
func CollectStdTxs(cdc *codec.Codec, moniker string, genTxsDir string, genDoc tmtypes.GenesisDoc) (
appGenTxs []auth.StdTx, persistentPeers string, err error) {
var fos []os.FileInfo
fos, err = ioutil.ReadDir(genTxsDir)
if err != nil {
return
return appGenTxs, persistentPeers, err
}
var addresses []string
// prepare a map of all accounts in genesis state to then validate
// against the validators addresses
var appState GenesisState
if err := cdc.UnmarshalJSON(genDoc.AppState, &appState); err != nil {
return appGenTxs, persistentPeers, err
}
addrMap := make(map[string]GenesisAccount, len(appState.Accounts))
for i := 0; i < len(appState.Accounts); i++ {
acc := appState.Accounts[i]
strAddr := string(acc.Address)
addrMap[strAddr] = acc
}
// addresses and IPs (and port) validator server info
var addressesIPs []string
for _, fo := range fos {
filename := filepath.Join(genTxsDir, fo.Name())
if !fo.IsDir() && (filepath.Ext(filename) != ".json") {
@@ -204,48 +223,55 @@ func CollectStdTxs(moniker string, genTxsDir string, cdc *codec.Codec) (
// get the genStdTx
var jsonRawTx []byte
jsonRawTx, err = ioutil.ReadFile(filename)
if err != nil {
return
if jsonRawTx, err = ioutil.ReadFile(filename); err != nil {
return appGenTxs, persistentPeers, err
}
var genStdTx auth.StdTx
err = cdc.UnmarshalJSON(jsonRawTx, &genStdTx)
if err != nil {
return
if err = cdc.UnmarshalJSON(jsonRawTx, &genStdTx); err != nil {
return appGenTxs, persistentPeers, err
}
appGenTxs = append(appGenTxs, genStdTx)
nodeAddr := genStdTx.GetMemo()
if len(nodeAddr) == 0 {
err = fmt.Errorf("couldn't find node's address in %s", fo.Name())
return
// the memo flag is used to store
// the ip and node-id, for example this may be:
// "528fd3df22b31f4969b05652bfe8f0fe921321d5@192.168.2.37:26656"
nodeAddrIP := genStdTx.GetMemo()
if len(nodeAddrIP) == 0 {
return appGenTxs, persistentPeers, fmt.Errorf(
"couldn't find node's address and IP in %s", fo.Name())
}
// genesis transactions must be single-message
msgs := genStdTx.GetMsgs()
if len(msgs) != 1 {
err = errors.New("each genesis transaction must provide a single genesis message")
return
return appGenTxs, persistentPeers, errors.New(
"each genesis transaction must provide a single genesis message")
}
// TODO: this could be decoupled from stake.MsgCreateValidator
// TODO: and we likely want to do it for real world Gaia
// validate the validator address and funds against the accounts in the state
msg := msgs[0].(stake.MsgCreateValidator)
validators = append(validators, tmtypes.GenesisValidator{
PubKey: msg.PubKey,
Power: freeFermionVal,
Name: msg.Description.Moniker,
})
addr := string(sdk.AccAddress(msg.ValidatorAddr))
acc, ok := addrMap[addr]
if !ok {
return appGenTxs, persistentPeers, fmt.Errorf(
"account %v not in genesis.json: %+v", addr, addrMap)
}
if acc.Coins.AmountOf(msg.Delegation.Denom).LT(msg.Delegation.Amount) {
err = fmt.Errorf("insufficient fund for the delegation: %s < %s",
acc.Coins.AmountOf(msg.Delegation.Denom), msg.Delegation.Amount)
}
// exclude itself from persistent peers
if msg.Description.Moniker != moniker {
addresses = append(addresses, nodeAddr)
addressesIPs = append(addressesIPs, nodeAddrIP)
}
}
sort.Strings(addresses)
persistentPeers = strings.Join(addresses, ",")
sort.Strings(addressesIPs)
persistentPeers = strings.Join(addressesIPs, ",")
return
return appGenTxs, persistentPeers, nil
}
func NewDefaultGenesisAccount(addr sdk.AccAddress) GenesisAccount {
+33 -11
View File
@@ -1,11 +1,13 @@
package app
import (
"encoding/json"
"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"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/stake"
stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types"
"github.com/stretchr/testify/require"
@@ -27,7 +29,8 @@ var (
func makeGenesisState(t *testing.T, genTxs []auth.StdTx) GenesisState {
// start with the default staking genesis state
stakeData := stake.DefaultGenesisState()
appState := NewDefaultGenesisState()
stakeData := appState.StakeData
genAccs := make([]GenesisAccount, len(genTxs))
for i, genTx := range genTxs {
@@ -35,17 +38,15 @@ func makeGenesisState(t *testing.T, genTxs []auth.StdTx) GenesisState {
require.Equal(t, 1, len(msgs))
msg := msgs[0].(stake.MsgCreateValidator)
// get genesis flag account information
genAccs[i] = genesisAccountFromMsgCreateValidator(msg, freeFermionsAcc)
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
acc := auth.NewBaseAccountWithAddress(sdk.AccAddress(msg.ValidatorAddr))
acc.Coins = sdk.Coins{sdk.NewInt64Coin(bondDenom, 150)}
genAccs[i] = NewGenesisAccount(&acc)
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDec(150)) // increase the supply
}
// create the final app state
return GenesisState{
Accounts: genAccs,
StakeData: stakeData,
GovData: gov.DefaultGenesisState(),
}
appState.Accounts = genAccs
return appState
}
func TestToAccount(t *testing.T) {
@@ -68,6 +69,19 @@ func TestGaiaAppGenTx(t *testing.T) {
func TestGaiaAppGenState(t *testing.T) {
cdc := MakeCodec()
_ = cdc
var genDoc tmtypes.GenesisDoc
// test unmarshalling error
_, err := GaiaAppGenState(cdc, genDoc, []json.RawMessage{})
require.Error(t, err)
appState := makeGenesisState(t, []auth.StdTx{})
genDoc.AppState, err = json.Marshal(appState)
require.NoError(t, err)
// test validation error
_, err = GaiaAppGenState(cdc, genDoc, []json.RawMessage{})
require.Error(t, err)
// TODO test must provide at least genesis transaction
// TODO test with both one and two genesis transactions:
@@ -77,7 +91,8 @@ 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("steak", 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, "")
}
@@ -106,3 +121,10 @@ func TestGaiaGenesisValidation(t *testing.T) {
err = GaiaValidateGenesisState(genesisState)
require.NotNil(t, err)
}
func TestNewDefaultGenesisAccount(t *testing.T) {
addr := secp256k1.GenPrivKeySecp256k1([]byte("")).PubKey().Address()
acc := NewDefaultGenesisAccount(sdk.AccAddress(addr))
require.Equal(t, sdk.NewInt(1000), acc.Coins.AmountOf("fooToken"))
require.Equal(t, sdk.NewInt(150), acc.Coins.AmountOf(bondDenom))
}
+65 -13
View File
@@ -8,6 +8,7 @@ import (
"math/rand"
"os"
"testing"
"time"
"github.com/stretchr/testify/require"
@@ -50,42 +51,93 @@ func init() {
func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
var genesisAccounts []GenesisAccount
amt := int64(10000)
amount := int64(r.Intn(1e6))
numInitiallyBonded := int64(r.Intn(250))
numAccs := int64(len(accs))
if numInitiallyBonded > numAccs {
numInitiallyBonded = numAccs
}
fmt.Printf("Selected randomly generated parameters for simulated genesis: {amount of steak per account: %v, initially bonded validators: %v}\n", amount, numInitiallyBonded)
// Randomly generate some genesis accounts
for _, acc := range accs {
coins := sdk.Coins{sdk.Coin{"steak", sdk.NewInt(amt)}}
coins := sdk.Coins{sdk.Coin{"steak", sdk.NewInt(amount)}}
genesisAccounts = append(genesisAccounts, GenesisAccount{
Address: acc.Address,
Coins: coins,
})
}
// Default genesis state
govGenesis := gov.DefaultGenesisState()
stakeGenesis := stake.DefaultGenesisState()
slashingGenesis := slashing.DefaultGenesisState()
// Random genesis states
govGenesis := gov.GenesisState{
StartingProposalID: int64(r.Intn(100)),
DepositProcedure: gov.DepositProcedure{
MinDeposit: sdk.Coins{sdk.NewInt64Coin("steak", int64(r.Intn(1e3)))},
MaxDepositPeriod: time.Duration(r.Intn(2*172800)) * time.Second,
},
VotingProcedure: gov.VotingProcedure{
VotingPeriod: time.Duration(r.Intn(2*172800)) * time.Second,
},
TallyingProcedure: gov.TallyingProcedure{
Threshold: sdk.NewDecWithPrec(5, 1),
Veto: sdk.NewDecWithPrec(334, 3),
GovernancePenalty: sdk.NewDecWithPrec(1, 2),
},
}
fmt.Printf("Selected randomly generated governance parameters: %+v\n", govGenesis)
stakeGenesis := stake.GenesisState{
Pool: stake.InitialPool(),
Params: stake.Params{
UnbondingTime: time.Duration(r.Intn(60*60*24*3*2)) * time.Second,
MaxValidators: uint16(r.Intn(250)),
BondDenom: "steak",
},
}
fmt.Printf("Selected randomly generated staking parameters: %+v\n", stakeGenesis)
slashingGenesis := slashing.GenesisState{
Params: slashing.Params{
MaxEvidenceAge: stakeGenesis.Params.UnbondingTime,
DoubleSignUnbondDuration: time.Duration(r.Intn(60*60*24)) * time.Second,
SignedBlocksWindow: int64(r.Intn(1000)),
DowntimeUnbondDuration: time.Duration(r.Intn(86400)) * time.Second,
MinSignedPerWindow: sdk.NewDecWithPrec(int64(r.Intn(10)), 1),
SlashFractionDoubleSign: sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(50) + 1))),
SlashFractionDowntime: sdk.NewDec(1).Quo(sdk.NewDec(int64(r.Intn(200) + 1))),
},
}
fmt.Printf("Selected randomly generated slashing parameters: %+v\n", slashingGenesis)
mintGenesis := mint.GenesisState{
Minter: mint.Minter{
InflationLastTime: time.Unix(0, 0),
Inflation: sdk.NewDecWithPrec(int64(r.Intn(99)), 2),
},
Params: mint.Params{
MintDenom: "steak",
InflationRateChange: sdk.NewDecWithPrec(int64(r.Intn(99)), 2),
InflationMax: sdk.NewDecWithPrec(20, 2),
InflationMin: sdk.NewDecWithPrec(7, 2),
GoalBonded: sdk.NewDecWithPrec(67, 2),
},
}
fmt.Printf("Selected randomly generated minting parameters: %v\n", mintGenesis)
var validators []stake.Validator
var delegations []stake.Delegation
// XXX Try different numbers of initially bonded validators
numInitiallyBonded := int64(50)
valAddrs := make([]sdk.ValAddress, numInitiallyBonded)
for i := 0; i < int(numInitiallyBonded); i++ {
valAddr := sdk.ValAddress(accs[i].Address)
valAddrs[i] = valAddr
validator := stake.NewValidator(valAddr, accs[i].PubKey, stake.Description{})
validator.Tokens = sdk.NewDec(amt)
validator.DelegatorShares = sdk.NewDec(amt)
delegation := stake.Delegation{accs[i].Address, valAddr, sdk.NewDec(amt), 0}
validator.Tokens = sdk.NewDec(amount)
validator.DelegatorShares = sdk.NewDec(amount)
delegation := stake.Delegation{accs[i].Address, valAddr, sdk.NewDec(amount), 0}
validators = append(validators, validator)
delegations = append(delegations, delegation)
}
stakeGenesis.Pool.LooseTokens = sdk.NewDec(amt*250 + (numInitiallyBonded * amt))
stakeGenesis.Pool.LooseTokens = sdk.NewDec((amount * numAccs) + (numInitiallyBonded * amount))
stakeGenesis.Validators = validators
stakeGenesis.Bonds = delegations
mintGenesis := mint.DefaultGenesisState()
genesis := GenesisState{
Accounts: genesisAccounts,
+35 -6
View File
@@ -5,9 +5,11 @@ package clitest
import (
"encoding/json"
"fmt"
"github.com/tendermint/tendermint/types"
"io/ioutil"
"os"
"path"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
@@ -207,7 +209,7 @@ func TestGaiaCLIGasAuto(t *testing.T) {
func TestGaiaCLICreateValidator(t *testing.T) {
chainID, servAddr, port := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)
flags := fmt.Sprintf("--home=%s --chain-id=%v --node=%s", gaiacliHome, chainID, servAddr)
// start gaiad server
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr))
@@ -548,7 +550,7 @@ func TestGaiaCLIConfig(t *testing.T) {
servAddr, port, err := server.FreeTCPAddr()
require.NoError(t, err)
node := fmt.Sprintf("%s:%s", servAddr, port)
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome))
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --moniker=foo --home=%s", gaiadHome))
executeWrite(t, fmt.Sprintf("gaiacli --home=%s config", gaiadHome), gaiacliHome, node, "y")
config, err := ioutil.ReadFile(path.Join(gaiacliHome, "config", "config.toml"))
require.NoError(t, err)
@@ -598,12 +600,27 @@ func initializeFixtures(t *testing.T) (chainID, servAddr, port string) {
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe-reset-all", gaiadHome), "")
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass)
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass)
chainID = executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome))
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s foo", gaiacliHome), app.DefaultKeyPass)
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass)
fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf(
"gaiacli keys show foo --output=json --home=%s", gaiacliHome))
chainID = executeInit(t, fmt.Sprintf("gaiad init -o --moniker=foo --home=%s", gaiadHome))
genFile := filepath.Join(gaiadHome, "config", "genesis.json")
genDoc := readGenesisFile(t, genFile)
var appState app.GenesisState
err := codec.Cdc.UnmarshalJSON(genDoc.AppState, &appState)
require.NoError(t, err)
appState.Accounts = []app.GenesisAccount{app.NewDefaultGenesisAccount(fooAddr)}
appStateJSON, err := codec.Cdc.MarshalJSON(appState)
require.NoError(t, err)
genDoc.AppState = appStateJSON
genDoc.SaveAs(genFile)
executeWrite(t, fmt.Sprintf(
"gaiad gentx --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome),
app.DefaultKeyPass)
executeWrite(t, fmt.Sprintf("gaiad collect-gentxs --home=%s", gaiadHome), app.DefaultKeyPass)
// get a free port, also setup some common flags
servAddr, port, err := server.FreeTCPAddr()
servAddr, port, err = server.FreeTCPAddr()
require.NoError(t, err)
return
}
@@ -622,6 +639,18 @@ func writeToNewTempFile(t *testing.T, s string) *os.File {
return fp
}
func readGenesisFile(t *testing.T, genFile string) types.GenesisDoc {
var genDoc types.GenesisDoc
fp, err := os.Open(genFile)
require.NoError(t, err)
fileContents, err := ioutil.ReadAll(fp)
require.NoError(t, err)
defer fp.Close()
err = codec.Cdc.UnmarshalJSON(fileContents, &genDoc)
require.NoError(t, err)
return genDoc
}
//___________________________________________________________________________________
// executors
+2 -1
View File
@@ -39,7 +39,8 @@ func main() {
}
appInit := app.GaiaAppInit()
rootCmd.AddCommand(gaiaInit.InitCmd(ctx, cdc, appInit))
rootCmd.AddCommand(gaiaInit.TestnetFilesCmd(ctx, cdc, appInit))
rootCmd.AddCommand(gaiaInit.CollectGenTxsCmd(ctx, cdc))
rootCmd.AddCommand(gaiaInit.TestnetFilesCmd(ctx, cdc, server.AppInit{}))
rootCmd.AddCommand(gaiaInit.GenTxCmd(ctx, cdc))
server.AddCommands(ctx, cdc, rootCmd, appInit,
+1 -1
View File
@@ -220,7 +220,7 @@ func runTxCmd(cmd *cobra.Command, args []string) error {
var tx = auth.StdTx{}
cdc := gaia.MakeCodec()
err = cdc.UnmarshalBinary(txBytes, &tx)
err = cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx)
if err != nil {
return err
}
+119
View File
@@ -0,0 +1,119 @@
package init
import (
"encoding/json"
"io/ioutil"
"path/filepath"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server"
"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"
"github.com/tendermint/tendermint/types"
)
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
}
toPrint := printInfo{
Moniker: config.Moniker,
ChainID: genDoc.ChainID,
NodeID: nodeID,
}
initCfg := initConfig{
ChainID: genDoc.ChainID,
GenTxsDir: filepath.Join(config.RootDir, "config", "gentx"),
Name: name,
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)
},
}
cmd.Flags().String(cli.HomeFlag, app.DefaultNodeHome, "node's home directory")
return cmd
}
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
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.GaiaAppGenStateJSON(cdc, genDoc, genTxs)
if err != nil {
return
}
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
}
+34 -10
View File
@@ -55,9 +55,20 @@ following delegation and commission default parameters:
if err != nil {
return err
}
genDoc, err := loadGenesisDoc(cdc, config.GenesisFile())
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
}
}
// Run gaiad tx create-validator
prepareFlagsForTxCreateValidator(config, nodeID, ip, valPubKey)
prepareFlagsForTxCreateValidator(config, nodeID, ip, genDoc.ChainID, valPubKey)
createValidatorCmd := cli.GetCmdCreateValidator(cdc)
w, err := ioutil.TempFile("", "gentx")
@@ -82,28 +93,41 @@ following delegation and commission default parameters:
},
}
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.FlagChainID, "", "genesis file chain-id")
cmd.Flags().String(client.FlagName, "", "name of private key with which to sign the gentx")
cmd.Flags().AddFlagSet(cli.FsCommissionCreate)
cmd.Flags().AddFlagSet(cli.FsAmount)
cmd.Flags().AddFlagSet(cli.FsPk)
cmd.MarkFlagRequired(client.FlagName)
return cmd
}
func prepareFlagsForTxCreateValidator(config *cfg.Config, nodeID, ip string, valPubKey crypto.PubKey) {
viper.Set(tmcli.HomeFlag, viper.GetString(flagClientHome)) // --home
func prepareFlagsForTxCreateValidator(config *cfg.Config, nodeID, ip, chainID string,
valPubKey crypto.PubKey) {
viper.Set(tmcli.HomeFlag, viper.GetString(flagClientHome)) // --home
viper.Set(client.FlagChainID, chainID)
viper.Set(client.FlagFrom, viper.GetString(client.FlagName)) // --from
viper.Set(cli.FlagNodeID, nodeID) // --node-id
viper.Set(cli.FlagIP, ip) // --ip
viper.Set(cli.FlagPubKey, sdk.MustBech32ifyConsPub(valPubKey)) // --pubkey
viper.Set(cli.FlagAmount, defaultAmount) // --amount
viper.Set(cli.FlagCommissionRate, defaultCommissionRate)
viper.Set(cli.FlagCommissionMaxRate, defaultCommissionMaxRate)
viper.Set(cli.FlagCommissionMaxChangeRate, defaultCommissionMaxChangeRate)
viper.Set(cli.FlagGenesisFormat, true) // --genesis-format
viper.Set(cli.FlagMoniker, config.Moniker) // --moniker
viper.Set(cli.FlagGenesisFormat, true) // --genesis-format
viper.Set(cli.FlagMoniker, config.Moniker) // --moniker
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)
}
}
func prepareFlagsForTxSign() {
+35 -166
View File
@@ -2,24 +2,19 @@ package init
import (
"encoding/json"
"errors"
"fmt"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
"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/crypto"
"github.com/tendermint/tendermint/privval"
"os"
"path/filepath"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
"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"
@@ -27,26 +22,11 @@ import (
)
const (
flagWithTxs = "with-txs"
flagOverwrite = "overwrite"
flagClientHome = "home-client"
flagOverwriteKey = "overwrite-key"
flagSkipGenesis = "skip-genesis"
flagMoniker = "moniker"
flagOverwrite = "overwrite"
flagClientHome = "home-client"
flagMoniker = "moniker"
)
type initConfig struct {
ChainID string
GenTxsDir string
Name string
NodeID string
ClientHome string
WithTxs bool
Overwrite bool
OverwriteKey bool
ValPubKey crypto.PubKey
}
type printInfo struct {
Moniker string `json:"moniker"`
ChainID string `json:"chain_id"`
@@ -70,22 +50,16 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
cmd := &cobra.Command{
Use: "init",
Short: "Initialize private validator, p2p, genesis, and application configuration files",
Long: `Initialize validators's and node's configuration files.
Note that only node's configuration files will be written if the flag --skip-genesis is
enabled, and the genesis file will not be generated.
`,
Args: cobra.NoArgs,
Long: `Initialize validators's and node's configuration files.`,
Args: cobra.NoArgs,
RunE: func(_ *cobra.Command, _ []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(cli.HomeFlag))
name := viper.GetString(client.FlagName)
chainID := viper.GetString(client.FlagChainID)
if chainID == "" {
chainID = fmt.Sprintf("test-chain-%v", common.RandStr(6))
}
nodeID, valPubKey, err := InitializeNodeValidatorFiles(config)
nodeID, _, err := InitializeNodeValidatorFiles(config)
if err != nil {
return err
}
@@ -93,37 +67,26 @@ enabled, and the genesis file will not be generated.
if viper.GetString(flagMoniker) != "" {
config.Moniker = viper.GetString(flagMoniker)
}
if config.Moniker == "" && name != "" {
config.Moniker = name
}
toPrint := printInfo{
ChainID: chainID,
Moniker: config.Moniker,
NodeID: nodeID,
}
if viper.GetBool(flagSkipGenesis) {
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
return displayInfo(cdc, toPrint)
}
initCfg := initConfig{
ChainID: chainID,
GenTxsDir: filepath.Join(config.RootDir, "config", "gentx"),
Name: name,
NodeID: nodeID,
ClientHome: viper.GetString(flagClientHome),
WithTxs: viper.GetBool(flagWithTxs),
Overwrite: viper.GetBool(flagOverwrite),
OverwriteKey: viper.GetBool(flagOverwriteKey),
ValPubKey: valPubKey,
var appState json.RawMessage
genFile := config.GenesisFile()
if appState, err = initializeEmptyGenesis(cdc, genFile, chainID,
viper.GetBool(flagOverwrite)); err != nil {
return err
}
appMessage, err := initWithConfig(cdc, config, initCfg)
// print out some key information
if err != nil {
if err = WriteGenesisFile(genFile, chainID, nil, appState); err != nil {
return err
}
toPrint.AppMessage = appMessage
toPrint := printInfo{
ChainID: chainID,
Moniker: config.Moniker,
NodeID: nodeID,
AppMessage: appState,
}
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
return displayInfo(cdc, toPrint)
},
}
@@ -131,12 +94,7 @@ enabled, and the genesis file will not be generated.
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")
cmd.Flags().Bool(flagWithTxs, false, "apply existing genesis transactions from [--home]/config/gentx/")
cmd.Flags().String(client.FlagName, "", "name of private key with which to sign the gentx")
cmd.Flags().String(flagMoniker, "", "overrides --name flag and set the validator's moniker to a different value; ignored if it runs without the --with-txs flag")
cmd.Flags().String(flagClientHome, app.DefaultCLIHome, "client's home directory")
cmd.Flags().Bool(flagOverwriteKey, false, "overwrite client's key")
cmd.Flags().Bool(flagSkipGenesis, false, "do not create genesis.json")
cmd.Flags().String(flagMoniker, "", "set the validator's moniker")
return cmd
}
@@ -151,105 +109,6 @@ func InitializeNodeValidatorFiles(config *cfg.Config) (nodeID string, valPubKey
return
}
func initWithConfig(cdc *codec.Codec, config *cfg.Config, initCfg initConfig) (
appMessage json.RawMessage, err error) {
genFile := config.GenesisFile()
if !initCfg.Overwrite && common.FileExists(genFile) {
err = fmt.Errorf("genesis.json file already exists: %v", genFile)
return
}
// process genesis transactions, else create default genesis.json
var appGenTxs []auth.StdTx
var persistentPeers string
var genTxs []json.RawMessage
var appState json.RawMessage
var jsonRawTx json.RawMessage
chainID := initCfg.ChainID
if initCfg.WithTxs {
_, appGenTxs, persistentPeers, err = app.CollectStdTxs(config.Moniker, initCfg.GenTxsDir, cdc)
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
}
} else {
var ip, keyPass, secret string
var addr sdk.AccAddress
var signedTx auth.StdTx
if initCfg.Name == "" {
err = errors.New("must specify validator's moniker (--name)")
return
}
config.Moniker = initCfg.Name
ip, err = server.ExternalIP()
if err != nil {
return
}
memo := fmt.Sprintf("%s@%s:26656", initCfg.NodeID, ip)
buf := client.BufferStdin()
prompt := fmt.Sprintf("Password for account %q (default: %q):", initCfg.Name, 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
}
if keyPass == "" {
keyPass = app.DefaultKeyPass
}
addr, secret, err = server.GenerateSaveCoinKey(initCfg.ClientHome, initCfg.Name, keyPass, initCfg.OverwriteKey)
if err != nil {
return
}
appMessage, err = json.Marshal(map[string]string{"secret": secret})
if err != nil {
return
}
msg := stake.NewMsgCreateValidator(
sdk.ValAddress(addr),
initCfg.ValPubKey,
sdk.NewInt64Coin("steak", 100),
stake.NewDescription(config.Moniker, "", "", ""),
stake.NewCommissionMsg(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
)
txBldr := authtx.NewTxBuilderFromCLI().WithCodec(cdc).WithMemo(memo).WithChainID(chainID)
signedTx, err = txBldr.SignStdTx(
initCfg.Name, keyPass, auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, []auth.StdSignature{}, memo), false,
)
if err != nil {
return
}
jsonRawTx, err = cdc.MarshalJSON(signedTx)
if err != nil {
return
}
genTxs = []json.RawMessage{jsonRawTx}
}
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
appState, err = app.GaiaAppGenStateJSON(cdc, genTxs)
if err != nil {
return
}
err = WriteGenesisFile(genFile, chainID, nil, appState)
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
@@ -279,3 +138,13 @@ func ReadOrCreatePrivValidator(privValFile string) crypto.PubKey {
}
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())
}
-1
View File
@@ -42,7 +42,6 @@ func setupClientHome(t *testing.T) func() {
clientDir, err := ioutil.TempDir("", "mock-sdk-cmd")
require.Nil(t, err)
viper.Set(flagClientHome, clientDir)
viper.Set(flagOverwriteKey, true)
return func() {
if err := os.RemoveAll(clientDir); err != nil {
// TODO: Handle with #870
+52 -15
View File
@@ -10,6 +10,7 @@ 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"
@@ -35,7 +36,9 @@ var (
const nodeDirPerm = 0755
// get cmd to initialize all files for tendermint testnet and application
func TestnetFilesCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cobra.Command {
func TestnetFilesCmd(ctx *server.Context, cdc *codec.Codec,
appInit server.AppInit) *cobra.Command {
cmd := &cobra.Command{
Use: "testnet",
Short: "Initialize files for a Gaiad testnet",
@@ -50,7 +53,7 @@ Example:
`,
RunE: func(_ *cobra.Command, _ []string) error {
config := ctx.Config
return testnetWithConfig(config, cdc, appInit)
return testnetWithConfig(config, cdc)
},
}
cmd.Flags().Int(nValidators, 4,
@@ -69,7 +72,7 @@ Example:
return cmd
}
func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppInit) error {
func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error {
outDir := viper.GetString(outputDir)
numValidators := viper.GetInt(nValidators)
@@ -80,6 +83,8 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppI
valPubKeys := make([]crypto.PubKey, numValidators)
// Generate private key, node ID, initial transaction
var accs []app.GenesisAccount
var genFiles []string
for i := 0; i < numValidators; i++ {
nodeDirName := fmt.Sprintf("%s%d", viper.GetString(nodeDirPrefix), i)
nodeDaemonHomeName := viper.GetString(nodeDaemonHome)
@@ -115,8 +120,12 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppI
}
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
// write genesis
genFiles = append(genFiles, config.GenesisFile())
buf := client.BufferStdin()
prompt := fmt.Sprintf("Password for account '%s' (default %s):", nodeDirName, app.DefaultKeyPass)
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
@@ -138,12 +147,20 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppI
if err != nil {
return err
}
// Save private key seed words
// save private key seed words
err = writeFile(fmt.Sprintf("%v.json", "key_seed"), clientDir, cliPrint)
if err != nil {
return err
}
accs = append(accs, app.GenesisAccount{
Address: addr,
Coins: sdk.Coins{
sdk.NewInt64Coin(fmt.Sprintf("%sToken", nodeDirName), 1000),
sdk.NewInt64Coin("steak", 150),
},
})
msg := stake.NewMsgCreateValidator(
sdk.ValAddress(addr),
valPubKeys[i],
@@ -173,8 +190,27 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppI
}
}
for i := 0; i < numValidators; i++ {
// Generate empty genesis.json
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
for i := 0; i < numValidators; i++ {
if err := genDoc.SaveAs(genFiles[i]); err != nil {
return err
}
}
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)
@@ -186,16 +222,17 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec, appInit server.AppI
nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
// Run `init` and generate genesis.json and config.toml
initCfg := initConfig{
ChainID: chainID,
GenTxsDir: gentxsDir,
Name: moniker,
WithTxs: true,
Overwrite: true,
OverwriteKey: false,
NodeID: nodeID,
ValPubKey: valPubKey,
ChainID: chainID,
GenTxsDir: gentxsDir,
Name: moniker,
NodeID: nodeID,
ValPubKey: valPubKey,
}
if _, err := initWithConfig(cdc, config, initCfg); err != nil {
genDoc, err := loadGenesisDoc(cdc, config.GenesisFile())
if err != nil {
return err
}
if _, err := genAppStateFromConfig(cdc, config, initCfg, genDoc); err != nil {
return err
}
}