Merge branch 'develop' into sunny/get_all_delegations_validator_querier
This commit is contained in:
+11
-8
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user